Счётчик кликов для Modx Revo
Возникло желание реализовать на Modx Revolution счётчик кликов по элементу. Например по ссылке «скачать карту сокровищ», с выводом значения накликанного где-нибудь поблизости, вида «жмакнули ХХХ раз». Для реализации первым делом нужно создать TV параметр с именем «clickCount». Сразу уточню, что имена параметров и т.п. либо надо использовать как в примере ниже, либо менять на свои внимательно отслеживая, чтобы изменения были внесены во всех частях PHP и Java Script кода. Тип ввода у TV может быть или «текст» или «число», со значением, по-умолчанию равным нулю.
Вывод содержимого TV поля реализован с помощью сниппета «getClickCount» с кодом:
<?php
$tvId= 5;
if ($tv = $modx->getObject('modTemplateVarResource', ['tmplvarid' => $tvId, 'contentid' => $modx->resource->id])) {
$clicks = (int)$tv->get('value');
return ($clicks > 0) ? $clicks : 0;
}
return 0;
Где для «$tvId» указывается ID доп. поля TV «clickCount», созданного ранее. Обработка клика возложена на Java Script, который должен быть после элемента который мы считаем на странице и до вызова скрипта должен быть подключен jQuery. Код скрипта:
<script>
$(document).ready(function() {
let linkElement = '#counted';
$(linkElement).click(function(){
$.ajax({
url: '/ВАШ_ПУТЬ_К_ФАЙЛУ/count.php',
type: 'POST',
dataType: 'json',
data: {
url: window.location.href
}
});
});
});
</script>
Код упомянутого в JS выше файла «count.php», который и будет увеличивать счётчик в ответ на JS событие «клик по элементу с заданным id»:
<?php
$tvName= 'clickCount';
define('MODX_API_MODE', true);
require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/index.php';
$modx->getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
$modx->setLogTarget('FILE');
if ($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {
$modx->sendRedirect($modx->makeUrl($modx->getOption('site_start'),'','','full'));
}
$url = trim(htmlspecialchars($_POST['url']));
if(!$url){
return;
}
$alias = basename($url, '.html');
$page = $modx->getObject('modResource', ['alias' => $alias]);
if(!$page){
return;
}
$count = (int)$page->getTVValue($tvName);
$page->setTVValue($tvName, $count+1);
$page->save();
exit();
Отображение числа, которое будет увеличиваться сообразно кликам по элементу на странице идёт через вызов сниппета, и может быть представлено на Fenom в виде:
<a href="#" id="
counted
" title="Тыкнуто мышей{'!getClickCount' | snippet | declension : 'раз|раза|раз' : true}>Тыкай тутЪ</a>
Ещё один вариант, без внешнего файла и сниппета, через плагин на событие «OnHandleRequest». Код плагина:
<?php
if ($modx->context->key == 'mgr') {return;}
if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {return;}
if (empty($_POST['action'])) {return;}
$output = [];
switch ($_POST['action']) {
case 'dr/click':
$id = (int) $_POST['id'];
if (!empty($id)) {
if ($resource = $modx->getObject('modResource', $id)) {
$value = (int) $resource->getTVValue('clickCount') + 1;
$resource->setTVValue('clickCount', $value);
$resource->save();
$resource->clearCache();
$output['success'] = true;
$output['id'] = $id;
$output['value'] = $value;
}
}
break;
default:
$output['success'] = false;
}
if (!empty($output)) {
echo json_encode($output);
exit;
}
Код скрипта:
<script>
$('.dr-link').click(function(){
$.post(document.location.href, {
action: 'dr/click',
id: $(this).data('id')
}, function(response) {
if (response.success) {
$('.dr-counter-' + response.id).html(response.value);
}
}, 'json');
return false;
});
</script>
Код ссылки и вывода значений:
<p><a href="" class="dr-link text-info" data-id="{$_modx->resource.id}">Жмакни меня</a></p>
<p>Жмакнуто <span class="dr-counter-{$_modx->resource.id}">{$_modx->resource.clickCount | declension : 'раз|раза|раз' : true}</span></p>