Добавление фото пользователю с использованием MODX Login

Добавление фото пользователю с использованием MODX Login
Содержание:
  1. Требования
  2. Создание папки для файлов
  3. Изменение содержимого ресурса для обновления данных пользователя
  4. Хук для обновления фото пользователя
  5. Комментарии

В этой статье добавим пользователям возможность устанавливать фото профиля для CMS MODX с использованием расширения Login.

Требования

Возможность добавления фотографии пользователям осуществим в ресурсе «Редактирование данных».

Перед тем как переходить к изучению этой статьи необходимо выполнить все действия, описанные в этих статьях:

  1. Регистрация пользователей
  2. Авторизация пользователей
  3. Личный кабинет пользователя

Все эти статьи основаны на расширении Login.

Создание папки для файлов

Процесс добавления нового функционала начнём с выполнения простых вещей:

  1. Создания папки img-users в assets. В ней будем хранить фото (аватарки) пользователей.
  2. Загрузки в эту папку изображения default.svg, которое будет иметь пользователь по умолчанию.

Хранить аватарки будем в разрешении 100x100.

Изменение содержимого ресурса для обновления данных пользователя

Откроем ресурс «Редактирование данных»:

Изменение содержимого ресурса, содержащего вызов спиппета UpdateProfile, предназначенного для обновления профиля пользователя с использованием MODX Login

Внесём в его содержимое следующие изменения:

1. Добавим в вызов сниппета UpdateProfile параметр preHooks и укажем в качестве значения сниппет hookProfileUpdatePhoto. С помощью него мы будем изменять поле photo в профиле пользователя. Выполнять действия hookProfileUpdatePhoto будет выполнять до обновления профиля пользователя, но после проверки полей формы:

[[!UpdateProfile?
  &validate=`fullname:required`
  &reloadOnSuccess=`1`
  &preHooks=`hookProfileUpdatePhoto`
]]

2. Изменим HTML форму:

<div class="container pt-3">
  <div class="card text-dark bg-white mx-auto mb-3" style="max-width: 30rem;">
    <div class="card-header">Редактирование данных</div>
    <div class="card-body">
      <!-- форма, содержащая кнопку для удаления фото -->
      [[+photo:notempty=`<form class="form" action="[[~[[*id]]]]" method="post">
        <div class="mb-3 text-end">
          <input type="hidden" name="remove-photo">
          <input type="hidden" name="fullname" value="[[+fullname]]">
          <input type="submit" class="btn btn-danger" value="Удалить фото" name="login-updprof-btn" id="login-updprof-btn">
        </div>
      </form>`]]
      <div class="mb-3">
        <img src="[[+photo:default=`/assets/img-users/default.svg`]]" class="rounded-circle mx-auto mb-2 d-block" id="photouser" alt="[[+email]]" width="100" height="100" style="object-fit: cover;">
        <div class="fw-bold text-center">[[+email]]</div>
      </div>

      [[+login.update_success:is=`1`:then=`<div class="alert alert-success" role="alert">[[%login.profile_updated? &namespace=`login` &topic=`updateprofile`]]</div>`:else=`[[+error.message:notempty=`<div class="updprof-error alert alert-danger" role="alert">[[+error.message]]</div>`]]`]]
      <form class="form" action="[[~[[*id]]]]" method="post" enctype="multipart/form-data">
        <input type="hidden" name="nospam" value="">
        <div class="mb-3">
          <label for="fullname" class="form-label">[[!%login.fullname? &namespace=`login` &topic=`updateprofile`]]</label>
          <input type="text" name="fullname" class="form-control[[+error.fullname:notempty=` is-invalid`]]" id="fullname" value="[[+fullname]]">
          <div class="invalid-feedback">[[+error.fullname]]</div>
        </div>
        <!-- блок, содержащий поле photo, с помощью которого будем загружать фото -->
        <div class="mb-3">
          <label for="photo" class="form-label">Фото</label>
          <input type="file" id="photo" name="photo" class="form-control">
          <div class="invalid-feedback"></div>
        </div>
        <div class="mb-3">
          <label for="phone" class="form-label">[[!%login.phone]]</label>
          <input type="text" name="phone" class="form-control[[+error.phone:notempty=` is-invalid`]]" id="phone" value="[[+phone]]">
          <div class="invalid-feedback">[[+error.phone]]</div>
        </div>
        <div class="mb-3">
          <label for="country" class="form-label">[[!%login.country]]</label>
          <input type="text" name="country" class="form-control[[+error.country:notempty=` is-invalid`]]" id="country" value="[[+country]]">
          <div class="invalid-feedback">[[+error.country]]</div>
        </div>
        <div class="mb-3">
          <label for="website" class="form-label">[[!%login.website]]</label>
          <input type="text" name="website" class="form-control[[+error.website:notempty=` is-invalid`]]" id="website" value="[[+website]]">
          <div class="invalid-feedback">[[+error.website]]</div>
        </div>
        <input type="submit" class="btn btn-primary" value="Обновить профиль" name="login-updprof-btn" id="login-updprof-btn">
      </form>
    </div>
  </div>
