Подсчёт значений из присоединённой таблицы на xPDO
Сегодня понадобилось вывести список блогов с подсчетом количества тикетов внутри. Желательно, за один запрос, и чтобы обращал внимание на состояние дочернего тикета.
В итоге вышел простой и быстрый сниппет getSections:
В сниппет можно передать параметр section для указания активного раздела и tpl для оформления.
Еще нужно немного изменить чанк tpl.Tickets.form.section.row, для вывода count:
Данный способ присоединения таблицы и подсчета её рядов будет работать везде, не только с тикетами. Можно даже посчитать сумму значений и отсортировать по ней. Вот пример из будущей системы рейтинга тикетов:
В итоге вышел простой и быстрый сниппет getSections:
<?php
if (empty($tpl)) {$tpl = 'tpl.Tickets.form.section.row';}
if (empty($section)) {$section = 0;}
// Новый запрос - выбираем родителей
$q = $modx->newQuery('TicketsSection', array('class_key' => 'TicketsSection', 'published' => 1, 'deleted' => 0));
// Присоединяем потомков и указываем какое поле их связывают с родителем
$q->leftJoin('Ticket','Ticket','TicketsSection.id = Ticket.parent AND Ticket.published = 1 AND Ticket.deleted = 0');
// Группируем ряды по родителям, без этого работать не будет
$q->groupby('TicketsSection.id');
// Выбираем id, имя родителя и кол-во активных потомков функцией COUNT
$q->select('TicketsSection.id, TicketsSection.pagetitle, COUNT(Ticket.id) as count');
// Сортируем по menuindex
$q->sortby('TicketsSection.menuindex', 'ASC');
// Дальше обычный разбор результатов
if ($q->prepare() && $q->stmt->execute()) {
$res = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
$res = '';
foreach ($res as $v) {
if ($v['id'] == $section) {$v['selected'] = 'selected';} else {$v['selected'] = '';}
$res .= $modx->getChunk($tpl, $v);
}
return $res;
}
В сниппет можно передать параметр section для указания активного раздела и tpl для оформления.
Еще нужно немного изменить чанк tpl.Tickets.form.section.row, для вывода count:
<option value="[[+id]]" [[+selected]]>[[+pagetitle]][[+count:gt=`0`:then=` ([[+count]])`:else=``]]</option>
Данный способ присоединения таблицы и подсчета её рядов будет работать везде, не только с тикетами. Можно даже посчитать сумму значений и отсортировать по ней. Вот пример из будущей системы рейтинга тикетов:
$q = $modx->newQuery('Ticket', array('class_key' => 'Ticket','deleted' => 0, 'published' => 1));
$q->leftJoin('TicketVote','Vote', "Ticket.id = Vote.parent AND Vote.class = 'Ticket'");
$q->groupby('Ticket.id');
$q->select("SUM(Vote.value) as rating");
$q->sortby('rating', 'DESC');