Расширенные поля пользователей

Опубликовано: 08 Окт 2017

Взято тут.

Небольшая пошаговая инструкция, как научиться сохранять любые интересующие данные о юзере в специальное поле extended.

На самом деле, это никакой не секрет. Во многих объектах MODX есть специальное поле типа JSON, которое хранится в БД как текст, например, properties у modResource и extended у modUserProfile.

При работе с объектами xPDO, JSON текст из этих полей превращается в массивы. То есть, общий принцип выглядит так:

// id нужного пользователя
$user_id = 15;
// Получаем объект modUser
if ($user = $modx->getObject('modUser', $user_id)) {
    // Получаем связанный с ним профиль пользователя
    if ($profile = $user->getOne('Profile')) {
        // Получаем специальное поле extended
        $extended = $profile->get('extended');
        // Добавляем новое значение
        $extended['mykey'] = 'mydata';
        // И сохраняем обратно в профиль
        $profile->set('extended', $extended);
        $profile->save();
    }
}

Самое приятное, что эти данные вы можете не только просмотреть на странице пользователя, но и изменить.

Регистрация и активность

А теперь давайте напишем плагин, который будет сохранять данные о регистрации и последней активности пользователя, которые MODX сам, почему-то, не сохраняет.

Для плагина мы используем события OnUserSave и OnLoadWebDocument:

switch ($modx->event->name) {
    case 'OnUserSave':
        // Сохраняем дату создания нового пользователя
        if ($user && $mode == 'new') {
            if ($profile = $user->getOne('Profile')) {
                $extended = $profile->get('extended');
                $extended['registered'] = date('Y-m-d H:i:s');
                $profile->set('extended', $extended);
                $profile->save();
            }
        }
        break;
        
    case 'OnLoadWebDocument':
        // Сохраняем дату открытия любой страницы сайта, если пользователь авторизован
        if ($modx->user->isAuthenticated($modx->context->key)) {
            // Здесь мы работаем с текущим пользователем - у него профиль уже загружен
            $profile = $modx->user->Profile;
            $extended = $profile->get('extended');
            $extended['lastactivity'] = date('Y-m-d H:i:s');
            $profile->set('extended', $extended);
            $profile->save();
        }
        break;
}

И вот, что у нас получается:


Вывод полей профиля

Для вывода пользователей я советую использовать сниппет pdoUsers, который обладает всеми основными возможностями pdoTools.

Если вызвать его без чанка, то он распечатает массив всех плейсхолдеров юзера, включая поле extended.


pdoTools выводит массивы плейсхолдеров через точку, поэтому нас интересуют и .

[ [!pdoUsers?
    &tpl=`@INLINE <p> - Регистрация: , активность: </p>`
]]

Можно использовать фильтры вывода или параметр &prepareSnippet, чтобы подготовить эти даты для вывода в более приятном виде.

Вот пример вывода с указанием &prepareSnippet:

[ [!pdoPage?
    &element=`pdoUsers`
    &tpl=`tpl.Users.list.row`
    &prepareSnippet=`prepareUser`
]]

А вот и сам сниппет prepareUser:

<?php
// Комментарии юзера
$row['comments'] = $modx->getCount('TicketComment', array('createdby' => $row['id'], 'published' => 1));
// Тикеты
$row['tickets'] = $modx->getCount('Ticket', array('createdby' => $row['id'], 'class_key' => 'Ticket', 'published' => 1, 'deleted' => 0));
// Проверка и красивое форматирование дат через сниппет dateAgo
$row['registered'] = !empty($row['extended']['registered'])
    ? $modx->runSnippet('dateAgo', array('input' => $row['extended']['registered']))
    : '-';
$row['lastactivity'] = !empty($row['extended']['lastactivity'])
    ? $modx->runSnippet('dateAgo', array('input' => $row['extended']['lastactivity']))
    : '-';
    
return serialize($row);

&prepareSnippet — это особенность pdoTools, можно использовать со всеми сниппетами.

Недостатки

Из-за того, что в БД данные extended хранятся в виде JSON текста, по ним нельзя нормально осуществлять фильтрацию и сортировку.

Если вам нужно не просто выводить какие-то значения, то придётся написать дополнительную таблицу с id юзера и нужными колонками, чтобы сохранять данные в неё раздельно.

Тогда вы сможете присоединить эту таблицу в вызове сниппета pdoUsers и фильтровать\сортировать пользователяй по дополнительным полям.

Комментарии (0)


Оставить комментарий




Разрешённые теги: <b><i><br>Добавить новый комментарий: