Вывести только тикеты с рейтингом больше нуля
1
300
Итак, если вам нужно вывести тикеты с рейтингом выше ноля, то эту задачу можно решить двумя способами. Первый для высоконагруженных проектов, второй для менее нагруженных.
Первый вариант (относительно сложный в реализации, но выигрывает по скорости при большой выборке ресурсов):
Далее:
Создаем плагин (допустим, customTicketRating) со следующим содержанием:
Теперь осталось только вызвать сниппет с нужным условием:
За решение благодарим modx.pro/users/kaminari/
Второй вариант более простой в реализации и подойдет, если вам нужно выбрать тикеты из относительно небольшого кол-ва ресурсов:
1. Создаем сниппет:
Первый вариант (относительно сложный в реализации, но выигрывает по скорости при большой выборке ресурсов):
- Заходите в phpmyadmin.
- Выбираете таблицу modx_site_content
- — Переходите в закладку «структура»
- — Внизу открывшегося окна нажимаете ОК (Добавить 1 поле в конец таблицы)
Имя: ticket_rating Тип: int Длина/значение: 10 По умолчанию: Как определено (0) Null: галочка - Сохраняем
Далее:
Создаем плагин (допустим, customTicketRating) со следующим содержанием:
<?php
switch ($modx->event->name) {
case 'OnMODXInit':
$modx->loadClass('modResource');
$modx->map['modResource']['fields']['ticket_rating'] = 0;
$modx->map['modResource']['fieldMeta']['ticket_rating'] = array(
'dbtype' => 'int',
'precision' => 10,
'attributes' => '',
'phptype' => 'int',
'null' => true,
'default' => 0,
);
break;
case 'OnTicketVote':
if ($object->class == 'Ticket') {
if ($ticket = $modx->getObject('Ticket', $object->id)) {
$properties = $ticket->getProperties('tickets');
$rating = !empty($properties['rating'])
? $properties['rating']
: 0;
$ticket->set('ticket_rating', $rating + $object->value);
$ticket->save();
}
}
break;
}«Вешаем» его на события OnTicketVote и OnMODXInit. Теперь наше новое поле воспринимается модксом и изменяется после каждого голосования за любой ресурс.Теперь осталось только вызвать сниппет с нужным условием:
[[!pdoPage?
&element=`getTickets`
&where=`{"ticket_rating:>": 1}`
]]Важно: рейтинг начнет вычисляться только с последующих голосований за тикеты.За решение благодарим modx.pro/users/kaminari/
Второй вариант более простой в реализации и подойдет, если вам нужно выбрать тикеты из относительно небольшого кол-ва ресурсов:
1. Создаем сниппет:
<?php
$class = 'modResource';
$pdo = $modx->getService('pdoFetch');
$pdo->addTime('pdoFetch загружен');
$options = array(
'cacheTime' => '10',
);
if (!$output = $pdo->getCache($options)) {
$pdo->addTime('Кэш не найден, генерируем данные');
$pdo->setConfig(array(
'class' => $class,
'select' => 'id, properties',
'limit' => 0,
'parents' => 0,
'return' => 'data'
));
$data = $pdo->run();
$output = array();
foreach ($data as $row) {
if (isset($row['properties']['tickets']['rating']) && $row['properties']['tickets']['rating'] > 1) {
$output[] = $row['id'];
}
}
$output = implode(',', $output);
$pdo->setCache($output, $options);
$pdo->addTime('Данные сохранены в кэш');
} else {
$pdo->addTime('Данные загружены из кэша');
}
$pdo->addTime('Данные получены');
// print $pdo->getTime();
return $output;Здесь указано, сколько в секундах хранить кеш:$options = array(
'cacheTime' => '10',
);А здесь — больше какого значения должен быть рейтинг у ресурсов:if (isset($row['properties']['tickets']['rating']) && $row['properties']['tickets']['rating'] > 1) {
$output[] = $row['id'];
}2. Передаем результат его работы в getTickets или другой используемый сниппет, который принимает параметр resources. Например:[[getTickets?
&parents=`0`
&resources=`[[имя сниппета с кодом выше]]`
]]За вариант благодарим modx.pro/users/1801/ Комментарии: 23
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Поэтому, вот этот вариант, пожалуй, самый правильный для хранения таких данных. А дальше дело только за
— Выбираете таблицу modx_site_content
— Переходите в закладку «структура»
— Внизу открывшегося окна нажимаете ОК (Добавить 1 поле в конец таблицы)
Имя: ticket_rating
Тип: int
Длина/значение: 10
По умолчанию: Как определено (0)
Null: галочка
(сохраняем)
Таким способом мы расширили дефолтную таблицу MODX'a со списком ресурсов. Далее:
— Создаем плагин (допустим, customTicketRating) со следующим содержанием:
и включаем его на события OnTicketVote и OnMODXInit. Теперь наше новое поле воспринимается модксом и изменяется после каждого голосования за любой ресурс.
Теперь осталось только вызвать сниппет с нужным условием:
Важно: рейтинг начнет вычисляться только с последующих голосований за тикеты.
Мое решение просто проще в реализации. Решение Максима для человека, который знает, что он делает и зачем.
Сортировка такого поля в естественном виде как минимум требует дополнительную выборку (как в примере ниже), а как максимум — весьма ощутимо проигрывает в скорости.
(по этой же причине, например, очень нежелательно производить сортировку пользователей по extended-полям)
К слову, на modx.pro хранение рейтинга реализована примерно таким же способом.
Передаешь результат его работы в getTickets или другой используемый сниппет, который принимает параметр resources. Например:
Можно еще попробовать закешировать результаты сниппета, допустим, на 5-10 минут, чтобы уменьшить нагрузку, если сайт популярный. Для кеширования можно использовать методы getCache и setCache класса pdoTools.
П.С. Ещё обрати внимание на ошибку. Класс должен быть Ticket, а не modResource.
И еще нужно учитывать удаленные и опубликованные.
Еще один вариант с использованием кеша:
Без кеша:
С кешем:
В итоге, не нужно ничего кастомизировать.
P.S. Насчет «И еще нужно учитывать удаленные и опубликованные» не соглашусь. Нам нужно вернуть id ресурсов которые имеют положительный рейтинг больше единицы. А уж решать выводить неопубликованные или удаленные, должен сниппет, которому передаются эти id, у него для этого есть логика