Работа с полями 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);
Истории из жизни айти и обсуждение кода.