1 <?php
2
3 4 5 6 7 8 9 10
11
12 namespace Patron;
13
14 class Hook
15 {
16 static protected $hooks = array();
17
18 static public function config_constructor($configs)
19 {
20 $by_ns = array();
21
22 foreach ($configs as $config)
23 {
24 foreach ($config as $namespace => $hooks)
25 {
26 if (isset($hooks[0]))
27 {
28
29
30 \ICanBoogie\log('COMPAT: double array no longer needed: \1', array($hooks));
31
32 $hooks = array_shift($hooks);
33 }
34
35 foreach ($hooks as $name => $definition)
36 {
37 $by_ns[$namespace . '/' . $name] = $definition;
38 }
39 }
40 }
41
42
43
44
45
46 return (object) $by_ns;
47 }
48
49 static public function find($ns, $name)
50 {
51 global $core;
52
53 if (!self::$hooks)
54 {
55
56
57
58
59 self::$hooks = (array) $core->configs->synthesize('hooks', __CLASS__ . '::config_constructor');
60 }
61
62 if (empty(self::$hooks[$ns . '/' . $name]))
63 {
64 throw new \Exception(\ICanBoogie\format('Undefined hook %name in namespace %ns', array('%name' => $name, '%ns' => $ns)));
65 }
66
67 $hook = self::$hooks[$ns . '/' . $name];
68
69
70
71
72
73
74 if (is_array($hook))
75 {
76 $tags = $hook;
77
78 list($callback, $params) = $tags + array(1 => array());
79
80 unset($tags[0]);
81 unset($tags[1]);
82
83 if (is_string($callback) && $callback[1] == ':' && $callback[0] == 'o')
84 {
85 $class = substr($callback, 2);
86
87 $hook = new $class();
88 $hook->params = $params;
89 $hook->tags = $tags;
90 }
91 else
92 {
93 $hook = new Hook($callback, $params, $tags);
94 }
95
96 self::$hooks[$ns . '/' . $name] = $hook;
97 }
98
99 return $hook;
100 }
101
102 public $callback;
103 public $params = array();
104 public $tags = array();
105
106 public function __construct($callback, array $params=array(), array $tags=array())
107 {
108 $this->callback = $callback;
109 $this->params = $params;
110 $this->tags = $tags;
111 }
112
113 public function __invoke()
114 {
115 $args = func_get_args();
116
117 return call_user_func_array($this->callback, $args);
118 }
119 }