1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-07-03 06:55:03 +03:00

Возможность выносить обработку евента из экшена в отдельный класс.

This commit is contained in:
Mzhelskiy Maxim 2013-04-13 19:17:59 +07:00
parent 8d55ecf4e6
commit f1ac80cd58
3 changed files with 184 additions and 5 deletions

View file

@ -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
* <pre>/action/event/param0/param1/../paramN/</pre>
@ -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;
}

View file

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

View file

@ -0,0 +1,106 @@
<?php
/*-------------------------------------------------------
*
* LiveStreet Engine Social Networking
* Copyright © 2008 Mzhelskiy Maxim
*
*--------------------------------------------------------
*
* Official site: www.livestreet.ru
* Contact e-mail: rus.engine@gmail.com
*
* GNU General Public License, version 2:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
---------------------------------------------------------
*/
/**
* Абстрактный класс внешнего обработчика евента.
*
* От этого класса наследуются внешние обработчики евентов.
*
* @package engine
* @since 1.1
*/
abstract class Event extends LsObject {
/**
* Объект текущего экшена
*
* @var null|Action
*/
protected $oAction=null;
/**
* Список приватных методов экшена для проксирования из внешнего евента
*
* @var array
*/
protected $aMethodProxyAction=array(
'GetDefaultEvent','GetEventMatch','GetParamEventMatch','GetParam','GetParams',
'SetParam','SetTemplate','SetTemplateAction','EventNotFound',
);
public function __construct() {
/**
* Переводим доступные методы к нижнему регистру
*/
$aMethods=array();
foreach($this->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);
}
}