</div>
Обновленная форма, содержащее поле для добавления фото пользователю с использованием CMS MODX Login

В этом коде форма написана с использованием Bootstrap Forms.

Перед формой, как видно, добавлено <img> для вывода фото пользователя и его email. При отсутствия аватарки, в качестве изображения используется файл default.svg. Для его установки таким образом используется MODX фильтр default:

<img src="[[+photo:default=`/assets/img-users/default.svg`]]" class="rounded-circle mx-auto mb-2 d-block" id="photouser" alt="[[+email]]" width="100" height="100" style="object-fit: cover;">

Удаление фото осуществляется с использованием отдельной формы:

[[+photo:notempty=`<form class="form" action="[[~[[*id]]]]" method="post">
  <div class="mb-3 text-end">
    <input type="hidden" name="remove-photo">
    <input type="hidden" name="fullname" value="[[+fullname]]">
    <input type="submit" class="btn btn-danger" value="Удалить фото" name="login-updprof-btn" id="login-updprof-btn">
  </div>
</form>`]]

Добавление возможности прикрепления к основной форме файла осуществляется посредством:

  • добавления к тегу <form> атрибута enctype со значением "multipart/form-data";
  • добавления тега <input type="file" id="photo" name="photo">.

Для предварительного отображения аватарки напишем JavaScript. Чтение содержимого файла выполним с помощью FileReader:

// при изменении значения элемента #photo
document.querySelector('#photo').onchange = (e) => {
  // удалим у элемента класс is-invalid
  e.target.classList.remove('is-invalid');
  // если браузер не поддерживает FileReader, то прекращаем дальнейшие действия
  if (!window.FileReader) {
    console.log('Браузер не поддерживает File API');
    return;
  }
  // получаем выбранный файл
  const file = e.target.files[0];
  // выводим сообщение, если файл не является png или jpeg
  if (!((file.type == 'image/png') || (file.type == 'image/jpeg'))) {
    e.target.classList.add('is-invalid');
    e.target.nextSibling.textContent = 'Загруженный файл не является png или jpeg.';
    return;
  }
  // создаём экземпляр объекта FileReader, посредством которого будем читать файл
  const reader = new FileReader();
  // после успешного завершения чтения файла
  reader.onload = (e) => {
    // указываем в качестве значения атрибута src прочитанный файл
    document.querySelector('#photouser').src = e.target.result;
  }
  // запускаем процесс чтения файла
  reader.readAsDataURL(file);
}

В этом коде для получения различных элементов используется JavaScript метод querySelector, а для назначения событий свойство DOM-элемента on{событие}.

Итоговое содержимое ресурса «Редактирование данных» расположено на Github.

Сообщение, которое выводится, когда мы хотим задать пользователю не png или jpeg:

Ошибка при установке изображения для профиля пользователя с использованием MODX Login

Страница профиля, к которой добавлено изображения пользователя:

Профиль пользователя к которому добавлено изображение с использованием MODX Login

Хук для обновления фото пользователя

