Выдано 110010 лицензий

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

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

  • Контроллер Informationsystem_Controller_Show
    • Метод informationsystemItems() для ограничений информационных элементов.
      • Промежуточная таблица для свойств informationsystem_item_properties
    • Метод informationsystemGroups() для ограничений информационных групп.
      • Промежуточная таблица для свойств informationsystem_group_properties
  • Контроллер Shop_Controller_Show
    • Метод shopItems() для ограничений товаров.
      • Промежуточная таблица для свойств shop_item_properties
    • Метод shopGroups() для ограничений групп товаров.
      • Промежуточная таблица для свойств shop_group_properties

Рассмотрим пример ограничений выборки информационных элементов, ограничения будем добавлять с использованием 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()
    ->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`')))
  )
    )
    // Идентификатор дополнительного свойства
    ->where('informationsystem_item_properties.property_id', '=', 19)
    // Значение дополнительного свойства
    ->where('property_value_ints.value', '=', '123')
    ->groupBy('informationsystem_items.id')
    // Количество свойств, если 1, то можно не указывать
    ->having(Core_Querybuilder::expression('COUNT(DISTINCT `informationsystem_item_properties`.`property_id`)'), '=', 1);
    $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();

А если значения свойства может не быть?

Если допускается отсутствие значения свойства, то через ИЛИ проверяем на 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();