From f1ac80cd5806017531437305606155ad9156553e Mon Sep 17 00:00:00 2001 From: Mzhelskiy Maxim Date: Sat, 13 Apr 2013 19:17:59 +0700 Subject: [PATCH] =?UTF-8?q?=D0=92=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=8C=20=D0=B2=D1=8B=D0=BD=D0=BE=D1=81=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D1=83=20=D0=B5=D0=B2=D0=B5=D0=BD=D1=82=D0=B0=20=D0=B8=D0=B7=20?= =?UTF-8?q?=D1=8D=D0=BA=D1=88=D0=B5=D0=BD=D0=B0=20=D0=B2=20=D0=BE=D1=82?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20=D0=BA=D0=BB=D0=B0?= =?UTF-8?q?=D1=81=D1=81.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- engine/classes/Action.class.php | 54 +++++++++++++++- engine/classes/Engine.class.php | 29 ++++++++- engine/classes/Event.class.php | 106 ++++++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+), 5 deletions(-) create mode 100644 engine/classes/Event.class.php diff --git a/engine/classes/Action.class.php b/engine/classes/Action.class.php index a2454de2..6e4ff409 100644 --- a/engine/classes/Action.class.php +++ b/engine/classes/Action.class.php @@ -15,6 +15,7 @@ --------------------------------------------------------- */ +require_once("Event.class.php"); /** * Абстрактный класс экшена. * @@ -31,6 +32,12 @@ abstract class Action extends LsObject { * @var array */ protected $aRegisterEvent=array(); + /** + * Список евентов, которые нужно обрабатывать внешним обработчиком + * + * @var array + */ + protected $aRegisterEventExternal=array(); /** * Список параметров из URL *
/action/event/param0/param1/../paramN/
@@ -126,13 +133,25 @@ abstract class Action extends LsObject { */ $aNames=(array)func_get_arg($iCountArgs-1); $aEvent['method']=$aNames[0]; + /** + * Определяем наличие внешнего обработчика евента + */ + $aEvent['external']=null; + $aMethod=explode('::',$aEvent['method']); + if (count($aMethod)>1) { + $aEvent['method']=$aMethod[1]; + $aEvent['external']=$aMethod[0]; + } + if (isset($aNames[1])) { $aEvent['name']=$aNames[1]; } else { $aEvent['name']=$aEvent['method']; } - if (!method_exists($this,$aEvent['method'])) { - throw new Exception("Method of the event not found: ".$aEvent['method']); + if (!$aEvent['external']) { + if (!method_exists($this,$aEvent['method'])) { + throw new Exception("Method of the event not found: ".$aEvent['method']); + } } $aEvent['preg']=func_get_arg(0); $aEvent['params_preg']=array(); @@ -142,6 +161,16 @@ abstract class Action extends LsObject { $this->aRegisterEvent[]=$aEvent; } + /** + * Регистрируем внешние обработчики для евентов + * + * @param string $sEventName + * @param string|array $sExternalClass + */ + protected function RegisterEventExternal($sEventName,$sExternalClass) { + $this->aRegisterEventExternal[$sEventName]=$sExternalClass; + } + /** * Запускает евент на выполнение * Если текущий евент не определен то запускается тот которые определен по умолчанию(default event) @@ -166,8 +195,27 @@ abstract class Action extends LsObject { } } $this->sCurrentEventName=$aEvent['name']; + if ($aEvent['external']) { + if (!isset($this->aRegisterEventExternal[$aEvent['external']])) { + throw new Exception("External processing for event not found: ".$aEvent['external']); + } + } $this->Hook_Run("action_event_".strtolower($this->sCurrentAction)."_before",array('event'=>$this->sCurrentEvent,'params'=>$this->GetParams())); - $result=call_user_func_array(array($this,$aEvent['method']),array()); + /** + * Проверяем на наличие внешнего обработчика евента + */ + if ($aEvent['external']) { + $oEvent=new $this->aRegisterEventExternal[$aEvent['external']]; + $oEvent->SetActionObject($this); + $oEvent->Init(); + if (!$aEvent['method']) { + $result=$oEvent->Exec(); + } else { + $result=call_user_func_array(array($oEvent,$aEvent['method']),array()); + } + } else { + $result=call_user_func_array(array($this,$aEvent['method']),array()); + } $this->Hook_Run("action_event_".strtolower($this->sCurrentAction)."_after",array('event'=>$this->sCurrentEvent,'params'=>$this->GetParams())); return $result; } diff --git a/engine/classes/Engine.class.php b/engine/classes/Engine.class.php index 005441b2..cd71bf38 100644 --- a/engine/classes/Engine.class.php +++ b/engine/classes/Engine.class.php @@ -106,6 +106,12 @@ class Engine extends LsObject { */ const CI_BLOCK = 256; + /** + * Имя обработчика евента + * @var int + */ + const CI_EVENT = 512; + /** * Префикс плагина * @var int @@ -139,10 +145,10 @@ class Engine extends LsObject { /** * Объекты - * CI_ACTION | CI_MAPPER | CI_HOOK | CI_PLUGIN | CI_ACTION | CI_MODULE | CI_ENTITY | CI_BLOCK + * CI_ACTION | CI_MAPPER | CI_HOOK | CI_PLUGIN | CI_EVENT | CI_MODULE | CI_ENTITY | CI_BLOCK * @var int */ - const CI_OBJECT = 351 ; + const CI_OBJECT = 863 ; /** * Текущий экземпляр движка, используется для синглтона. @@ -930,6 +936,12 @@ class Engine extends LsObject { : null ; } + if($iFlag & self::CI_EVENT){ + $aResult[self::CI_EVENT] = preg_match('/_Event([^_]+)/',$sClassName,$aMatches) + ? $aMatches[1] + : null + ; + } if($iFlag & self::CI_METHOD){ $sModuleName = isset($aResult[self::CI_MODULE]) ? $aResult[self::CI_MODULE] @@ -1027,6 +1039,19 @@ class Engine extends LsObject { $sPath = str_replace('/classes/modules/','/engine/modules/',$sPath); } } + }elseif($aInfo[self::CI_EVENT]){ + // Евент + if($aInfo[self::CI_PLUGIN]){ + // Евент плагина + $sPath .= 'plugins/'.func_underscore($aInfo[self::CI_PLUGIN]) + .'/classes/actions/'.lcfirst($aInfo[self::CI_ACTION]).'/Event'.$aInfo[self::CI_EVENT].'.class.php' + ; + }else{ + // Евент ядра + $sPath .= 'classes/actions/'.lcfirst($aInfo[self::CI_ACTION]).'/Event' + .$aInfo[self::CI_EVENT].'.class.php' + ; + } }elseif($aInfo[self::CI_ACTION]){ // Экшн if($aInfo[self::CI_PLUGIN]){ diff --git a/engine/classes/Event.class.php b/engine/classes/Event.class.php new file mode 100644 index 00000000..9e29993a --- /dev/null +++ b/engine/classes/Event.class.php @@ -0,0 +1,106 @@ +aMethodProxyAction as $sMethod) { + $aMethods[]=strtolower($sMethod); + } + $this->aMethodProxyAction=$aMethods; + } + + /** + * Устанавливает объект экшена + * + * @param Action $oAction Объект текущего экшена + */ + public function SetActionObject($oAction) { + $this->oAction=$oAction; + } + + /** + * Запускается для обработки евента, если у него не указанно имя, например, "User::" + */ + public function Exec() { + + } + + /** + * Запускается всегда перед вызовом метода евента + */ + public function Init() { + + } + + public function __get($sName) { + if (property_exists($this->oAction,$sName)) { + return $this->oAction->$sName; + } + } + + public function __set($sName,$mValue) { + if (property_exists($this->oAction,$sName)) { + return $this->oAction->$sName=$mValue; + } + } + + public function __call($sName,$aArgs) { + /** + * Обработка вызова приватных методов экшена + */ + if (in_array(strtolower($sName),$this->aMethodProxyAction)) { + array_unshift($aArgs,$sName); + return call_user_func_array(array($this->oAction,'ActionCall'),$aArgs); + } + /** + * Обработка вызова публичных методов экшена + */ + if (method_exists($this->oAction,$sName)) { + return call_user_func_array(array($this->oAction,$sName),$aArgs); + } + return Engine::getInstance()->_CallModule($sName,$aArgs); + } +} \ No newline at end of file