С версии 6.9.4 контроллерам показа Informationsystem_Controller_Show, Shop_Controller_Show, Siteuser_List_Controller_Show добавлен метод addFilter(), реализующий простой интерфейс указания условий фильтрации. См. Фильтр и быстрый фильтр → Применение фильтров.
Контроллеры показа позволяют влиять на отбираемые элементы, добавлять дополнительные условия и т.п. Получение объекта, которому могут быть добавлены дополнительные ограничение выборки, осуществляется различными методами, зависящими от контроллера и выбираемых элементов:
Рассмотрим пример ограничений выборки информационных элементов, ограничения будем добавлять с использованием QueryBuilder.
Объект получаем через
$Informationsystem_Controller_Show->informationsystemItems()
Это уже объект ORM (Core_Entity), у которого можно получить ->queryBuilder() и далее добавлять ограничения. Пример фильтрации по одному свойству одного вида (целое число):
$Informationsystem_Controller_Show = new Informationsystem_Controller_Show( Core_Entity::factory('Informationsystem', 1) ); $Informationsystem_Controller_Show ->xsl( Core_Entity::factory('Xsl')->getByName('СписокНовостейНаГлавной') ) ->groupsMode('none') ->itemsForbiddenTags(array('text')) ->group(FALSE) ->limit(3) //->show() ;
// Объединение с нужной таблицей свойств $Informationsystem_Controller_Show ->informationsystemItems() ->queryBuilder() ->join('property_value_ints', 'informationsystem_items.id', '=', 'property_value_ints.entity_id') // Идентификатор дополнительного свойства ->where('property_value_ints.property_id', '=', 19) // Значение дополнительного свойства ->where('property_value_ints.value', '=', '123');
$Informationsystem_Controller_Show->show();
Обратите внимание, что сейчас значения всех доп. свойств хранятся в 6 разных таблицах:
В примере дано ограничение и объединение по числам, если используются другие таблицы, их аналогичным образом необходимо подключить.
При работе с магазином просто заменяете informationsystem на shop, при работе с группами вместо элементов заменяете item на group.
При фильтрации по нескольким свойствам в условие having необходимо подставить количество фильтруемых свойств, если фильтруете по одному свойству, то having можно опустить.
$Informationsystem_Controller_Show ->informationsystemItems() ->queryBuilder() ->leftJoin('informationsystem_item_properties', 'informationsystem_items.informationsystem_id', '=', 'informationsystem_item_properties.informationsystem_id') // Первое свойство будет целочисленное ->leftJoin('property_value_ints', 'informationsystem_items.id', '=', 'property_value_ints.entity_id', array( array('AND' => array('informationsystem_item_properties.property_id', '=', Core_QueryBuilder::expression('`property_value_ints`.`property_id`'))) ) ) // Второе свойство будет вещественное ->leftJoin('property_value_floats', 'informationsystem_items.id', '=', 'property_value_floats.entity_id', array( array('AND' => array('informationsystem_item_properties.property_id', '=', Core_QueryBuilder::expression('`property_value_floats`.`property_id`'))) ) ) // Открываем скобку ->open() // Идентификатор дополнительного свойства1 ->where('informationsystem_item_properties.property_id', '=', 19) // Значение дополнительного свойства1 ->where('property_value_ints.value', '=', '123') // Все варианты пар свойсвтво-значение добавляются через ИЛИ! ->setOr() // Идентификатор дополнительного свойства2 ->where('informationsystem_item_properties.property_id', '=', 17) // Значение дополнительного свойства2 ->where('property_value_floats.value', '>', 2.5) // Закрываем скобку ->close() ->groupBy('informationsystem_items.id') // Количество свойств у нас 2! ->having(Core_Querybuilder::expression('COUNT(DISTINCT `informationsystem_item_properties`.`property_id`)'), '=', 2); $Informationsystem_Controller_Show->show();
Пример фильтрации структуры по одному целочисленному свойству:
$Structure_Controller_Show ->structure() ->queryBuilder() ->join('property_value_ints', 'structures.id', '=', 'property_value_ints.entity_id') // Идентификатор дополнительного свойства ->where('property_value_ints.property_id', '=', 321) // Значение дополнительного свойства ->where('property_value_ints.value', '=', 1); $Structure_Controller_Show->show();
Если допускается отсутствие значения свойства, то через ИЛИ проверяем на NULL, пример для второго свойства с кодом 17:
$Informationsystem_Controller_Show ->informationsystemItems() ->queryBuilder() ->leftJoin('informationsystem_item_properties', 'informationsystem_items.informationsystem_id', '=', 'informationsystem_item_properties.informationsystem_id') // Первое свойство будет целочисленное ->leftJoin('property_value_ints', 'informationsystem_items.id', '=', 'property_value_ints.entity_id', array( array('AND' => array('informationsystem_item_properties.property_id', '=', Core_QueryBuilder::expression('`property_value_ints`.`property_id`'))) ) ) // Второе свойство будет вещественное ->leftJoin('property_value_floats', 'informationsystem_items.id', '=', 'property_value_floats.entity_id', array( array('AND' => array('informationsystem_item_properties.property_id', '=', Core_QueryBuilder::expression('`property_value_floats`.`property_id`'))) ) ) // Открываем скобку ->open() // Идентификатор дополнительного свойства1 ->where('informationsystem_item_properties.property_id', '=', 19) // Значение дополнительного свойства1 ->where('property_value_ints.value', '=', '123') // Все варианты пар свойсвтво-значение добавляются через ИЛИ! ->setOr() // Идентификатор дополнительного свойства2 ->where('informationsystem_item_properties.property_id', '=', 17) // Значение дополнительного свойства2, допускается отсутствие значения ->open() ->where('property_value_floats.value', '>', 2.5) ->setOr() ->where('property_value_floats.value', 'IS', NULL) ->close() // Закрываем скобку ->close() ->groupBy('informationsystem_items.id') // Количество свойств у нас 2! ->having(Core_Querybuilder::expression('COUNT(DISTINCT `informationsystem_item_properties`.`property_id`)'), '=', 2); $Informationsystem_Controller_Show->show();