Changeset View
Changeset View
Standalone View
Standalone View
branches/5.3.x/core/kernel/utility/event.php
<?php | <?php | ||||
/** | /** | ||||
* @version $Id$ | * @version $Id$ | ||||
* @package In-Portal | * @package In-Portal | ||||
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. | * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. | ||||
* @license GNU/GPL | * @license GNU/GPL | ||||
* In-Portal is Open Source software. | * In-Portal is Open Source software. | ||||
* This means that this software may have been modified pursuant | * This means that this software may have been modified pursuant | ||||
* the GNU General Public License, and as distributed it includes | * the GNU General Public License, and as distributed it includes | ||||
* or is derivative of works licensed under the GNU General Public License | * or is derivative of works licensed under the GNU General Public License | ||||
* or other free or open source software licenses. | * or other free or open source software licenses. | ||||
* See http://www.in-portal.org/license for copyright notices and details. | * See http://www.in-portal.org/license for copyright notices and details. | ||||
*/ | */ | ||||
defined('FULL_PATH') or die('restricted access!'); | defined('FULL_PATH') or die('restricted access!'); | ||||
final class kEvent extends kBase { | final class kEvent extends kBase | ||||
{ | |||||
/** | /** | ||||
* Event finished working succsessfully | * Event finished working successfully. | ||||
* | |||||
*/ | */ | ||||
const erSUCCESS = 0; | const erSUCCESS = 0; | ||||
/** | /** | ||||
* Event finished working, but result is unsuccsessfull | * Event finished working, but result is unsuccessful. | ||||
* | |||||
*/ | */ | ||||
const erFAIL = -1; | const erFAIL = -1; | ||||
/** | /** | ||||
* Event experienced FATAL error - no hooks should continue! | * Event experienced FATAL error - no hooks should continue! | ||||
* | |||||
*/ | */ | ||||
const erFATAL = -2; | const erFATAL = -2; | ||||
/** | /** | ||||
* Event failed on internal permission checking (user has no permission) | * Event failed on internal permission checking (user has no permission). | ||||
* | |||||
*/ | */ | ||||
const erPERM_FAIL = -3; | const erPERM_FAIL = -3; | ||||
/** | /** | ||||
* Event requested to stop processing (don't parse templates) | * Event requested to stop processing (don't parse templates). | ||||
* | |||||
*/ | */ | ||||
const erSTOP = -4; | const erSTOP = -4; | ||||
/** | /** | ||||
* Reference to event, that created given event | * Reference to event, that created given event. | ||||
* | * | ||||
* @var kEvent | * @var self | ||||
* @access public | |||||
*/ | */ | ||||
public $MasterEvent; | public $MasterEvent; | ||||
/** | /** | ||||
* Event name | * Event name. | ||||
* | * | ||||
* @var string | * @var string | ||||
* @access public | |||||
*/ | */ | ||||
public $Name; | public $Name; | ||||
/** | /** | ||||
* Don't execute hooks, before event processing | * Don't execute hooks, before event processing. | ||||
* | * | ||||
* @var bool | * @var boolean | ||||
* @access public | |||||
*/ | */ | ||||
public $SkipBeforeHooks = false; | public $SkipBeforeHooks = false; | ||||
/** | /** | ||||
* Don't execute hooks, after event processing | * Don't execute hooks, after event processing. | ||||
* | * | ||||
* @var bool | * @var boolean | ||||
* @access public | |||||
*/ | */ | ||||
public $SkipAfterHooks = false; | public $SkipAfterHooks = false; | ||||
/** | /** | ||||
* Perform redirect after event processing. | * Perform redirect after event processing. | ||||
* Redirect after event processing allows to prevent same event being present in resulting url. | * | ||||
* Also could contain template name, that needs to be shown after redirect. | * Redirect after event processing allows to prevent same event being | ||||
* present in resulting url. Also could contain template name, that | |||||
* needs to be shown after redirect. | |||||
* | * | ||||
* @var mixed | * @var mixed | ||||
* @access public | |||||
*/ | */ | ||||
public $redirect = true; | public $redirect = true; | ||||
/** | /** | ||||
* Params, used during redirect url building after event successful processing | * Params, used during redirect url building after event successful processing. | ||||
* | * | ||||
* @var bool | * @var array | ||||
* @access private | |||||
*/ | */ | ||||
private $redirectParams = Array (); | private $_redirectParams = array(); | ||||
/** | /** | ||||
* PHP file to redirect to. Defaults to "index.php" | * PHP file to redirect to. Defaults to "index.php". | ||||
* | * | ||||
* @var string | * @var string | ||||
* @access public | |||||
*/ | */ | ||||
public $redirectScript = null; | public $redirectScript = null; | ||||
/** | /** | ||||
* Event processing status | * Event processing status. | ||||
* | * | ||||
* @var int | * @var integer | ||||
* @access public | |||||
*/ | */ | ||||
public $status = kEvent::erSUCCESS; | public $status = self::erSUCCESS; | ||||
/** | /** | ||||
* Event parameters | * Event parameters. | ||||
* | |||||
* Usually indicate, how particular event should be processed. | * Usually indicate, how particular event should be processed. | ||||
* | * | ||||
* @var Array | * @var array | ||||
* @access private | |||||
*/ | */ | ||||
private $specificParams = Array (); | private $_specificParams = array(); | ||||
/** | /** | ||||
* Pseudo class used, to create object, based on event contents | * Pseudo class used, to create object, based on event contents. | ||||
* | * | ||||
* @var string | * @var string | ||||
* @access private | |||||
*/ | */ | ||||
private $pseudoClass = ''; | private $_pseudoClass = ''; | ||||
/** | |||||
* Creates an event from array. | |||||
* | |||||
* @param array $params Event string in array format with 'prefix', 'special' (optional) and 'name' keys. | |||||
* @param array $specific_params Specific params. | |||||
* | |||||
* @return self | |||||
*/ | |||||
public static function fromArray(array $params, array $specific_params = array()) | |||||
{ | |||||
$prefix = isset($params['prefix']) ? $params['prefix'] : false; | |||||
$special = isset($params['special']) ? $params['special'] : false; | |||||
$name = isset($params['name']) ? $params['name'] : ''; | |||||
return new self($prefix . '.' . $special . ':' . $name, $specific_params); | |||||
} | |||||
/** | /** | ||||
* Create event from given prefix, special, name and specific params. | * Create event from given prefix, special, name and specific params. | ||||
* Parameter $params could be be an an array with following keys: "prefix", "special" (optional), "name". | * Parameter $params could be be an an array with following keys: "prefix", "special" (optional), "name". | ||||
* Parameter $params could be a string in format: "prefix:name" or "prefix.special:name". | * Parameter $params could be a string in format: "prefix:name" or "prefix.special:name". | ||||
* | * | ||||
* @param mixed $params Params. | * @param mixed $event_string Params. | ||||
* @param array $specific_params Event specific params (none by default). | * @param array $specific_params Event specific params (none by default). | ||||
* | * | ||||
* @throws InvalidArgumentException When incorrect event string given. | * @throws InvalidArgumentException When incorrect event string given. | ||||
*/ | */ | ||||
public function __construct($params = Array(), $specific_params = null) | public function __construct($event_string, array $specific_params = array()) | ||||
{ | { | ||||
parent::__construct(); | parent::__construct(); | ||||
if ( $params ) { | if ( preg_match('/([^.:]*)[.]{0,1}([^:]*):(.*)/', $event_string, $regs) ) { | ||||
if ( is_array($params) ) { | |||||
$prefix = isset($params['prefix']) ? $params['prefix'] : false; | |||||
$special = isset($params['special']) ? $params['special'] : false; | |||||
if ( $prefix ) { | |||||
$this->Init($prefix, $special); | |||||
} | |||||
$this->Name = isset($params['name']) ? $params['name'] : ''; | |||||
} | |||||
elseif ( is_string($params) ) { | |||||
if ( preg_match('/([^.:]*)[.]{0,1}([^:]*):(.*)/', $params, $regs) ) { | |||||
$prefix = $regs[1]; | $prefix = $regs[1]; | ||||
$special = $regs[2]; | $special = $regs[2]; | ||||
if ( $prefix ) { | if ( $prefix ) { | ||||
$this->Init($prefix, $special); | $this->Init($prefix, $special); | ||||
} | } | ||||
$this->Name = $regs[3]; | $this->Name = $regs[3]; | ||||
$this->_specificParams = $specific_params; | |||||
} | } | ||||
else { | else { | ||||
$error_msg = 'Invalid event string: "<strong>' . $params . '</strong>". '; | $error_msg = 'Invalid event string: "<strong>' . $event_string . '</strong>". '; | ||||
$error_msg .= 'Should be in "prefix[.special]:OnEvent" format'; | $error_msg .= 'Should be in "prefix[.special]:OnEvent" format'; | ||||
throw new InvalidArgumentException($error_msg); | throw new InvalidArgumentException($error_msg); | ||||
} | } | ||||
} | } | ||||
} | |||||
if ( isset($specific_params) ) { | |||||
$this->specificParams = $specific_params; | |||||
} | |||||
} | |||||
/** | /** | ||||
* Returns joined prefix and special if any | * Returns joined prefix and special if any. | ||||
* | |||||
* @param boolean $from_submit If true, then joins prefix & special by "_", uses "." otherwise. | |||||
* | * | ||||
* @param bool $from_submit if true, then joins prefix & special by "_", uses "." otherwise | |||||
* @return string | * @return string | ||||
* @access public | |||||
*/ | */ | ||||
public function getPrefixSpecial($from_submit = false) | public function getPrefixSpecial($from_submit = false) | ||||
{ | { | ||||
if (!$from_submit) { | if ( !$from_submit ) { | ||||
return parent::getPrefixSpecial(); | return parent::getPrefixSpecial(); | ||||
} | } | ||||
return rtrim($this->Prefix . '_' . $this->Special, '_'); | return rtrim($this->Prefix . '_' . $this->Special, '_'); | ||||
} | } | ||||
/** | /** | ||||
* Sets event parameter | * Sets event parameter. | ||||
* | * | ||||
* @param string $name | * @param string $name Name. | ||||
* @param mixed $value | * @param mixed $value Value. | ||||
* @access public | * | ||||
* @return void | |||||
*/ | */ | ||||
public function setEventParam($name,$value) | public function setEventParam($name, $value) | ||||
{ | { | ||||
$this->specificParams[$name] = $value; | $this->_specificParams[$name] = $value; | ||||
} | } | ||||
/** | /** | ||||
* Returns event parameter by name (supports digging) | * Returns event parameter by name (supports digging). | ||||
* | |||||
* @param string $name Name. | |||||
* | * | ||||
* @param string $name | |||||
* @return mixed | * @return mixed | ||||
* @access public | |||||
*/ | */ | ||||
public function getEventParam($name) | public function getEventParam($name) | ||||
{ | { | ||||
$args = func_get_args(); | $args = func_get_args(); | ||||
if (count($args) > 1) { | if ( count($args) > 1 ) { | ||||
kUtil::array_unshift_ref($args, $this->specificParams); | kUtil::array_unshift_ref($args, $this->_specificParams); | ||||
return call_user_func_array('getArrayValue', $args); // getArrayValue($this->specificParams, $name); | return call_user_func_array('getArrayValue', $args); | ||||
} | } | ||||
return array_key_exists($name, $this->specificParams) ? $this->specificParams[$name] : false; | return array_key_exists($name, $this->_specificParams) ? $this->_specificParams[$name] : false; | ||||
} | } | ||||
/** | /** | ||||
* Returns all event parameters | * Returns all event parameters. | ||||
* | * | ||||
* @return Array | * @return array | ||||
* @access public | |||||
*/ | */ | ||||
public function getEventParams() | public function getEventParams() | ||||
{ | { | ||||
return $this->specificParams; | return $this->_specificParams; | ||||
} | } | ||||
/** | /** | ||||
* Set's pseudo class that differs from | * Set's pseudo class that differs from the one specified in $Prefix. | ||||
* the one specified in $Prefix | * | ||||
* @param string $appendix Appendix. | |||||
* | * | ||||
* @param string $appendix | * @return void | ||||
* @access public | |||||
*/ | */ | ||||
public function setPseudoClass($appendix) | public function setPseudoClass($appendix) | ||||
{ | { | ||||
$this->pseudoClass = $this->Prefix . $appendix; | $this->_pseudoClass = $this->Prefix . $appendix; | ||||
} | } | ||||
/** | /** | ||||
* Performs event initialization | * Performs event initialization. | ||||
* Also sets pseudo class same $prefix | |||||
* | * | ||||
* @param string $prefix | * Also sets pseudo class same $prefix. | ||||
* @param string $special | * | ||||
* @access public | * @param string $prefix Prefix. | ||||
* @param string $special Special. | |||||
* | |||||
* @return void | |||||
*/ | */ | ||||
public function Init($prefix, $special) | public function Init($prefix, $special) | ||||
{ | { | ||||
$this->pseudoClass = $prefix; | $this->_pseudoClass = $prefix; | ||||
parent::Init($prefix, $special); | parent::Init($prefix, $special); | ||||
} | } | ||||
/** | /** | ||||
* Returns object used in event | * Returns object used in event. | ||||
* | |||||
* @param array $params Params. | |||||
* | * | ||||
* @param Array $params | |||||
* @return kDBBase | * @return kDBBase | ||||
* @access public | |||||
*/ | */ | ||||
public function getObject(array $params = Array()) | public function getObject(array $params = array()) | ||||
{ | { | ||||
if ( !$this->Application->hasObject($this->prefixSpecial) ) { | if ( !$this->Application->hasObject($this->prefixSpecial) ) { | ||||
$top_event = $this; | $top_event = $this; | ||||
// when OnSave calls OnPreSave in first line, then this would make sure OnSave is used | // When OnSave calls OnPreSave in first line, then this would make sure OnSave is used. | ||||
while ( is_object($top_event->MasterEvent) ) { | while ( is_object($top_event->MasterEvent) ) { | ||||
$top_event = $top_event->MasterEvent; | $top_event = $top_event->MasterEvent; | ||||
} | } | ||||
$params['parent_event'] = $top_event; | $params['parent_event'] = $top_event; | ||||
} | } | ||||
return $this->Application->recallObject($this->prefixSpecial, $this->pseudoClass, $params); | return $this->Application->recallObject($this->prefixSpecial, $this->_pseudoClass, $params); | ||||
} | } | ||||
/** | /** | ||||
* Executes given event in context of current event | * Executes given event in context of current event. | ||||
* | |||||
* Sub-event gets this event in "kEvent::MasterEvent" attribute. | * Sub-event gets this event in "kEvent::MasterEvent" attribute. | ||||
* Sub-event execution results (status and redirect* properties) are copied back to current event. | * Sub-event execution results (status and redirect* properties) are copied back to current event. | ||||
* | * | ||||
* @param string $name name of callable event (optionally could contain prefix_special as well) | * @param string $name Name of callable event (optionally could contain prefix_special as well). | ||||
* | |||||
* @return void | |||||
* @see kEvent::MasterEvent | * @see kEvent::MasterEvent | ||||
* @todo Will overwrite master event data with called event data, which makes 'parent_event' useless in most cases | * @todo Overwrites master event data with called event data, which makes 'parent_event' useless in most cases. | ||||
*/ | */ | ||||
public function CallSubEvent($name) | public function CallSubEvent($name) | ||||
{ | { | ||||
if ( strpos($name, ':') === false ) { | if ( strpos($name, ':') === false ) { | ||||
// PrefixSpecial not specified -> use from current event | // PrefixSpecial not specified -> use from current event. | ||||
$name = $this->getPrefixSpecial() . ':' . $name; | $name = $this->getPrefixSpecial() . ':' . $name; | ||||
} | } | ||||
$child_event = new kEvent($name); | $child_event = new kEvent($name); | ||||
$child_event->copyFrom($this, true); | $child_event->copyFrom($this, true); | ||||
$this->Application->HandleEvent($child_event); | $this->Application->HandleEvent($child_event); | ||||
$this->copyFrom($child_event); | $this->copyFrom($child_event); | ||||
$this->specificParams = $child_event->specificParams; | $this->_specificParams = $child_event->_specificParams; | ||||
} | } | ||||
/** | /** | ||||
* Allows to copy data between events | * Allows to copy data between events. | ||||
* | |||||
* @param kEvent $source_event Source event. | |||||
* @param boolean $inherit Keep reference to source event in copied event. | |||||
* | * | ||||
* @param kEvent $source_event | * @return void | ||||
* @param bool $inherit | |||||
* @access public | |||||
*/ | */ | ||||
public function copyFrom($source_event, $inherit = false) | public function copyFrom(kEvent $source_event, $inherit = false) | ||||
{ | { | ||||
if ( $inherit ) { | if ( $inherit ) { | ||||
$this->MasterEvent = $source_event; | $this->MasterEvent = $source_event; | ||||
} | } | ||||
else { | else { | ||||
$this->status = $source_event->status; | $this->status = $source_event->status; | ||||
} | } | ||||
$this->redirect = $source_event->redirect; | $this->redirect = $source_event->redirect; | ||||
$this->redirectParams = $source_event->redirectParams; | $this->_redirectParams = $source_event->_redirectParams; | ||||
$this->redirectScript = $source_event->redirectScript; | $this->redirectScript = $source_event->redirectScript; | ||||
$this->specificParams = $source_event->specificParams; | $this->_specificParams = $source_event->_specificParams; | ||||
} | } | ||||
/** | /** | ||||
* Returns all redirect parameters | * Returns all redirect parameters. | ||||
* | * | ||||
* @return Array | * @return array | ||||
* @access public | |||||
*/ | */ | ||||
public function getRedirectParams() | public function getRedirectParams() | ||||
{ | { | ||||
return $this->redirectParams; | return $this->_redirectParams; | ||||
} | } | ||||
/** | /** | ||||
* Returns redirect parameter | * Returns redirect parameter. | ||||
* | |||||
* @param string $name Name. | |||||
* | * | ||||
* @param string $name | |||||
* @return mixed | * @return mixed | ||||
* @access public | |||||
*/ | */ | ||||
public function getRedirectParam($name) | public function getRedirectParam($name) | ||||
{ | { | ||||
return array_key_exists($name, $this->redirectParams) ? $this->redirectParams[$name] : false; | return array_key_exists($name, $this->_redirectParams) ? $this->_redirectParams[$name] : false; | ||||
} | } | ||||
/** | /** | ||||
* Set's redirect param for event | * Set's redirect param for event. | ||||
* | |||||
* @param string $name Name. | |||||
* @param string $value Value. | |||||
* | * | ||||
* @param string $name | * @return void | ||||
* @param string $value | |||||
* @access public | |||||
*/ | */ | ||||
public function SetRedirectParam($name, $value) | public function SetRedirectParam($name, $value) | ||||
{ | { | ||||
$this->redirectParams[$name] = $value; | $this->_redirectParams[$name] = $value; | ||||
} | } | ||||
/** | /** | ||||
* Allows to merge passed redirect params hash with existing ones | * Allows to merge passed redirect params hash with existing ones. | ||||
* | |||||
* @param array $params Params. | |||||
* @param boolean $append Append to existing parameters. | |||||
* | * | ||||
* @param Array $params | * @return void | ||||
* @param bool $append | |||||
* @access public | |||||
*/ | */ | ||||
public function setRedirectParams($params, $append = true) | public function setRedirectParams(array $params, $append = true) | ||||
{ | { | ||||
if ( $append ) { | if ( $append ) { | ||||
// append new parameters to parameters set before | $params = kUtil::array_merge_recursive($this->_redirectParams, $params); | ||||
$params = kUtil::array_merge_recursive($this->redirectParams, $params); | |||||
} | } | ||||
$this->redirectParams = $params; | $this->_redirectParams = $params; | ||||
} | } | ||||
/** | /** | ||||
* Allows to tell if this event was called some how (e.g. subevent, hook) from event requested | * Allows to tell if this event was called some how (e.g. sub-event, hook) from event requested. | ||||
* | * | ||||
* @param string $event_key event key in format [prefix[.special]:]event_name | * @param string $event_key Event key in format: "[prefix[.special]:]event_name". | ||||
* @return bool | * | ||||
* @access public | * @return boolean | ||||
*/ | */ | ||||
public function hasAncestor($event_key) | public function hasAncestor($event_key) | ||||
{ | { | ||||
if ( strpos($event_key, ':') === false ) { | if ( strpos($event_key, ':') === false ) { | ||||
$event_key = $this->getPrefixSpecial() . ':' . $event_key; | $event_key = $this->getPrefixSpecial() . ':' . $event_key; | ||||
} | } | ||||
return $this->Application->EventManager->eventRunning($event_key); | return $this->Application->EventManager->eventRunning($event_key); | ||||
} | } | ||||
/** | /** | ||||
* Returns permission section associated with event | * Returns permission section associated with event. | ||||
* | * | ||||
* @return string | * @return string | ||||
* @access public | * @throws Exception When permission section not specified for event's unit. | ||||
*/ | */ | ||||
public function getSection() | public function getSection() | ||||
{ | { | ||||
$perm_section = $this->getEventParam('PermSection'); | $perm_section = $this->getEventParam('PermSection'); | ||||
if ( $perm_section ) { | if ( $perm_section ) { | ||||
return $perm_section; | return $perm_section; | ||||
} | } | ||||
// 1. get section by current top_prefix | // 1. get section by current top_prefix. | ||||
$top_prefix = $this->getEventParam('top_prefix'); | $top_prefix = $this->getEventParam('top_prefix'); | ||||
if ( $top_prefix == false ) { | if ( $top_prefix == false ) { | ||||
$top_prefix = $this->Application->GetTopmostPrefix($this->Prefix, true); | $top_prefix = $this->Application->GetTopmostPrefix($this->Prefix, true); | ||||
$this->setEventParam('top_prefix', $top_prefix); | $this->setEventParam('top_prefix', $top_prefix); | ||||
} | } | ||||
$section = $this->Application->getUnitConfig($top_prefix)->getPermSectionByName('main'); | $section = $this->Application->getUnitConfig($top_prefix)->getPermSectionByName('main'); | ||||
// 2. check if this section has perm_prefix mapping to other prefix | // 2. check if this section has perm_prefix mapping to other prefix. | ||||
$sections_helper = $this->Application->recallObject('SectionsHelper'); | $sections_helper = $this->Application->recallObject('SectionsHelper'); | ||||
/* @var $sections_helper kSectionsHelper */ | /* @var $sections_helper kSectionsHelper */ | ||||
$section_data =& $sections_helper->getSectionData($section); | $section_data =& $sections_helper->getSectionData($section); | ||||
if ( $section_data && isset($section_data['perm_prefix']) && $section_data['perm_prefix'] != $top_prefix ) { | if ( $section_data && isset($section_data['perm_prefix']) && $section_data['perm_prefix'] != $top_prefix ) { | ||||
$this->setEventParam('top_prefix', $section_data['perm_prefix']); | $this->setEventParam('top_prefix', $section_data['perm_prefix']); | ||||
$section = $this->Application->getUnitConfig($section_data['perm_prefix'])->getPermSectionByName('main'); | $section = $this->Application->getUnitConfig($section_data['perm_prefix'])->getPermSectionByName('main'); | ||||
} | } | ||||
if ( !$section ) { | if ( !$section ) { | ||||
throw new Exception('Permission <strong>section</strong> not specified for prefix <strong>' . $top_prefix . '</strong>'); | $error_msg = 'Permission <strong>section</strong> not specified for'; | ||||
$error_msg .= ' prefix <strong>' . $top_prefix . '</strong>'; | |||||
throw new Exception($error_msg); | |||||
} | } | ||||
return $section; | return $section; | ||||
} | } | ||||
/** | |||||
* Casts object to string. | |||||
* | |||||
* @return string | |||||
*/ | |||||
public function __toString() | public function __toString() | ||||
{ | { | ||||
return $this->getPrefixSpecial() . ':' . $this->Name; | return $this->getPrefixSpecial() . ':' . $this->Name; | ||||
} | } | ||||
} | } |