Создадим сниппет hookProfileUpdatePhoto, который будем использовать в качестве хука в сниппете UpdateProfile.

Изучить, что такое сниппеты и как их создавать можно в этой статье.

Этот хук будет выполнять следующие действия:

  • загружать фото в директорию assets/img-users/;
  • устанавливать значения полю photo с помощью вызова метода $hook->setValue();
  • удалять файл при нажатии в форме на кнопку «Удалить фото».
Сниппет hookProfileUpdatePhoto, который используется в качестве хука в сниппете UpdateProfile для добавления фото пользователю

Содержимое hookProfileUpdatePhoto:

<?php
// разрешённые MIME типы
$allowedMimeTypes = ['jpg' => 'image/jpeg', 'png' => 'image/png'];
// директория для файлов
$path = $modx->config['base_path'] . 'assets/img-users/';
// параметры для создания уменьшенной копии изображения
$params = ['w' => 100, 'h' => 100, 'zc' => 1, 'q' => 80];

// получим профиль пользователя
$profile = $modx->user->getOne('Profile');

// если глобальный массив POST содержит ключ remove-photo
if (isset($_POST['remove-photo'])) {
  // если поле photo не пустое, то..
  if ($profile->get('photo')) {
    // полный имя файла
    $fileFullName = $modx->config['base_path'] . $profile->get('photo');
    // удалим файл
    if (file_exists($fileFullName)) {
      unlink($fileFullName);
    }
    // установим полю photo пустую строку
    $hook->setValue('photo', '');
  }
  return true;
}

// если upload не является файлом
if ($_FILES['photo']['error'] === UPLOAD_ERR_NO_FILE) {
  // установим полю photo текущее значение
  $hook->setValue('photo', $profile->get('photo'));
  return true;
}

// файл, принятый сервером
$fileTmp = $_FILES['photo']['tmp_name'];

// если файл загружен успешно, то
if (!is_uploaded_file($fileTmp) || $_FILES['photo']['error'] !== UPLOAD_ERR_OK) {
  $hook->addError('photo', 'Ошибка при загрузке изображения.');
  return false;
}

// расширение файла
$finfo = new finfo(FILEINFO_MIME_TYPE);
$fileMimeType = $finfo->file($fileTmp);
$fileExt = array_search($fileMimeType, $allowedMimeTypes, true);
if ($fileExt === false) {
  $hook->addError('photo', 'Файл имеет не допустимый формат.');
  return false;
}
// добавим хеш и расширение
$fileName = uniqid() . '.' . $fileExt;
// полное имя файла
$fileFullName = $path . $fileName;
// копируем файл
copy($fileTmp, $fileFullName);
// имя и путь для профиля, поскольку они отличаются из-за медиа-ресурса
$hook->setValue('photo', $modx->getOption('assets_url') . 'img-users/' . $fileName);

// подключим phpthumb.class.php
require_once MODX_CORE_PATH . 'vendor/james-heinrich/phpthumb/phpthumb.class.php';
// в MODX 2.8.x нужно раскомментировать нижнюю строчку и закомментировать верхнюю
// require_once MODX_CORE_PATH.'model/phpthumb/phpthumb.class.php';
// создадим новый экземпляр класса phpThumb
$phpThumb = new phpThumb();
// указываем исходное изображение
$phpThumb->setSourceFilename($fileFullName);
// устанавливаем параметры
foreach($params as $key => $value) {
  $phpThumb->setParameter($key, $value);
}
// генерируем уменьшенное изображение
if ($phpThumb->GenerateThumbnail()) {
  // сохраняем изображение в файл $fullNameFile
  if (!$phpThumb->RenderToFile($fileFullName)) {
    $modx->log(modX::LOG_LEVEL_ERROR, 'Ошибка при сохранении уменьшенного изображения в файл ' . $fileFullName);
  }
} else {
  $modx->log(modX::LOG_LEVEL_ERROR, print_r($phpThumb->debugmessages, 1));
}

return true;

