1 <?php
2 /**
3 * Event.php
4 *
5 * @author Elvyrra SAS
6 * @license http://rem.mit-license.org/ MIT
7 */
8
9 namespace Hawk;
10
11 /**
12 * This class describes script events that can be triggers and listened
13 *
14 * @package Core
15 */
16 class Event{
17 /**
18 * The event name
19 *
20 * @var string
21 */
22 private $name,
23
24 /**
25 * The event data
26 *
27 * @var array
28 */
29 $data;
30
31 /**
32 * The listened events
33 *
34 * @var array
35 */
36 private static $events = array();
37
38 /**
39 * Listener order as last
40 */
41 const ORDER_LAST = -1;
42
43 /**
44 * Listener order as first
45 */
46 const ORDER_FIRST = -2;
47
48
49 /**
50 * Constructor. Create a new event
51 *
52 * @param string $name The event name
53 * @param array $data The event initial data
54 */
55 public function __construct($name, $data = array()){
56 $this->name = $name;
57 $this->data = $data;
58 }
59
60
61 /**
62 * Get the event name
63 *
64 * @return string The event name
65 */
66 public function getName(){
67 return $this->name;
68 }
69
70
71 /**
72 * Get event data. This method is used to get all the data of the event, or a specific data property
73 *
74 * @param string $prop If set, this method will return the data property, else return all the event data
75 *
76 * @return mixed The event data
77 */
78 public function getData($prop = null){
79 return $prop ? $this->data[$prop] : $this->data;
80 }
81
82
83 /**
84 * Set data to the event
85 *
86 * @param string $prop The property name to set in the data
87 * @param mixed $value The value to set
88 */
89 public function setData($prop, $value){
90 $this->data[$prop] = $value;
91 }
92
93
94 /**
95 * Add a listener on a event type
96 *
97 * @param string $name The event name
98 * @param callable $action The action to perform when the event is triggered. This function take as argument the event itself
99 * @param int $order The listener order. If set, all the listeners on the same event type are executed following their order
100 */
101 public static function on($name, $action, $order = self::ORDER_LAST ){
102 if(preg_match('/ /', $name)) {
103 $names = explode(" ", $name);
104 foreach($names as $n){
105 self::on($n, $action, $order);
106 }
107 }
108 else{
109 switch($order){
110 case self::ORDER_FIRST:
111 $key = empty(self::$events[$name]) ? 0 : min(array_keys(self::$events[$name])) - 1;
112 break;
113
114 case self::ORDER_LAST :
115 $key = empty(self::$events[$name]) ? 1 : max(array_keys(self::$events[$name])) + 1;
116 break;
117
118 default :
119 $key = $order;
120 while(isset(self::$events[$name][$key]))
121 $key ++;
122 break;
123 }
124
125 self::$events[$name][$key] = $action;
126 }
127 }
128
129
130 /**
131 * Remove all listeners on a event type
132 *
133 * @param string $name The event name
134 */
135 public static function unbind($name){
136 if(isset(self::$events[$name])) {
137 unset(self::$events[$name]);
138 }
139 }
140
141
142 /**
143 * Trigger the event
144 */
145 public function trigger(){
146 $name = $this->getName();
147
148 $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0];
149 App::logger()->debug('The event ' . $name . ' has been triggered from ' . $trace['file'] . ':' . $trace['line']);
150
151 if(isset(self::$events[$name])) {
152 ksort(self::$events[$name]);
153 foreach(self::$events[$name] as $action){
154 $action($this);
155 }
156 }
157 }
158 }
159