Работа с полями migx

май 3 , 2015
Метки:

Как работать с полями migx. Как создать поле, вывести его содержимое, как добавить новые записи и удалить их через Modx API - об этом рассказывается в нашей статье.

Задача: нужно сделать комментарии на сайте.
Готовым движком, например, Disqus, мы по каким-то причинам пользоваться не хотим, поэтому реализуем все руками. К тому же это неплохой пример посмотреть, как работать с migx-полями в Modx Revo. Я не буду описывать очень подробно, как создать поле migx, как связать его с шаблонами, как спроектировать форму для отправки и удаления комментариев... Описаны будут только ключевые вещи.
Идея такая. Есть сайт-блог со статьями. Мы хотим реализовать на нем простую систему комментариев. Создадим migx-поле, назовем его migx_comments, включим 3 столбца - name, date, comment, соответственно, имя оставившего комментарий, дату/время и сам комментарий. Выведем наши комментарии на экран и покажем, как добавить новый комментарий и удалить ненужные средствами Modx API.

Описываем вкладки формы

    [
        {
            "caption":"Комментарии", 
            "fields":[
                {"field":"name","caption":"Имя"},
                {"field":"date","caption":"Дата и время"},
                {"field":"comment","caption":"Комментарий"}
            ]
        }
    ]

Разметка колонок

    [
        {"header": "Имя", "width": "100", "sortable": "true", "dataIndex": "name"},
        {"header": "Дата и время", "width": "100", "sortable": "true", "dataIndex": "date"},
        {"header": "Комментарий", "width": "500", "sortable": "true", "dataIndex": "comment"}
    ]

Выводим в браузер.


Предварительно проверяем, если комментариев еще нет, выводим соответствующее сообщение. Если есть, то выводим комментарии, используя чанк item_comment.

    [ [*migx_comments:is=``:or:is=`[]`:then=`
    
Комментариев пока нет. Ваш будет первым!
`:else=`
    [ [!getImageList? &tvname=`migx_comments` &tpl=`item_comment` &limit=`0` ] ]
`] ]

Чанк item_comment.


Атрибут data-migx-id будет использоваться для удаления комментария через Modx API.

    
  • [ [+name] ]
    [ [+date] ]
    [ [+comment] ]
  • Функция очистки кэша одного ресурса.

    Добавим функцию clearResourceCache, которая очищает кэш нужного ресурса

        function clearResourceCache($modx, $res) {
            $cache = $modx->cacheManager->getCacheProvider($modx->getOption('cache_resource_key', null, 'resource'));
            $res->_contextKey = $res->context_key;
            $key = $res->getCacheKey();
            $cache->delete($key, array('deleteTop' => true));
            $cache->delete($key);
        }
    

    Добавление комментария средствами API.

    Как подключить Modx API, читайте в статье "Как подключить Modx API во внешнем файле"
    На сервер нужно передать поля docid - id ресурса (статьи, для кот. добавляется комментарий), name - имя комментатора, message - сам комментарий. Ниже приведен код готовой функции.

        function addComment($modx) {
            try {
                $docid = intval($_POST['docid']);
                // Получаем документ
                $resource = $modx->getObject('modResource', $docid);                        
                $comments = $resource->getTVValue('migx_comments');
                // Преобразуем комментарии в ассоциативный массив
                $ar = json_decode($comments, true);
            
                // Получаем нужные данные для добавления комментария
                $new_id = (empty($ar)) ? 1 : intval($ar[count($ar)-1]['MIGX_id'])+1;
                $name = addslashes($_POST['name']);
                $comment = addslashes($_POST['message']);
                $date = date('d.m.Y в H:i');
                
                Добавляем в массив наш комментарий
                array_push($ar, array(
                    'MIGX_id' => $new_id,
                    'name' => $name,
                    'date' => $date,
                    'comment' => $comment
                ));    
            
                // Сохраняем новое значение поля
                $resource->setTVValue('migx_comments', json_encode($ar));
                $resource->save();
                // Если нужно, очищаем кэш для нашего ресурса
                clearResourceCache($modx, $resource);
        
                // Отправляем клиенту в браузер сигнал об успешном добавлении комментария
                return json_encode(array('code' => 0, 'message' => 'Спасибо! Ваш комментарий отправлен'));
            }
            catch (Exception $e) {
                // Что-то пошло не так... Соответствующее сообщение выдаем клиенту
                return json_encode(array('code' => -1, 'message' => 'Ошибка отправки комментария. Попробуйте еще раз', 'error' => $e->getMessage()));
            }
        }
    

    Изменяются комментарии точно так же, как и в предыдущем примере, с той разницей, что нужно не добавить новый элемент в массив, а отредактировать существующий. Как найти интересующий нас комментарий, видно ниже, из кода удаления

    Удаление комментариев.

    Передаются поля docid и migx_id.

        function deleteComment($modx) {
            $docid = $_POST['docid'];
            $migx_id = intval($_POST['migx_id']);
            $resource = $modx->getObject('modResource', $docid);                        
            $comments = $resource->getTVValue('migx_comments');
            // Получаем ассоциативный массив с комментариями по аналогии с добавлением
            $ar = json_decode($comments, true);
        
            // В $ar_new будет новый массив без нашего, удаленного
            $ar_new = array();
            foreach($ar as $a) {
                if($a['MIGX_id']!=$migx_id)
                    array_push($ar_new, $a);
            }
            
            // Сохраняем новое значение
            $resource->setTVValue('migx_comments', json_encode($ar_new));
            $resource->save();
            clearResourceCache($modx, $resource);
            
            // Возвращаем строку json с комментариями (вы же можете вернуть что угодно)
            return json_encode($ar_new);
        }
    

    Для получения нового массива лучше вместо ручного перебора использовать функцию array_filter. Если у вас установлена подходящая версия php, то используйте ее.

        $ar_new = array_filter($ar, function($value, $key) {
            return $value['MIGX_id']!=$migx_id;
        }, ARRAY_FILTER_USE_BOTH);
    
    Метки:
    Заходите в группу в контакте - https://vk.com/webdevkin
    Анонсы статей, обсуждения интернет-магазинов, vue, фронтенда, php, гита.
    Истории из жизни айти и обсуждение кода.
    Как Вам статья? Оцените!