Сбор пользовательской статистики с помощью modMonitor

Сегодня вышла новая версия modMonitor-2.6.0. Эта версия компонента интересна тем, что теперь можно, не влезая в ядро, добавлять собственные колонки и фильтры для вывода и фильтра собираемых данных.

Вот совсем свежий кейс (собственно, для чего и делалось это обновление): на одном не маленьком проекте у нас используется сразу несколько версий Smarty-скинов, и для наглядности хотелось бы в собираемой статистике видеть какой именно скин был использован при генерации страницы (скин переключается на уровне плагина, поэтому это не всегда прозрачно). Как я это сделал с новым modMonitor, я здесь подробно и распишу.

  1. Для хранения значения скина добавляем колонку в таблицу запросов. Для этого в плагине на событие OnMODXInit прописываем:
$modx->loadClass('modMonitorRequest');

$modx->map['modMonitorRequest']['fields']['smarty_template'] = '';
$modx->map['modMonitorRequest']['fieldMeta']['smarty_template'] = array(
	'dbtype' => 'varchar',
	'precision' => '100',
	'phptype' => 'string',
	'null' => false,
	'default' => '',
);

$modx->map['modMonitorRequest']['indexes']['smarty_template'] = array(
    'alias' => 'smarty_template',
    'primary' => false,
    'unique' => false,
    'type' => 'BTREE',
    'columns' => 
    array (
        'smarty_template' => 
        array (
            'length' => '',
            'collation' => 'A',
            'null' => true,
        ),
    ),
);

Здесь важный момент: так как объект запроса создается тоже в плагине на событие OnMODXInit, вызов нашему кастомному плагину на это событие нужно прописать ранг меньше нуля, к примеру -100, чтобы он вызвался раньше, и на момент создания объекта запроса в мап-данных уже была информация об этой колонке. На самом деле работать будет в любом случае, но для порядка лучше так сделать. Иначе вот такое сработает:

$modMonitor = & $modx->getService('modMonitor');
$modMonitor->request->set("smarty_template", "sdfsdf");

А вот такое нет:

$modMonitor = & $modx->getService('modMonitor');
$modMonitor->request->smarty_template = "sdfsdf";

После сохранения плагина надо добавить колонку и индекс в саму таблицу в базе данных. Для этого выполняем такой код:

$modx->getManager()->addField("modMonitorRequest", "smarty_template");
$modx->getManager()->addIndex("modMonitorRequest", "smarty_template");

Здесь средствами xPDO будут созданы колонка и индекс.

  1. Колонка в таблице создана, добавим сохранение информации в объект запроса. Для этого я в своем плагине, где инициализируется кастомный скин, прописываю:
if(
    $smarty_template
    AND $modMonitor = $modx->getService('modMonitor')
    AND $modMonitor->request
){
    $modMonitor->request->smarty_template = $smarty_template;
}

Сохранять ничего не надо, запрос сам в конечном итоге сохранится.

  1. Данные у нас наверняка записываются в базу данных, теперь надо в интерфейсе статистики запросов добавить колонку, которая выводила бы эту информацию. Для этого создаем плагин (а лучше прописываем в тот же плагин, просто по условию на другое событие) и прописываем на событие OnManagerPageBeforeRender вот такой код:
// Добавляем поле для объекта записи
$controller->requests_grid_fields[] = 'smarty_template';

// Добавляем колонку в грид
$controller->requests_grid_columns[] = array(
    "header"    => "Смарти-шаблон",
    "dataIndex" => "smarty_template",
);

// Добавляем поле поиска
$controller->requests_grid_filters[] = array(
    "xtype"    => "textfield",
    "width"    => 150,
    "name"    => "smarty_template",
    "emptyText" => "Смарти-шаблон",
);

Здесь вот мы не только колонку для грида добавляем, но и сразу фильтр поиска добавляем. В итоге получается вот такое:

![20-11-2016 01-53-02.jpg](/assets/images/resized/2016/2242/20-11-2016 01-53-02.jpg)

  1. Вот теперь нам остается только добавить поиск по этому полю. Для этого в плагине на событие OnModMonitorPrepareRequestQuery прописываем такое:
if($smarty_template = trim($processor->getProperty("smarty_template"))){
    $query->where(array(
        "smarty_template:like"  => "%{$smarty_template}%",
    ));
}

Вот теперь у нас еще и поиск по этому полю работает.

Здесь следует отметить, что понимание работы ExtJS безусловно способствует большему пониманию как это все работает. Так же опыт работы с migx неплохо поможет. В любом случае, если у кого возникнут сложности: обращайтесь.

Вообще, этот функционал и для подобных кейсов полезен: https://modx.pro/howto/10362-modmonitor-case-find-the-cause-of-the-reset-cache/