Реализовано единое хранилище списка свойств для информационных систем, интернет-магазина, структуры сайта и пользователей сайта с разделением хранения значений в нескольких таблицах. Все свойства хранятся в таблице properties, разделы дополнительных свойств в таблице property_dirs.
Значения дополнительных свойств хранятся в 6 разных таблицах в зависимости от типа свойства: property_value_datetimes, property_value_files, property_value_floats, property_value_ints, property_value_strings, property_value_texts.
Для доступа к списку дополнительных свойств используются специальные модели (мы называем их linkedObject) с настроенными связями для таблиц свойств, унаследованных от соответствующих моделей. Например, Shop_Item_Property_List_Model унаследовано от Shop_Model.
linkedObjects свойств групп информационной системы
$linkedObject = Core_Entity::factory('Informationsystem_Group_Property_List', $informationsystem_id);
// Массив свойств
$aProperties = $linkedObject->Properties->findAll();
// Массив разделов свойств
$aProperty_Dirs = $linkedObject->Property_Dirs->findAll();
linkedObjects свойств элементов информационной системы
$linkedObject = Core_Entity::factory('Informationsystem_Item_Property_List', $informationsystem_id);
// Массив свойств
$aProperties = $linkedObject->Properties->findAll();
// Массив разделов свойств
$aProperty_Dirs = $linkedObject->Property_Dirs->findAll();
linkedObjects свойств групп магазина
$linkedObject = Core_Entity::factory('Shop_Group_Property_List', $shop_id);
// Массив свойств
$aProperties = $linkedObject->Properties->findAll();
// Массив разделов свойств
$aProperty_Dirs = $linkedObject->Property_Dirs->findAll();
linkedObjects свойств товаров магазина
$linkedObject = Core_Entity::factory('Shop_Item_Property_List', $shop_id);
// Массив свойств
$aProperties = $linkedObject->Properties->findAll();
// Массив разделов свойств
$aProperty_Dirs = $linkedObject->Property_Dirs->findAll();
linkedObjects заказов магазина
$linkedObject = Core_Entity::factory('Shop_Order_Property_List', $shop_id);
// Массив свойств
$aProperties = $linkedObject->Properties->findAll();
// Массив разделов свойств
$aProperty_Dirs = $linkedObject->Property_Dirs->findAll();
linkedObjects структуры сайта
$linkedObject = Core_Entity::factory('Structure_Property_List', $site_id);
// Массив свойств
$aProperties = $linkedObject->Properties->findAll();
// Массив разделов свойств
$aProperty_Dirs = $linkedObject->Property_Dirs->findAll();
linkedObjects пользователей сайта
$linkedObject = Core_Entity::factory('Siteuser_Property_List', $site_id);
// Массив свойств
$aProperties = $linkedObject->Properties->findAll();
// Массив разделов свойств
$aProperty_Dirs = $linkedObject->Property_Dirs->findAll();
Получение списка дополнительных свойств через linkedObject
// Массив свойств
$aProperties = $linkedObject->Properties->findAll();
// Массив разделов свойств
$aProperty_Dirs = $linkedObject->Property_Dirs->findAll();
Получение списка дополнительных свойств товаров, доступных группе магазина
$linkedObject = Core_Entity::factory('Shop_Item_Property_List', $shop_id);
// Массив свойств товаров, разрешенных для группы $shop_group_id
$aProperties = $linkedObject->getPropertiesForGroup($shop_group_id);
Получение списка разделов дополнительных свойств
// Массив свойств
$aProperties = $linkedObject->Properties->findAll();
// Массив разделов свойств
$aProperty_Dirs = $linkedObject->Property_Dirs->findAll();
Получение объекта дополнительного свойства по его идентификатору (см.
$oProperty = Core_Entity::factory('Property', 123);
Так как каждое дополнительное свойство может иметь несколько значений, то в массиве значений может быть ноль, одно или несколько значений.
// Объект дополнительного свойства с идентификатором 123
$oProperty = Core_Entity::factory('Property', 123);
// Массив значений свойства 123 для информационного элемента $informationsystem_item_id
$aPropertyValues = $oProperty->getValues($informationsystem_item_id);
Получение массива значений дополнительного свойства по значению свойства.
// Объект дополнительного свойства с идентификатором 123
$oProperty = Core_Entity::factory('Property', 123);
$aPropertyValues = $oProperty->getValuesByValue('Значение свойства');
В зависимости от типа дополнительного свойства объект значения может иметь атрибуты:
для свойств типа файл:
Дополнительно модели групп и элементов информационных систем, групп и товаров магазина, структуры сайта и пользователей сайта имеют метод getPropertyValues(), возвращающий все значения дополнительных свойств этого объекта.
$oStructure = Core_Entity::factory('Structure', 777);
$aPropertyValues = $oStructure->getPropertyValues();
foreach($aPropertyValues as $oPropertyValue)
{
echo '<br />Property ', htmlspecialchars($oPropertyValue->Property->name), ', value = ', htmlspecialchars($oPropertyValue->Property->type == 2
? $oPropertyValue->file
: $oPropertyValue->value);
}
С использованием метода createNewValue() получим объект нового значения дополнительного свойства, который зависит от типа дополнительного свойства. Аргументом передается идентификатор объекта, для которого создается значение.
// Объект дополнительного свойства с идентификатором 123
$oProperty = Core_Entity::factory('Property', 123);
// Объект нового значение свойства 123 для $informationsystem_item_id
$oPropertyValue = $oProperty->createNewValue($informationsystem_item_id);
// Задаем значение
$oPropertyValue->value = 1;
// Сохраняем
$oPropertyValue->save();
Изменение или установка значения дополнительного свойства, если значения не было
// Объект дополнительного свойства с идентификатором 123
$oProperty = Core_Entity::factory('Property', 123);
// Получаем массив всех значений дополнительного свойства 123 для информационного элемента $informationsystem_item_id
$aPropertyValues = $oProperty->getValues($informationsystem_item_id);
// Если нет ни одного значение, то добавляем в массив новое значение
!isset($aPropertyValues[0]) && $aPropertyValues[0] = $oProperty->createNewValue($informationsystem_item_id);
// Устанавливаем значение
$aPropertyValues[0]->value = 'Значение';
// Сохраняем
$aPropertyValues[0]->save();
Дополнительное свойство не знает о месте размещения файлов, что требует указание таких директорий для значения свойства.
Пример указания для структуры сайта
$oProperty_Value
->setHref('/' . $oStructure->getDirHref())
->setDir($oStructure->getDirPath());
для информационной группы
$oProperty_Value
->setHref($oInformationsystem_Group->getGroupHref())
->setDir($oInformationsystem_Group->getGroupPath());
для информационного элемента
$oProperty_Value
->setHref($oInformationsystem_Item->getItemHref())
->setDir($oInformationsystem_Item->getItemPath());
для группы магазина
$oProperty_Value
->setHref($oShop_Group->getGroupHref())
->setDir($oShop_Group->getGroupPath());
для товара
$oProperty_Value
->setHref($oShop_Item->getItemHref())
->setDir($oShop_Item->getItemPath());
В интернет-магазине для каждой группы товаров указываются свойства товаров, доступные товарам этой группы. Включение свойства товаров $oProperty для группы магазина $oShop_Group:
// Объект дополнительного свойства с идентификатором 123
$oProperty = Core_Entity::factory('Property', 123);
// Объект магазина с идентификатором 1
$oShop = Core_Entity::factory('Shop', 1);
// Объект группы магазина с идентификатором 5
$oShop_Group = Core_Entity::factory('Shop_Group', 5);
$oShop->Shop_Item_Property_For_Groups->allowAccess($oProperty->Shop_Item_Property->id, $oShop_Group->id);
Значения свойств хранятся в таблицах, зависящих от вида свойства. В случае изменения типа свойства может потребоваться перенести значения из одной таблицы в другую. Рассмотрим пример смены типа свойства со строки (property_value_strings) на большое текстовое поле (property_value_texts) для свойства номер 17. Изменив тип свойства перенесем значения свойства из таблицы строк в таблицу текстов:
INSERT INTO `property_value_texts` (`property_id`, `entity_id`, `value`) SELECT `property_id`, `entity_id`, `value` FROM `property_value_strings` WHERE `property_id` = 17;
Проверяем наличие значений с новым типом, если все нормально перенеслось, то удаляем значения в таблице предыдущего типа:
DELETE FROM `property_value_strings` WHERE `property_id` = 17;