Счётчик кликов для 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>
Сделал по второму варианту через событие OnHandleRequest. При нажатии на ссылку идет подсчет, но перехода по ссылке нет. Как это можно исправить?
Переход по ссылке обрабатывается html кодом, т.е. для href должно быть указано нужное значение