1
0
Fork 0
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:
Mzhelskiy Maxim 2014-06-17 13:19:17 +07:00
parent 6c7f4a4cec
commit 99711f4ef6
7 changed files with 211 additions and 132 deletions

View file

@ -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);
}
}
}

View file

@ -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) {

View file

@ -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'));
}
}
}

View file

@ -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;
}
}

View file

@ -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
*/

View file

@ -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