[wp-trac] [WordPress Trac] #54860: Enhancement for more accurate doing_action, doing_filter

WordPress Trac noreply at wordpress.org
Thu Jan 20 00:34:06 UTC 2022


#54860: Enhancement for more accurate doing_action, doing_filter
-------------------------------+-----------------------------
 Reporter:  Starbuck           |      Owner:  (none)
     Type:  enhancement        |     Status:  new
 Priority:  normal             |  Milestone:  Awaiting Review
Component:  Posts, Post Types  |    Version:  4.7
 Severity:  minor              |   Keywords:
  Focuses:                     |
-------------------------------+-----------------------------
 **Problem**

 The `doing_action` function returns true if the currently active hook is a
 filter, not an action.

 Since all actions are filters, in a legacy and technical sense, this is OK
 for general purposes - we want to know if a hook is in progress, whether
 it's a filter or an action.

 But since there are two functions, `doing_action` and `doing_filter`,
 there is an implication that they should do something different. As of
 v4.7, the WP_Hook class does make an internal distinction that can be
 helpful elsewhere if surfaced.

 **Remedy**

 I suggest that going forward these functions should accurately reflect
 whether a __filter__ is being applied (from `apply_filters`, value being
 returned) **OR** whether an __action__ is being executed (from
 `do_action`, no value returned).

 ----

 **Verification of this condition/claim:**

 [https://core.trac.wordpress.org/browser/tags/5.8.3/src/wp-includes/class-
 wp-hook.php?rev=52509#L52 Here] (ref current 5.8.3 source) in WP_Hook we
 verify that `$doing_action = false`, defaulting to the state of "doing" a
 filter. This was implemented in v4.7.0.

 [https://core.trac.wordpress.org/browser/tags/5.8.3/src/wp-includes/class-
 wp-hook.php?rev=52509#L325 Here] in WP_Hook we also see that `do_action`
 sets the value to true before passing on to the common `apply_filters`
 function.

 {{{#!php
 public function do_action( $args ) {
    $this->doing_action = true;
    $this->apply_filters( '', $args );
    ...
 }}}

 [https://core.trac.wordpress.org/browser/tags/5.8.3/src/wp-
 includes/plugin.php#L590 In plugin.php] we see `doing_action` (implemented
 in v3.9.0) just wraps/returns `doing_filter`.

 {{{#!php
 function doing_action( $hook_name = null ) {
    return doing_filter( $hook_name );
 }
 }}}

 The doing_filter function just tells us if we are processing a hook - it
 does not look into the hook to determine what kind of hook it is, action
 or filter. In short, this specific code just hasn't been enhanced yet in-
 line with WP_Hook.

 {{{#!php
 function doing_filter( $hook_name = null ) {
   global $wp_current_filter;
   if ( null === $hook_name ) {
      return ! empty( $wp_current_filter );
   }
   return in_array( $hook_name, $wp_current_filter, true );
 }
 }}}

 ----

 **Proposed Enhancement Implementation !#1**

 While I'm a newcomer to WP internals I believe it would be more accurate
 to do something like this:

 {{{#!php
 function doing_filter( $hook_name = null ) {
   global $wp_filter, $wp_current_filter;

   if ( null === $hook_name ) {
      if(empty( $wp_current_filter )) {
        return false;
      }
      return $wp_filter[current_filter()]->isFilter();
   }

   if($hook_name == current_filter()) {
     return $wp_filter[$hook_name]->isFilter();
   }
 }
 }}}

 In WP_Hook, add the getter `isFilter()` to return the opposite value of
 $doing_action. Add another getter, `isAction()` that simply returns
 $doing_action. This encapsulation eliminates all confusion outside of
 WP_Hook about how it works.

 The `doing_action` function cannot simply negate the value from
 `doing_filter`. If $wp_current_filter is empty, both functions might
 return false. The new code for `doing_action` needs to be like
 `doing_filter`, but returning the value of isAction() for the
 `current_filter()`.

 To avoid breaking legacy code, perhaps new functions should be created,
 and the 'doing' functions can get a long-term deprecation.

 - executing_action
 - executing_filter
 - executing_hook

 The new executing_hook function should return the OR of executing_action()
 with executing_filter() - this is what developers should use to replace
 the current functions for code that doesn't actually care what kind of
 hook is being processed.

 (Also consider the prefix 'processing_'.)

 ----

 **Proposed Enhancement Implementation !#2**

 Another way to implement this would be to add a second parameter to the
 existing functions, essentially a Boolean to invoke higher accuracy, with
 a default of false. Then the new functions above can be internal, there's
 no API change, no deprecation, etc.

 ----

 **Bug or Feature?**

 I suggest this is an enhancement to address a v4.7 oversight. As noted
 above, this isn't a bug, since internally an action **is** a filter, so
 the result of `doing_action` is technically valid when a __filter__ is
 active. This enhancement can be stated as an introduction of more nuanced
 functionality, where the current functions are essentially synonymous with
 a less refined "doing_hook".

 Thanks for consideration.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/54860>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list