Выбрать только ресурсы с потомками в pdoResources
Задача — выбрать только те ресурсы, у которых есть потомки, то есть, к примеру, не пустые категории. А также само количество поменстить в плейсхолдер для вывода в чанке.
Пояснение по сниппету pdoResources
&select
— тут мы выбираем modResource
(ресурсы, т.е. страницы сайта), и кол-во ресурсов count
из временной таблицы Children
, которую мы создаем в &leftJoin
(таблицы Children
в базе данных не существует). В шаблоне tpl
мы сможем использовать плейсхолдер [[+count]]
.
&leftJoin
— создаем временную таблицу, куда помещаем те записи, у которых parent
соответсвует id
базовому modResource
, и методом leftJoin
связываем ее с "базовой" modResource
. Также после AND
мы указываем условие для выборки уже этих самых потомков.
&where
— Так как мы связали через leftJoin
базовую modResource
(которую и хотим выбрать) и временную таблицу Children
, то мы можем выюрать только те записи, в которых Children.id
не равны не пустые, т.е. базовый modResource
, у которых есть прямые потомки.
Минум метода — он считает только прямых потомков. Чтобы посчитать всех пложенных потомков используйте сниппет countChildren
(на этой странице ниже).
Код вызова сниппета pdoResources
[[!pdoResources? &parents=`0` &depth=`0` &tpl=`@INLINE <li>[[+pagetitle]] — [[+count]]</li>` &limit=`0` &select=`{ "modResource":"id, pagetitle", "Children":"COUNT(Children.id) as count" }` &leftJoin=`{ "Children":{"class":"modResource", "on":"modResource.id = Children.parent AND (Children.deleted != 1 AND Children.published = 1)"} }` &where=`{"Children.id:IS NOT":null}` &sortby=`{"id":"ASC"}` &groupby=`modResource.id` ]]
Также, теоретически мы можем основываться на параметре isfolder
у ресурса. То есть когда в ресурс становится парентом для другого ресурса эта настройка автоматически переводится в положение true
. Однако проблема в том, что если мы уберем потомка, бывший «родитель» так и останется с isfolder = true
. В принципе можно написать плагин, или еще как-то привязаться этой настроке. Но это все равно менее надежно, чем выборка по фактическому положению дел в БД. Просто имейте в виду, что такой вариант тоже есть.
Отобразить кол-во потомков в pdoMenu для категорий товаров minishop2
[[pdoMenu? &parents=`[[*id]]` &level=`0` &tplOuter=`@INLINE [[+wrapper]]` &tplStart=`@INLINE ` &tpl=`catalog_categories_tpl` &tplParentRow=`catalog_categories_tpl` &where=`{"class_key:=":"msCategory"}` ]]
Чанк catalog_categories_tpl
<li> <a href="[[+link]]" [[+attributes]]> [[+menutitle:default=`[[+pagetitle]]`]] <span>[[!countChildren? &parent=`[[+id]]`]]</span> </a> </li>
Код сниппета countChildren
$count = 0; $parent = isset($parent) ? (integer) $parent : 0; // Define Parents $q = $modx->newQuery('modResource'); $q->where(array( 'class_key' => 'msCategory' // Только категории Minishop )); $q->select(array( 'id', 'parent' )); $q->prepare(); $q->stmt->execute(); $res = $q->stmt->fetchAll(PDO::FETCH_ASSOC); $parent_ids = array($parent); $i = 0; while(true){ $i++; $action = false; foreach($res as $v){ if(in_array($v['parent'], $parent_ids) AND !in_array($v['id'], $parent_ids)){ $parent_ids[] = $v['id']; $action = true; } } if(!$action || $i > count($res)){ break; } } //return $i; if ($parent > 0) { $q = $modx->newQuery('modResource'); $q->where(array( 'parent:IN' => $parent_ids )); $q->select(array( 'id' )); $q->prepare(); $q->stmt->execute(); $count = count($q->stmt->fetchAll(PDO::FETCH_ASSOC)); } return (string) $count;
Комментарии (0)
Не писать ответ