Выборка данных из разных типов данных с фильтрацией по определенному свойству в режиме ИЛИ

Материал из Umicms
Перейти к:навигация, поиск

Актуально для 2.9


Задача: Получить страницы в результате выборки по различным типам данных (страница контента, лента новостей, фотоальбом и др.) с фильтрацией по определенному свойству в режиме ИЛИ.
Решение: Для решения данной задачи использовать Usel-выборку не получится, так как usel будет работать в режиме ИЛИ только до тех пор, пока не задана фильтрация в теге <property /> . В этом случае, свойство, указанное в данном теге, будет искаться только в том типе, который указан в первом теге <type />, т.е. следующая выборка не принесет ожидаемого результата:

<?xml version="1.0" encoding="utf-8"?>
<selection>
 <target expected-result="pages">
	<type module="content" method="page"/>
	<type module="news" method="rubric"/>
	<type module="photoalbum" method="albums" />
	<category depth="1">{1}</category> 
 </target>
 <property name="pokazyvat" value="1" />
</selection>

Для решения задачи необходимо написать кастомный макрос с использованием API Selector. Для данного примера в типах данных "Страница контента", "Лента новостей" и "Фотогалерея" было создано поле "Показывать" с типом "кнопка-флажок" и данное свойство было отмечено у некоторых страниц указанных типов:

public function sortMultiType($parentId, $template = "default") {
	if(!$template) $template = "default";
	list($templateBlock, $templateItem) = self::loadTemplates("data/".$template, "sortblock", "sortitem");
	$items = array();
	// Получаем id текущей страницы
	$currentElementId = cmsController::getInstance()->getCurrentElementId();
	// поиск объектов каталога в текущем разделе 
	for ($i=0; $i < 3; $i++) {
		$sel = new selector('pages');
		if ($i==0) $sel->types('hierarchy-type')->name('content', 'page');
		if ($i==1) $sel->types('hierarchy-type')->name('news', 'rubric');
		if ($i==2) $sel->types('hierarchy-type')->name('photoalbum', 'album');
		$sel->where('hierarchy')->page($parentId)->childs(1);
		$sel->where('pokazyvat')->equals(1);
		$result = $sel->result();

		foreach($result as $page){
			$item = Array();
			$item['@id'] = $page->id;
			// Если страница текущая, то помечаем её классом
			if ($page->id == $currentElementId) $item['@active'] = "class = 'active'";
			else $item['@active'] = '';
			
			$item['@link'] = $page->link;
			$item['node:name'] = $page->name;
			$items[] = self::parseTemplate($templateItem, $item);
		}
	}
	$blockItems = Array();
	$blockItems['subnodes:items'] = $items;

	return def_module::parseTemplate($templateBlock, $blockItems);
}

Результат работы макроса в XML-виде: udata://custom/sortMultiType/33

<?xml version="1.0" encoding="utf-8"?>
<udata xmlns:xlink="http://www.w3.org/TR/xlink" module="custom" method="sortMultiType" generation-time="0.039474">
  <items>
    <item id="68" link="/obychnaya_stranica/test/">test</item>
    <item id="32" link="/obychnaya_stranica/akcii/">Акции</item>
    <item id="27" link="/obychnaya_stranica/fotogalereya/">Фотогалерея</item>
  </items>
</udata>
<!-- This page generated in 1.172077 secs by XSLT, HTTP SCHEME MODE -->

Для TPL, необходимо в шаблоне /tpls/data/default.tpl создать два блока:

$FORMS['sortblock'] = <<<END
%items%
%scope%
END;

$FORMS['sortitem'] = <<<END
%scope%
END;

Результат работы макроса в TPL:
SortMultiType.png