В этом коде используются различные методы MODX для работы с объектами. PHP библиотека, которая предоставляет их называется xPDO. Начать изучение этой библиотеки можно с этой статьи.

Все необходимые файлы и код доступен также на Github.

Комментарии: 54

Reut
Reut

Но, появилась другая проблема....Как удалить аккаунт пользователя окончательно? Чтобы MODX забыл его. И далее, при повторной регистрации этого пользователя, ему снова приходили сообщения на почту при регистрации?

P.s.

Просто сейчас, когда удаляю юзера из группы пользователя, он, как бы, все равно остается в системе и сообщения на почту о регистрации не приходят... Как быть ?
Reut
Reut

Помогите пожалуйста! Не могу найти ответа в сети.

Александр Мальцев
Александр Мальцев

Когда удаляете пользователя из группы, он просто перестаёт быть членом этой группы. В данном случае его необходимо просто удалить из таблицы «Пользователи».

Reut
Reut

Привет. Есть такой вопрос. На странице редактирование данных все круто выводиться, меняется и обновляется. Но на странице Личный кабинет вместо аватарки выводится только путь к фото, как это исправить ? Вывожу через [[+usr.photo]]

[[!Profile? &prefix=usr.]]

<div class="container pt-3">

<div class="card text-dark bg-white mx-auto mb-3" style="max-width: 30rem;">

<div class="card-header">Личный кабинет пользователя</div>

<div class="card-body">

<ul class="list-group">

<li class="list-group-item">Аватар: <span class="fw-bold">[[+usr.photo]]</span></li>

<li class="list-group-item">Полное имя: <span class="fw-bold">[[+usr.fullname]]</span></li>

<li class="list-group-item">Пол: <span class="fw-bold">[[+usr.gender]]</span></li>

<li class="list-group-item">Имя пользователя: <span class="fw-bold">[[+usr.username]]</span></li>

<li class="list-group-item">Телефон: <span class="fw-bold">[[+usr.phone]]</span></li>

<li class="list-group-item">Email: <span class="fw-bold">[[+usr.email]]</span></li>

<li class="list-group-item">Страна: <span class="fw-bold">[[+usr.country]]</span></li>

<li class="list-group-item">Веб-сайт: <span class="fw-bold">[[+usr.website]]</span></li>

<a class="list-group-item list-group-item-primary list-group-item-action" href="[[~153]]">Изменение пароля</a>

<a class="list-group-item list-group-item-primary list-group-item-action" href="[[~154]]">Редактирование данных</a>

</ul>

</div>

</div>

</div>

Reut
Reut

Проблема решена!

biper
biper
Проблема с картинкой… картинка дефолтная отображается штатно, но если делаю «выбор файла» — вылетает «ошибка 500»… При этом картинка в папку «assets/photouser» подгружается — я ее вижу, но поделать ничего не могу… может права какие то нужно на папку установить или разрешение к БД?
Никита Витальевич
Никита Витальевич

// подключим phpthumb.class.php
require_once MODX_CORE_PATH . 'vendor/james-heinrich/phpthumb/phpthumb.class.php';
// в MODX 2.8.x нужно раскомментировать нижнюю строчку и закомментировать верхнюю
// require_once MODX_CORE_PATH.'model/phpthumb/phpthumb.class.php';
// создадим новый экземпляр класса phpThumb
Почитайте внимательнее. Я тоже сразу не заметил, только на этой странице есть такой комментарий, а с гитхаба брал код — там нет такого.
Reut
Reut

Доброго времени суток. Подскажите, получилось решить проблему? У меня ситуация аналогичная....

Александр Мальцев
Александр Мальцев

Привет! По простому из-за чего вылетает «ошибка 500» можно определить очень просто. Сначала закомментируй все строчки кода. Потом разкомментируй первую строчку и проверь. Если всё хорошо и ошибки 500 нет, то переходи к разкомментированию следующей и т.д. Если на каком-то шаге в этом процессе вылетит ошибка 500, то последняя строчка и будет этому причиной. Только внимательно для инструкций if. Если найдёте эту строчку, то тогда уже можно будет подсказать из-за чего это и как можно исправить.

