Index: trunk/phase3/includes/Hooks.php |
— | — | @@ -4,26 +4,25 @@ |
5 | 5 | * |
6 | 6 | * Copyright 2004, 2005 Evan Prodromou <evan@wikitravel.org>. |
7 | 7 | * |
8 | | - * This program is free software; you can redistribute it and/or modify |
9 | | - * it under the terms of the GNU General Public License as published by |
10 | | - * the Free Software Foundation; either version 2 of the License, or |
11 | | - * (at your option) any later version. |
| 8 | + * This program is free software; you can redistribute it and/or modify |
| 9 | + * it under the terms of the GNU General Public License as published by |
| 10 | + * the Free Software Foundation; either version 2 of the License, or |
| 11 | + * (at your option) any later version. |
12 | 12 | * |
13 | | - * This program is distributed in the hope that it will be useful, |
14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | - * GNU General Public License for more details. |
| 13 | + * This program is distributed in the hope that it will be useful, |
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | + * GNU General Public License for more details. |
17 | 17 | * |
18 | | - * You should have received a copy of the GNU General Public License |
19 | | - * along with this program; if not, write to the Free Software |
20 | | - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
| 18 | + * You should have received a copy of the GNU General Public License |
| 19 | + * along with this program; if not, write to the Free Software |
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
21 | 21 | * |
22 | 22 | * @author Evan Prodromou <evan@wikitravel.org> |
23 | 23 | * @see hooks.txt |
24 | 24 | * @file |
25 | 25 | */ |
26 | 26 | |
27 | | - |
28 | 27 | /** |
29 | 28 | * Call hook functions defined in $wgHooks |
30 | 29 | * |
— | — | @@ -45,72 +44,58 @@ |
46 | 45 | |
47 | 46 | class MWHookException extends MWException {} |
48 | 47 | |
49 | | - |
50 | 48 | /** |
51 | 49 | * Hooks class. |
52 | | - * |
53 | | - * Used to supersede $wgHooks, because globals are EVIL. |
54 | 50 | * |
| 51 | + * Used to supersede $wgHooks, because globals are EVIL. |
55 | 52 | */ |
56 | 53 | class Hooks { |
57 | | - |
| 54 | + |
58 | 55 | protected static $handlers = array(); |
59 | | - |
| 56 | + |
60 | 57 | /** |
61 | 58 | * Attach an event handler to a given hook |
62 | | - * |
63 | | - * @access public |
64 | | - * @param mixed $name Name of hook |
65 | | - * @param mixed $callback Callback function to attach |
| 59 | + * |
| 60 | + * @param $name Mixed: name of hook |
| 61 | + * @param $callback Mixed: callback function to attach |
66 | 62 | * @return void |
67 | 63 | */ |
68 | 64 | public static function register( $name, $callback ) { |
69 | | - |
70 | 65 | if( !isset( self::$handlers[$name] ) ) { |
71 | 66 | self::$handlers[$name] = array(); |
72 | 67 | } |
73 | | - |
| 68 | + |
74 | 69 | self::$handlers[$name][] = $callback; |
75 | | - |
76 | 70 | } |
77 | | - |
| 71 | + |
78 | 72 | /** |
79 | 73 | * Returns true if a hook has a function registered to it. |
80 | | - * |
81 | | - * @access public |
82 | | - * @param mixed $name Name of hook |
83 | | - * @return bool |
| 74 | + * |
| 75 | + * @param $name Mixed: name of hook |
| 76 | + * @return Boolean: true if a hook has a function registered to it |
84 | 77 | */ |
85 | 78 | public static function isRegistered( $name ) { |
86 | | - |
87 | 79 | if( !isset( self::$handlers[$name] ) ) { |
88 | 80 | self::$handlers[$name] = array(); |
89 | 81 | } |
90 | | - |
| 82 | + |
91 | 83 | return ( count( self::$handlers[$name] ) != 0 ); |
92 | | - |
93 | 84 | } |
94 | | - |
| 85 | + |
95 | 86 | /** |
96 | 87 | * Returns an array of all the event functions attached to a hook |
97 | | - * |
98 | | - * @access public |
99 | | - * @param mixed $name Name of hook |
| 88 | + * |
| 89 | + * @param $name Mixed: name of the hook |
100 | 90 | * @return array |
101 | 91 | */ |
102 | 92 | public static function getHandlers( $name ) { |
103 | | - |
104 | 93 | if( !isset( self::$handlers[$name] ) ) { |
105 | 94 | return array(); |
106 | 95 | } |
107 | | - |
| 96 | + |
108 | 97 | return self::$handlers[$name]; |
109 | | - |
110 | 98 | } |
111 | | - |
112 | | - |
113 | | - |
114 | | - |
| 99 | + |
115 | 100 | /** |
116 | 101 | * Call hook functions defined in Hooks::register |
117 | 102 | * |
— | — | @@ -123,33 +108,31 @@ |
124 | 109 | * @return Boolean |
125 | 110 | */ |
126 | 111 | public static function run( $event, $args = array() ) { |
127 | | - |
128 | 112 | global $wgHooks; |
129 | | - |
| 113 | + |
130 | 114 | // Return quickly in the most common case |
131 | 115 | if ( !isset( self::$handlers[$event] ) && !isset( $wgHooks[$event] ) ) { |
132 | 116 | return true; |
133 | 117 | } |
134 | | - |
135 | | - if (!is_array(self::$handlers)) { |
136 | | - throw new MWException("Local hooks array is not an array!\n"); |
| 118 | + |
| 119 | + if ( !is_array( self::$handlers ) ) { |
| 120 | + throw new MWException( "Local hooks array is not an array!\n" ); |
137 | 121 | } |
138 | | - |
139 | | - if (!is_array($wgHooks)) { |
140 | | - throw new MWException("Global hooks array is not an array!\n"); |
| 122 | + |
| 123 | + if ( !is_array( $wgHooks ) ) { |
| 124 | + throw new MWException( "Global hooks array is not an array!\n" ); |
141 | 125 | } |
142 | | - |
| 126 | + |
143 | 127 | $new_handlers = (array) self::$handlers; |
144 | 128 | $old_handlers = (array) $wgHooks; |
145 | | - |
| 129 | + |
146 | 130 | $hook_array = array_merge( $new_handlers, $old_handlers ); |
147 | | - |
148 | | - if ( !is_array($hook_array[$event]) ) { |
149 | | - throw new MWException("Hooks array for event '$event' is not an array!\n"); |
| 131 | + |
| 132 | + if ( !is_array( $hook_array[$event] ) ) { |
| 133 | + throw new MWException( "Hooks array for event '$event' is not an array!\n" ); |
150 | 134 | } |
151 | | - |
152 | | - foreach ($hook_array[$event] as $index => $hook) { |
153 | | - |
| 135 | + |
| 136 | + foreach ( $hook_array[$event] as $index => $hook ) { |
154 | 137 | $object = null; |
155 | 138 | $method = null; |
156 | 139 | $func = null; |
— | — | @@ -157,16 +140,16 @@ |
158 | 141 | $have_data = false; |
159 | 142 | $closure = false; |
160 | 143 | $badhookmsg = false; |
161 | | - |
162 | | - /* $hook can be: a function, an object, an array of $function and $data, |
163 | | - * an array of just a function, an array of object and method, or an |
164 | | - * array of object, method, and data. |
| 144 | + |
| 145 | + /** |
| 146 | + * $hook can be: a function, an object, an array of $function and |
| 147 | + * $data, an array of just a function, an array of object and |
| 148 | + * method, or an array of object, method, and data. |
165 | 149 | */ |
166 | | - |
167 | 150 | if ( is_array( $hook ) ) { |
168 | 151 | if ( count( $hook ) < 1 ) { |
169 | | - throw new MWException("Empty array in hooks for " . $event . "\n"); |
170 | | - } else if ( is_object( $hook[0] ) ) { |
| 152 | + throw new MWException( 'Empty array in hooks for ' . $event . "\n" ); |
| 153 | + } elseif ( is_object( $hook[0] ) ) { |
171 | 154 | $object = $hook_array[$event][$index][0]; |
172 | 155 | if ( $object instanceof Closure ) { |
173 | 156 | $closure = true; |
— | — | @@ -176,7 +159,7 @@ |
177 | 160 | } |
178 | 161 | } else { |
179 | 162 | if ( count( $hook ) < 2 ) { |
180 | | - $method = "on" . $event; |
| 163 | + $method = 'on' . $event; |
181 | 164 | } else { |
182 | 165 | $method = $hook[1]; |
183 | 166 | if ( count( $hook ) > 2 ) { |
— | — | @@ -185,18 +168,18 @@ |
186 | 169 | } |
187 | 170 | } |
188 | 171 | } |
189 | | - } else if ( is_string( $hook[0] ) ) { |
| 172 | + } elseif ( is_string( $hook[0] ) ) { |
190 | 173 | $func = $hook[0]; |
191 | 174 | if ( count( $hook ) > 1) { |
192 | 175 | $data = $hook[1]; |
193 | 176 | $have_data = true; |
194 | 177 | } |
195 | 178 | } else { |
196 | | - throw new MWException( "Unknown datatype in hooks for " . $event . "\n" ); |
| 179 | + throw new MWException( 'Unknown datatype in hooks for ' . $event . "\n" ); |
197 | 180 | } |
198 | | - } else if ( is_string( $hook ) ) { # functions look like strings, too |
| 181 | + } elseif ( is_string( $hook ) ) { # functions look like strings, too |
199 | 182 | $func = $hook; |
200 | | - } else if ( is_object( $hook ) ) { |
| 183 | + } elseif ( is_object( $hook ) ) { |
201 | 184 | $object = $hook_array[$event][$index]; |
202 | 185 | if ( $object instanceof Closure ) { |
203 | 186 | $closure = true; |
— | — | @@ -204,17 +187,16 @@ |
205 | 188 | $method = "on" . $event; |
206 | 189 | } |
207 | 190 | } else { |
208 | | - throw new MWException( "Unknown datatype in hooks for " . $event . "\n" ); |
| 191 | + throw new MWException( 'Unknown datatype in hooks for ' . $event . "\n" ); |
209 | 192 | } |
210 | | - |
| 193 | + |
211 | 194 | /* We put the first data element on, if needed. */ |
212 | | - |
213 | 195 | if ( $have_data ) { |
214 | | - $hook_args = array_merge(array($data), $args); |
| 196 | + $hook_args = array_merge( array( $data ), $args ); |
215 | 197 | } else { |
216 | 198 | $hook_args = $args; |
217 | 199 | } |
218 | | - |
| 200 | + |
219 | 201 | if ( $closure ) { |
220 | 202 | $callback = $object; |
221 | 203 | $func = "hook-$event-closure"; |
— | — | @@ -226,11 +208,12 @@ |
227 | 209 | } else { |
228 | 210 | $callback = $func; |
229 | 211 | } |
230 | | - |
| 212 | + |
231 | 213 | // Run autoloader (workaround for call_user_func_array bug) |
232 | 214 | is_callable( $callback ); |
233 | | - |
234 | | - /* Call the hook. The documentation of call_user_func_array clearly |
| 215 | + |
| 216 | + /** |
| 217 | + * Call the hook. The documentation of call_user_func_array clearly |
235 | 218 | * states that FALSE is returned on failure. However this is not |
236 | 219 | * case always. In some version of PHP if the function signature |
237 | 220 | * does not match the call signature, PHP will issue an warning: |
— | — | @@ -240,7 +223,7 @@ |
241 | 224 | * catches that warning and provides better error message. The |
242 | 225 | * function documentation also says that: |
243 | 226 | * In other words, it does not depend on the function signature |
244 | | - * whether the parameter is passed by a value or by a reference. |
| 227 | + * whether the parameter is passed by a value or by a reference. |
245 | 228 | * There is also PHP bug http://bugs.php.net/bug.php?id=47554 which |
246 | 229 | * is unsurprisingly marked as bogus. In short handling of failures |
247 | 230 | * with call_user_func_array is a failure, the documentation for that |
— | — | @@ -257,7 +240,7 @@ |
258 | 241 | } |
259 | 242 | wfProfileOut( $func ); |
260 | 243 | restore_error_handler(); |
261 | | - |
| 244 | + |
262 | 245 | /* String return is an error; false return means stop processing. */ |
263 | 246 | if ( is_string( $retval ) ) { |
264 | 247 | global $wgOut; |
— | — | @@ -277,22 +260,32 @@ |
278 | 261 | $prettyFunc = strval( $callback ); |
279 | 262 | } |
280 | 263 | if ( $badhookmsg ) { |
281 | | - throw new MWException( "Detected bug in an extension! " . |
282 | | - "Hook $prettyFunc has invalid call signature; " . $badhookmsg ); |
| 264 | + throw new MWException( |
| 265 | + 'Detected bug in an extension! ' . |
| 266 | + "Hook $prettyFunc has invalid call signature; " . $badhookmsg |
| 267 | + ); |
283 | 268 | } else { |
284 | | - throw new MWException( "Detected bug in an extension! " . |
| 269 | + throw new MWException( |
| 270 | + 'Detected bug in an extension! ' . |
285 | 271 | "Hook $prettyFunc failed to return a value; " . |
286 | | - "should return true to continue hook processing or false to abort." ); |
| 272 | + 'should return true to continue hook processing or false to abort.' |
| 273 | + ); |
287 | 274 | } |
288 | 275 | } else if ( !$retval ) { |
289 | 276 | return false; |
290 | 277 | } |
291 | 278 | } |
292 | | - |
| 279 | + |
293 | 280 | return true; |
294 | 281 | } |
295 | | - |
296 | | - //This REALLY should be protected... but it's public for compatibility |
| 282 | + |
| 283 | + /** |
| 284 | + * This REALLY should be protected... but it's public for compatibility |
| 285 | + * |
| 286 | + * @param $errno Unused |
| 287 | + * @param $errstr String: error message |
| 288 | + * @return Boolean: false |
| 289 | + */ |
297 | 290 | public static function hookErrorHandler( $errno, $errstr ) { |
298 | 291 | if ( strpos( $errstr, 'expected to be a reference, value given' ) !== false ) { |
299 | 292 | throw new MWHookException( $errstr ); |