Как сделать выборку чтобы в нее попали только страницы из активных разделов
Актуально для версии 2.9.1
Задача №1
Допустим, нам нужно получить все страницы объектов каталога, отмеченные как активные, из какой-либо раздела с определенной вложенность. Это сделать очень просто, в документации, см. "Полезные ссылки", есть примеры:
$pages = new selector('pages');
$pages->types('object-type')->name('catalog', 'object');
$pages->where('hierarchy')->page('/shop/')->childs(10);
$pages->where('is_active')->equals(1);
Но, например мы имеем следующую структуру:
И хотим, чтобы товары из раздела "Музыкальные центры" не попали в результат, так как раздел каталога, где они находятся не отмечен, как активный, в такой задаче одного Selector'a нам не хватит.
Решение №1
Для этого нам нужно будет воспользоваться классом иерархической модели данных - umiHierarchy, см. "Полезные ссылки". Мы создадим результирующий массив, в который будут попадать только те страницы, родители которых отмечены, как активные, для этого модифицируем наш код:
//получаем экземпляр класса umiHierarchy
$hierarchy = umiHierarchy::getInstance();
//инициализируем массив, в который попадут только нужные нам объекты
$resultObject = array();
//делаем выборку по Selector, которая была приведена ранее
$pages = new selector('pages');
$pages->types('object-type')->name('catalog', 'object');
$pages->where('hierarchy')->page('/shop/')->childs(10);
$pages->where('is_active')->equals(1);
//перебираем массив страниц, полученных в выборке страниц
foreach($pages as $page){
//инициализируем переменную $pageId и присваиваем ей id страницы
$pageId=$page->id;
//инициализируем переменную $parentId и присваиваем ей идентификатор родительской страницы с помощью getParent(), см. "Полезные ссылки"
$parentId=$hierarchy->getParent($pageId);
//инициализируем переменную $parentElement и присваиваем ей экземпляр страницы с помощью getElement(), см. "Полезные ссылки"
$parentElement=$hierarchy->getElement($parentId);
//если родительская страница активна (узнаем это с помощью метода getIsActive(), см. "Полезные ссылки")
if($parentElement->getIsActive()== true){
//то запишем в результирующий массив, страницу из выборки
$resultObject[]=$page;
}
}
//для пример выведем число элементов в результирующем массиве
echo count($resultObject);
Задача №2
Однако, если мы потом будет выводить результат работы выборки, используя постраничную пагинацию, то возможны случаи, когда на странице не будет ни одного объекта, то есть нам нужно исключить все неактивные элементы еще на стадии формирования запроса.
Решение №2
Для этого нам нужно будет сначала с помощью Selector выбирать все активные разделы каталога и записывать их идентификаторы в массив, потом делать новую выборку активных объектов каталога, являющимися дочерними к полученным идентификаторам активных разделов каталога, то есть наш скрипт примет следующий вид:
//получаем экземпляр класса umiHierarchy
$hierarchy = umiHierarchy::getInstance();
//инициализируем массив $activeCategoryIdes, в который попадут идентификаторы активных разделов каталога
$activeCategoryIdes= array();
//получаем страницы активных разделов каталога
$activeCategories = new selector('pages');
$activeCategories->types('object-type')->name('catalog', 'category');
$activeCategories->where('hierarchy')->page('/shop/')->childs(10);
$activeCategories->where('is_active')->equals(1);
//у каждой полученной в выборке страницы
foreach ($activeCategories as $activeCategory){
//берем id и записываем в переменную $activeCategoryId
$activeCategoryId = $activeCategory->id;
//полученные id записываем в массив $activeCategoryIdes
$activeCategoryIdes[]=$activeCategoryId;
}
//для примера, выведем количество активных страниц разделов каталога
echo "<br/>Total active category: {$activeCategories->length}";
//получаем страницы объектов каталога
$activeObjects = new selector('pages');
$activeObjects->types('object-type')->name('catalog', 'object');
//перебираем массив $activeCategoryIdes
foreach ($activeCategoryIdes as $activeCategoryId){
//искать страницы объекты каталога только в разделах каталога c id из массива $activeCategoryIdes, вложенность '1' здесь обязательна
$activeObjects->where('hierarchy')->page($activeCategoryId)->childs(1);
}
//берем только активные страницы объектов каталога
$activeObjects->where('is_active')->equals(1);
//для примера, выведем количество активных страниц объектов каталога
echo "<br/>Total active pages: {$activeObjects->length}";