Егор
Егор
В снипите loadUserPhoto картинка постояно улетала в кэш браузера так как имела одно и тоже название. решил, проблему, поправив код id заменил на time() теперь у нас всегда будут уникальные имена у аватарок

$nameFilePhoto = 'user'.$modx->user->get('id'). '_'. time(). '.'. $extFile;
Александр Мальцев
Александр Мальцев
Да, правильно. Также можно вместо time() использовать функцию uniqid(). Она в php предназначена для генерации уникального id.
Amsterdam
Amsterdam
Вот об этом речь:


Почему то источник файлов читает путь от КОРНЯ ПАПКИ, а не от корня сайта, из-за этого путь изображения формируется неверно. Почему так получается?
Amsterdam
Amsterdam
Александр, доброго времени суток

Не подскажешь? Никак не могу разобраться с источником файлов. Создаю свой собственный, указываю в basePath и baseUrlRelative путь до нужной папки, куда планируется грузить файлы. Присваиваю TVшке этот новый источник файлов на вкладке «источник файлов».

Загружаю файл через TV, которая как и надо, открывает нужную папку, указанную в источнике. НО, проблема в том, что этот источник не выстраивает полный путь до файла, а выводит только его название, изза чего вывести его на страницу невозможно.

Почему так получается? Бьюсь уже несколько часов, не могу понять почему такой бред выходит
Александр Мальцев
Александр Мальцев
Доброго!
Кроме basePath источнику файлов нужно ещё задать baseUrl, т.е. URL по которому будет доступен этот источник файлов.
Amsterdam
Amsterdam
Да, так и делается, оба источника идентичны. Однако проблема имеет место быть. Как я понял, в MODx, почему то, так и есть по умолчанию. А различные плагины и сниппеты уже сами подставляют полный путь до файла.

Какая то немного абсурдная система получается, но если я правильно понял, так оно и есть. Рад был бы ошибаться
Александр Мальцев
Александр Мальцев
Мне кажется тут всё логично: URL файла в определённом контексте будет складываться из baseUrl + путь от корня источника файлов до картинки.
Amsterdam
Amsterdam
Ну смотрите:

baseUrl: templates/img/
basePath: templates/img/

В итоге при выборе картинки в файлменеджере она получает путь от корня папки, в которой находится, т.е. в пути высвечивается просто imagename.jpg, без фактического его местоположения: templates/img/imagename.jpg

И как при таком раскладе вывести фото во фронте?
Александр Мальцев
Александр Мальцев
В MODX 2.7.1 таких проблем нет. В шаблоне просто указываем имя TV, на фронте получаем полный путь.
Например:
<img src="[[*image]]" alt="">
У TV в настройках во вкладке «Источники файлов» указывается источник файлов, который будет использован этим TV в каждом указанном контексте. Т.е. при выводе TV в указанном контексте путь до картинки будет составляться из значения baseUrl источника файлов и пути от корня источника файлов до картинки.
Amsterdam
Amsterdam
Да, действительно… Недосмотрел. Это в паре с MIGx происходит вышеописанная проблема. Особенно если выводить таким способом:

"sourceFrom":"config","sources":"[{\"MIGX_id\":\"1\",\"context\":\"web\",\"sourceid\":\"3\"}
Либо упрощенным, когда создаешь специальное TV и задаешь для него источник файлов, тоже не выводится корректно

"inputTV":"image"
Как с ним решить проблему, более интересный вопрос…
Александр Мальцев
Александр Мальцев
При настройке полей в MIGX есть вкладка «Mediasources». Там определяется источник.

Например, если вы создаёте поле «image» c «inputTVType: image», то можно указать источник «migx». А в таблице создать строку, в которой задать, какой id источника файлов использовать для конкретного контекста.
Amsterdam
Amsterdam
Имеете ввиду вот так?:
"field":"image2",
"caption":"Image",
"inputTVtype":"image",
"sourceFrom":"migx",
"sources":"[{\"MIGX_id\":\"1\",\"context\":\"web\",\"sourceid\":\"3\"}]
Где «3» — id источника файлов, присвоенного TV MIGx? Об этом речь (пример на скриншоте), или о какой то другой таблице?

