Make WordPress Core

Changeset 53803


Ignore:
Timestamp:
07/31/2022 02:18:36 PM (2 years ago)
Author:
SergeyBiryukov
Message:

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.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/plugin.php

    r53770 r53803  
    3030/** @var int[] $wp_actions */
    3131global $wp_actions;
     32
     33/** @var int[] $wp_filters */
     34global $wp_filters;
    3235
    3336/** @var string[] $wp_current_filter */
     
    4245if ( ! isset( $wp_actions ) ) {
    4346    $wp_actions = array();
     47}
     48
     49if ( ! isset( $wp_filters ) ) {
     50    $wp_filters = array();
    4451}
    4552
     
    156163 *
    157164 * @global WP_Hook[] $wp_filter         Stores all of the filters and actions.
     165 * @global int[]     $wp_filters        Stores the number of times each filter was triggered.
    158166 * @global string[]  $wp_current_filter Stores the list of current filters with the current one last.
    159167 *
     
    164172 */
    165173function apply_filters( $hook_name, $value, ...$args ) {
    166     global $wp_filter, $wp_current_filter;
     174    global $wp_filter, $wp_filters, $wp_current_filter;
     175
     176    if ( ! isset( $wp_filters[ $hook_name ] ) ) {
     177        $wp_filters[ $hook_name ] = 1;
     178    } else {
     179        ++$wp_filters[ $hook_name ];
     180    }
    167181
    168182    // Do 'all' actions first.
     
    205219 *
    206220 * @global WP_Hook[] $wp_filter         Stores all of the filters and actions.
     221 * @global int[]     $wp_filters        Stores the number of times each filter was triggered.
    207222 * @global string[]  $wp_current_filter Stores the list of current filters with the current one last.
    208223 *
     
    212227 */
    213228function apply_filters_ref_array( $hook_name, $args ) {
    214     global $wp_filter, $wp_current_filter;
     229    global $wp_filter, $wp_filters, $wp_current_filter;
     230
     231    if ( ! isset( $wp_filters[ $hook_name ] ) ) {
     232        $wp_filters[ $hook_name ] = 1;
     233    } else {
     234        ++$wp_filters[ $hook_name ];
     235    }
    215236
    216237    // Do 'all' actions first.
     
    376397
    377398    return in_array( $hook_name, $wp_current_filter, true );
     399}
     400
     401/**
     402 * Retrieves the number of times a filter has been applied during the current request.
     403 *
     404 * @since 6.1.0
     405 *
     406 * @global int[] $wp_filters Stores the number of times each filter was triggered.
     407 *
     408 * @param string $hook_name The name of the filter hook.
     409 * @return int The number of times the filter hook has been applied.
     410 */
     411function did_filter( $hook_name ) {
     412    global $wp_filters;
     413
     414    if ( ! isset( $wp_filters[ $hook_name ] ) ) {
     415        return 0;
     416    }
     417
     418    return $wp_filters[ $hook_name ];
    378419}
    379420
  • trunk/tests/phpunit/tests/filters.php

    r53802 r53803  
    151151    }
    152152
     153    /**
     154     * @covers ::did_filter
     155     */
     156    public function test_did_filter() {
     157        $tag1 = 'filter1';
     158        $tag2 = 'filter2';
     159        $val  = __FUNCTION__ . '_val';
     160
     161        // Apply filter $tag1 but not $tag2.
     162        apply_filters( $tag1, $val );
     163        $this->assertSame( 1, did_filter( $tag1 ) );
     164        $this->assertSame( 0, did_filter( $tag2 ) );
     165
     166        // Apply filter $tag2 10 times.
     167        $count = 10;
     168        for ( $i = 0; $i < $count; $i++ ) {
     169            apply_filters( $tag2, $val );
     170        }
     171
     172        // $tag1's count hasn't changed, $tag2 should be correct.
     173        $this->assertSame( 1, did_filter( $tag1 ) );
     174        $this->assertSame( $count, did_filter( $tag2 ) );
     175
     176    }
     177
    153178    public function test_all_filter() {
    154179        $a    = new MockAction();
Note: See TracChangeset for help on using the changeset viewer.