Ограничения по дополнительным свойствам в контроллерах

С версии 6.9.4 контроллерам показа Informationsystem_Controller_Show, Shop_Controller_Show, Siteuser_List_Controller_Show добавлен метод addFilter(), реализующий простой интерфейс указания условий фильтрации. См. Фильтр и быстрый фильтр → Применение фильтров.

Самостоятельное указание условий через QueryBuilder

Контроллеры показа позволяют влиять на отбираемые элементы, добавлять дополнительные условия и т.п. Получение объекта, которому могут быть добавлены дополнительные ограничение выборки, осуществляется различными методами, зависящими от контроллера и выбираемых элементов:

Рассмотрим пример ограничений выборки информационных элементов, ограничения будем добавлять с использованием 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 разных таблицах:

  1. property_value_datetimes для даты и даты-времени;
  2. property_value_files для файлов;
  3. property_value_ints для целых чисел;
  4. property_value_floats для чисел с плавающей запятой;
  5. property_value_strings для строк;
  6. property_value_texts для текстов.

В примере дано ограничение и объединение по числам, если используются другие таблицы, их аналогичным образом необходимо подключить.

При работе с магазином просто заменяете 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();

Не нашли ответ на свой вопрос в документации? Направьте обращение в службу поддержки или онлайн чат.