Александр Мальцев
Александр Мальцев
Да, про источник самого файла (скриншот момента, но это когда используется мастер):

Но в качестве sourceid указать id источника файлов, который вы хотите использовать для вывода этого поля (картинки). Не обязательно он должен совпадать с id источника файлов, который используется для самого TV.
Amsterdam
Amsterdam
Интересно, но никак не могу найти, где расположена эта вкладка Mediasources?.. как до нее добраться, в настройках MIGx не вижу
Александр Мальцев
Александр Мальцев
Это вкладка расположена не в разделе где вы создаете TV, а в MIGX. На вкладке «Formtabs», предназначенной для создания полей.
Т.к. вы не используете MIGX мастер, то источник файлов указывается с помощью sourceid, как вы написали выше:
"sourceFrom":"migx", 
"sources":"[{\"MIGX_id\":\"1\",\"context\":\"web\",\"sourceid\":\"3\"}
Сергей
Сергей
Добрый день! Скажите, а как интегрировать Login и Modxtalks, чтобы в комментариях эта фотка присутствовала?
А то сейчас фото только в личном кабинете, а в комментариях стандартная с граватара.
Спасибо
Александр Мальцев
Александр Мальцев
Добрый! Фото сохраняется в стандартное поле photo пользователя. Можете просто написать простенький сниппет, которому на вход будете передавать id пользователя, а на выходе получать url картинки. После этого данный сниппет поместить в чанк и в качестве параметра передавать ему на вход плейсхолдер, содержащий id пользователя.
Дмитрий
Дмитрий
а можно сделать так. чтобы фото само обрабатывалось до нужного размера и формата. если не подошло?
Александр Мальцев
Александр Мальцев
На сервере, это можно, например, выполнить с помощью библиотеки phpthumb.
Константин
Константин
Добрый вечер! Спасибо за данную инструкцию! Есть небольшая проблемка. У меня создан еще один источник файлов Images и в системных настройках выбран по-умолчанию. Значение basePath и baseUrl в нем assets/img/ Отсюда и возникают проблемы.

Дело в том, что когда я загружаю фото, то на самом сайте в профиле пользователя, в комментариях от Tickets, аватарка отображается корректно, но в админке аватарка не отображается, так как не корректно формируются пути к ней из-за выбранного по-умолчанию другого источника файлов:

При каждом обновлении любой страницы в админке, в журнале ошибок появляется по одной такой записи:
[2018-05-19 23:06:59] (ERROR @ /.../public_html/core/model/phpthumb/modphpthumb.class.php : 121) phpThumb was unable to generate a thumbnail for: /.../public_html/core/cache/phpthumb/news.kos076.beget.tech__srce764e99ef2773adcc608592623680f4a_par397327b300e2532553c171cb19a456f3_dat0.jpeg
[2018-05-19 23:06:59] (ERROR @ /.../public_html/core/model/phpthumb/modphpthumb.class.php : 133) Error outputting thumbnail:
OutputThumbnail() failed because !is_resource($this->gdimg_output) in file "phpthumb.class.php" on line 618
Я так понимаю, что phpthumb не может сгенерировать мою аватарку, поэтому она не отображается и сыпятся ошибки.

При загрузке фото, в админке в профиле, там где поле Фотография пользователя, формируется путь к фото /assets/img/photouser/user1-1631743318.png (я немного изменил Ваш сниппет и указал в строке 28 $pathToPhoto = $modx->config['base_path']. 'assets/img/photouser/';), а реальный путь к фото в админке такой /.../public_html/assets/img//assets/img/photouser/user1-1631743318.png, поэтому такая проблема.

Как переделать сниппет, чтобы учитывался любой другой источник файлов и все отображалось корректно? буду благодарен за любую помощь!
Александр Мальцев
Александр Мальцев
Добрый! Для этого необходимо настроить пути. Например: yadi.sk/d/_LwyYrJ43WMChv
Папку photouser в этом случае нужно переместить в /assets/img/.

