1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152:
<?php
/**
* icms_Event class definition
*
* @category ICMS
*
* @copyright The ImpressCMS Project <http://www.impresscms.org>
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU General Public License (GPL)
* @version SVN: $Id$
*/
class icms_Event {
/**
* Registered event handlers
* @var array
*/
static protected $handlers = array();
/**
* Events currently being processed
* @var array
*/
static protected $events = array();
/**
* Returns information about a fired event.
* @param int $index 0 for current, 1 for parent (if current event due to another event), and so on...
* @return icms_Event
*/
static public function current($index = 0) {
return isset(self::$events[$index]) ? self::$events[$index] : false;
}
/**
* Registers an event handler
*
* icms_Event::attach( 'icms_db_IConnection', 'connect', 'something' );
* => will call something( $eventParams, $event ) when the event is fired
* icms_Event::attach( 'icms_db_IConnection', 'connect', array( $object, 'something' ) );
* => will call $object->something( $eventParams, $event ) when the event is fired
* icms_Event::attach( 'icms_db_IConnection', '*', array( 'MyClass', 'something' ) );
* => will call MyClass::something( $eventParams, $event ) when any event that
* belongs to the 'icms_db_IConnection' namespace is fired
* Also, on PHP 5.3+, you can use closures:
* icms_Event::attach( 'icms_db_IConnection', 'execute', function ( $params, $event ) {
* echo 'Executing: ' . $params['sql'];
* } );
*
* @param string $namespace Event namespace
* @param string $name Event name (use * to attach to all signals of $namespace)
* @param mixed $callback
* @return void
*/
static public function attach($namespace, $name, $callback) {
if (!isset(self::$handlers[$namespace][$name])) {
self::$handlers[$namespace][$name] = array();
}
self::$handlers[$namespace][$name][] = $callback;
}
/**
* Detach the specified event handler.
* @param string $namespace
* @param string $name
* @param mixed $callback
*/
static public function detach($namespace, $name, $callback) {
if (isset(self::$handlers[$namespace][$name])) {
foreach (self::$handlers[$namespace][$name] as $k => $handler) {
if ($handler === $callback) {
unset(self::$handlers[$namespace][$name][$k]);
return;
}
}
}
}
/**
* Triggers an event.
*
* @param string $namespace Event namespace
* @param string $name Event name (use * to attach to all events of $namespace)
* @param object $source Object that triggered this event
* @param array $parameters Event parameters
* @return icms_Event
*/
static public function trigger($namespace, $name, $source, $parameters = array()) {
$cancancel = false;
if (substr($name, 0, 1) == "*") {
$cancancel = true;
$name = substr($name, 1);
}
$event = new icms_Event($namespace, $name, $source, $parameters, $cancancel);
array_unshift(self::$events, $event);
foreach (array("*", $name) as $handlers) {
if (isset(self::$handlers[$namespace][$handlers])) {
foreach (self::$handlers[$namespace][$handlers] as $callback) {
call_user_func($callback, $parameters, $event);
if ($cancancel && $event->canceled) break 2;
}
}
}
return array_shift(self::$events);
}
/**
* Namespace this event belongs to.
* @var string
* @readonly
*/
public $namespace = "";
/**
* Name of this event
* @var string
* @readonly
*/
public $name = "";
/**
* Object that fired this event.
* @var object
* @readonly
*/
public $source;
/**
* Parameters
* @var array()
* @readonly
*/
public $parameters = array();
/**
* Whether this event can be canceled or not.
* @var bool
* @readonly
*/
public $canCancel = false;
/**
* Whether this event has been canceled or not.
* @var bool
*/
public $canceled = false;
public function __construct($namespace, $name, $source, $params = array(), $canCancel = false) {
$this->namespace = $namespace;
$this->name = $name;
$this->source = $source;
$this->parameters = $params;
$this->canCancel = $canCancel;
}
}