2006-06-20 04:03:24 +02:00
|
|
|
<?php
|
2007-10-19 19:45:08 +02:00
|
|
|
/**
|
|
|
|
* The plugin API is located in this file, which allows for creating actions
|
|
|
|
* and filters and hooking functions, and methods. The functions or methods will
|
|
|
|
* then be run when the action or filter is called.
|
|
|
|
*
|
|
|
|
* The API callback examples reference functions, but can be methods of classes.
|
|
|
|
* To hook methods, you'll need to pass an array one of two ways.
|
|
|
|
*
|
|
|
|
* Any of the syntaxes explained in the PHP documentation for the
|
2020-01-20 04:14:06 +01:00
|
|
|
* {@link https://www.php.net/manual/en/language.pseudo-types.php#language.types.callback 'callback'}
|
2007-12-06 06:56:38 +01:00
|
|
|
* type are valid.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2019-07-26 00:45:57 +02:00
|
|
|
* Also see the {@link https://developer.wordpress.org/plugins/ Plugin API} for
|
2008-08-30 23:23:43 +02:00
|
|
|
* more information and examples on how to use a lot of these functions.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2016-08-19 06:10:30 +02:00
|
|
|
* This file should have no external dependencies.
|
|
|
|
*
|
2007-10-19 19:45:08 +02:00
|
|
|
* @package WordPress
|
|
|
|
* @subpackage Plugin
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 1.5.0
|
2007-10-19 19:45:08 +02:00
|
|
|
*/
|
2006-06-20 04:03:24 +02:00
|
|
|
|
2013-09-24 21:05:10 +02:00
|
|
|
// Initialize the filter globals.
|
2020-02-06 07:33:11 +01:00
|
|
|
require __DIR__ . '/class-wp-hook.php';
|
2013-09-24 21:05:10 +02:00
|
|
|
|
Hooks: Add the new class `WP_Hook`, and modify hook handling to make use of it.
Filters and actions have been the basis of WordPress' plugin functionality since time immemorial, they've always been a reliable method for acting upon the current state of WordPress, and will continue to be so.
Over the years, however, edge cases have cropped up. Particularly when it comes to recursively executing hooks, or a hook adding and removing itself, the existing implementation struggled to keep up with more complex use cases.
And so, we introduce `WP_Hook`. By changing `$wp_filter` from an array of arrays, to an array of objects, we reduce the complexity of the hook handling code, as the processing code (see `::apply_filters()`) only needs to be aware of itself, rather than the state of all hooks. At the same time, we're able te handle more complex use cases, as the object can more easily keep track of its own state than an array ever could.
Props jbrinley for the original architecture and design of this patch.
Props SergeyBiryukov, cheeserolls, Denis-de-Bernardy, leewillis77, wonderboymusic, nacin, jorbin, DrewAPicture, ocean90, dougwollison, khag7, pento, noplanman and aaroncampbell for their testing, suggestions, contributions, patch maintenance, cajoling and patience as we got through this.
Fixes #17817.
Built from https://develop.svn.wordpress.org/trunk@38571
git-svn-id: http://core.svn.wordpress.org/trunk@38514 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-09-08 05:55:31 +02:00
|
|
|
/** @var WP_Hook[] $wp_filter */
|
2020-10-18 21:19:06 +02:00
|
|
|
global $wp_filter;
|
|
|
|
|
|
|
|
/** @var int[] $wp_actions */
|
|
|
|
global $wp_actions;
|
|
|
|
|
Plugins: Introduce `did_filter()` function.
While most of the action functions are aliases for the respective filter functions, using `did_action()` to detect whether a filter has been run is not possible, as it only works specifically for actions.
This is now resolved by introducing a new function, `did_filter()`, which retrieves the number of times a filter has been applied during the current request, bringing parity with `did_action()`.
Follow-up to [4630], [6318], [27294].
Props mordauk, chriscct7, andykeith, nacin, dd32, markparnell, SergeyBiryukov.
Fixes #35357.
Built from https://develop.svn.wordpress.org/trunk@53803
git-svn-id: http://core.svn.wordpress.org/trunk@53362 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2022-07-31 16:20:12 +02:00
|
|
|
/** @var int[] $wp_filters */
|
|
|
|
global $wp_filters;
|
|
|
|
|
2020-10-18 21:19:06 +02:00
|
|
|
/** @var string[] $wp_current_filter */
|
|
|
|
global $wp_current_filter;
|
Hooks: Add the new class `WP_Hook`, and modify hook handling to make use of it.
Filters and actions have been the basis of WordPress' plugin functionality since time immemorial, they've always been a reliable method for acting upon the current state of WordPress, and will continue to be so.
Over the years, however, edge cases have cropped up. Particularly when it comes to recursively executing hooks, or a hook adding and removing itself, the existing implementation struggled to keep up with more complex use cases.
And so, we introduce `WP_Hook`. By changing `$wp_filter` from an array of arrays, to an array of objects, we reduce the complexity of the hook handling code, as the processing code (see `::apply_filters()`) only needs to be aware of itself, rather than the state of all hooks. At the same time, we're able te handle more complex use cases, as the object can more easily keep track of its own state than an array ever could.
Props jbrinley for the original architecture and design of this patch.
Props SergeyBiryukov, cheeserolls, Denis-de-Bernardy, leewillis77, wonderboymusic, nacin, jorbin, DrewAPicture, ocean90, dougwollison, khag7, pento, noplanman and aaroncampbell for their testing, suggestions, contributions, patch maintenance, cajoling and patience as we got through this.
Fixes #17817.
Built from https://develop.svn.wordpress.org/trunk@38571
git-svn-id: http://core.svn.wordpress.org/trunk@38514 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-09-08 05:55:31 +02:00
|
|
|
|
|
|
|
if ( $wp_filter ) {
|
|
|
|
$wp_filter = WP_Hook::build_preinitialized_hooks( $wp_filter );
|
|
|
|
} else {
|
2013-09-24 21:05:10 +02:00
|
|
|
$wp_filter = array();
|
Hooks: Add the new class `WP_Hook`, and modify hook handling to make use of it.
Filters and actions have been the basis of WordPress' plugin functionality since time immemorial, they've always been a reliable method for acting upon the current state of WordPress, and will continue to be so.
Over the years, however, edge cases have cropped up. Particularly when it comes to recursively executing hooks, or a hook adding and removing itself, the existing implementation struggled to keep up with more complex use cases.
And so, we introduce `WP_Hook`. By changing `$wp_filter` from an array of arrays, to an array of objects, we reduce the complexity of the hook handling code, as the processing code (see `::apply_filters()`) only needs to be aware of itself, rather than the state of all hooks. At the same time, we're able te handle more complex use cases, as the object can more easily keep track of its own state than an array ever could.
Props jbrinley for the original architecture and design of this patch.
Props SergeyBiryukov, cheeserolls, Denis-de-Bernardy, leewillis77, wonderboymusic, nacin, jorbin, DrewAPicture, ocean90, dougwollison, khag7, pento, noplanman and aaroncampbell for their testing, suggestions, contributions, patch maintenance, cajoling and patience as we got through this.
Fixes #17817.
Built from https://develop.svn.wordpress.org/trunk@38571
git-svn-id: http://core.svn.wordpress.org/trunk@38514 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-09-08 05:55:31 +02:00
|
|
|
}
|
2013-09-24 21:05:10 +02:00
|
|
|
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( ! isset( $wp_actions ) ) {
|
2013-09-24 21:05:10 +02:00
|
|
|
$wp_actions = array();
|
2017-12-01 00:11:00 +01:00
|
|
|
}
|
2013-09-24 21:05:10 +02:00
|
|
|
|
Plugins: Introduce `did_filter()` function.
While most of the action functions are aliases for the respective filter functions, using `did_action()` to detect whether a filter has been run is not possible, as it only works specifically for actions.
This is now resolved by introducing a new function, `did_filter()`, which retrieves the number of times a filter has been applied during the current request, bringing parity with `did_action()`.
Follow-up to [4630], [6318], [27294].
Props mordauk, chriscct7, andykeith, nacin, dd32, markparnell, SergeyBiryukov.
Fixes #35357.
Built from https://develop.svn.wordpress.org/trunk@53803
git-svn-id: http://core.svn.wordpress.org/trunk@53362 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2022-07-31 16:20:12 +02:00
|
|
|
if ( ! isset( $wp_filters ) ) {
|
|
|
|
$wp_filters = array();
|
|
|
|
}
|
|
|
|
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( ! isset( $wp_current_filter ) ) {
|
2013-09-24 21:05:10 +02:00
|
|
|
$wp_current_filter = array();
|
2017-12-01 00:11:00 +01:00
|
|
|
}
|
2013-09-24 21:05:10 +02:00
|
|
|
|
2007-03-29 04:45:34 +02:00
|
|
|
/**
|
2021-05-04 12:48:03 +02:00
|
|
|
* Adds a callback function to a filter hook.
|
2007-09-04 01:32:58 +02:00
|
|
|
*
|
2013-09-18 09:48:10 +02:00
|
|
|
* WordPress offers filter hooks to allow plugins to modify
|
|
|
|
* various types of internal data at runtime.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2013-09-18 09:48:10 +02:00
|
|
|
* A plugin can modify data by binding a callback to a filter hook. When the filter
|
|
|
|
* is later applied, each bound callback is run in order of priority, and given
|
|
|
|
* the opportunity to modify a value by returning a new value.
|
|
|
|
*
|
|
|
|
* The following example shows how a callback function is bound to a filter hook.
|
2008-08-30 23:23:43 +02:00
|
|
|
*
|
2014-11-24 07:05:23 +01:00
|
|
|
* Note that `$example` is passed to the callback, (maybe) modified, then returned:
|
|
|
|
*
|
|
|
|
* function example_callback( $example ) {
|
|
|
|
* // Maybe modify $example in some way.
|
2016-01-25 19:58:27 +01:00
|
|
|
* return $example;
|
2014-11-24 07:05:23 +01:00
|
|
|
* }
|
|
|
|
* add_filter( 'example_filter', 'example_callback' );
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2015-09-18 16:53:28 +02:00
|
|
|
* Bound callbacks can accept from none to the total number of arguments passed as parameters
|
|
|
|
* in the corresponding apply_filters() call.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2015-09-18 16:53:28 +02:00
|
|
|
* In other words, if an apply_filters() call passes four total arguments, callbacks bound to
|
|
|
|
* it can accept none (the same as 1) of the arguments or up to four. The important part is that
|
|
|
|
* the `$accepted_args` value must reflect the number of arguments the bound callback *actually*
|
|
|
|
* opted to accept. If no arguments were accepted by the callback that is considered to be the
|
|
|
|
* same as accepting 1 argument. For example:
|
|
|
|
*
|
|
|
|
* // Filter call.
|
|
|
|
* $value = apply_filters( 'hook', $value, $arg2, $arg3 );
|
|
|
|
*
|
|
|
|
* // Accepting zero/one arguments.
|
|
|
|
* function example_callback() {
|
|
|
|
* ...
|
|
|
|
* return 'some value';
|
|
|
|
* }
|
|
|
|
* add_filter( 'hook', 'example_callback' ); // Where $priority is default 10, $accepted_args is default 1.
|
|
|
|
*
|
|
|
|
* // Accepting two arguments (three possible).
|
|
|
|
* function example_callback( $value, $arg2 ) {
|
|
|
|
* ...
|
|
|
|
* return $maybe_modified_value;
|
|
|
|
* }
|
|
|
|
* add_filter( 'hook', 'example_callback', 10, 2 ); // Where $priority is 10, $accepted_args is 2.
|
|
|
|
*
|
|
|
|
* *Note:* The function will return true whether or not the callback is valid.
|
|
|
|
* It is up to you to take care. This is done for optimization purposes, so
|
|
|
|
* everything is as quick as possible.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2013-09-18 09:48:10 +02:00
|
|
|
* @since 0.71
|
|
|
|
*
|
2020-10-18 21:19:06 +02:00
|
|
|
* @global WP_Hook[] $wp_filter A multidimensional array of all hooks and the callbacks hooked to them.
|
2014-06-29 11:19:15 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @param string $hook_name The name of the filter to add the callback to.
|
|
|
|
* @param callable $callback The callback to be run when the filter is applied.
|
|
|
|
* @param int $priority Optional. Used to specify the order in which the functions
|
|
|
|
* associated with a particular filter are executed.
|
|
|
|
* Lower numbers correspond with earlier execution,
|
|
|
|
* and functions with the same priority are executed
|
|
|
|
* in the order in which they were added to the filter. Default 10.
|
|
|
|
* @param int $accepted_args Optional. The number of arguments the function accepts. Default 1.
|
|
|
|
* @return true Always returns true.
|
2007-03-29 04:45:34 +02:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function add_filter( $hook_name, $callback, $priority = 10, $accepted_args = 1 ) {
|
Hooks: Add the new class `WP_Hook`, and modify hook handling to make use of it.
Filters and actions have been the basis of WordPress' plugin functionality since time immemorial, they've always been a reliable method for acting upon the current state of WordPress, and will continue to be so.
Over the years, however, edge cases have cropped up. Particularly when it comes to recursively executing hooks, or a hook adding and removing itself, the existing implementation struggled to keep up with more complex use cases.
And so, we introduce `WP_Hook`. By changing `$wp_filter` from an array of arrays, to an array of objects, we reduce the complexity of the hook handling code, as the processing code (see `::apply_filters()`) only needs to be aware of itself, rather than the state of all hooks. At the same time, we're able te handle more complex use cases, as the object can more easily keep track of its own state than an array ever could.
Props jbrinley for the original architecture and design of this patch.
Props SergeyBiryukov, cheeserolls, Denis-de-Bernardy, leewillis77, wonderboymusic, nacin, jorbin, DrewAPicture, ocean90, dougwollison, khag7, pento, noplanman and aaroncampbell for their testing, suggestions, contributions, patch maintenance, cajoling and patience as we got through this.
Fixes #17817.
Built from https://develop.svn.wordpress.org/trunk@38571
git-svn-id: http://core.svn.wordpress.org/trunk@38514 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-09-08 05:55:31 +02:00
|
|
|
global $wp_filter;
|
2006-06-20 04:03:24 +02:00
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
if ( ! isset( $wp_filter[ $hook_name ] ) ) {
|
|
|
|
$wp_filter[ $hook_name ] = new WP_Hook();
|
2007-11-07 05:30:11 +01:00
|
|
|
}
|
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
$wp_filter[ $hook_name ]->add_filter( $hook_name, $callback, $priority, $accepted_args );
|
|
|
|
|
|
|
|
return true;
|
2007-11-07 05:30:11 +01:00
|
|
|
}
|
|
|
|
|
2007-03-29 04:45:34 +02:00
|
|
|
/**
|
2019-05-26 00:52:54 +02:00
|
|
|
* Calls the callback functions that have been added to a filter hook.
|
2007-09-04 01:32:58 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* This function invokes all functions attached to filter hook `$hook_name`.
|
|
|
|
* It is possible to create new filter hooks by simply calling this function,
|
|
|
|
* specifying the name of the new hook using the `$hook_name` parameter.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2019-05-26 00:52:54 +02:00
|
|
|
* The function also allows for multiple additional arguments to be passed to hooks.
|
2014-11-24 07:05:23 +01:00
|
|
|
*
|
2019-05-26 00:52:54 +02:00
|
|
|
* Example usage:
|
|
|
|
*
|
2020-01-29 01:45:18 +01:00
|
|
|
* // The filter callback function.
|
2014-11-24 07:05:23 +01:00
|
|
|
* function example_callback( $string, $arg1, $arg2 ) {
|
2020-01-29 01:45:18 +01:00
|
|
|
* // (maybe) modify $string.
|
2014-11-24 07:05:23 +01:00
|
|
|
* return $string;
|
|
|
|
* }
|
|
|
|
* add_filter( 'example_filter', 'example_callback', 10, 3 );
|
|
|
|
*
|
|
|
|
* /*
|
2020-01-29 01:45:18 +01:00
|
|
|
* * Apply the filters by calling the 'example_callback()' function
|
|
|
|
* * that's hooked onto `example_filter` above.
|
2019-05-26 00:52:54 +02:00
|
|
|
* *
|
2020-01-29 01:45:18 +01:00
|
|
|
* * - 'example_filter' is the filter hook.
|
|
|
|
* * - 'filter me' is the value being filtered.
|
2014-11-24 07:05:23 +01:00
|
|
|
* * - $arg1 and $arg2 are the additional arguments passed to the callback.
|
|
|
|
* $value = apply_filters( 'example_filter', 'filter me', $arg1, $arg2 );
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2014-06-29 11:19:15 +02:00
|
|
|
* @since 0.71
|
2022-03-18 19:23:04 +01:00
|
|
|
* @since 6.0.0 Formalized the existing and already documented `...$args` parameter
|
|
|
|
* by adding it to the function signature.
|
2014-06-29 11:19:15 +02:00
|
|
|
*
|
2020-10-18 21:19:06 +02:00
|
|
|
* @global WP_Hook[] $wp_filter Stores all of the filters and actions.
|
Plugins: Introduce `did_filter()` function.
While most of the action functions are aliases for the respective filter functions, using `did_action()` to detect whether a filter has been run is not possible, as it only works specifically for actions.
This is now resolved by introducing a new function, `did_filter()`, which retrieves the number of times a filter has been applied during the current request, bringing parity with `did_action()`.
Follow-up to [4630], [6318], [27294].
Props mordauk, chriscct7, andykeith, nacin, dd32, markparnell, SergeyBiryukov.
Fixes #35357.
Built from https://develop.svn.wordpress.org/trunk@53803
git-svn-id: http://core.svn.wordpress.org/trunk@53362 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2022-07-31 16:20:12 +02:00
|
|
|
* @global int[] $wp_filters Stores the number of times each filter was triggered.
|
2020-10-18 21:19:06 +02:00
|
|
|
* @global string[] $wp_current_filter Stores the list of current filters with the current one last.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @param string $hook_name The name of the filter hook.
|
|
|
|
* @param mixed $value The value to filter.
|
|
|
|
* @param mixed ...$args Additional parameters to pass to the callback functions.
|
2007-12-06 06:56:38 +01:00
|
|
|
* @return mixed The filtered value after all hooked functions are applied to it.
|
2007-03-29 04:45:34 +02:00
|
|
|
*/
|
2022-03-18 19:23:04 +01:00
|
|
|
function apply_filters( $hook_name, $value, ...$args ) {
|
Plugins: Introduce `did_filter()` function.
While most of the action functions are aliases for the respective filter functions, using `did_action()` to detect whether a filter has been run is not possible, as it only works specifically for actions.
This is now resolved by introducing a new function, `did_filter()`, which retrieves the number of times a filter has been applied during the current request, bringing parity with `did_action()`.
Follow-up to [4630], [6318], [27294].
Props mordauk, chriscct7, andykeith, nacin, dd32, markparnell, SergeyBiryukov.
Fixes #35357.
Built from https://develop.svn.wordpress.org/trunk@53803
git-svn-id: http://core.svn.wordpress.org/trunk@53362 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2022-07-31 16:20:12 +02:00
|
|
|
global $wp_filter, $wp_filters, $wp_current_filter;
|
|
|
|
|
|
|
|
if ( ! isset( $wp_filters[ $hook_name ] ) ) {
|
|
|
|
$wp_filters[ $hook_name ] = 1;
|
|
|
|
} else {
|
|
|
|
++$wp_filters[ $hook_name ];
|
|
|
|
}
|
2007-11-06 22:38:04 +01:00
|
|
|
|
2014-06-29 11:19:15 +02:00
|
|
|
// Do 'all' actions first.
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( isset( $wp_filter['all'] ) ) {
|
2021-05-04 12:48:03 +02:00
|
|
|
$wp_current_filter[] = $hook_name;
|
2022-03-18 19:23:04 +01:00
|
|
|
|
|
|
|
$all_args = func_get_args(); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection
|
|
|
|
_wp_call_all_hook( $all_args );
|
2007-11-06 19:31:43 +01:00
|
|
|
}
|
2006-06-20 04:03:24 +02:00
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
if ( ! isset( $wp_filter[ $hook_name ] ) ) {
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( isset( $wp_filter['all'] ) ) {
|
|
|
|
array_pop( $wp_current_filter );
|
|
|
|
}
|
2021-05-04 12:48:03 +02:00
|
|
|
|
2007-10-19 19:45:08 +02:00
|
|
|
return $value;
|
2007-11-06 22:38:04 +01:00
|
|
|
}
|
2006-06-20 04:03:24 +02:00
|
|
|
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( ! isset( $wp_filter['all'] ) ) {
|
2021-05-04 12:48:03 +02:00
|
|
|
$wp_current_filter[] = $hook_name;
|
2017-12-01 00:11:00 +01:00
|
|
|
}
|
2011-04-14 20:05:30 +02:00
|
|
|
|
2022-03-18 19:23:04 +01:00
|
|
|
// Pass the value to WP_Hook.
|
|
|
|
array_unshift( $args, $value );
|
2012-07-21 22:24:21 +02:00
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
$filtered = $wp_filter[ $hook_name ]->apply_filters( $value, $args );
|
2008-02-05 07:47:27 +01:00
|
|
|
|
2007-11-06 22:38:04 +01:00
|
|
|
array_pop( $wp_current_filter );
|
2010-03-18 22:24:07 +01:00
|
|
|
|
Hooks: Add the new class `WP_Hook`, and modify hook handling to make use of it.
Filters and actions have been the basis of WordPress' plugin functionality since time immemorial, they've always been a reliable method for acting upon the current state of WordPress, and will continue to be so.
Over the years, however, edge cases have cropped up. Particularly when it comes to recursively executing hooks, or a hook adding and removing itself, the existing implementation struggled to keep up with more complex use cases.
And so, we introduce `WP_Hook`. By changing `$wp_filter` from an array of arrays, to an array of objects, we reduce the complexity of the hook handling code, as the processing code (see `::apply_filters()`) only needs to be aware of itself, rather than the state of all hooks. At the same time, we're able te handle more complex use cases, as the object can more easily keep track of its own state than an array ever could.
Props jbrinley for the original architecture and design of this patch.
Props SergeyBiryukov, cheeserolls, Denis-de-Bernardy, leewillis77, wonderboymusic, nacin, jorbin, DrewAPicture, ocean90, dougwollison, khag7, pento, noplanman and aaroncampbell for their testing, suggestions, contributions, patch maintenance, cajoling and patience as we got through this.
Fixes #17817.
Built from https://develop.svn.wordpress.org/trunk@38571
git-svn-id: http://core.svn.wordpress.org/trunk@38514 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-09-08 05:55:31 +02:00
|
|
|
return $filtered;
|
2010-03-18 22:24:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-05-26 00:52:54 +02:00
|
|
|
* Calls the callback functions that have been added to a filter hook, specifying arguments in an array.
|
2010-03-18 22:24:07 +01:00
|
|
|
*
|
2015-12-23 08:13:26 +01:00
|
|
|
* @since 3.0.0
|
2010-03-18 22:24:07 +01:00
|
|
|
*
|
2014-11-24 07:05:23 +01:00
|
|
|
* @see apply_filters() This function is identical, but the arguments passed to the
|
2021-05-04 12:48:03 +02:00
|
|
|
* functions hooked to `$hook_name` are supplied using an array.
|
2014-06-29 11:19:15 +02:00
|
|
|
*
|
2020-10-18 21:19:06 +02:00
|
|
|
* @global WP_Hook[] $wp_filter Stores all of the filters and actions.
|
Plugins: Introduce `did_filter()` function.
While most of the action functions are aliases for the respective filter functions, using `did_action()` to detect whether a filter has been run is not possible, as it only works specifically for actions.
This is now resolved by introducing a new function, `did_filter()`, which retrieves the number of times a filter has been applied during the current request, bringing parity with `did_action()`.
Follow-up to [4630], [6318], [27294].
Props mordauk, chriscct7, andykeith, nacin, dd32, markparnell, SergeyBiryukov.
Fixes #35357.
Built from https://develop.svn.wordpress.org/trunk@53803
git-svn-id: http://core.svn.wordpress.org/trunk@53362 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2022-07-31 16:20:12 +02:00
|
|
|
* @global int[] $wp_filters Stores the number of times each filter was triggered.
|
2020-10-18 21:19:06 +02:00
|
|
|
* @global string[] $wp_current_filter Stores the list of current filters with the current one last.
|
2010-03-18 22:24:07 +01:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @param string $hook_name The name of the filter hook.
|
|
|
|
* @param array $args The arguments supplied to the functions hooked to `$hook_name`.
|
2010-03-18 22:24:07 +01:00
|
|
|
* @return mixed The filtered value after all hooked functions are applied to it.
|
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function apply_filters_ref_array( $hook_name, $args ) {
|
Plugins: Introduce `did_filter()` function.
While most of the action functions are aliases for the respective filter functions, using `did_action()` to detect whether a filter has been run is not possible, as it only works specifically for actions.
This is now resolved by introducing a new function, `did_filter()`, which retrieves the number of times a filter has been applied during the current request, bringing parity with `did_action()`.
Follow-up to [4630], [6318], [27294].
Props mordauk, chriscct7, andykeith, nacin, dd32, markparnell, SergeyBiryukov.
Fixes #35357.
Built from https://develop.svn.wordpress.org/trunk@53803
git-svn-id: http://core.svn.wordpress.org/trunk@53362 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2022-07-31 16:20:12 +02:00
|
|
|
global $wp_filter, $wp_filters, $wp_current_filter;
|
|
|
|
|
|
|
|
if ( ! isset( $wp_filters[ $hook_name ] ) ) {
|
|
|
|
$wp_filters[ $hook_name ] = 1;
|
|
|
|
} else {
|
|
|
|
++$wp_filters[ $hook_name ];
|
|
|
|
}
|
2010-03-18 22:24:07 +01:00
|
|
|
|
2020-01-29 01:45:18 +01:00
|
|
|
// Do 'all' actions first.
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( isset( $wp_filter['all'] ) ) {
|
2021-05-04 12:48:03 +02:00
|
|
|
$wp_current_filter[] = $hook_name;
|
2020-06-03 19:40:12 +02:00
|
|
|
$all_args = func_get_args(); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection
|
2017-12-01 00:11:00 +01:00
|
|
|
_wp_call_all_hook( $all_args );
|
2010-03-18 22:24:07 +01:00
|
|
|
}
|
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
if ( ! isset( $wp_filter[ $hook_name ] ) ) {
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( isset( $wp_filter['all'] ) ) {
|
|
|
|
array_pop( $wp_current_filter );
|
|
|
|
}
|
2021-05-04 12:48:03 +02:00
|
|
|
|
2010-03-31 23:39:18 +02:00
|
|
|
return $args[0];
|
2010-03-18 22:24:07 +01:00
|
|
|
}
|
|
|
|
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( ! isset( $wp_filter['all'] ) ) {
|
2021-05-04 12:48:03 +02:00
|
|
|
$wp_current_filter[] = $hook_name;
|
2017-12-01 00:11:00 +01:00
|
|
|
}
|
2011-04-14 20:05:30 +02:00
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
$filtered = $wp_filter[ $hook_name ]->apply_filters( $args[0], $args );
|
2010-03-18 22:24:07 +01:00
|
|
|
|
|
|
|
array_pop( $wp_current_filter );
|
2007-02-28 02:09:20 +01:00
|
|
|
|
Hooks: Add the new class `WP_Hook`, and modify hook handling to make use of it.
Filters and actions have been the basis of WordPress' plugin functionality since time immemorial, they've always been a reliable method for acting upon the current state of WordPress, and will continue to be so.
Over the years, however, edge cases have cropped up. Particularly when it comes to recursively executing hooks, or a hook adding and removing itself, the existing implementation struggled to keep up with more complex use cases.
And so, we introduce `WP_Hook`. By changing `$wp_filter` from an array of arrays, to an array of objects, we reduce the complexity of the hook handling code, as the processing code (see `::apply_filters()`) only needs to be aware of itself, rather than the state of all hooks. At the same time, we're able te handle more complex use cases, as the object can more easily keep track of its own state than an array ever could.
Props jbrinley for the original architecture and design of this patch.
Props SergeyBiryukov, cheeserolls, Denis-de-Bernardy, leewillis77, wonderboymusic, nacin, jorbin, DrewAPicture, ocean90, dougwollison, khag7, pento, noplanman and aaroncampbell for their testing, suggestions, contributions, patch maintenance, cajoling and patience as we got through this.
Fixes #17817.
Built from https://develop.svn.wordpress.org/trunk@38571
git-svn-id: http://core.svn.wordpress.org/trunk@38514 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-09-08 05:55:31 +02:00
|
|
|
return $filtered;
|
2006-06-20 04:03:24 +02:00
|
|
|
}
|
|
|
|
|
2007-03-29 04:45:34 +02:00
|
|
|
/**
|
2021-05-04 12:48:03 +02:00
|
|
|
* Checks if any filter has been registered for a hook.
|
|
|
|
*
|
|
|
|
* When using the `$callback` argument, this function may return a non-boolean value
|
|
|
|
* that evaluates to false (e.g. 0), so use the `===` operator for testing the return value.
|
|
|
|
*
|
|
|
|
* @since 2.5.0
|
2007-09-04 01:32:58 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @global WP_Hook[] $wp_filter Stores all of the filters and actions.
|
|
|
|
*
|
2021-12-01 14:22:01 +01:00
|
|
|
* @param string $hook_name The name of the filter hook.
|
|
|
|
* @param callable|string|array|false $callback Optional. The callback to check for.
|
|
|
|
* This function can be called unconditionally to speculatively check
|
|
|
|
* a callback that may or may not exist. Default false.
|
2021-05-04 12:48:03 +02:00
|
|
|
* @return bool|int If `$callback` is omitted, returns boolean for whether the hook has
|
|
|
|
* anything registered. When checking a specific function, the priority
|
|
|
|
* of that hook is returned, or false if the function is not attached.
|
|
|
|
*/
|
|
|
|
function has_filter( $hook_name, $callback = false ) {
|
|
|
|
global $wp_filter;
|
|
|
|
|
|
|
|
if ( ! isset( $wp_filter[ $hook_name ] ) ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $wp_filter[ $hook_name ]->has_filter( $hook_name, $callback );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes a callback function from a filter hook.
|
|
|
|
*
|
|
|
|
* This can be used to remove default functions attached to a specific filter
|
2007-03-29 04:45:34 +02:00
|
|
|
* hook and possibly replace them with a substitute.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* To remove a hook, the `$callback` and `$priority` arguments must match
|
2008-08-08 01:39:27 +02:00
|
|
|
* when the hook was added. This goes for both filters and actions. No warning
|
2007-10-19 19:45:08 +02:00
|
|
|
* will be given on removal failure.
|
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 1.2.0
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2020-10-18 21:19:06 +02:00
|
|
|
* @global WP_Hook[] $wp_filter Stores all of the filters and actions.
|
2015-05-27 17:56:26 +02:00
|
|
|
*
|
2021-12-01 14:22:01 +01:00
|
|
|
* @param string $hook_name The filter hook to which the function to be removed is hooked.
|
|
|
|
* @param callable|string|array $callback The callback to be removed from running when the filter is applied.
|
|
|
|
* This function can be called unconditionally to speculatively remove
|
|
|
|
* a callback that may or may not exist.
|
|
|
|
* @param int $priority Optional. The exact priority used when adding the original
|
|
|
|
* filter callback. Default 10.
|
2021-05-04 12:48:03 +02:00
|
|
|
* @return bool Whether the function existed before it was removed.
|
2007-03-29 04:45:34 +02:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function remove_filter( $hook_name, $callback, $priority = 10 ) {
|
Hooks: Add the new class `WP_Hook`, and modify hook handling to make use of it.
Filters and actions have been the basis of WordPress' plugin functionality since time immemorial, they've always been a reliable method for acting upon the current state of WordPress, and will continue to be so.
Over the years, however, edge cases have cropped up. Particularly when it comes to recursively executing hooks, or a hook adding and removing itself, the existing implementation struggled to keep up with more complex use cases.
And so, we introduce `WP_Hook`. By changing `$wp_filter` from an array of arrays, to an array of objects, we reduce the complexity of the hook handling code, as the processing code (see `::apply_filters()`) only needs to be aware of itself, rather than the state of all hooks. At the same time, we're able te handle more complex use cases, as the object can more easily keep track of its own state than an array ever could.
Props jbrinley for the original architecture and design of this patch.
Props SergeyBiryukov, cheeserolls, Denis-de-Bernardy, leewillis77, wonderboymusic, nacin, jorbin, DrewAPicture, ocean90, dougwollison, khag7, pento, noplanman and aaroncampbell for their testing, suggestions, contributions, patch maintenance, cajoling and patience as we got through this.
Fixes #17817.
Built from https://develop.svn.wordpress.org/trunk@38571
git-svn-id: http://core.svn.wordpress.org/trunk@38514 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-09-08 05:55:31 +02:00
|
|
|
global $wp_filter;
|
2007-02-28 02:09:20 +01:00
|
|
|
|
Hooks: Add the new class `WP_Hook`, and modify hook handling to make use of it.
Filters and actions have been the basis of WordPress' plugin functionality since time immemorial, they've always been a reliable method for acting upon the current state of WordPress, and will continue to be so.
Over the years, however, edge cases have cropped up. Particularly when it comes to recursively executing hooks, or a hook adding and removing itself, the existing implementation struggled to keep up with more complex use cases.
And so, we introduce `WP_Hook`. By changing `$wp_filter` from an array of arrays, to an array of objects, we reduce the complexity of the hook handling code, as the processing code (see `::apply_filters()`) only needs to be aware of itself, rather than the state of all hooks. At the same time, we're able te handle more complex use cases, as the object can more easily keep track of its own state than an array ever could.
Props jbrinley for the original architecture and design of this patch.
Props SergeyBiryukov, cheeserolls, Denis-de-Bernardy, leewillis77, wonderboymusic, nacin, jorbin, DrewAPicture, ocean90, dougwollison, khag7, pento, noplanman and aaroncampbell for their testing, suggestions, contributions, patch maintenance, cajoling and patience as we got through this.
Fixes #17817.
Built from https://develop.svn.wordpress.org/trunk@38571
git-svn-id: http://core.svn.wordpress.org/trunk@38514 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-09-08 05:55:31 +02:00
|
|
|
$r = false;
|
2021-05-04 12:48:03 +02:00
|
|
|
|
|
|
|
if ( isset( $wp_filter[ $hook_name ] ) ) {
|
|
|
|
$r = $wp_filter[ $hook_name ]->remove_filter( $hook_name, $callback, $priority );
|
|
|
|
|
|
|
|
if ( ! $wp_filter[ $hook_name ]->callbacks ) {
|
|
|
|
unset( $wp_filter[ $hook_name ] );
|
2014-06-28 06:38:15 +02:00
|
|
|
}
|
2007-11-06 19:31:43 +01:00
|
|
|
}
|
2007-05-05 01:27:12 +02:00
|
|
|
|
|
|
|
return $r;
|
2006-06-20 04:03:24 +02:00
|
|
|
}
|
|
|
|
|
2008-08-17 13:15:38 +02:00
|
|
|
/**
|
2021-05-04 12:48:03 +02:00
|
|
|
* Removes all of the callback functions from a filter hook.
|
2008-08-17 13:15:38 +02:00
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 2.7.0
|
2008-08-17 13:15:38 +02:00
|
|
|
*
|
2020-10-18 21:19:06 +02:00
|
|
|
* @global WP_Hook[] $wp_filter Stores all of the filters and actions.
|
2015-05-27 17:56:26 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @param string $hook_name The filter to remove callbacks from.
|
|
|
|
* @param int|false $priority Optional. The priority number to remove them from.
|
|
|
|
* Default false.
|
|
|
|
* @return true Always returns true.
|
2008-08-17 13:15:38 +02:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function remove_all_filters( $hook_name, $priority = false ) {
|
Hooks: Add the new class `WP_Hook`, and modify hook handling to make use of it.
Filters and actions have been the basis of WordPress' plugin functionality since time immemorial, they've always been a reliable method for acting upon the current state of WordPress, and will continue to be so.
Over the years, however, edge cases have cropped up. Particularly when it comes to recursively executing hooks, or a hook adding and removing itself, the existing implementation struggled to keep up with more complex use cases.
And so, we introduce `WP_Hook`. By changing `$wp_filter` from an array of arrays, to an array of objects, we reduce the complexity of the hook handling code, as the processing code (see `::apply_filters()`) only needs to be aware of itself, rather than the state of all hooks. At the same time, we're able te handle more complex use cases, as the object can more easily keep track of its own state than an array ever could.
Props jbrinley for the original architecture and design of this patch.
Props SergeyBiryukov, cheeserolls, Denis-de-Bernardy, leewillis77, wonderboymusic, nacin, jorbin, DrewAPicture, ocean90, dougwollison, khag7, pento, noplanman and aaroncampbell for their testing, suggestions, contributions, patch maintenance, cajoling and patience as we got through this.
Fixes #17817.
Built from https://develop.svn.wordpress.org/trunk@38571
git-svn-id: http://core.svn.wordpress.org/trunk@38514 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-09-08 05:55:31 +02:00
|
|
|
global $wp_filter;
|
2008-08-17 13:15:38 +02:00
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
if ( isset( $wp_filter[ $hook_name ] ) ) {
|
|
|
|
$wp_filter[ $hook_name ]->remove_all_filters( $priority );
|
|
|
|
|
|
|
|
if ( ! $wp_filter[ $hook_name ]->has_filters() ) {
|
|
|
|
unset( $wp_filter[ $hook_name ] );
|
2014-06-28 06:27:15 +02:00
|
|
|
}
|
2008-08-17 13:15:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2007-11-06 19:31:43 +01:00
|
|
|
|
2007-11-06 22:38:04 +01:00
|
|
|
/**
|
2021-05-04 12:48:03 +02:00
|
|
|
* Retrieves the name of the current filter hook.
|
2007-12-06 06:56:38 +01:00
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 2.5.0
|
2007-12-06 06:56:38 +01:00
|
|
|
*
|
2020-10-18 21:19:06 +02:00
|
|
|
* @global string[] $wp_current_filter Stores the list of current filters with the current one last
|
2015-05-27 17:56:26 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @return string Hook name of the current filter.
|
2007-11-06 22:38:04 +01:00
|
|
|
*/
|
|
|
|
function current_filter() {
|
|
|
|
global $wp_current_filter;
|
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
return end( $wp_current_filter );
|
2014-02-26 19:44:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-05-04 12:48:03 +02:00
|
|
|
* Returns whether or not a filter hook is currently being processed.
|
2014-02-26 19:44:14 +01:00
|
|
|
*
|
2022-08-01 13:15:14 +02:00
|
|
|
* The function current_filter() only returns the most recent filter being executed.
|
|
|
|
* did_filter() returns the number of times a filter has been applied during
|
|
|
|
* the current request.
|
2014-06-29 11:19:15 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* This function allows detection for any filter currently being executed
|
|
|
|
* (regardless of whether it's the most recent filter to fire, in the case of
|
2014-02-26 19:44:14 +01:00
|
|
|
* hooks called from hook callbacks) to be verified.
|
|
|
|
*
|
|
|
|
* @since 3.9.0
|
2014-04-07 23:30:14 +02:00
|
|
|
*
|
2014-02-26 19:44:14 +01:00
|
|
|
* @see current_filter()
|
2022-08-01 13:15:14 +02:00
|
|
|
* @see did_filter()
|
2020-10-18 21:19:06 +02:00
|
|
|
* @global string[] $wp_current_filter Current filter.
|
2014-02-26 19:44:14 +01:00
|
|
|
*
|
Docs: List the expected type first in a few functions:
* `is_allowed_http_origin()`
* `doing_filter()`
* `wp_get_post_revisions_url()`
Follow-up to [28010], [28889], [30674], [46696], [47060], [48068], [49929], [49963], [52095], [51286], [52111].
See #55646.
Built from https://develop.svn.wordpress.org/trunk@53770
git-svn-id: http://core.svn.wordpress.org/trunk@53329 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2022-07-23 18:57:09 +02:00
|
|
|
* @param string|null $hook_name Optional. Filter hook to check. Defaults to null,
|
2021-05-04 12:48:03 +02:00
|
|
|
* which checks if any filter is currently being run.
|
2014-06-29 11:19:15 +02:00
|
|
|
* @return bool Whether the filter is currently in the stack.
|
2014-02-26 19:44:14 +01:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function doing_filter( $hook_name = null ) {
|
2014-02-26 19:44:14 +01:00
|
|
|
global $wp_current_filter;
|
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
if ( null === $hook_name ) {
|
2014-02-26 19:44:14 +01:00
|
|
|
return ! empty( $wp_current_filter );
|
|
|
|
}
|
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
return in_array( $hook_name, $wp_current_filter, true );
|
2014-02-26 19:44:14 +01:00
|
|
|
}
|
|
|
|
|
Plugins: Introduce `did_filter()` function.
While most of the action functions are aliases for the respective filter functions, using `did_action()` to detect whether a filter has been run is not possible, as it only works specifically for actions.
This is now resolved by introducing a new function, `did_filter()`, which retrieves the number of times a filter has been applied during the current request, bringing parity with `did_action()`.
Follow-up to [4630], [6318], [27294].
Props mordauk, chriscct7, andykeith, nacin, dd32, markparnell, SergeyBiryukov.
Fixes #35357.
Built from https://develop.svn.wordpress.org/trunk@53803
git-svn-id: http://core.svn.wordpress.org/trunk@53362 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2022-07-31 16:20:12 +02:00
|
|
|
/**
|
|
|
|
* Retrieves the number of times a filter has been applied during the current request.
|
|
|
|
*
|
|
|
|
* @since 6.1.0
|
|
|
|
*
|
|
|
|
* @global int[] $wp_filters Stores the number of times each filter was triggered.
|
|
|
|
*
|
|
|
|
* @param string $hook_name The name of the filter hook.
|
|
|
|
* @return int The number of times the filter hook has been applied.
|
|
|
|
*/
|
|
|
|
function did_filter( $hook_name ) {
|
|
|
|
global $wp_filters;
|
|
|
|
|
|
|
|
if ( ! isset( $wp_filters[ $hook_name ] ) ) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $wp_filters[ $hook_name ];
|
|
|
|
}
|
|
|
|
|
2014-02-26 19:44:14 +01:00
|
|
|
/**
|
2021-05-04 12:48:03 +02:00
|
|
|
* Adds a callback function to an action hook.
|
2007-09-04 01:32:58 +02:00
|
|
|
*
|
|
|
|
* Actions are the hooks that the WordPress core launches at specific points
|
2007-03-29 04:45:34 +02:00
|
|
|
* during execution, or when specific events occur. Plugins can specify that
|
2007-09-04 01:32:58 +02:00
|
|
|
* one or more of its PHP functions are executed at these points, using the
|
2007-03-29 04:45:34 +02:00
|
|
|
* Action API.
|
2007-09-04 01:32:58 +02:00
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 1.2.0
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @param string $hook_name The name of the action to add the callback to.
|
|
|
|
* @param callable $callback The callback to be run when the action is called.
|
2014-06-29 10:42:16 +02:00
|
|
|
* @param int $priority Optional. Used to specify the order in which the functions
|
2021-05-04 12:48:03 +02:00
|
|
|
* associated with a particular action are executed.
|
2014-06-29 10:42:16 +02:00
|
|
|
* Lower numbers correspond with earlier execution,
|
|
|
|
* and functions with the same priority are executed
|
2021-05-04 12:48:03 +02:00
|
|
|
* in the order in which they were added to the action. Default 10.
|
2015-06-18 10:37:25 +02:00
|
|
|
* @param int $accepted_args Optional. The number of arguments the function accepts. Default 1.
|
2021-05-04 12:48:03 +02:00
|
|
|
* @return true Always returns true.
|
2007-03-29 04:45:34 +02:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function add_action( $hook_name, $callback, $priority = 10, $accepted_args = 1 ) {
|
|
|
|
return add_filter( $hook_name, $callback, $priority, $accepted_args );
|
2006-06-20 04:03:24 +02:00
|
|
|
}
|
|
|
|
|
2007-03-29 04:45:34 +02:00
|
|
|
/**
|
2021-05-04 12:48:03 +02:00
|
|
|
* Calls the callback functions that have been added to an action hook.
|
2007-09-04 01:32:58 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* This function invokes all functions attached to action hook `$hook_name`.
|
|
|
|
* It is possible to create new action hooks by simply calling this function,
|
|
|
|
* specifying the name of the new hook using the `$hook_name` parameter.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2019-05-26 00:52:54 +02:00
|
|
|
* You can pass extra arguments to the hooks, much like you can with `apply_filters()`.
|
|
|
|
*
|
|
|
|
* Example usage:
|
|
|
|
*
|
2020-01-29 01:45:18 +01:00
|
|
|
* // The action callback function.
|
2019-05-26 00:52:54 +02:00
|
|
|
* function example_callback( $arg1, $arg2 ) {
|
2020-01-29 01:45:18 +01:00
|
|
|
* // (maybe) do something with the args.
|
2019-05-26 00:52:54 +02:00
|
|
|
* }
|
|
|
|
* add_action( 'example_action', 'example_callback', 10, 2 );
|
|
|
|
*
|
|
|
|
* /*
|
2020-01-29 01:45:18 +01:00
|
|
|
* * Trigger the actions by calling the 'example_callback()' function
|
|
|
|
* * that's hooked onto `example_action` above.
|
2019-05-26 00:52:54 +02:00
|
|
|
* *
|
2020-01-29 01:45:18 +01:00
|
|
|
* * - 'example_action' is the action hook.
|
2019-05-26 00:52:54 +02:00
|
|
|
* * - $arg1 and $arg2 are the additional arguments passed to the callback.
|
2022-07-21 16:32:12 +02:00
|
|
|
* do_action( 'example_action', $arg1, $arg2 );
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 1.2.0
|
2019-10-09 06:28:02 +02:00
|
|
|
* @since 5.3.0 Formalized the existing and already documented `...$arg` parameter
|
|
|
|
* by adding it to the function signature.
|
2013-12-24 19:57:12 +01:00
|
|
|
*
|
2020-10-18 21:19:06 +02:00
|
|
|
* @global WP_Hook[] $wp_filter Stores all of the filters and actions.
|
|
|
|
* @global int[] $wp_actions Stores the number of times each action was triggered.
|
|
|
|
* @global string[] $wp_current_filter Stores the list of current filters with the current one last.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @param string $hook_name The name of the action to be executed.
|
|
|
|
* @param mixed ...$arg Optional. Additional arguments which are passed on to the
|
|
|
|
* functions hooked to the action. Default empty.
|
2007-03-29 04:45:34 +02:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function do_action( $hook_name, ...$arg ) {
|
Hooks: Add the new class `WP_Hook`, and modify hook handling to make use of it.
Filters and actions have been the basis of WordPress' plugin functionality since time immemorial, they've always been a reliable method for acting upon the current state of WordPress, and will continue to be so.
Over the years, however, edge cases have cropped up. Particularly when it comes to recursively executing hooks, or a hook adding and removing itself, the existing implementation struggled to keep up with more complex use cases.
And so, we introduce `WP_Hook`. By changing `$wp_filter` from an array of arrays, to an array of objects, we reduce the complexity of the hook handling code, as the processing code (see `::apply_filters()`) only needs to be aware of itself, rather than the state of all hooks. At the same time, we're able te handle more complex use cases, as the object can more easily keep track of its own state than an array ever could.
Props jbrinley for the original architecture and design of this patch.
Props SergeyBiryukov, cheeserolls, Denis-de-Bernardy, leewillis77, wonderboymusic, nacin, jorbin, DrewAPicture, ocean90, dougwollison, khag7, pento, noplanman and aaroncampbell for their testing, suggestions, contributions, patch maintenance, cajoling and patience as we got through this.
Fixes #17817.
Built from https://develop.svn.wordpress.org/trunk@38571
git-svn-id: http://core.svn.wordpress.org/trunk@38514 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-09-08 05:55:31 +02:00
|
|
|
global $wp_filter, $wp_actions, $wp_current_filter;
|
2006-12-08 04:45:34 +01:00
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
if ( ! isset( $wp_actions[ $hook_name ] ) ) {
|
|
|
|
$wp_actions[ $hook_name ] = 1;
|
2017-12-01 00:11:00 +01:00
|
|
|
} else {
|
2021-05-04 12:48:03 +02:00
|
|
|
++$wp_actions[ $hook_name ];
|
2017-12-01 00:11:00 +01:00
|
|
|
}
|
2007-05-08 01:22:50 +02:00
|
|
|
|
2020-01-29 01:45:18 +01:00
|
|
|
// Do 'all' actions first.
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( isset( $wp_filter['all'] ) ) {
|
2021-05-04 12:48:03 +02:00
|
|
|
$wp_current_filter[] = $hook_name;
|
2020-06-03 19:40:12 +02:00
|
|
|
$all_args = func_get_args(); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection
|
2017-12-01 00:11:00 +01:00
|
|
|
_wp_call_all_hook( $all_args );
|
2007-11-06 19:31:43 +01:00
|
|
|
}
|
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
if ( ! isset( $wp_filter[ $hook_name ] ) ) {
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( isset( $wp_filter['all'] ) ) {
|
|
|
|
array_pop( $wp_current_filter );
|
|
|
|
}
|
2021-05-04 12:48:03 +02:00
|
|
|
|
2006-06-20 04:03:24 +02:00
|
|
|
return;
|
2007-11-06 22:38:04 +01:00
|
|
|
}
|
2007-11-08 02:05:43 +01:00
|
|
|
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( ! isset( $wp_filter['all'] ) ) {
|
2021-05-04 12:48:03 +02:00
|
|
|
$wp_current_filter[] = $hook_name;
|
2017-12-01 00:11:00 +01:00
|
|
|
}
|
2011-04-14 20:05:30 +02:00
|
|
|
|
2019-09-26 15:53:58 +02:00
|
|
|
if ( empty( $arg ) ) {
|
|
|
|
$arg[] = '';
|
2019-10-22 02:11:03 +02:00
|
|
|
} elseif ( is_array( $arg[0] ) && 1 === count( $arg[0] ) && isset( $arg[0][0] ) && is_object( $arg[0][0] ) ) {
|
|
|
|
// Backward compatibility for PHP4-style passing of `array( &$this )` as action `$arg`.
|
|
|
|
$arg[0] = $arg[0][0];
|
2017-12-01 00:11:00 +01:00
|
|
|
}
|
2007-11-08 02:05:43 +01:00
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
$wp_filter[ $hook_name ]->do_action( $arg );
|
2006-12-08 04:45:34 +01:00
|
|
|
|
2017-12-01 00:11:00 +01:00
|
|
|
array_pop( $wp_current_filter );
|
2006-12-08 04:45:34 +01:00
|
|
|
}
|
|
|
|
|
2007-03-29 04:45:34 +02:00
|
|
|
/**
|
2019-05-26 00:52:54 +02:00
|
|
|
* Calls the callback functions that have been added to an action hook, specifying arguments in an array.
|
2007-09-04 01:32:58 +02:00
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 2.1.0
|
|
|
|
*
|
2014-06-29 11:19:15 +02:00
|
|
|
* @see do_action() This function is identical, but the arguments passed to the
|
2021-05-04 12:48:03 +02:00
|
|
|
* functions hooked to `$hook_name` are supplied using an array.
|
2020-10-18 21:19:06 +02:00
|
|
|
*
|
|
|
|
* @global WP_Hook[] $wp_filter Stores all of the filters and actions.
|
|
|
|
* @global int[] $wp_actions Stores the number of times each action was triggered.
|
|
|
|
* @global string[] $wp_current_filter Stores the list of current filters with the current one last.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @param string $hook_name The name of the action to be executed.
|
|
|
|
* @param array $args The arguments supplied to the functions hooked to `$hook_name`.
|
2007-03-29 04:45:34 +02:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function do_action_ref_array( $hook_name, $args ) {
|
Hooks: Add the new class `WP_Hook`, and modify hook handling to make use of it.
Filters and actions have been the basis of WordPress' plugin functionality since time immemorial, they've always been a reliable method for acting upon the current state of WordPress, and will continue to be so.
Over the years, however, edge cases have cropped up. Particularly when it comes to recursively executing hooks, or a hook adding and removing itself, the existing implementation struggled to keep up with more complex use cases.
And so, we introduce `WP_Hook`. By changing `$wp_filter` from an array of arrays, to an array of objects, we reduce the complexity of the hook handling code, as the processing code (see `::apply_filters()`) only needs to be aware of itself, rather than the state of all hooks. At the same time, we're able te handle more complex use cases, as the object can more easily keep track of its own state than an array ever could.
Props jbrinley for the original architecture and design of this patch.
Props SergeyBiryukov, cheeserolls, Denis-de-Bernardy, leewillis77, wonderboymusic, nacin, jorbin, DrewAPicture, ocean90, dougwollison, khag7, pento, noplanman and aaroncampbell for their testing, suggestions, contributions, patch maintenance, cajoling and patience as we got through this.
Fixes #17817.
Built from https://develop.svn.wordpress.org/trunk@38571
git-svn-id: http://core.svn.wordpress.org/trunk@38514 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-09-08 05:55:31 +02:00
|
|
|
global $wp_filter, $wp_actions, $wp_current_filter;
|
2006-12-08 04:45:34 +01:00
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
if ( ! isset( $wp_actions[ $hook_name ] ) ) {
|
|
|
|
$wp_actions[ $hook_name ] = 1;
|
2017-12-01 00:11:00 +01:00
|
|
|
} else {
|
2021-05-04 12:48:03 +02:00
|
|
|
++$wp_actions[ $hook_name ];
|
2017-12-01 00:11:00 +01:00
|
|
|
}
|
2006-09-12 19:45:23 +02:00
|
|
|
|
2020-01-29 01:45:18 +01:00
|
|
|
// Do 'all' actions first.
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( isset( $wp_filter['all'] ) ) {
|
2021-05-04 12:48:03 +02:00
|
|
|
$wp_current_filter[] = $hook_name;
|
2020-06-03 19:40:12 +02:00
|
|
|
$all_args = func_get_args(); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection
|
2017-12-01 00:11:00 +01:00
|
|
|
_wp_call_all_hook( $all_args );
|
2007-11-06 19:31:43 +01:00
|
|
|
}
|
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
if ( ! isset( $wp_filter[ $hook_name ] ) ) {
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( isset( $wp_filter['all'] ) ) {
|
|
|
|
array_pop( $wp_current_filter );
|
|
|
|
}
|
2021-05-04 12:48:03 +02:00
|
|
|
|
2006-09-12 19:45:23 +02:00
|
|
|
return;
|
2007-12-06 06:56:38 +01:00
|
|
|
}
|
2006-09-12 19:45:23 +02:00
|
|
|
|
2017-12-01 00:11:00 +01:00
|
|
|
if ( ! isset( $wp_filter['all'] ) ) {
|
2021-05-04 12:48:03 +02:00
|
|
|
$wp_current_filter[] = $hook_name;
|
2017-12-01 00:11:00 +01:00
|
|
|
}
|
2011-04-14 20:05:30 +02:00
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
$wp_filter[ $hook_name ]->do_action( $args );
|
2007-02-28 02:09:20 +01:00
|
|
|
|
2017-12-01 00:11:00 +01:00
|
|
|
array_pop( $wp_current_filter );
|
2006-06-20 04:03:24 +02:00
|
|
|
}
|
|
|
|
|
2007-11-07 05:30:11 +01:00
|
|
|
/**
|
2021-01-04 17:58:08 +01:00
|
|
|
* Checks if any action has been registered for a hook.
|
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* When using the `$callback` argument, this function may return a non-boolean value
|
2021-01-04 17:58:08 +01:00
|
|
|
* that evaluates to false (e.g. 0), so use the `===` operator for testing the return value.
|
2007-12-06 06:56:38 +01:00
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 2.5.0
|
|
|
|
*
|
2007-12-06 06:56:38 +01:00
|
|
|
* @see has_filter() has_action() is an alias of has_filter().
|
2007-11-07 05:30:11 +01:00
|
|
|
*
|
2021-12-01 14:22:01 +01:00
|
|
|
* @param string $hook_name The name of the action hook.
|
|
|
|
* @param callable|string|array|false $callback Optional. The callback to check for.
|
|
|
|
* This function can be called unconditionally to speculatively check
|
|
|
|
* a callback that may or may not exist. Default false.
|
2021-05-04 12:48:03 +02:00
|
|
|
* @return bool|int If `$callback` is omitted, returns boolean for whether the hook has
|
|
|
|
* anything registered. When checking a specific function, the priority
|
|
|
|
* of that hook is returned, or false if the function is not attached.
|
2007-11-07 05:30:11 +01:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function has_action( $hook_name, $callback = false ) {
|
|
|
|
return has_filter( $hook_name, $callback );
|
2007-11-07 05:30:11 +01:00
|
|
|
}
|
|
|
|
|
2007-03-29 04:45:34 +02:00
|
|
|
/**
|
2021-05-04 12:48:03 +02:00
|
|
|
* Removes a callback function from an action hook.
|
2007-09-04 01:32:58 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* This can be used to remove default functions attached to a specific action
|
2007-03-29 04:45:34 +02:00
|
|
|
* hook and possibly replace them with a substitute.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* To remove a hook, the `$callback` and `$priority` arguments must match
|
|
|
|
* when the hook was added. This goes for both filters and actions. No warning
|
|
|
|
* will be given on removal failure.
|
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 1.2.0
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2021-12-01 14:22:01 +01:00
|
|
|
* @param string $hook_name The action hook to which the function to be removed is hooked.
|
|
|
|
* @param callable|string|array $callback The name of the function which should be removed.
|
|
|
|
* This function can be called unconditionally to speculatively remove
|
|
|
|
* a callback that may or may not exist.
|
|
|
|
* @param int $priority Optional. The exact priority used when adding the original
|
|
|
|
* action callback. Default 10.
|
2015-06-27 03:03:25 +02:00
|
|
|
* @return bool Whether the function is removed.
|
2007-03-29 04:45:34 +02:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function remove_action( $hook_name, $callback, $priority = 10 ) {
|
|
|
|
return remove_filter( $hook_name, $callback, $priority );
|
2006-06-20 04:03:24 +02:00
|
|
|
}
|
|
|
|
|
2008-08-17 13:15:38 +02:00
|
|
|
/**
|
2021-05-04 12:48:03 +02:00
|
|
|
* Removes all of the callback functions from an action hook.
|
2008-08-17 13:15:38 +02:00
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 2.7.0
|
2008-08-17 13:15:38 +02:00
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @param string $hook_name The action to remove callbacks from.
|
|
|
|
* @param int|false $priority Optional. The priority number to remove them from.
|
|
|
|
* Default false.
|
|
|
|
* @return true Always returns true.
|
|
|
|
*/
|
|
|
|
function remove_all_actions( $hook_name, $priority = false ) {
|
|
|
|
return remove_all_filters( $hook_name, $priority );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves the name of the current action hook.
|
|
|
|
*
|
|
|
|
* @since 3.9.0
|
|
|
|
*
|
|
|
|
* @return string Hook name of the current action.
|
|
|
|
*/
|
|
|
|
function current_action() {
|
|
|
|
return current_filter();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether or not an action hook is currently being processed.
|
|
|
|
*
|
2022-08-01 13:15:14 +02:00
|
|
|
* The function current_action() only returns the most recent action being executed.
|
|
|
|
* did_action() returns the number of times an action has been fired during
|
|
|
|
* the current request.
|
|
|
|
*
|
|
|
|
* This function allows detection for any action currently being executed
|
|
|
|
* (regardless of whether it's the most recent action to fire, in the case of
|
|
|
|
* hooks called from hook callbacks) to be verified.
|
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @since 3.9.0
|
|
|
|
*
|
2022-08-01 13:15:14 +02:00
|
|
|
* @see current_action()
|
|
|
|
* @see did_action()
|
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @param string|null $hook_name Optional. Action hook to check. Defaults to null,
|
|
|
|
* which checks if any action is currently being run.
|
|
|
|
* @return bool Whether the action is currently in the stack.
|
|
|
|
*/
|
|
|
|
function doing_action( $hook_name = null ) {
|
|
|
|
return doing_filter( $hook_name );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves the number of times an action has been fired during the current request.
|
|
|
|
*
|
|
|
|
* @since 2.1.0
|
|
|
|
*
|
|
|
|
* @global int[] $wp_actions Stores the number of times each action was triggered.
|
|
|
|
*
|
|
|
|
* @param string $hook_name The name of the action hook.
|
|
|
|
* @return int The number of times the action hook has been fired.
|
2008-08-17 13:15:38 +02:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function did_action( $hook_name ) {
|
|
|
|
global $wp_actions;
|
|
|
|
|
|
|
|
if ( ! isset( $wp_actions[ $hook_name ] ) ) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $wp_actions[ $hook_name ];
|
2008-08-17 13:15:38 +02:00
|
|
|
}
|
|
|
|
|
2016-06-26 16:26:29 +02:00
|
|
|
/**
|
|
|
|
* Fires functions attached to a deprecated filter hook.
|
|
|
|
*
|
|
|
|
* When a filter hook is deprecated, the apply_filters() call is replaced with
|
|
|
|
* apply_filters_deprecated(), which triggers a deprecation notice and then fires
|
|
|
|
* the original filter hook.
|
|
|
|
*
|
2017-08-23 17:52:46 +02:00
|
|
|
* Note: the value and extra arguments passed to the original apply_filters() call
|
|
|
|
* must be passed here to `$args` as an array. For example:
|
|
|
|
*
|
|
|
|
* // Old filter.
|
|
|
|
* return apply_filters( 'wpdocs_filter', $value, $extra_arg );
|
|
|
|
*
|
|
|
|
* // Deprecated.
|
2019-11-09 14:57:03 +01:00
|
|
|
* return apply_filters_deprecated( 'wpdocs_filter', array( $value, $extra_arg ), '4.9.0', 'wpdocs_new_filter' );
|
2017-08-23 17:52:46 +02:00
|
|
|
*
|
2016-06-26 16:26:29 +02:00
|
|
|
* @since 4.6.0
|
|
|
|
*
|
|
|
|
* @see _deprecated_hook()
|
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @param string $hook_name The name of the filter hook.
|
2016-06-26 16:26:29 +02:00
|
|
|
* @param array $args Array of additional function arguments to be passed to apply_filters().
|
|
|
|
* @param string $version The version of WordPress that deprecated the hook.
|
2020-07-05 23:09:03 +02:00
|
|
|
* @param string $replacement Optional. The hook that should have been used. Default empty.
|
|
|
|
* @param string $message Optional. A message regarding the change. Default empty.
|
2016-06-26 16:26:29 +02:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function apply_filters_deprecated( $hook_name, $args, $version, $replacement = '', $message = '' ) {
|
|
|
|
if ( ! has_filter( $hook_name ) ) {
|
2016-06-29 15:22:27 +02:00
|
|
|
return $args[0];
|
2016-06-26 16:26:29 +02:00
|
|
|
}
|
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
_deprecated_hook( $hook_name, $version, $replacement, $message );
|
2016-06-26 16:26:29 +02:00
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
return apply_filters_ref_array( $hook_name, $args );
|
2016-06-26 16:26:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fires functions attached to a deprecated action hook.
|
|
|
|
*
|
|
|
|
* When an action hook is deprecated, the do_action() call is replaced with
|
|
|
|
* do_action_deprecated(), which triggers a deprecation notice and then fires
|
|
|
|
* the original hook.
|
|
|
|
*
|
|
|
|
* @since 4.6.0
|
|
|
|
*
|
|
|
|
* @see _deprecated_hook()
|
|
|
|
*
|
2021-05-04 12:48:03 +02:00
|
|
|
* @param string $hook_name The name of the action hook.
|
2016-06-26 16:26:29 +02:00
|
|
|
* @param array $args Array of additional function arguments to be passed to do_action().
|
|
|
|
* @param string $version The version of WordPress that deprecated the hook.
|
2020-07-05 23:09:03 +02:00
|
|
|
* @param string $replacement Optional. The hook that should have been used. Default empty.
|
|
|
|
* @param string $message Optional. A message regarding the change. Default empty.
|
2016-06-26 16:26:29 +02:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function do_action_deprecated( $hook_name, $args, $version, $replacement = '', $message = '' ) {
|
|
|
|
if ( ! has_action( $hook_name ) ) {
|
2016-06-26 16:26:29 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
_deprecated_hook( $hook_name, $version, $replacement, $message );
|
2016-06-26 16:26:29 +02:00
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
do_action_ref_array( $hook_name, $args );
|
2016-06-26 16:26:29 +02:00
|
|
|
}
|
|
|
|
|
2006-06-20 04:03:24 +02:00
|
|
|
//
|
|
|
|
// Functions for handling plugins.
|
|
|
|
//
|
|
|
|
|
2007-03-29 04:45:34 +02:00
|
|
|
/**
|
2008-08-08 01:39:27 +02:00
|
|
|
* Gets the basename of a plugin.
|
2007-09-04 01:32:58 +02:00
|
|
|
*
|
2008-05-27 19:55:24 +02:00
|
|
|
* This method extracts the name of a plugin from its filename.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 1.5.0
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2015-05-27 17:56:26 +02:00
|
|
|
* @global array $wp_plugin_paths
|
|
|
|
*
|
2007-03-29 04:45:34 +02:00
|
|
|
* @param string $file The filename of plugin.
|
|
|
|
* @return string The name of a plugin.
|
|
|
|
*/
|
2014-02-11 00:00:15 +01:00
|
|
|
function plugin_basename( $file ) {
|
|
|
|
global $wp_plugin_paths;
|
|
|
|
|
2016-04-30 17:09:27 +02:00
|
|
|
// $wp_plugin_paths contains normalized paths.
|
|
|
|
$file = wp_normalize_path( $file );
|
|
|
|
|
2016-07-06 11:45:27 +02:00
|
|
|
arsort( $wp_plugin_paths );
|
2021-05-04 12:48:03 +02:00
|
|
|
|
2014-02-11 00:00:15 +01:00
|
|
|
foreach ( $wp_plugin_paths as $dir => $realdir ) {
|
|
|
|
if ( strpos( $file, $realdir ) === 0 ) {
|
|
|
|
$file = $dir . substr( $file, strlen( $realdir ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-01 00:11:00 +01:00
|
|
|
$plugin_dir = wp_normalize_path( WP_PLUGIN_DIR );
|
2014-02-11 00:00:15 +01:00
|
|
|
$mu_plugin_dir = wp_normalize_path( WPMU_PLUGIN_DIR );
|
|
|
|
|
2020-01-29 01:45:18 +01:00
|
|
|
// Get relative path from plugins directory.
|
|
|
|
$file = preg_replace( '#^' . preg_quote( $plugin_dir, '#' ) . '/|^' . preg_quote( $mu_plugin_dir, '#' ) . '/#', '', $file );
|
2017-12-01 00:11:00 +01:00
|
|
|
$file = trim( $file, '/' );
|
2010-11-24 21:25:26 +01:00
|
|
|
return $file;
|
2006-06-20 04:03:24 +02:00
|
|
|
}
|
|
|
|
|
2014-02-11 00:00:15 +01:00
|
|
|
/**
|
|
|
|
* Register a plugin's real path.
|
|
|
|
*
|
2014-04-07 23:34:14 +02:00
|
|
|
* This is used in plugin_basename() to resolve symlinked paths.
|
|
|
|
*
|
|
|
|
* @since 3.9.0
|
|
|
|
*
|
2016-07-13 21:22:28 +02:00
|
|
|
* @see wp_normalize_path()
|
2014-02-11 00:00:15 +01:00
|
|
|
*
|
2015-05-27 17:56:26 +02:00
|
|
|
* @global array $wp_plugin_paths
|
|
|
|
*
|
2014-02-11 00:00:15 +01:00
|
|
|
* @param string $file Known path to the file.
|
2014-04-07 22:15:15 +02:00
|
|
|
* @return bool Whether the path was able to be registered.
|
2014-02-11 00:00:15 +01:00
|
|
|
*/
|
|
|
|
function wp_register_plugin_realpath( $file ) {
|
|
|
|
global $wp_plugin_paths;
|
|
|
|
|
2020-01-29 01:45:18 +01:00
|
|
|
// Normalize, but store as static to avoid recalculation of a constant value.
|
2015-05-29 17:43:29 +02:00
|
|
|
static $wp_plugin_path = null, $wpmu_plugin_path = null;
|
2021-05-04 12:48:03 +02:00
|
|
|
|
2014-04-07 22:15:15 +02:00
|
|
|
if ( ! isset( $wp_plugin_path ) ) {
|
2017-12-01 00:11:00 +01:00
|
|
|
$wp_plugin_path = wp_normalize_path( WP_PLUGIN_DIR );
|
2014-04-07 22:15:15 +02:00
|
|
|
$wpmu_plugin_path = wp_normalize_path( WPMU_PLUGIN_DIR );
|
|
|
|
}
|
|
|
|
|
2017-12-01 00:11:00 +01:00
|
|
|
$plugin_path = wp_normalize_path( dirname( $file ) );
|
2014-02-11 00:00:15 +01:00
|
|
|
$plugin_realpath = wp_normalize_path( dirname( realpath( $file ) ) );
|
|
|
|
|
2014-04-07 22:15:15 +02:00
|
|
|
if ( $plugin_path === $wp_plugin_path || $plugin_path === $wpmu_plugin_path ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-02-11 00:00:15 +01:00
|
|
|
if ( $plugin_path !== $plugin_realpath ) {
|
|
|
|
$wp_plugin_paths[ $plugin_path ] = $plugin_realpath;
|
|
|
|
}
|
2014-04-07 22:15:15 +02:00
|
|
|
|
|
|
|
return true;
|
2014-02-11 00:00:15 +01:00
|
|
|
}
|
|
|
|
|
2009-03-10 20:50:55 +01:00
|
|
|
/**
|
2014-06-29 11:19:15 +02:00
|
|
|
* Get the filesystem directory path (with trailing slash) for the plugin __FILE__ passed in.
|
2014-02-25 18:14:14 +01:00
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 2.8.0
|
2009-03-10 20:50:55 +01:00
|
|
|
*
|
2014-06-29 11:19:15 +02:00
|
|
|
* @param string $file The filename of the plugin (__FILE__).
|
|
|
|
* @return string the filesystem path of the directory that contains the plugin.
|
2009-03-10 20:50:55 +01:00
|
|
|
*/
|
|
|
|
function plugin_dir_path( $file ) {
|
|
|
|
return trailingslashit( dirname( $file ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-06-29 11:19:15 +02:00
|
|
|
* Get the URL directory path (with trailing slash) for the plugin __FILE__ passed in.
|
2014-02-25 18:14:14 +01:00
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 2.8.0
|
2009-03-10 20:50:55 +01:00
|
|
|
*
|
2014-06-29 11:19:15 +02:00
|
|
|
* @param string $file The filename of the plugin (__FILE__).
|
|
|
|
* @return string the URL path of the directory that contains the plugin.
|
2009-03-10 20:50:55 +01:00
|
|
|
*/
|
|
|
|
function plugin_dir_url( $file ) {
|
|
|
|
return trailingslashit( plugins_url( '', $file ) );
|
|
|
|
}
|
|
|
|
|
2007-03-29 04:45:34 +02:00
|
|
|
/**
|
2008-08-08 01:39:27 +02:00
|
|
|
* Set the activation hook for a plugin.
|
2007-09-04 01:32:58 +02:00
|
|
|
*
|
2007-03-29 04:45:34 +02:00
|
|
|
* When a plugin is activated, the action 'activate_PLUGINNAME' hook is
|
2013-04-16 11:53:02 +02:00
|
|
|
* called. In the name of this hook, PLUGINNAME is replaced with the name
|
|
|
|
* of the plugin, including the optional subdirectory. For example, when the
|
|
|
|
* plugin is located in wp-content/plugins/sampleplugin/sample.php, then
|
|
|
|
* the name of this hook will become 'activate_sampleplugin/sample.php'.
|
|
|
|
*
|
|
|
|
* When the plugin consists of only one file and is (as by default) located at
|
2012-12-20 16:49:55 +01:00
|
|
|
* wp-content/plugins/sample.php the name of this hook will be
|
2007-03-29 04:45:34 +02:00
|
|
|
* 'activate_sample.php'.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 2.0.0
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2014-06-29 11:19:15 +02:00
|
|
|
* @param string $file The filename of the plugin including the path.
|
2021-05-04 12:48:03 +02:00
|
|
|
* @param callable $callback The function hooked to the 'activate_PLUGIN' action.
|
2007-03-29 04:45:34 +02:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function register_activation_hook( $file, $callback ) {
|
2017-12-01 00:11:00 +01:00
|
|
|
$file = plugin_basename( $file );
|
2021-05-04 12:48:03 +02:00
|
|
|
add_action( 'activate_' . $file, $callback );
|
2006-06-20 04:03:24 +02:00
|
|
|
}
|
|
|
|
|
2007-03-29 04:45:34 +02:00
|
|
|
/**
|
2021-05-04 12:48:03 +02:00
|
|
|
* Sets the deactivation hook for a plugin.
|
2007-09-04 01:32:58 +02:00
|
|
|
*
|
2007-03-29 04:45:34 +02:00
|
|
|
* When a plugin is deactivated, the action 'deactivate_PLUGINNAME' hook is
|
2013-04-16 11:53:02 +02:00
|
|
|
* called. In the name of this hook, PLUGINNAME is replaced with the name
|
2008-08-08 01:39:27 +02:00
|
|
|
* of the plugin, including the optional subdirectory. For example, when the
|
2012-12-20 16:49:55 +01:00
|
|
|
* plugin is located in wp-content/plugins/sampleplugin/sample.php, then
|
2013-04-16 11:53:02 +02:00
|
|
|
* the name of this hook will become 'deactivate_sampleplugin/sample.php'.
|
2008-08-08 01:39:27 +02:00
|
|
|
*
|
2007-09-04 01:32:58 +02:00
|
|
|
* When the plugin consists of only one file and is (as by default) located at
|
2012-12-20 16:49:55 +01:00
|
|
|
* wp-content/plugins/sample.php the name of this hook will be
|
2013-04-16 11:53:02 +02:00
|
|
|
* 'deactivate_sample.php'.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 2.0.0
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
2014-06-29 11:19:15 +02:00
|
|
|
* @param string $file The filename of the plugin including the path.
|
2021-05-04 12:48:03 +02:00
|
|
|
* @param callable $callback The function hooked to the 'deactivate_PLUGIN' action.
|
2007-03-29 04:45:34 +02:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function register_deactivation_hook( $file, $callback ) {
|
2017-12-01 00:11:00 +01:00
|
|
|
$file = plugin_basename( $file );
|
2021-05-04 12:48:03 +02:00
|
|
|
add_action( 'deactivate_' . $file, $callback );
|
2006-06-20 04:03:24 +02:00
|
|
|
}
|
|
|
|
|
2008-02-05 07:47:27 +01:00
|
|
|
/**
|
2021-05-04 12:48:03 +02:00
|
|
|
* Sets the uninstallation hook for a plugin.
|
2008-08-08 01:39:27 +02:00
|
|
|
*
|
|
|
|
* Registers the uninstall hook that will be called when the user clicks on the
|
|
|
|
* uninstall link that calls for the plugin to uninstall itself. The link won't
|
|
|
|
* be active unless the plugin hooks into the action.
|
|
|
|
*
|
|
|
|
* The plugin should not run arbitrary code outside of functions, when
|
|
|
|
* registering the uninstall hook. In order to run using the hook, the plugin
|
|
|
|
* will have to be included, which means that any code laying outside of a
|
2017-08-22 13:52:48 +02:00
|
|
|
* function will be run during the uninstallation process. The plugin should not
|
|
|
|
* hinder the uninstallation process.
|
2008-08-08 01:39:27 +02:00
|
|
|
*
|
|
|
|
* If the plugin can not be written without running code within the plugin, then
|
|
|
|
* the plugin should create a file named 'uninstall.php' in the base plugin
|
2017-08-22 13:52:48 +02:00
|
|
|
* folder. This file will be called, if it exists, during the uninstallation process
|
2008-08-08 01:39:27 +02:00
|
|
|
* bypassing the uninstall hook. The plugin, when using the 'uninstall.php'
|
2008-11-11 13:43:04 +01:00
|
|
|
* should always check for the 'WP_UNINSTALL_PLUGIN' constant, before
|
2008-08-08 01:39:27 +02:00
|
|
|
* executing.
|
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 2.7.0
|
2008-08-08 06:15:03 +02:00
|
|
|
*
|
2014-06-29 11:19:15 +02:00
|
|
|
* @param string $file Plugin file.
|
2015-09-26 01:58:25 +02:00
|
|
|
* @param callable $callback The callback to run when the hook is called. Must be
|
2014-06-29 11:19:15 +02:00
|
|
|
* a static method or function.
|
2008-08-08 01:39:27 +02:00
|
|
|
*/
|
2010-11-13 10:45:57 +01:00
|
|
|
function register_uninstall_hook( $file, $callback ) {
|
|
|
|
if ( is_array( $callback ) && is_object( $callback[0] ) ) {
|
2016-07-06 14:40:29 +02:00
|
|
|
_doing_it_wrong( __FUNCTION__, __( 'Only a static class method or function can be used in an uninstall hook.' ), '3.1.0' );
|
2010-11-13 10:45:57 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-06-29 11:19:15 +02:00
|
|
|
/*
|
|
|
|
* The option should not be autoloaded, because it is not needed in most
|
|
|
|
* cases. Emphasis should be put on using the 'uninstall.php' way of
|
|
|
|
* uninstalling the plugin.
|
|
|
|
*/
|
2019-09-27 00:08:57 +02:00
|
|
|
$uninstallable_plugins = (array) get_option( 'uninstall_plugins' );
|
|
|
|
$plugin_basename = plugin_basename( $file );
|
2021-05-04 12:48:03 +02:00
|
|
|
|
2019-09-27 00:08:57 +02:00
|
|
|
if ( ! isset( $uninstallable_plugins[ $plugin_basename ] ) || $uninstallable_plugins[ $plugin_basename ] !== $callback ) {
|
|
|
|
$uninstallable_plugins[ $plugin_basename ] = $callback;
|
|
|
|
update_option( 'uninstall_plugins', $uninstallable_plugins );
|
|
|
|
}
|
2008-08-08 01:39:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-05-04 12:48:03 +02:00
|
|
|
* Calls the 'all' hook, which will process the functions hooked into it.
|
2007-12-06 06:56:38 +01:00
|
|
|
*
|
2008-08-08 01:39:27 +02:00
|
|
|
* The 'all' hook passes all of the arguments or parameters that were used for
|
|
|
|
* the hook, which this function was called for.
|
2007-12-06 06:56:38 +01:00
|
|
|
*
|
2008-08-08 01:39:27 +02:00
|
|
|
* This function is used internally for apply_filters(), do_action(), and
|
|
|
|
* do_action_ref_array() and is not meant to be used from outside those
|
|
|
|
* functions. This function does not check for the existence of the all hook, so
|
|
|
|
* it will fail unless the all hook exists prior to this function call.
|
2007-12-06 06:56:38 +01:00
|
|
|
*
|
2013-12-24 19:57:12 +01:00
|
|
|
* @since 2.5.0
|
2007-12-06 06:56:38 +01:00
|
|
|
* @access private
|
|
|
|
*
|
2020-10-18 21:19:06 +02:00
|
|
|
* @global WP_Hook[] $wp_filter Stores all of the filters and actions.
|
2015-05-27 17:56:26 +02:00
|
|
|
*
|
2007-12-06 06:56:38 +01:00
|
|
|
* @param array $args The collected parameters from the hook that was called.
|
2008-02-05 07:47:27 +01:00
|
|
|
*/
|
2017-12-01 00:11:00 +01:00
|
|
|
function _wp_call_all_hook( $args ) {
|
2008-02-05 07:47:27 +01:00
|
|
|
global $wp_filter;
|
2007-12-06 06:56:38 +01:00
|
|
|
|
Hooks: Add the new class `WP_Hook`, and modify hook handling to make use of it.
Filters and actions have been the basis of WordPress' plugin functionality since time immemorial, they've always been a reliable method for acting upon the current state of WordPress, and will continue to be so.
Over the years, however, edge cases have cropped up. Particularly when it comes to recursively executing hooks, or a hook adding and removing itself, the existing implementation struggled to keep up with more complex use cases.
And so, we introduce `WP_Hook`. By changing `$wp_filter` from an array of arrays, to an array of objects, we reduce the complexity of the hook handling code, as the processing code (see `::apply_filters()`) only needs to be aware of itself, rather than the state of all hooks. At the same time, we're able te handle more complex use cases, as the object can more easily keep track of its own state than an array ever could.
Props jbrinley for the original architecture and design of this patch.
Props SergeyBiryukov, cheeserolls, Denis-de-Bernardy, leewillis77, wonderboymusic, nacin, jorbin, DrewAPicture, ocean90, dougwollison, khag7, pento, noplanman and aaroncampbell for their testing, suggestions, contributions, patch maintenance, cajoling and patience as we got through this.
Fixes #17817.
Built from https://develop.svn.wordpress.org/trunk@38571
git-svn-id: http://core.svn.wordpress.org/trunk@38514 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2016-09-08 05:55:31 +02:00
|
|
|
$wp_filter['all']->do_all_hook( $args );
|
2007-12-06 06:56:38 +01:00
|
|
|
}
|
|
|
|
|
2007-10-07 09:31:14 +02:00
|
|
|
/**
|
2021-05-04 12:48:03 +02:00
|
|
|
* Builds Unique ID for storage and retrieval.
|
2007-10-19 19:45:08 +02:00
|
|
|
*
|
|
|
|
* The old way to serialize the callback caused issues and this function is the
|
2015-03-22 23:56:27 +01:00
|
|
|
* solution. It works by checking for objects and creating a new property in
|
2007-10-19 19:45:08 +02:00
|
|
|
* the class to keep track of the object and new objects of the same class that
|
|
|
|
* need to be added.
|
|
|
|
*
|
|
|
|
* It also allows for the removal of actions and filters for objects after they
|
|
|
|
* change class properties. It is possible to include the property $wp_filter_id
|
2008-08-08 01:39:27 +02:00
|
|
|
* in your class and set it to "null" or a number to bypass the workaround.
|
|
|
|
* However this will prevent you from adding new classes and any new classes
|
|
|
|
* will overwrite the previous hook by the same class.
|
2007-10-07 09:31:14 +02:00
|
|
|
*
|
2008-08-08 01:39:27 +02:00
|
|
|
* Functions and static method callbacks are just returned as strings and
|
|
|
|
* shouldn't have any speed penalty.
|
2007-10-07 09:31:14 +02:00
|
|
|
*
|
2014-09-29 15:37:16 +02:00
|
|
|
* @link https://core.trac.wordpress.org/ticket/3875
|
2007-10-07 09:31:14 +02:00
|
|
|
*
|
2014-06-29 11:19:15 +02:00
|
|
|
* @since 2.2.3
|
2019-11-29 22:42:01 +01:00
|
|
|
* @since 5.3.0 Removed workarounds for spl_object_hash().
|
2021-05-04 12:48:03 +02:00
|
|
|
* `$hook_name` and `$priority` are no longer used,
|
2019-11-29 22:42:01 +01:00
|
|
|
* and the function always returns a string.
|
2021-12-01 14:22:01 +01:00
|
|
|
*
|
2014-06-29 11:19:15 +02:00
|
|
|
* @access private
|
|
|
|
*
|
2021-12-01 14:22:01 +01:00
|
|
|
* @param string $hook_name Unused. The name of the filter to build ID for.
|
|
|
|
* @param callable|string|array $callback The callback to generate ID for. The callback may
|
|
|
|
* or may not exist.
|
|
|
|
* @param int $priority Unused. The order in which the functions
|
|
|
|
* associated with a particular action are executed.
|
2019-11-29 23:14:01 +01:00
|
|
|
* @return string Unique function ID for usage as array key.
|
2007-10-07 09:31:14 +02:00
|
|
|
*/
|
2021-05-04 12:48:03 +02:00
|
|
|
function _wp_filter_build_unique_id( $hook_name, $callback, $priority ) {
|
|
|
|
if ( is_string( $callback ) ) {
|
|
|
|
return $callback;
|
2017-12-01 00:11:00 +01:00
|
|
|
}
|
2010-01-07 09:27:02 +01:00
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
if ( is_object( $callback ) ) {
|
2019-11-29 22:42:01 +01:00
|
|
|
// Closures are currently implemented as objects.
|
2021-05-04 12:48:03 +02:00
|
|
|
$callback = array( $callback, '' );
|
2010-05-16 10:10:39 +02:00
|
|
|
} else {
|
2021-05-04 12:48:03 +02:00
|
|
|
$callback = (array) $callback;
|
2010-05-16 10:10:39 +02:00
|
|
|
}
|
2010-05-26 04:42:15 +02:00
|
|
|
|
2021-05-04 12:48:03 +02:00
|
|
|
if ( is_object( $callback[0] ) ) {
|
2019-11-29 22:42:01 +01:00
|
|
|
// Object class calling.
|
2021-05-04 12:48:03 +02:00
|
|
|
return spl_object_hash( $callback[0] ) . $callback[1];
|
|
|
|
} elseif ( is_string( $callback[0] ) ) {
|
2019-11-29 22:42:01 +01:00
|
|
|
// Static calling.
|
2021-05-04 12:48:03 +02:00
|
|
|
return $callback[0] . '::' . $callback[1];
|
2009-10-22 21:33:11 +02:00
|
|
|
}
|
2007-08-24 16:18:08 +02:00
|
|
|
}
|