Константин
Константин
Спасибо, но не получается по Вашему. В админке аватарка теперь отображается, но на сайте ее нет. Путь к изображению на сайте примерно такой:
<img id="img-photo" src="photouser/user1.png">
Естественно, что по такому пути фото нет, так как оно загружается в:
assets/img/photouser/user1.png
Не знаю куда уже и думать. Почему не добавляется часть пути assets/img/, которую я указал в basePath и baseUrl в источнике файлов?
Александр Мальцев
Александр Мальцев
В чанке просто необходимо добавить к картинке часть пути, т.е. /assets/img/.
<img id="img-photo" src="/assets/img/[[+photo:default=`photouser/default.jpg`]]">
Benni
Benni
Такая же проблема. Вместо аватарки в админ-панели вот что (тот же скрин что у комментария выше):

/connectors/system/phpthumb.php?zc=1&h=128&w=128&src=/var/www/.../public_html/domain/assets/files/images/photouser/user1.jpg?1658906912
При этом дефолтный источник файлов —
assets/files/images/
Как добиться такого пути —
/assets/img/photouser/user1.jpg?1658906912
?

P.S.
На самом сайте все хорошо выводится.
Pasha
Pasha
какая полезная статья! очень сократило время, спасибо!

А у вас на сайте используется какое дополнение для регистрации, авторизации и редактирования профиля пользователя?
cheizer
cheizer
Спасибо, работает, но похоже требует много доработок, например таких как задать уникальное имя загружаемого файла, иначе в отчетах ошибки мол файл существует и тд, класть файл в созданную автоматом папку с именем как id пользователя и тд. Так же очищать кеш после отправки формы, иначе старый показывает часто файл. В любом случае спасибо за сниппет.

Но я не об этом хотел спросить, скажите пожалуйста, каким снипетом реализована у вас регистрация пользователей по методу AJAX?
Александр Мальцев
Александр Мальцев
На основе компонента MODX Revolution Office.
Sergey
Sergey
Всё работает кроме одного момента
Когда отправляешь форму с обновленной картинкой, т.е. была какая-то, установил новую и отправил
Сначала, при выборе новой картинки, как и положено JS устанавливает картинку новую, но после отправления формы, страница перегружается и картинка опять старая и нужно рефрешить страницу что бы показалась новая картинка. Видимо берется из кеша.
Как решить проблему?
Sergey
Sergey
Нашел такое решение, надо в снипете в строке, где возвращаем путь до файла, дописать случайный параметр:

$hook->setValue('photo',$modx->getOption('assets_url'). 'photouser/' . $nameFilePhoto . '?' . rand());
тогда браузер будет думать что это новая картинка и не будет брать ее из кеша
Ми
Ми
Как я понимаю — это скрипт не отрабатывает.
Александр Мальцев
Александр Мальцев
Здравствуйте. Вам необходимо к странице подключить библиотеку jQuery.
Ми
Ми
Доброго времени суток!
Огромное спасибо за создание и поддержание очень интересного, нужного ресурса.
При работе с данным уроком (выполнял всё как написано и перепроверял) столкнулся со следующими проблемами:
1. Когда изначально фото аватарки не загруженно, но мы редактируем другие параметры, а аватар не трогаем (не подгружаем), то модекс выдает ошибку
[2016-11-14 22:24:07] (ERROR @ /home/........../core/cache/includes/elements/modsnippet/22.include.cache.php: 87) Ошибка при загрузке файла. Код ошибки: 4
2. В консоле браузера весит такая ошибка
Uncaught ReferenceError: jQuery is not defined
3. Не происходит проверки изображения на максимальный размер и на соответствие формату
4. При загрузке фото и редактирования профиля — всё работает, но чтобы фотография поменялась над формой нужно еще раз обновить страницу.
5. Согласно вашему 6 пункту «Напишем скрипт на языке JavaScript с использованием функций библиотеки jQuery. Данный скрипт будет показывать аватар (фото) пользователя ещё до загрузки его на сервер. Функционал скрипта основывается на File API, который появился в HTML5.» — вот с этим тоже проблема. Файл на сервер грузится, но до загрузки его на сервер не отображается

