75 |
84 |
76 $priority_existed = isset( $this->callbacks[ $priority ] ); |
85 $priority_existed = isset( $this->callbacks[ $priority ] ); |
77 |
86 |
78 $this->callbacks[ $priority ][ $idx ] = array( |
87 $this->callbacks[ $priority ][ $idx ] = array( |
79 'function' => $callback, |
88 'function' => $callback, |
80 'accepted_args' => $accepted_args, |
89 'accepted_args' => (int) $accepted_args, |
81 ); |
90 ); |
82 |
91 |
83 // If we're adding a new priority to the list, put them back in sorted order. |
92 // If we're adding a new priority to the list, put them back in sorted order. |
84 if ( ! $priority_existed && count( $this->callbacks ) > 1 ) { |
93 if ( ! $priority_existed && count( $this->callbacks ) > 1 ) { |
85 ksort( $this->callbacks, SORT_NUMERIC ); |
94 ksort( $this->callbacks, SORT_NUMERIC ); |
86 } |
95 } |
|
96 |
|
97 $this->priorities = array_keys( $this->callbacks ); |
87 |
98 |
88 if ( $this->nesting_level > 0 ) { |
99 if ( $this->nesting_level > 0 ) { |
89 $this->resort_active_iterations( $priority, $priority_existed ); |
100 $this->resort_active_iterations( $priority, $priority_existed ); |
90 } |
101 } |
91 } |
102 } |
99 * for no priority being added. |
110 * for no priority being added. |
100 * @param bool $priority_existed Optional. Flag for whether the priority already existed before the new |
111 * @param bool $priority_existed Optional. Flag for whether the priority already existed before the new |
101 * filter was added. Default false. |
112 * filter was added. Default false. |
102 */ |
113 */ |
103 private function resort_active_iterations( $new_priority = false, $priority_existed = false ) { |
114 private function resort_active_iterations( $new_priority = false, $priority_existed = false ) { |
104 $new_priorities = array_keys( $this->callbacks ); |
115 $new_priorities = $this->priorities; |
105 |
116 |
106 // If there are no remaining hooks, clear out all running iterations. |
117 // If there are no remaining hooks, clear out all running iterations. |
107 if ( ! $new_priorities ) { |
118 if ( ! $new_priorities ) { |
108 foreach ( $this->iterations as $index => $iteration ) { |
119 foreach ( $this->iterations as $index => $iteration ) { |
109 $this->iterations[ $index ] = $new_priorities; |
120 $this->iterations[ $index ] = $new_priorities; |
183 if ( $exists ) { |
194 if ( $exists ) { |
184 unset( $this->callbacks[ $priority ][ $function_key ] ); |
195 unset( $this->callbacks[ $priority ][ $function_key ] ); |
185 |
196 |
186 if ( ! $this->callbacks[ $priority ] ) { |
197 if ( ! $this->callbacks[ $priority ] ) { |
187 unset( $this->callbacks[ $priority ] ); |
198 unset( $this->callbacks[ $priority ] ); |
|
199 |
|
200 $this->priorities = array_keys( $this->callbacks ); |
188 |
201 |
189 if ( $this->nesting_level > 0 ) { |
202 if ( $this->nesting_level > 0 ) { |
190 $this->resort_active_iterations(); |
203 $this->resort_active_iterations(); |
191 } |
204 } |
192 } |
205 } |
259 if ( ! $this->callbacks ) { |
272 if ( ! $this->callbacks ) { |
260 return; |
273 return; |
261 } |
274 } |
262 |
275 |
263 if ( false === $priority ) { |
276 if ( false === $priority ) { |
264 $this->callbacks = array(); |
277 $this->callbacks = array(); |
|
278 $this->priorities = array(); |
265 } elseif ( isset( $this->callbacks[ $priority ] ) ) { |
279 } elseif ( isset( $this->callbacks[ $priority ] ) ) { |
266 unset( $this->callbacks[ $priority ] ); |
280 unset( $this->callbacks[ $priority ] ); |
|
281 $this->priorities = array_keys( $this->callbacks ); |
267 } |
282 } |
268 |
283 |
269 if ( $this->nesting_level > 0 ) { |
284 if ( $this->nesting_level > 0 ) { |
270 $this->resort_active_iterations(); |
285 $this->resort_active_iterations(); |
271 } |
286 } |
286 return $value; |
301 return $value; |
287 } |
302 } |
288 |
303 |
289 $nesting_level = $this->nesting_level++; |
304 $nesting_level = $this->nesting_level++; |
290 |
305 |
291 $this->iterations[ $nesting_level ] = array_keys( $this->callbacks ); |
306 $this->iterations[ $nesting_level ] = $this->priorities; |
292 $num_args = count( $args ); |
307 |
|
308 $num_args = count( $args ); |
293 |
309 |
294 do { |
310 do { |
295 $this->current_priority[ $nesting_level ] = current( $this->iterations[ $nesting_level ] ); |
311 $this->current_priority[ $nesting_level ] = current( $this->iterations[ $nesting_level ] ); |
296 $priority = $this->current_priority[ $nesting_level ]; |
312 |
|
313 $priority = $this->current_priority[ $nesting_level ]; |
297 |
314 |
298 foreach ( $this->callbacks[ $priority ] as $the_ ) { |
315 foreach ( $this->callbacks[ $priority ] as $the_ ) { |
299 if ( ! $this->doing_action ) { |
316 if ( ! $this->doing_action ) { |
300 $args[0] = $value; |
317 $args[0] = $value; |
301 } |
318 } |
302 |
319 |
303 // Avoid the array_slice() if possible. |
320 // Avoid the array_slice() if possible. |
304 if ( 0 == $the_['accepted_args'] ) { |
321 if ( 0 === $the_['accepted_args'] ) { |
305 $value = call_user_func( $the_['function'] ); |
322 $value = call_user_func( $the_['function'] ); |
306 } elseif ( $the_['accepted_args'] >= $num_args ) { |
323 } elseif ( $the_['accepted_args'] >= $num_args ) { |
307 $value = call_user_func_array( $the_['function'], $args ); |
324 $value = call_user_func_array( $the_['function'], $args ); |
308 } else { |
325 } else { |
309 $value = call_user_func_array( $the_['function'], array_slice( $args, 0, (int) $the_['accepted_args'] ) ); |
326 $value = call_user_func_array( $the_['function'], array_slice( $args, 0, $the_['accepted_args'] ) ); |
310 } |
327 } |
311 } |
328 } |
312 } while ( false !== next( $this->iterations[ $nesting_level ] ) ); |
329 } while ( false !== next( $this->iterations[ $nesting_level ] ) ); |
313 |
330 |
314 unset( $this->iterations[ $nesting_level ] ); |
331 unset( $this->iterations[ $nesting_level ] ); |
315 unset( $this->current_priority[ $nesting_level ] ); |
332 unset( $this->current_priority[ $nesting_level ] ); |
316 |
333 |
317 $this->nesting_level--; |
334 --$this->nesting_level; |
318 |
335 |
319 return $value; |
336 return $value; |
320 } |
337 } |
321 |
338 |
322 /** |
339 /** |
343 * |
360 * |
344 * @param array $args Arguments to pass to the hook callbacks. Passed by reference. |
361 * @param array $args Arguments to pass to the hook callbacks. Passed by reference. |
345 */ |
362 */ |
346 public function do_all_hook( &$args ) { |
363 public function do_all_hook( &$args ) { |
347 $nesting_level = $this->nesting_level++; |
364 $nesting_level = $this->nesting_level++; |
348 $this->iterations[ $nesting_level ] = array_keys( $this->callbacks ); |
365 $this->iterations[ $nesting_level ] = $this->priorities; |
349 |
366 |
350 do { |
367 do { |
351 $priority = current( $this->iterations[ $nesting_level ] ); |
368 $priority = current( $this->iterations[ $nesting_level ] ); |
352 |
369 |
353 foreach ( $this->callbacks[ $priority ] as $the_ ) { |
370 foreach ( $this->callbacks[ $priority ] as $the_ ) { |
354 call_user_func_array( $the_['function'], $args ); |
371 call_user_func_array( $the_['function'], $args ); |
355 } |
372 } |
356 } while ( false !== next( $this->iterations[ $nesting_level ] ) ); |
373 } while ( false !== next( $this->iterations[ $nesting_level ] ) ); |
357 |
374 |
358 unset( $this->iterations[ $nesting_level ] ); |
375 unset( $this->iterations[ $nesting_level ] ); |
359 $this->nesting_level--; |
376 --$this->nesting_level; |
360 } |
377 } |
361 |
378 |
362 /** |
379 /** |
363 * Return the current priority level of the currently running iteration of the hook. |
380 * Return the current priority level of the currently running iteration of the hook. |
364 * |
381 * |
407 public static function build_preinitialized_hooks( $filters ) { |
424 public static function build_preinitialized_hooks( $filters ) { |
408 /** @var WP_Hook[] $normalized */ |
425 /** @var WP_Hook[] $normalized */ |
409 $normalized = array(); |
426 $normalized = array(); |
410 |
427 |
411 foreach ( $filters as $hook_name => $callback_groups ) { |
428 foreach ( $filters as $hook_name => $callback_groups ) { |
412 if ( is_object( $callback_groups ) && $callback_groups instanceof WP_Hook ) { |
429 if ( $callback_groups instanceof WP_Hook ) { |
413 $normalized[ $hook_name ] = $callback_groups; |
430 $normalized[ $hook_name ] = $callback_groups; |
414 continue; |
431 continue; |
415 } |
432 } |
416 |
433 |
417 $hook = new WP_Hook(); |
434 $hook = new WP_Hook(); |
490 * @param mixed $offset The offset to unset. |
509 * @param mixed $offset The offset to unset. |
491 */ |
510 */ |
492 #[ReturnTypeWillChange] |
511 #[ReturnTypeWillChange] |
493 public function offsetUnset( $offset ) { |
512 public function offsetUnset( $offset ) { |
494 unset( $this->callbacks[ $offset ] ); |
513 unset( $this->callbacks[ $offset ] ); |
|
514 $this->priorities = array_keys( $this->callbacks ); |
495 } |
515 } |
496 |
516 |
497 /** |
517 /** |
498 * Returns the current element. |
518 * Returns the current element. |
499 * |
519 * |