1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-06-30 21:45:01 +03:00
ifhub.club/application/classes/modules/property/Property.class.php

969 lines
36 KiB
PHP
Raw Normal View History

<?php
2014-10-08 08:20:29 +03:00
/*
* LiveStreet CMS
* Copyright © 2013 OOO "ЛС-СОФТ"
*
* ------------------------------------------------------
*
* Official site: www.livestreetcms.com
* Contact e-mail: office@livestreetcms.com
*
* GNU General Public License, version 2:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* ------------------------------------------------------
*
* @link http://www.livestreetcms.com
* @copyright 2013 OOO "ЛС-СОФТ"
* @author Maxim Mzhelskiy <rus.engine@gmail.com>
*
*/
2014-10-08 08:20:29 +03:00
/**
* Модуль управления дополнительными полями
*
* @package application.modules.property
* @since 2.0
*/
class ModuleProperty extends ModuleORM
{
/**
* Список возможных типов свойств/полей
*/
const PROPERTY_TYPE_INT = 'int';
const PROPERTY_TYPE_FLOAT = 'float';
const PROPERTY_TYPE_VARCHAR = 'varchar';
const PROPERTY_TYPE_TEXT = 'text';
const PROPERTY_TYPE_CHECKBOX = 'checkbox';
const PROPERTY_TYPE_TAGS = 'tags';
const PROPERTY_TYPE_VIDEO_LINK = 'video_link';
const PROPERTY_TYPE_SELECT = 'select';
const PROPERTY_TYPE_DATE = 'date';
const PROPERTY_TYPE_FILE = 'file';
const PROPERTY_TYPE_IMAGE = 'image';
/**
* Список состояний типов объектов
*/
const TARGET_STATE_ACTIVE = 1;
const TARGET_STATE_NOT_ACTIVE = 2;
const TARGET_STATE_REMOVE = 3;
protected $oMapper = null;
/**
* Список доступных типов полей
*
* @var array
*/
protected $aPropertyTypes = array(
self::PROPERTY_TYPE_INT,
self::PROPERTY_TYPE_FLOAT,
self::PROPERTY_TYPE_VARCHAR,
self::PROPERTY_TYPE_TEXT,
self::PROPERTY_TYPE_CHECKBOX,
self::PROPERTY_TYPE_TAGS,
self::PROPERTY_TYPE_VIDEO_LINK,
self::PROPERTY_TYPE_SELECT,
self::PROPERTY_TYPE_DATE,
self::PROPERTY_TYPE_FILE,
self::PROPERTY_TYPE_IMAGE
);
/**
* Список разрешенных типов
* На данный момент допустимы параметры entity=>ModuleTest_EntityTest - указывает на класс сущности
* name=>Статьи
*
* @var array
*/
protected $aTargetTypes = array();
public function Init()
{
parent::Init();
$this->oMapper = Engine::GetMapper(__CLASS__);
/**
* Получаем типы из БД и активируем их
*/
if ($aTargetItems = $this->GetTargetItemsByFilter(array('state' => self::TARGET_STATE_ACTIVE))) {
foreach ($aTargetItems as $oTarget) {
$this->Property_AddTargetType($oTarget->getType(), $oTarget->getParams());
}
}
}
/**
* Возвращает список типов объектов
*
* @return array
*/
public function GetTargetTypes()
{
return $this->aTargetTypes;
}
/**
* Добавляет в разрешенные новый тип
*
* @param string $sTargetType Тип
* @param array $aParams Параметры
* @return bool
*/
public function AddTargetType($sTargetType, $aParams = array())
{
if (!array_key_exists($sTargetType, $this->aTargetTypes)) {
$this->aTargetTypes[$sTargetType] = $aParams;
return true;
}
return false;
}
/**
* Проверяет разрешен ли данный тип
*
* @param string $sTargetType Тип
* @return bool
*/
public function IsAllowTargetType($sTargetType)
{
return in_array($sTargetType, array_keys($this->aTargetTypes));
}
/**
* Возвращает парметры нужного типа
*
* @param string $sTargetType
*
* @return mixed
*/
public function GetTargetTypeParams($sTargetType)
{
if ($this->IsAllowTargetType($sTargetType)) {
return $this->aTargetTypes[$sTargetType];
}
}
/**
* Проверяет разрешен ли тип поля
*
* @param string $sType
*
* @return bool
*/
public function IsAllowPropertyType($sType)
{
return in_array($sType, $this->aPropertyTypes);
}
/**
* Для каждого из свойств получает значение
*
* @param array $aProperties Список свойств
* @param string $sTargetType Тип объекта
* @param int $iTargetId ID объекта
*
* @return bool
*/
public function AttachValueForProperties($aProperties, $sTargetType, $iTargetId)
{
if (!$aProperties) {
return false;
}
/**
* Формируем список ID свойств
*/
$aPropertyIds = array();
foreach ($aProperties as $oProperty) {
$aPropertyIds[] = $oProperty->getId();
}
/**
* Получаем список значений
*/
$aValues = $this->Property_GetValueItemsByFilter(array(
2017-01-13 12:19:12 +02:00
'target_id' => $iTargetId,
'target_type' => $sTargetType,
'property_id in' => $aPropertyIds,
'#index-from' => 'property_id'
));
/**
* Аттачим значения к свойствам
*/
foreach ($aProperties as $oProperty) {
if (isset($aValues[$oProperty->getId()])) {
$oProperty->setValue($aValues[$oProperty->getId()]);
} else {
$oProperty->setValue(Engine::GetEntity('ModuleProperty_EntityValue', array(
2017-01-13 12:19:12 +02:00
'property_id' => $oProperty->getId(),
'property_type' => $oProperty->getType(),
'target_type' => $sTargetType,
'target_id' => $iTargetId
)));
}
$oProperty->getValue()->setProperty($oProperty);
}
return true;
}
/**
* Сохраняет текущие значения свойств
*
* @param array $aProperties
* @param Entity|int $oTarget Объект сущности или ID сущности
*/
public function UpdatePropertiesValue($aProperties, $oTarget)
{
if ($aProperties) {
foreach ($aProperties as $oProperty) {
$oValue = $oProperty->getValue();
$oValue->setTargetId(is_object($oTarget) ? $oTarget->getId() : $oTarget);
$oValue->setPropertyType($oProperty->getType());
$oValue->Save();
}
}
}
/**
* Удаление всех свойств у конкретного объекта/сущности
*
* @param Entity $oTarget
*/
public function RemovePropertiesValue($oTarget)
{
$aProperties = $this->Property_GetPropertyItemsByFilter(array('target_type' => $oTarget->property->getPropertyTargetType()));
if ($aProperties) {
$this->AttachValueForProperties($aProperties, $oTarget->property->getPropertyTargetType(),
$oTarget->getId());
foreach ($aProperties as $oProperty) {
$oValue = $oProperty->getValue();
if ($oValue and $oValue->getId()) {
$oValueType = $oValue->getValueTypeObject();
/**
* Кастомное удаление
*/
$oValueType->removeValue();
/**
* Удаляем основные данные
*/
$oValue->Delete();
}
}
}
}
/**
* Валидирует значение свойств у объекта
*
* @param Entity $oTarget
*
* @return bool|string
*/
public function ValidateEntityPropertiesCheck($oTarget)
{
/**
* Пробуем получить свойства из реквеста
*/
$oTarget->setProperties($oTarget->getProperties() ? $oTarget->getProperties() : getRequest('property'));
$aPropertiesValue = $oTarget->getProperties();
$aPropertiesResult = array();
/**
* Получаем весь список свойств у объекта
*/
$aPropertiesObject = $this->Property_GetPropertyItemsByFilter(array('target_type' => $oTarget->property->getPropertyTargetType()));
$this->Property_AttachValueForProperties($aPropertiesObject, $oTarget->property->getPropertyTargetType(),
$oTarget->getId());
foreach ($aPropertiesObject as $oProperty) {
$oValue = $oProperty->getValue();
$sValue = isset($aPropertiesValue[$oProperty->getId()]) ? $aPropertiesValue[$oProperty->getId()] : null;
/**
* Валидируем значение
*/
$oValueType = $oValue->getValueTypeObject();
$oValueType->setValueForValidate($sValue);
if (true === ($sRes = $oValueType->validate())) {
$oValueType->setValue($oValueType->getValueForValidate());
$aPropertiesResult[$oProperty->getId()] = $oProperty;
} else {
return $this->Lang_Get('property.notices.validate_value_wrong',
array('field' => $oProperty->getTitle())) . ($sRes ? $sRes : $this->Lang_Get('property.notices.validate_value_wrong_base'));
}
}
$oTarget->setPropertiesObject($aPropertiesResult);
return true;
}
/**
* Возвращает значение свойсва у объекта
*
* @param Entity $oTarget Объект сущности
* @param int $sPropertyId ID свойства
*
* @return null|mixed
*/
public function GetEntityPropertyValue($oTarget, $sPropertyId)
{
if ($oProperty = $this->GetEntityPropertyValueObject($oTarget, $sPropertyId)) {
return $oProperty->getValue()->getValueForDisplay();
}
return null;
}
/**
* Возвращает объект свойства сущности
*
* @param Entity $oTarget Объект сущности
* @param int $sPropertyId ID свойства
*
* @return null|ModuleProperty_EntityProperty
*/
public function GetEntityProperty($oTarget, $sPropertyId)
{
if ($oProperty = $this->GetEntityPropertyValueObject($oTarget, $sPropertyId)) {
return $oProperty;
}
return null;
}
/**
* Возвращает список свойств сущности
*
* @param Entity $oTarget Объект сущности
*
* @return array
*/
public function GetEntityPropertyList($oTarget)
{
$sTargetType = $oTarget->property->getPropertyTargetType();
/**
* Проверяем зарегистрирован ли такой тип
*/
if (!$this->IsAllowTargetType($sTargetType)) {
return array();
}
if (!$oTarget->getPropertyIsLoadAll()) {
$aProperties = $this->oMapper->GetPropertiesValueByTarget($oTarget->property->getPropertyTargetType(),
$oTarget->getId());
$this->AttachPropertiesForTarget($oTarget, $aProperties);
}
return $oTarget->_getDataOne('property_list');
}
/**
* Служебный метод для аттача свойст к сущности
*
* @param Entity $oTarget Объект сущности
* @param array $aProperties Список свойств
*/
public function AttachPropertiesForTarget($oTarget, $aProperties)
{
$oTarget->setPropertyList($aProperties);
$oTarget->setPropertyIsLoadAll(true);
$aMapperCode = array();
foreach ($aProperties as $oProperty) {
$aMapperCode[$oProperty->getCode()] = $oProperty->getId();
}
$oTarget->setPropertyMapperCode($aMapperCode);
}
/**
* Возвращает объект свойства
*
* @param Entity $oTarget Объект сущности
* @param array $sPropertyId ID свойства
*
* @return null
*/
public function GetEntityPropertyValueObject($oTarget, $sPropertyId)
{
if (!$oTarget->getPropertyIsLoadAll()) {
/**
* Загружаем все свойства
*/
$aProperties = $this->oMapper->GetPropertiesValueByTarget($oTarget->property->getPropertyTargetType(),
$oTarget->getId());
$this->AttachPropertiesForTarget($oTarget, $aProperties);
}
if (!is_numeric($sPropertyId)) {
$aMapperCode = $oTarget->getPropertyMapperCode();
if (isset($aMapperCode[$sPropertyId])) {
$sPropertyId = $aMapperCode[$sPropertyId];
} else {
return null;
}
}
$aProperties = $oTarget->property->getPropertyList();
if (isset($aProperties[$sPropertyId])) {
return $aProperties[$sPropertyId];
}
return null;
}
/**
* Переопределяем метод для возможности цеплять свои кастомные данные при ORM запросах - свойства
*
* @param array $aResult
* @param array $aFilter
* @param null|string $sEntityFull
*/
public function RewriteGetItemsByFilter($aResult, $aFilter = array(), $sEntityFull = null)
{
if (!$aResult) {
return;
}
/**
* Список на входе может быть двух видом:
* 1 - одномерный массив
* 2 - двумерный, если применялась группировка (использование '#index-group')
*
* Поэтому сначала сформируем линейный список
*/
if (isset($aFilter['#index-group']) and $aFilter['#index-group']) {
$aEntitiesWork = array();
foreach ($aResult as $aItems) {
foreach ($aItems as $oItem) {
$aEntitiesWork[] = $oItem;
}
}
} else {
$aEntitiesWork = $aResult;
}
if (!$aEntitiesWork) {
return;
}
$oEntityFirst = reset($aEntitiesWork);
if (!$oEntityFirst->property) {
return;
}
/**
* Проверяем необходимость цеплять свойства
*/
if (isset($aFilter['#properties']) and $aFilter['#properties']) {
$aEntitiesId = array();
2017-01-13 12:19:12 +02:00
$aTargetTypes = array();
foreach ($aEntitiesWork as $oEntity) {
$sTargetType = $oEntity->property->getPropertyTargetType();
if ($this->IsAllowTargetType($sTargetType)) {
$aEntitiesId[] = $oEntity->getId();
$aTargetTypes[] = $sTargetType;
}
}
2017-01-13 12:19:12 +02:00
$aTargetTypes = array_unique($aTargetTypes);
/**
* Получаем все свойства со значениями для всех объектов
*/
2017-01-13 12:19:12 +02:00
$aResult = $this->oMapper->GetPropertiesValueByTargetArray($aTargetTypes, $aEntitiesId);
if ($aResult) {
/**
* Формируем список свойств и значений
*/
$aProperties = array();
$aValues = array();
foreach ($aResult as $aRow) {
$aPropertyData = array();
$aValueData = array();
foreach ($aRow as $k => $v) {
if (strpos($k, 'prop_') === 0) {
$aPropertyData[str_replace('prop_', '', $k)] = $v;
} else {
$aValueData[$k] = $v;
}
}
if (!isset($aProperties[$aRow['prop_id']])) {
$oProperty = Engine::GetEntity('ModuleProperty_EntityProperty', $aPropertyData);
$aProperties[$aRow['prop_id']] = $oProperty;
}
if ($aRow['target_id']) {
$sKey = $aRow['property_id'] . '_' . $aRow['target_id'];
$aValues[$sKey] = Engine::GetEntity('ModuleProperty_EntityValue', $aValueData);
}
}
/**
* Собираем данные
*/
foreach ($aEntitiesWork as $oEntity) {
$aPropertiesClone = array();
foreach ($aProperties as $oProperty) {
if ($oEntity->property->getPropertyTargetType() != $oProperty->getTargetType()) {
continue;
}
$oPropertyNew = clone $oProperty;
$sKey = $oProperty->getId() . '_' . $oEntity->getId();
if (isset($aValues[$sKey])) {
$oValue = $aValues[$sKey];
} else {
$oValue = Engine::GetEntity('ModuleProperty_EntityValue', array(
2017-01-13 12:19:12 +02:00
'property_type' => $oProperty->getType(),
'property_id' => $oProperty->getId(),
'target_type' => $oProperty->getTargetType(),
'target_id' => $oEntity->getId()
));
}
$oPropertyNew->setValue($oValue);
$oValue->setProperty($oPropertyNew);
$aPropertiesClone[$oPropertyNew->getId()] = $oPropertyNew;
}
$this->AttachPropertiesForTarget($oEntity, $aPropertiesClone);
}
}
}
}
/**
* Обработка фильтра ORM запросов
*
* @param array $aFilter
* @param array $sEntityFull
*
* @return array
*/
public function RewriteFilter($aFilter, $sEntityFull)
{
$oEntitySample = Engine::GetEntity($sEntityFull);
if (!$oEntitySample->property) {
return $aFilter;
}
if (!isset($aFilter['#join'])) {
$aFilter['#join'] = array();
}
$aPropFields = array();
foreach ($aFilter as $k => $v) {
if (preg_match('@^#prop:(.+)$@i', $k, $aMatch)) {
/**
* Сначала формируем список полей с операндами
*/
$aK = explode(' ', trim($aMatch[1]), 2);
$sPropCurrent = $aK[0];
$sConditionCurrent = ' = ';
if (count($aK) > 1) {
$sConditionCurrent = strtolower($aK[1]);
}
$aPropFields[$sPropCurrent] = array('value' => $v, 'condition' => $sConditionCurrent);
}
}
/**
* Проверяем на наличие сортировки по полям
*/
$aOrders = array();
if (isset($aFilter['#order'])) {
if (!is_array($aFilter['#order'])) {
$aFilter['#order'] = array($aFilter['#order']);
}
foreach ($aFilter['#order'] as $key => $value) {
$aKeys = explode(':', $key);
if (count($aKeys) == 2 and strtolower($aKeys[0]) == 'prop') {
$aOrders[$aKeys[1]] = array('way' => $value, 'replace' => $key);
}
}
}
/**
* Получаем данные по полям
*/
if ($aPropFields) {
$sTargetType = $oEntitySample->property->getPropertyTargetType();
$aProperties = $this->Property_GetPropertyItemsByFilter(array(
2017-01-13 12:19:12 +02:00
'code in' => array_keys($aPropFields),
'target_type' => $sTargetType
));
$iPropNum = 0;
foreach ($aProperties as $oProperty) {
/**
* По каждому полю строим JOIN запрос
*/
$sCondition = $aPropFields[$oProperty->getCode()]['condition'];
$bIsArray = in_array(strtolower($sCondition), array('in', 'not in')) ? true : false;
if (in_array($oProperty->getType(),
array(ModuleProperty::PROPERTY_TYPE_INT, ModuleProperty::PROPERTY_TYPE_CHECKBOX))) {
$sFieldValue = "value_int";
$sConditionFull = $sCondition . ($bIsArray ? ' (?a) ' : ' ?d ');
} elseif ($oProperty->getType() == ModuleProperty::PROPERTY_TYPE_FLOAT) {
$sFieldValue = "value_float";
$sConditionFull = $sCondition . ($bIsArray ? ' (?a) ' : ' ?f ');
} elseif (in_array($oProperty->getType(), array(
2017-01-13 12:19:12 +02:00
ModuleProperty::PROPERTY_TYPE_VARCHAR,
ModuleProperty::PROPERTY_TYPE_TAGS,
ModuleProperty::PROPERTY_TYPE_VIDEO_LINK
))) {
$sFieldValue = "value_varchar";
$sConditionFull = $sCondition . ($bIsArray ? ' (?a) ' : ' ? ');
} elseif ($oProperty->getType() == ModuleProperty::PROPERTY_TYPE_TEXT) {
$sFieldValue = "value_text";
$sConditionFull = $sCondition . ($bIsArray ? ' (?a) ' : ' ? ');
} else {
$sFieldValue = "value_varchar";
$sConditionFull = $sCondition . ($bIsArray ? ' (?a) ' : ' ? ');
}
$iPropNum++;
$sJoin = "JOIN " . Config::Get('db.table.property_value') . " propv{$iPropNum} ON
t.`{$oEntitySample->_getPrimaryKey()}` = propv{$iPropNum}.target_id and
propv{$iPropNum}.target_type = '{$sTargetType}' and
propv{$iPropNum}.property_id = {$oProperty->getId()} and
propv{$iPropNum}.{$sFieldValue} {$sConditionFull}";
$aFilter['#join'][$sJoin] = array($aPropFields[$oProperty->getCode()]['value']);
/**
* Проверяем на сортировку по текущему полю
*/
if (isset($aOrders[$oProperty->getCode()])) {
$aOrders[$oProperty->getCode()]['field'] = "propv{$iPropNum}.{$sFieldValue}";
}
}
}
/**
* Подменяем сортировку
*/
foreach ($aOrders as $aItem) {
if (isset($aFilter['#order'][$aItem['replace']])) {
$aFilter['#order'] = $this->ArrayReplaceKey($aFilter['#order'], $aItem['replace'], $aItem['field']);
}
}
return $aFilter;
}
/**
* Служебный метод для замены ключа в массиве
*
* @param array $aArray
* @param string $sKeyOld
* @param string $sKeyNew
*
* @return array|bool
*/
protected function ArrayReplaceKey($aArray, $sKeyOld, $sKeyNew)
{
$aKeys = array_keys($aArray);
if (false === $iIndex = array_search($sKeyOld, $aKeys)) {
return false;
}
$aKeys[$iIndex] = $sKeyNew;
return array_combine($aKeys, array_values($aArray));
}
/**
* Удаляет теги свойства у сущности
*
* @param string $sTargetType Тип объекта сущности
* @param int $iTargetId ID объекта сущности
* @param int $iPropertyId ID свойства
*
* @return mixed
*/
public function RemoveValueTagsByTarget($sTargetType, $iTargetId, $iPropertyId)
{
// сбрасываем кеш
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('ModuleProperty_EntityValueTag_delete'));
return $this->oMapper->RemoveValueTagsByTarget($sTargetType, $iTargetId, $iPropertyId);
}
/**
* Удаляет значения типа select
*
* @param string $sTargetType Тип объекта сущности
* @param int $iTargetId ID объекта сущности
* @param int $iPropertyId ID свойства
*
* @return mixed
*/
public function RemoveValueSelectsByTarget($sTargetType, $iTargetId, $iPropertyId)
{
// сбрасываем кеш
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('ModuleProperty_EntityValueSelect_delete'));
return $this->oMapper->RemoveValueSelectsByTarget($sTargetType, $iTargetId, $iPropertyId);
}
/**
* Возвращает список тегов/знаяений свойства. Используется для авкомплиттера тегов.
*
* @param string $sTag
* @param int $iPropertyId
* @param int $iLimit
*
* @return mixed
*/
public function GetPropertyTagsByLike($sTag, $iPropertyId, $iLimit)
{
return $this->oMapper->GetPropertyTagsByLike($sTag, $iPropertyId, $iLimit);
}
/**
* Возвращет список группированных тегов с их количеством для необходимого свойства
*
* @param int $iPropertyId
* @param int $iLimit
*
* @return mixed
*/
public function GetPropertyTagsGroup($iPropertyId, $iLimit)
{
return $this->oMapper->GetPropertyTagsGroup($iPropertyId, $iLimit);
}
/**
* Формирует и возвращает облако тегов необходимого свойства
*
* @param int $iPropertyId
* @param int $iLimit
*
* @return mixed
*/
public function GetPropertyTagsCloud($iPropertyId, $iLimit)
{
$aTags = $this->Property_GetPropertyTagsGroup($iPropertyId, $iLimit);
if ($aTags) {
$this->Tools_MakeCloud($aTags);
}
return $aTags;
}
/**
* Список ID сущностей по тегу конкретного свойства
*
* @param int $iPropertyId
* @param string $sTag
* @param int $iCurrPage
* @param int $iPerPage
*
* @return array
*/
public function GetTargetsByTag($iPropertyId, $sTag, $iCurrPage, $iPerPage)
{
return array(
'collection' => $this->oMapper->GetTargetsByTag($iPropertyId, $sTag, $iCount, $iCurrPage, $iPerPage),
'count' => $iCount
);
}
/**
* Производит изменение названия типа объекта, например "article" меняем на "news"
*
* @param $sType
* @param $sTypeNew
*/
public function ChangeTargetType($sType, $sTypeNew)
{
$this->oMapper->UpdatePropertyByTargetType($sType, $sTypeNew);
$this->oMapper->UpdatePropertyTargetByTargetType($sType, $sTypeNew);
$this->oMapper->UpdatePropertySelectByTargetType($sType, $sTypeNew);
$this->oMapper->UpdatePropertyValueByTargetType($sType, $sTypeNew);
$this->oMapper->UpdatePropertyValueSelectByTargetType($sType, $sTypeNew);
$this->oMapper->UpdatePropertyValueTagByTargetType($sType, $sTypeNew);
/**
* Сбрасываем кеши
*/
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array(
'ModuleProperty_EntityProperty_save',
'ModuleProperty_EntityTarget_save',
'ModuleProperty_EntitySelect_save',
'ModuleProperty_EntityValue_save',
'ModuleProperty_EntityValueSelect_save',
'ModuleProperty_EntityValueTag_save',
));
}
/**
* Создает новый тип объекта в БД для дополнительных полей
*
* @param string $sType
* @param array $aParams
* @param bool $bRewrite
*
* @return bool|ModuleProperty_EntityTarget
*/
public function CreateTargetType($sType, $aParams, $bRewrite = false)
{
/**
* Проверяем есть ли уже такой тип
*/
if ($oTarget = $this->GetTargetByType($sType)) {
if (!$bRewrite) {
return false;
}
} else {
$oTarget = Engine::GetEntity('ModuleProperty_EntityTarget');
$oTarget->setType($sType);
}
$oTarget->setState(self::TARGET_STATE_ACTIVE);
$oTarget->setParams($aParams);
if ($oTarget->Save()) {
return $oTarget;
}
return false;
}
/**
* Отключает тип объекта для дополнительных полей
*
* @param string $sType
* @param int $iState self::TARGET_STATE_NOT_ACTIVE или self::TARGET_STATE_REMOVE
*/
public function RemoveTargetType($sType, $iState = self::TARGET_STATE_NOT_ACTIVE)
{
if ($oTarget = $this->GetTargetByType($sType)) {
$oTarget->setState($iState);
$oTarget->Save();
}
}
/**
* Возвращает набор полей/свойств для показа их на форме редактирования
*
* @param $sTargetType
* @param $iTargetId
*
* @return mixed
*/
public function GetPropertiesForUpdate($sTargetType, $iTargetId)
{
/**
* Проверяем зарегистрирован ли такой тип
*/
if (!$this->IsAllowTargetType($sTargetType)) {
return array();
}
/**
* Получаем набор свойств
*/
$aProperties = $this->Property_GetPropertyItemsByFilter(array(
2017-01-13 12:19:12 +02:00
'target_type' => $sTargetType,
'#order' => array('sort' => 'desc')
));
$this->Property_AttachValueForProperties($aProperties, $sTargetType, $iTargetId);
return $aProperties;
}
/**
* Автоматическое создание дополнительного поля
* TODO: учитывать $aAdditional для создание вариантов в типе select
*
* @param string $sTargetType Тип объекта дял которого добавляем поле
* @param array $aData Данные поля: array('type'=>'int','title'=>'Название','code'=>'newfield','description'=>'Описание поля','sort'=>100);
* @param bool $bSkipErrorUniqueCode Пропускать ошибку при дублировании кода поля (такое поле уже существует)
* @param array $aValidateRules Данные валидатора поля, зависят от конкретного типа поля: array('allowEmpty'=>true,'max'=>1000)
* @param array $aParams Дополнительные параметры поля, зависят от типа поля
* @param array $aAdditional Дополнительные данные, которые нужно учитывать при создании поля, зависят от типа поля
*
* @return bool|ModuleProperty_EntityProperty
*/
public function CreateTargetProperty(
$sTargetType,
$aData,
$bSkipErrorUniqueCode = true,
$aValidateRules = array(),
$aParams = array(),
$aAdditional = array()
) {
/**
* Если необходимо и поле уже существует, то пропускаем создание
*/
if ($bSkipErrorUniqueCode and isset($aData['code']) and $this->GetPropertyByTargetTypeAndCode($sTargetType,
$aData['code'])
) {
return true;
}
$oProperty = Engine::GetEntity('ModuleProperty_EntityProperty');
$oProperty->_setValidateScenario('auto');
$oProperty->_setDataSafe($aData);
$oProperty->setValidateRulesRaw($aValidateRules);
$oProperty->setParamsRaw($aParams);
$oProperty->setTargetType($sTargetType);
if ($oProperty->_Validate()) {
if ($oProperty->Add()) {
return $oProperty;
} else {
return $this->Lang_Get('property.notices.create_error');
}
} else {
return $oProperty->_getValidateError();
}
return false;
}
/**
* Используется для создания дефолтных дополнительных полей при активации плагина
*
* @param array $aProperties Список полей
* <pre>
* array(
* array(
* 'data'=>array(
* 'type'=>ModuleProperty::PROPERTY_TYPE_INT,
* 'title'=>'Номер',
* 'code'=>'number',
* 'sort'=>100
* ),
* 'validate_rule'=>array(
* 'min'=>10
* ),
* 'params'=>array(),
* 'additional'=>array()
* )
* );
* </pre>
* @param string $sTargetType Тип объекта
*
* @return bool
*/
public function CreateDefaultTargetPropertyFromPlugin($aProperties, $sTargetType)
{
foreach ($aProperties as $aProperty) {
$sResultMsg = $this->CreateTargetProperty($sTargetType, $aProperty['data'], true,
$aProperty['validate_rule'], $aProperty['params'], $aProperty['additional']);
if ($sResultMsg !== true and !is_object($sResultMsg)) {
if (is_string($sResultMsg)) {
$this->Message_AddErrorSingle($sResultMsg, $this->Lang_Get('common.error.error'), true);
}
/**
* Отменяем добавление типа
*/
$this->RemoveTargetType($sTargetType, ModuleProperty::TARGET_STATE_NOT_ACTIVE);
return false;
}
}
return true;
}
public function RemoveValueByPropertyId($iPropertyId)
{
$bRes = $this->oMapper->RemoveValueByPropertyId($iPropertyId);
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('ModuleProperty_EntityValue_delete'));
return $bRes;
}
public function RemoveValueTagByPropertyId($iPropertyId)
{
$bRes = $this->oMapper->RemoveValueTagByPropertyId($iPropertyId);
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('ModuleProperty_EntityValueTag_delete'));
return $bRes;
}
public function RemoveValueSelectByPropertyId($iPropertyId)
{
$bRes = $this->oMapper->RemoveValueSelectByPropertyId($iPropertyId);
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('ModuleProperty_EntityValueSelect_delete'));
return $bRes;
}
public function RemoveSelectByPropertyId($iPropertyId)
{
$bRes = $this->oMapper->RemoveSelectByPropertyId($iPropertyId);
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('ModuleProperty_EntitySelect_delete'));
return $bRes;
}
public function CheckAllowTargetObject($sTargetType, $iTargetId, $aParams = array())
{
$sMethod = 'CheckAllowTargetObject' . func_camelize($sTargetType);
if (method_exists($this, $sMethod)) {
if (!array_key_exists('user', $aParams)) {
$aParams['user'] = $this->oUserCurrent;
}
return $this->$sMethod($iTargetId, $aParams);
}
/**
* По умолчанию считаем доступ разрешен
*/
return true;
}
}