Счётчик кликов для Modx Revo

09.02.2023
1808 просмотров

Возникло желание реализовать на 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>
Оставьте комментарий
Андрей
Вчера в 09:09

Сделал по второму варианту через событие OnHandleRequest. При нажатии на ссылку идет подсчет, но перехода по ссылке нет. Как это можно исправить?

Artem Makarov aka Robin
Вчера в 11:02

Переход по ссылке обрабатывается html кодом, т.е. для href должно быть указано нужное значение