Во всём остальном всё работает. Фото удаляет, изменения вносятся и работает как часы.

Подскажите каким образом можно поправить данные ошибки?
Александр
Александр
Нет, не забыл.

1. Создания директории photouser в каталоге assets. Данную директорию будем использовать для хранения фото (аватарок) пользователей.
Аноним
Аноним
Автор забыл добавить, что нужно создать папку в assets «photouser».
После этого фотографии успешно загружаются.
Аноним
Аноним
И еще — вы не написали как выводить фотку в кабинет теперь? Добавлю — пишет — профиль обновлен, а фотка не меняется. Убрал лишние библиотеки — все равно не работает.
Александр Мальцев
Александр Мальцев
Если хотите это сделать на любой странице, то это будет так:
[[!+modx.user.id:isloggedin:is=`1`:then=`<img src="[[!+modx.user.id:userinfo=`photo`:default=`/assets/photouser/default.jpg`]]">`:else=``]]
Можно также использовать сниппет Profile:
[[!Profile]]
<img src="[[+photo:default=`/assets/photouser/default.jpg`]]">
Аноним
Аноним
Спасибо. Получилось.
Аноним
Аноним
Долгожданно, спасибо. Но возникли сложности. Судя по всему не работает скрипт (подозреваю только у меня). Не обновляется по нажатию кнопки «Обновить» и имя файла добавляется, а самого файла нет. Подскажите в чем может быть проблема — замечал и в другом месте: примитивный скрипт отрабатывает, а что-то посолиднее нет. Может из-за конфликта с $?
Александр Мальцев
Александр Мальцев
Попробуйте безопасное использование $. Для этого код скрипта необходимо обернуть в следующий контейнер:
jQuery(function($) {
  //...
});
Кроме этого код скрипта, необходимо размещать после подключения библиотеки jQuery. В противном случае: если Вы разместите код до подключения библиотеки jQuery, то она (jQuery) будет недоступна.
Аноним
Аноним
Спасибо за подсказку. Пока не получилось, однако как минимум одну другую ошибку устранил у себя после переноса подключения библиотеки jQuery выше.
jQuery(function($) {
  //...
});
Пробовал и такой вариант, но увы, не работает. Разбираюсь в коде скрипта и запутался с photo и img-photo. Это не одно и тоже? простите за не понимание…
— И еще: может причина в этом:

if (move_uploaded_file($tmpFile, $fullNameFilePhoto)) {
        // если файл phpthumb.class.php не был подключён, то включить его
        require_once MODX_CORE_PATH.'model/phpthumb/phpthumb.class.php';
Тут путь относительный или полный. У меня он лежит:
assets/core/model/phpthumb/phpthumb.class.php
Аноним
Аноним
попробовал пути менять — бесполезно. Получается, что имя файла записывается (я вижу его имя), оно сформировано правильно — user[[id]].jpd а внутри файл пустой.
Александр Мальцев
Александр Мальцев
Путь полный, т.е. до директории core которая лежит в корне сайта.
.../core/model/phpthumb/phpthumb.class.php
Каталога assets не должно быть.
Александр Мальцев
Александр Мальцев
img-photo — это id картинки
photo — это id элемента, с помощью которого загружаем картинку
Александр Мальцев
Александр Мальцев
Если Вы сомневаетесь в наличии phpthumb.class.php то удалите следующее содержимое:
if (move_uploaded_file($tmpFile, $fullNameFilePhoto)) {
  // <- удалить содержмое 
}
Аноним
Аноним
Я понемногу продвигаюсь вперед. Уже точно могу сказать что был конфликт с одной из подключаемых js библиотек. Оставил только jQuery и теперь мои скрипты работают. Ваш тоже изменил свое поведение. При загрузке картинки на странице редактирования профиля она стала появляться на странице, но после нажатия на кнопку «обновить» — возвращается старая.