diff -r 3d4e9c994f10 -r a86126ab1dd4 wp/wp-includes/plugin.php --- a/wp/wp-includes/plugin.php Tue Oct 22 16:11:46 2019 +0200 +++ b/wp/wp-includes/plugin.php Tue Dec 15 13:49:49 2020 +0100 @@ -8,10 +8,10 @@ * 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 - * {@link https://secure.php.net/manual/en/language.pseudo-types.php#language.types.callback 'callback'} + * {@link https://www.php.net/manual/en/language.pseudo-types.php#language.types.callback 'callback'} * type are valid. * - * Also see the {@link https://codex.wordpress.org/Plugin_API Plugin API} for + * Also see the {@link https://developer.wordpress.org/plugins/ Plugin API} for * more information and examples on how to use a lot of these functions. * * This file should have no external dependencies. @@ -22,7 +22,7 @@ */ // Initialize the filter globals. -require( dirname( __FILE__ ) . '/class-wp-hook.php' ); +require __DIR__ . '/class-wp-hook.php'; /** @var WP_Hook[] $wp_filter */ global $wp_filter, $wp_actions, $wp_current_filter; @@ -93,15 +93,15 @@ * * @since 0.71 * - * @global array $wp_filter A multidimensional array of all hooks and the callbacks hooked to them. + * @global array $wp_filter A multidimensional array of all hooks and the callbacks hooked to them. * * @param string $tag The name of the filter to hook the $function_to_add callback to. * @param callable $function_to_add 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 action are executed. Default 10. + * associated with a particular action 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 action. + * in the order in which they were added to the action. Default 10. * @param int $accepted_args Optional. The number of arguments the function accepts. Default 1. * @return true */ @@ -119,7 +119,7 @@ * * @since 2.5.0 * - * @global array $wp_filter Stores all of the filters. + * @global array $wp_filter Stores all of the filters and actions. * * @param string $tag The name of the filter hook. * @param callable|bool $function_to_check Optional. The callback to check for. Default false. @@ -141,49 +141,51 @@ } /** - * Call the functions added to a filter hook. + * Calls the callback functions that have been added to a filter hook. * - * The callback functions attached to filter hook $tag are invoked by calling + * The callback functions attached to the filter hook are invoked by calling * this function. This function can be used to create a new filter hook by * simply calling this function with the name of the new hook specified using - * the $tag parameter. + * the `$tag` parameter. * - * The function allows for additional arguments to be added and passed to hooks. + * The function also allows for multiple additional arguments to be passed to hooks. * - * // Our filter callback function + * Example usage: + * + * // The filter callback function. * function example_callback( $string, $arg1, $arg2 ) { - * // (maybe) modify $string + * // (maybe) modify $string. * return $string; * } * add_filter( 'example_filter', 'example_callback', 10, 3 ); * * /* - * * Apply the filters by calling the 'example_callback' function we - * * "hooked" to 'example_filter' using the add_filter() function above. - * * - 'example_filter' is the filter hook $tag - * * - 'filter me' is the value being filtered + * * Apply the filters by calling the 'example_callback()' function + * * that's hooked onto `example_filter` above. + * * + * * - 'example_filter' is the filter hook. + * * - 'filter me' is the value being filtered. * * - $arg1 and $arg2 are the additional arguments passed to the callback. * $value = apply_filters( 'example_filter', 'filter me', $arg1, $arg2 ); * * @since 0.71 * - * @global array $wp_filter Stores all of the filters. + * @global array $wp_filter Stores all of the filters and actions. * @global array $wp_current_filter Stores the list of current filters with the current one last. * * @param string $tag The name of the filter hook. - * @param mixed $value The value on which the filters hooked to `$tag` are applied on. - * @param mixed $var,... Additional variables passed to the functions hooked to `$tag`. + * @param mixed $value The value to filter. + * @param mixed ...$args Additional parameters to pass to the callback functions. * @return mixed The filtered value after all hooked functions are applied to it. */ function apply_filters( $tag, $value ) { global $wp_filter, $wp_current_filter; - $args = array(); + $args = func_get_args(); // Do 'all' actions first. if ( isset( $wp_filter['all'] ) ) { $wp_current_filter[] = $tag; - $args = func_get_args(); _wp_call_all_hook( $args ); } @@ -198,11 +200,7 @@ $wp_current_filter[] = $tag; } - if ( empty( $args ) ) { - $args = func_get_args(); - } - - // don't pass the tag name to WP_Hook + // Don't pass the tag name to WP_Hook. array_shift( $args ); $filtered = $wp_filter[ $tag ]->apply_filters( $value, $args ); @@ -213,15 +211,15 @@ } /** - * Execute functions hooked on a specific filter hook, specifying arguments in an array. + * Calls the callback functions that have been added to a filter hook, specifying arguments in an array. * * @since 3.0.0 * * @see apply_filters() This function is identical, but the arguments passed to the * functions hooked to `$tag` are supplied using an array. * - * @global array $wp_filter Stores all of the filters - * @global array $wp_current_filter Stores the list of current filters with the current one last + * @global array $wp_filter Stores all of the filters and actions. + * @global array $wp_current_filter Stores the list of current filters with the current one last. * * @param string $tag The name of the filter hook. * @param array $args The arguments supplied to the functions hooked to $tag. @@ -230,10 +228,10 @@ function apply_filters_ref_array( $tag, $args ) { global $wp_filter, $wp_current_filter; - // Do 'all' actions first + // Do 'all' actions first. if ( isset( $wp_filter['all'] ) ) { $wp_current_filter[] = $tag; - $all_args = func_get_args(); + $all_args = func_get_args(); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection _wp_call_all_hook( $all_args ); } @@ -268,7 +266,7 @@ * * @since 1.2.0 * - * @global array $wp_filter Stores all of the filters + * @global array $wp_filter Stores all of the filters and actions. * * @param string $tag The filter hook to which the function to be removed is hooked. * @param callable $function_to_remove The name of the function which should be removed. @@ -294,7 +292,7 @@ * * @since 2.7.0 * - * @global array $wp_filter Stores all of the filters + * @global array $wp_filter Stores all of the filters and actions. * * @param string $tag The filter to remove hooks from. * @param int|bool $priority Optional. The priority number to remove. Default false. @@ -366,7 +364,7 @@ return ! empty( $wp_current_filter ); } - return in_array( $filter, $wp_current_filter ); + return in_array( $filter, $wp_current_filter, true ); } /** @@ -413,19 +411,37 @@ * possible to create new action hooks by simply calling this function, * specifying the name of the new hook using the `$tag` parameter. * - * You can pass extra arguments to the hooks, much like you can with apply_filters(). + * You can pass extra arguments to the hooks, much like you can with `apply_filters()`. + * + * Example usage: + * + * // The action callback function. + * function example_callback( $arg1, $arg2 ) { + * // (maybe) do something with the args. + * } + * add_action( 'example_action', 'example_callback', 10, 2 ); + * + * /* + * * Trigger the actions by calling the 'example_callback()' function + * * that's hooked onto `example_action` above. + * * + * * - 'example_action' is the action hook. + * * - $arg1 and $arg2 are the additional arguments passed to the callback. + * $value = do_action( 'example_action', $arg1, $arg2 ); * * @since 1.2.0 - * - * @global array $wp_filter Stores all of the filters - * @global array $wp_actions Increments the amount of times action was triggered. - * @global array $wp_current_filter Stores the list of current filters with the current one last + * @since 5.3.0 Formalized the existing and already documented `...$arg` parameter + * by adding it to the function signature. * - * @param string $tag 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. + * @global array $wp_filter Stores all of the filters and actions. + * @global array $wp_actions Increments the amount of times action was triggered. + * @global array $wp_current_filter Stores the list of current filters with the current one last. + * + * @param string $tag 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. */ -function do_action( $tag, $arg = '' ) { +function do_action( $tag, ...$arg ) { global $wp_filter, $wp_actions, $wp_current_filter; if ( ! isset( $wp_actions[ $tag ] ) ) { @@ -434,10 +450,10 @@ ++$wp_actions[ $tag ]; } - // Do 'all' actions first + // Do 'all' actions first. if ( isset( $wp_filter['all'] ) ) { $wp_current_filter[] = $tag; - $all_args = func_get_args(); + $all_args = func_get_args(); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection _wp_call_all_hook( $all_args ); } @@ -452,17 +468,14 @@ $wp_current_filter[] = $tag; } - $args = array(); - if ( is_array( $arg ) && 1 == count( $arg ) && isset( $arg[0] ) && is_object( $arg[0] ) ) { // array(&$this) - $args[] =& $arg[0]; - } else { - $args[] = $arg; - } - for ( $a = 2, $num = func_num_args(); $a < $num; $a++ ) { - $args[] = func_get_arg( $a ); + if ( empty( $arg ) ) { + $arg[] = ''; + } 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]; } - $wp_filter[ $tag ]->do_action( $args ); + $wp_filter[ $tag ]->do_action( $arg ); array_pop( $wp_current_filter ); } @@ -488,15 +501,15 @@ } /** - * Execute functions hooked on a specific action hook, specifying arguments in an array. + * Calls the callback functions that have been added to an action hook, specifying arguments in an array. * * @since 2.1.0 * * @see do_action() This function is identical, but the arguments passed to the - * functions hooked to $tag< are supplied using an array. - * @global array $wp_filter Stores all of the filters + * functions hooked to `$tag` are supplied using an array. + * @global array $wp_filter Stores all of the filters and actions. * @global array $wp_actions Increments the amount of times action was triggered. - * @global array $wp_current_filter Stores the list of current filters with the current one last + * @global array $wp_current_filter Stores the list of current filters with the current one last. * * @param string $tag The name of the action to be executed. * @param array $args The arguments supplied to the functions hooked to `$tag`. @@ -510,10 +523,10 @@ ++$wp_actions[ $tag ]; } - // Do 'all' actions first + // Do 'all' actions first. if ( isset( $wp_filter['all'] ) ) { $wp_current_filter[] = $tag; - $all_args = func_get_args(); + $all_args = func_get_args(); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection _wp_call_all_hook( $all_args ); } @@ -598,7 +611,7 @@ * return apply_filters( 'wpdocs_filter', $value, $extra_arg ); * * // Deprecated. - * return apply_filters_deprecated( 'wpdocs_filter', array( $value, $extra_arg ), '4.9', 'wpdocs_new_filter' ); + * return apply_filters_deprecated( 'wpdocs_filter', array( $value, $extra_arg ), '4.9.0', 'wpdocs_new_filter' ); * * @since 4.6.0 * @@ -607,10 +620,10 @@ * @param string $tag The name of the filter hook. * @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. - * @param string $replacement Optional. The hook that should have been used. Default false. - * @param string $message Optional. A message regarding the change. Default null. + * @param string $replacement Optional. The hook that should have been used. Default empty. + * @param string $message Optional. A message regarding the change. Default empty. */ -function apply_filters_deprecated( $tag, $args, $version, $replacement = false, $message = null ) { +function apply_filters_deprecated( $tag, $args, $version, $replacement = '', $message = '' ) { if ( ! has_filter( $tag ) ) { return $args[0]; } @@ -634,10 +647,10 @@ * @param string $tag The name of the action hook. * @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. - * @param string $replacement Optional. The hook that should have been used. - * @param string $message Optional. A message regarding the change. + * @param string $replacement Optional. The hook that should have been used. Default empty. + * @param string $message Optional. A message regarding the change. Default empty. */ -function do_action_deprecated( $tag, $args, $version, $replacement = false, $message = null ) { +function do_action_deprecated( $tag, $args, $version, $replacement = '', $message = '' ) { if ( ! has_action( $tag ) ) { return; } @@ -679,7 +692,8 @@ $plugin_dir = wp_normalize_path( WP_PLUGIN_DIR ); $mu_plugin_dir = wp_normalize_path( WPMU_PLUGIN_DIR ); - $file = preg_replace( '#^' . preg_quote( $plugin_dir, '#' ) . '/|^' . preg_quote( $mu_plugin_dir, '#' ) . '/#', '', $file ); // get relative path from plugins dir + // Get relative path from plugins directory. + $file = preg_replace( '#^' . preg_quote( $plugin_dir, '#' ) . '/|^' . preg_quote( $mu_plugin_dir, '#' ) . '/#', '', $file ); $file = trim( $file, '/' ); return $file; } @@ -695,16 +709,13 @@ * * @global array $wp_plugin_paths * - * @staticvar string $wp_plugin_path - * @staticvar string $wpmu_plugin_path - * * @param string $file Known path to the file. * @return bool Whether the path was able to be registered. */ function wp_register_plugin_realpath( $file ) { global $wp_plugin_paths; - // Normalize, but store as static to avoid recalculation of a constant value + // Normalize, but store as static to avoid recalculation of a constant value. static $wp_plugin_path = null, $wpmu_plugin_path = null; if ( ! isset( $wp_plugin_path ) ) { $wp_plugin_path = wp_normalize_path( WP_PLUGIN_DIR ); @@ -832,10 +843,12 @@ * cases. Emphasis should be put on using the 'uninstall.php' way of * uninstalling the plugin. */ - $uninstallable_plugins = (array) get_option( 'uninstall_plugins' ); - $uninstallable_plugins[ plugin_basename( $file ) ] = $callback; - - update_option( 'uninstall_plugins', $uninstallable_plugins ); + $uninstallable_plugins = (array) get_option( 'uninstall_plugins' ); + $plugin_basename = plugin_basename( $file ); + if ( ! isset( $uninstallable_plugins[ $plugin_basename ] ) || $uninstallable_plugins[ $plugin_basename ] !== $callback ) { + $uninstallable_plugins[ $plugin_basename ] = $callback; + update_option( 'uninstall_plugins', $uninstallable_plugins ); + } } /** @@ -852,7 +865,7 @@ * @since 2.5.0 * @access private * - * @global array $wp_filter Stores all of the filters + * @global array $wp_filter Stores all of the filters and actions. * * @param array $args The collected parameters from the hook that was called. */ @@ -882,56 +895,34 @@ * @link https://core.trac.wordpress.org/ticket/3875 * * @since 2.2.3 + * @since 5.3.0 Removed workarounds for spl_object_hash(). + * `$tag` and `$priority` are no longer used, + * and the function always returns a string. * @access private * - * @global array $wp_filter Storage for all of the filters and actions. - * @staticvar int $filter_id_count - * - * @param string $tag Used in counting how many hooks were applied - * @param callable $function Used for creating unique id - * @param int|bool $priority Used in counting how many hooks were applied. If === false - * and $function is an object reference, we return the unique - * id only if it already has one, false otherwise. - * @return string|false Unique ID for usage as array key or false if $priority === false - * and $function is an object reference, and it does not already have - * a unique id. + * @param string $tag Unused. The name of the filter to build ID for. + * @param callable $function The function to generate ID for. + * @param int $priority Unused. The order in which the functions + * associated with a particular action are executed. + * @return string Unique function ID for usage as array key. */ function _wp_filter_build_unique_id( $tag, $function, $priority ) { - global $wp_filter; - static $filter_id_count = 0; - if ( is_string( $function ) ) { return $function; } if ( is_object( $function ) ) { - // Closures are currently implemented as objects + // Closures are currently implemented as objects. $function = array( $function, '' ); } else { $function = (array) $function; } if ( is_object( $function[0] ) ) { - // Object Class Calling - if ( function_exists( 'spl_object_hash' ) ) { - return spl_object_hash( $function[0] ) . $function[1]; - } else { - $obj_idx = get_class( $function[0] ) . $function[1]; - if ( ! isset( $function[0]->wp_filter_id ) ) { - if ( false === $priority ) { - return false; - } - $obj_idx .= isset( $wp_filter[ $tag ][ $priority ] ) ? count( (array) $wp_filter[ $tag ][ $priority ] ) : $filter_id_count; - $function[0]->wp_filter_id = $filter_id_count; - ++$filter_id_count; - } else { - $obj_idx .= $function[0]->wp_filter_id; - } - - return $obj_idx; - } + // Object class calling. + return spl_object_hash( $function[0] ) . $function[1]; } elseif ( is_string( $function[0] ) ) { - // Static Calling + // Static calling. return $function[0] . '::' . $function[1]; } }