Работа с полями migx
Как работать с полями 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.
Функция очистки кэша одного ресурса.
Добавим функцию 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);
Истории из жизни айти и обсуждение кода.