mirror of
https://github.com/Oreolek/ifhub.club.git
synced 2024-06-26 03:30:48 +03:00
Переработка модуля дополнительных полей (property) под функционал поведений (behavior).
This commit is contained in:
parent
6c7f4a4cec
commit
99711f4ef6
|
@ -1,119 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Хук для работы свойств(дополнительных полей сущности)
|
||||
*/
|
||||
class HookProperty extends Hook {
|
||||
|
||||
public function RegisterHook() {
|
||||
$this->AddHook('lang_init_start','InitStart',null,-10000);
|
||||
$this->AddHook('module_orm_GetItemsByFilter_after','GetItemsByFilterAfter',null,10000);
|
||||
$this->AddHook('module_orm_GetItemsByFilter_before','GetItemsByFilterBefore',null,10000);
|
||||
$this->AddHook('module_orm_GetByFilter_before','GetItemsByFilterBefore',null,10000);
|
||||
}
|
||||
|
||||
public function InitStart() {
|
||||
/**
|
||||
* Регистрируем кастомный загрузчик классов
|
||||
*/
|
||||
spl_autoload_register(array($this,'autoload'),true,true);
|
||||
/**
|
||||
* Добавляем через наследование в объекты необходимый функционал по работе со свойствами EAV
|
||||
*/
|
||||
$aTargetTypes=$this->Property_GetTargetTypes();
|
||||
$aUseEntities=array();
|
||||
foreach($aTargetTypes as $sType=>$aParams) {
|
||||
/**
|
||||
* Защита от дубля при наследовании
|
||||
*/
|
||||
if (!in_array($aParams['entity'],$aUseEntities)) {
|
||||
$this->Plugin_Inherit($aParams['entity'],'ModuleProperty_Target_'.$aParams['entity'],'ModuleProperty');
|
||||
$aUseEntities[]=$aParams['entity'];
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Дополнительная пост-обработка результатов запроса ORM
|
||||
*
|
||||
* @param $aParams
|
||||
*/
|
||||
public function GetItemsByFilterAfter($aParams) {
|
||||
$aEntities=$aParams['aEntities'];
|
||||
$aFilter=$aParams['aFilter'];
|
||||
$this->Property_RewriteGetItemsByFilter($aEntities,$aFilter);
|
||||
}
|
||||
/**
|
||||
* Обработка фильтра для запросов к ORM
|
||||
*
|
||||
* @param $aParams
|
||||
*/
|
||||
public function GetItemsByFilterBefore($aParams) {
|
||||
$aFilter=$this->Property_RewriteFilter($aParams['aFilter'],$aParams['sEntityFull']);
|
||||
$aParams['aFilter']=$aFilter;
|
||||
}
|
||||
/**
|
||||
* Автозагрузчик классов
|
||||
* Создает новый фейковый класс для создания цепочки наследования
|
||||
* Поддерживаются только ORM сущности
|
||||
* TODO: продумать использование сценариев валидации отличных от дефолтного
|
||||
*
|
||||
* @param string $sClassName
|
||||
*/
|
||||
public function autoload($sClassName) {
|
||||
if (preg_match("#^ModuleProperty_Target_(.+)$#i",$sClassName,$aMatch)) {
|
||||
$sClass="
|
||||
class {$sClassName} extends ModuleProperty_Inherit_{$aMatch[1]} {
|
||||
public function Init() {
|
||||
parent::Init();
|
||||
\$this->aValidateRules[]=array('properties','properties_check');
|
||||
}
|
||||
|
||||
public function ValidatePropertiesCheck() {
|
||||
return \$this->Property_ValidateEntityPropertiesCheck(\$this);
|
||||
}
|
||||
|
||||
protected function afterSave() {
|
||||
parent::afterSave();
|
||||
\$this->Property_UpdatePropertiesValue(\$this->getPropertiesObject(),\$this);
|
||||
}
|
||||
|
||||
protected function afterDelete() {
|
||||
parent::afterDelete();
|
||||
\$this->Property_RemovePropertiesValue(\$this);
|
||||
}
|
||||
|
||||
public function getPropertyValue(\$sPropertyId) {
|
||||
return \$this->Property_GetEntityPropertyValue(\$this,\$sPropertyId);
|
||||
}
|
||||
|
||||
public function getProperty(\$sPropertyId) {
|
||||
return \$this->Property_GetEntityProperty(\$this,\$sPropertyId);
|
||||
}
|
||||
|
||||
public function getPropertyList() {
|
||||
return \$this->Property_GetEntityPropertyList(\$this);
|
||||
}
|
||||
}";
|
||||
eval($sClass);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -187,9 +187,9 @@ class ModuleProperty extends ModuleORM {
|
|||
* @param Entity $oTarget
|
||||
*/
|
||||
public function RemovePropertiesValue($oTarget) {
|
||||
$aProperties=$this->Property_GetPropertyItemsByFilter(array('target_type'=>$oTarget->getPropertyTargetType()));
|
||||
$aProperties=$this->Property_GetPropertyItemsByFilter(array('target_type'=>$oTarget->property->getPropertyTargetType()));
|
||||
if ($aProperties) {
|
||||
$this->AttachValueForProperties($aProperties,$oTarget->getPropertyTargetType(),$oTarget->getId());
|
||||
$this->AttachValueForProperties($aProperties,$oTarget->property->getPropertyTargetType(),$oTarget->getId());
|
||||
foreach($aProperties as $oProperty) {
|
||||
$oValue=$oProperty->getValue();
|
||||
if ($oValue and $oValue->getId()) {
|
||||
|
@ -223,8 +223,8 @@ class ModuleProperty extends ModuleORM {
|
|||
/**
|
||||
* Получаем весь список свойств у объекта
|
||||
*/
|
||||
$aPropertiesObject=$this->Property_GetPropertyItemsByFilter(array('target_type'=>$oTarget->getPropertyTargetType()));
|
||||
$this->Property_AttachValueForProperties($aPropertiesObject,$oTarget->getPropertyTargetType(),$oTarget->getId());
|
||||
$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;
|
||||
|
@ -279,7 +279,7 @@ class ModuleProperty extends ModuleORM {
|
|||
* @return array
|
||||
*/
|
||||
public function GetEntityPropertyList($oTarget) {
|
||||
$sTargetType=$oTarget->getPropertyTargetType();
|
||||
$sTargetType=$oTarget->property->getPropertyTargetType();
|
||||
/**
|
||||
* Проверяем зарегистрирован ли такой тип
|
||||
*/
|
||||
|
@ -287,7 +287,7 @@ class ModuleProperty extends ModuleORM {
|
|||
return array();
|
||||
}
|
||||
if (!$oTarget->getPropertyIsLoadAll()) {
|
||||
$aProperties=$this->oMapper->GetPropertiesValueByTarget($oTarget->getPropertyTargetType(),$oTarget->getId());
|
||||
$aProperties=$this->oMapper->GetPropertiesValueByTarget($oTarget->property->getPropertyTargetType(),$oTarget->getId());
|
||||
$this->AttachPropertiesForTarget($oTarget,$aProperties);
|
||||
}
|
||||
return $oTarget->_getDataOne('property_list');
|
||||
|
@ -320,7 +320,7 @@ class ModuleProperty extends ModuleORM {
|
|||
/**
|
||||
* Загружаем все свойства
|
||||
*/
|
||||
$aProperties=$this->oMapper->GetPropertiesValueByTarget($oTarget->getPropertyTargetType(),$oTarget->getId());
|
||||
$aProperties=$this->oMapper->GetPropertiesValueByTarget($oTarget->property->getPropertyTargetType(),$oTarget->getId());
|
||||
$this->AttachPropertiesForTarget($oTarget,$aProperties);
|
||||
}
|
||||
|
||||
|
@ -332,7 +332,7 @@ class ModuleProperty extends ModuleORM {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
$aProperties=$oTarget->getPropertyList();
|
||||
$aProperties=$oTarget->property->getPropertyList();
|
||||
if (isset($aProperties[$sPropertyId])) {
|
||||
return $aProperties[$sPropertyId];
|
||||
}
|
||||
|
@ -371,7 +371,7 @@ class ModuleProperty extends ModuleORM {
|
|||
return;
|
||||
}
|
||||
$oEntityFirst=reset($aEntitiesWork);
|
||||
$sTargetType=$oEntityFirst->getPropertyTargetType();
|
||||
$sTargetType=$oEntityFirst->property->getPropertyTargetType();
|
||||
/**
|
||||
* Проверяем зарегистрирован ли такой тип
|
||||
*/
|
||||
|
@ -486,7 +486,7 @@ class ModuleProperty extends ModuleORM {
|
|||
* Получаем данные по полям
|
||||
*/
|
||||
if ($aPropFields) {
|
||||
$sTargetType=$oEntitySample->getPropertyTargetType();
|
||||
$sTargetType=$oEntitySample->property->getPropertyTargetType();
|
||||
$aProperties=$this->Property_GetPropertyItemsByFilter(array('code in'=>array_keys($aPropFields),'target_type'=>$sTargetType));
|
||||
$iPropNum=0;
|
||||
foreach($aProperties as $oProperty) {
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
*/
|
||||
|
||||
class ModuleProperty_BehaviorPropertyEntity extends Behavior {
|
||||
/**
|
||||
* Дефолтные параметры
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $aParams=array(
|
||||
'target_type'=>'',
|
||||
);
|
||||
/**
|
||||
* Список хуков
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $aHooks=array(
|
||||
'validate_after'=>'CallbackValidateAfter',
|
||||
'after_save'=>'CallbackAfterSave',
|
||||
'after_delete'=>'CallbackAfterDelete',
|
||||
);
|
||||
|
||||
/**
|
||||
* Коллбэк
|
||||
* Выполняется при инициализации сущности
|
||||
*
|
||||
* @param $aParams
|
||||
*/
|
||||
public function CallbackValidateAfter($aParams) {
|
||||
if ($aParams['bResult']) {
|
||||
$aFields=$aParams['aFields'];
|
||||
if (is_null($aFields) or in_array('properties',$aFields)) {
|
||||
$oValidator=$this->Validate_CreateValidator('properties_check',$this,'properties');
|
||||
$oValidator->validateEntity($this->oObject,$aFields);
|
||||
$aParams['bResult']=!$this->oObject->_hasValidateErrors();
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Коллбэк
|
||||
* Выполняется после сохранения сущности
|
||||
*/
|
||||
public function CallbackAfterSave() {
|
||||
$this->Property_UpdatePropertiesValue($this->oObject->getPropertiesObject(),$this->oObject);
|
||||
}
|
||||
/**
|
||||
* Коллбэк
|
||||
* Выполняется после удаления сущности
|
||||
*/
|
||||
public function CallbackAfterDelete() {
|
||||
$this->Property_RemovePropertiesValue($this->oObject);
|
||||
}
|
||||
/**
|
||||
* Дополнительный метод для сущности
|
||||
* Запускает валидацию дополнительных полей
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function ValidatePropertiesCheck() {
|
||||
return $this->Property_ValidateEntityPropertiesCheck($this->oObject);
|
||||
}
|
||||
/**
|
||||
* Возвращает полный список свойств сущности
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPropertyList() {
|
||||
return $this->Property_GetEntityPropertyList($this->oObject);
|
||||
}
|
||||
/**
|
||||
* Возвращает значение конкретного свойства
|
||||
* @see ModuleProperty_EntityValue::getValueForDisplay
|
||||
*
|
||||
* @param int|string $sPropertyId ID или код свойства
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPropertyValue($sPropertyId) {
|
||||
return $this->Property_GetEntityPropertyValue($this->oObject,$sPropertyId);
|
||||
}
|
||||
/**
|
||||
* Возвращает объект конкретного свойства сущности
|
||||
*
|
||||
* @param int|string $sPropertyId ID или код свойства
|
||||
*
|
||||
* @return ModuleProperty_EntityProperty|null
|
||||
*/
|
||||
public function getProperty($sPropertyId) {
|
||||
return $this->Property_GetEntityProperty($this->oObject,$sPropertyId);
|
||||
}
|
||||
/**
|
||||
* Возвращает тип объекта для дополнительных полей
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPropertyTargetType() {
|
||||
if ($sType=$this->getParam('target_type')) {
|
||||
return $sType;
|
||||
}
|
||||
/**
|
||||
* Иначе дополнительно смотрим на наличие данного метода у сущности
|
||||
* Это необходимо, если тип вычисляется динамически по какой-то своей логике
|
||||
*/
|
||||
if (func_method_exists($this->oObject,'getPropertyTargetType','public')) {
|
||||
return call_user_func(array($this->oObject,'getPropertyTargetType'));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
*/
|
||||
|
||||
class ModuleProperty_BehaviorPropertyModule extends Behavior {
|
||||
/**
|
||||
* Список хуков
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $aHooks=array(
|
||||
'module_orm_GetItemsByFilter_after'=>array(
|
||||
'CallbackGetItemsByFilterAfter',1000
|
||||
),
|
||||
'module_orm_GetItemsByFilter_before'=>array(
|
||||
'CallbackGetItemsByFilterBefore',1000
|
||||
),
|
||||
'module_orm_GetByFilter_before'=>array(
|
||||
'CallbackGetItemsByFilterBefore',1000
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Модифицирует фильтр в ORM запросе
|
||||
*
|
||||
* @param $aParams
|
||||
*/
|
||||
public function CallbackGetItemsByFilterAfter($aParams) {
|
||||
$aEntities=$aParams['aEntities'];
|
||||
$aFilter=$aParams['aFilter'];
|
||||
$this->Property_RewriteGetItemsByFilter($aEntities,$aFilter);
|
||||
}
|
||||
/**
|
||||
* Модифицирует результат ORM запроса
|
||||
*
|
||||
* @param $aParams
|
||||
*/
|
||||
public function CallbackGetItemsByFilterBefore($aParams) {
|
||||
$aFilter=$this->Property_RewriteFilter($aParams['aFilter'],$aParams['sEntityFull']);
|
||||
$aParams['aFilter']=$aFilter;
|
||||
}
|
||||
}
|
|
@ -28,7 +28,17 @@ class ModuleTopic_EntityTopic extends Entity {
|
|||
* @var array
|
||||
*/
|
||||
protected $aExtra=null;
|
||||
|
||||
/**
|
||||
* Список поведений
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $aBehaviors=array(
|
||||
/**
|
||||
* Дополнительные поля
|
||||
*/
|
||||
'property'=>'ModuleProperty_BehaviorPropertyEntity',
|
||||
);
|
||||
/**
|
||||
* Определяем правила валидации
|
||||
*/
|
||||
|
@ -475,6 +485,8 @@ class ModuleTopic_EntityTopic extends Entity {
|
|||
/**
|
||||
* Возвращает тип объекта для дополнительных полей
|
||||
* Метод необходим для интеграции с дополнительными полями (модуль Property)
|
||||
* Данный метод автоматически добавляется поведением 'property' ( $this->property->getPropertyTargetType() ),
|
||||
* который возвращает тип из параметра. Но т.к. у нас тип является вычисляемым (зависит от $this->getType() ), то необходимо явно объявить данный метод
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
{* Дополнительные поля *}
|
||||
{block name='topic_content_properties'}
|
||||
{if ! $bTopicList}
|
||||
{$aProperties = $oTopic->getPropertyList()}
|
||||
{$aProperties = $oTopic->property->getPropertyList()}
|
||||
{$aInfoList = []}
|
||||
|
||||
{foreach $aProperties as $oProperty}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit bb7aa3841ae32890b5572521008583ff0e94ea14
|
||||
Subproject commit 0018b24974a73eb6234e31ad5e6ea5c31a19fdd0
|
Loading…
Reference in a new issue