Динамические свойства (Dynprops)

Динамические свойства позволяют комплексно добавлять свойства к сущности (объекту) и удобно использовать их в разрезе фильтрации по списку.
Данные свойства могут быть прикреплены к объекту только посредством дополнительной сущности, обычно это категория за которой закрепляется объект. В зависимости от указанной категории у объекта может быть разный набор свойств. Для примера это может быть объект в категории недвижимость и подкатегории новостройки.

Для корректной работы компонента динамических свойств нам понадобятся таблицы определенной структуры, рассмотрим их подробно:

Таблицы динамических свойств

  1. таблица объектов, в ней будут храниться как свойства общие для всех объектов, такие как например название и дата создания объекта, так связь с категорией и значения привязанных к ней свойств, поля f1-f20 (должны называться именно так);
CREATE TABLE `bff_test_posts` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT, -- ID объекта
  `title` varchar(200) NOT NULL DEFAULT '', -- Название
  `cat_id` int(11) unsigned NOT NULL DEFAULT '0', -- ID категории
  `enabled` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `content` text,
  `content_search` text,
  -- значения дин. свойств:
  `f1` float NOT NULL DEFAULT '0',
  `f2` float NOT NULL DEFAULT '0',
  `f3` float NOT NULL DEFAULT '0',
  `f4` float NOT NULL DEFAULT '0',
  `f5` float NOT NULL DEFAULT '0',
  `f6` float NOT NULL DEFAULT '0',
  `f7` float NOT NULL DEFAULT '0',
  `f8` float NOT NULL DEFAULT '0',
  `f9` float NOT NULL DEFAULT '0',
  `f10` float NOT NULL DEFAULT '0',
  `f11` float NOT NULL DEFAULT '0',
  `f12` float NOT NULL DEFAULT '0',
  `f13` float NOT NULL DEFAULT '0',
  `f14` float NOT NULL DEFAULT '0',
  `f15` float NOT NULL DEFAULT '0',
  `f16` text,
  `f17` text,
  `f18` text,
  `f19` text,
  `f20` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
  1. таблица категорий объекта, за которыми будут закрепляться свойства:
CREATE TABLE `bff_test_cats` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(200) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
  1. таблицы для хранения настроек динамических свойств категорий:
CREATE TABLE `bff_test_cats_dp` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `owner_id` int(11) unsigned NOT NULL DEFAULT '0',
  `title_ru` varchar(100) NOT NULL DEFAULT '',
  `description_ru` text,
  `type` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `default_value` text,
  `req` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `is_search` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `is_cache` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `cache_key` varchar(100) NOT NULL DEFAULT '',
  `extra` text,
  `parent` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `parent_id` int(11) unsigned NOT NULL DEFAULT '0',
  `parent_value` smallint(5) unsigned NOT NULL DEFAULT '0',
  `enabled` tinyint(3) unsigned NOT NULL DEFAULT '1',
  `data_field` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `num` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `search_hidden` tinyint(3) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `owner_id` (`owner_id`),
  CONSTRAINT `bff_test_cats_dp_ibfk_1` FOREIGN KEY (`owner_id`) REFERENCES `bff_test_cats` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- таблица значений свойств полей с множественным выбором
CREATE TABLE `bff_test_cats_dpm` (
  `dynprop_id` int(11) unsigned NOT NULL DEFAULT '0',
  `name_ru` varchar(100) NOT NULL DEFAULT '',
  `value` int(11) NOT NULL DEFAULT '0',
  `num` tinyint(3) unsigned NOT NULL DEFAULT '0',
  KEY `dynprop_id` (`dynprop_id`),
  CONSTRAINT `bff_test_cats_dpm_ibfk_1` FOREIGN KEY (`dynprop_id`) REFERENCES `bff_test_cats_dp` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Обратим внимание на поле owner_id, оно указывает на ID категории, для которой создаются динамические свойства. Далее будет использоваться при инициализации компонента.

Инициализация компонента динамических свойств

Работа с динамическими свойствами начинается с инициализации компонента Dynprops new Dynprops(field_owner_id, table_categories, table_dp, table_dpm) и установки настроек:

/**
 * Инициализация компонента работы с дин. свойствами
 * @return \bff\db\Dynprops объект
 */
public function dp()
{
    # сохраняем объект для последующих вызовов метода
    static $dp = null;
    if (isset($dp)) {
        return $dp;
    }

    # подключаем "Динамические свойства"
    $dp = $this->attachComponent(
        'dynprops',
        new \bff\db\Dynprops(
            'owner_id', # название столбца характеристки "владельца" свойств                               
            'bff_test_cats', # таблица характеристик "владельцев", в примере категорий статей
            'bff_test_cats_dp', # таблица свойств
            'bff_test_cats_dpm' # таблица значений свойств полей с множественным выбором
        )
    );

    $dp->setSettings(array(
        'module_name'  => $this->module_name,   
        'typesAllowed' => array(
            $dp::typeCheckboxGroup,
            $dp::typeRadioGroup,
            $dp::typeRadioYesNo,
            $dp::typeCheckbox,
            $dp::typeSelect,
            $dp::typeInputText,
            $dp::typeTextarea,
            $dp::typeNumber,
            $dp::typeRange,
        ),
        'langs' => $this->locale->getLanguages(false),
        'langText' => array(
            'yes'    => _t('', 'Да'),
            'no'     => _t('', 'Нет'),
            'all'    => _t('', 'Все'),
            'select' => _t('', 'Выбрать'),
        ),
        'typesAllowedParent' => array($dp::typeSelect),
        # данные параметры соответствуют столбцам в таблице объектов (bff_test_posts)
        'datafield_int_last' => 15, # номер последнего поля для числового свойства 
        'datafield_text_first' => 16, # номер первого поля для текстового свойства 
        'datafield_text_last'  => 20, # номер последнего поля для текстового свойства 
        'searchRanges' => true,
        'cacheKey' => false,
    ));

    return $dp;
}

Использование объекта в админ-панели

Развернуто о порядке применения данного компонента в списках и формах вы найдете в данной статье