[wp-trac] [WordPress Trac] #38743: Introduce add_action_once()
WordPress Trac
noreply at wordpress.org
Thu Nov 10 10:26:26 UTC 2016
#38743: Introduce add_action_once()
-----------------------------+-----------------------------
Reporter: tfrommen | Owner:
Type: feature request | Status: new
Priority: normal | Milestone: Awaiting Review
Component: General | Version:
Severity: normal | Keywords:
Focuses: |
-----------------------------+-----------------------------
Hi there.
I was wondering if noone ever needed to add a callback to some action or
filter hook only if it hasn't been added (potentially by someone else)
before.
Possible use cases are:
* only add `my_callback` if it hasn't been added before, no matter with
what priority;
* only add `my_callback` if it hasn't been added before with a specific
priority.
Naming-wise, I'd suggest `add_action_once()` and `add_filter_once()`,
respetively, although one could be more verbose (e.g.,
`add_action_if_not_exists()` etc.).
Here is a possible implementation of this:
{{{#!php
<?php
function add_action_once(
$tag,
callable $function_to_add,
$priority = 10,
$accepted_args = 1,
$check_priority = false
) {
return add_filter_once( $tag, $function_to_add, $priority,
$accepted_args, $check_priority );
}
function add_filter_once(
$tag,
callable $function_to_add,
$priority = 10,
$accepted_args = 1,
$check_priority = false
) {
global $wp_filter;
if ( empty( $wp_filter[ $tag ] ) ) {
return add_filter( $tag, $function_to_add, $priority,
$accepted_args );
}
if ( false === $check_priority ) ) {
if ( has_filter( $tag, $function_to_add ) ) {
return false;
}
} else {
foreach ( $wp_filter[ $tag ] as $functions ) {
foreach ( $functions as $data ) {
if ( isset( $data['function'] ) && $function_to_add ===
$data['function'] ) {
return false;
}
}
}
}
return add_filter( $tag, $function_to_add, $priority, $accepted_args
);
}
}}}
Yes, it is possible to check whether or not a specific callback has been
added to an action or filter hook by using `has_filter()`. And as you can
see, the above code uses that function internally.
However, this would mean that your code, where you want to add a callback
if it hasn't been added before, would have to perform `has_filter()` and
`add_action()`/`add_filter()`.
And secondly, by using `has_filter()`, you cannot check if a callback has
been added with a specific priority.
The two functions above take care of both as well.
'''Example:'''
{{{#!php
<?php
// Somewhere in your code... Maybe!
add_filter( 'the_title', 'add_exclamation_mark', 20 );
// Some other place, that maybe doesn't know about the place above...
add_filter( 'the_title', 'add_exclamation_mark', 10 );
// Yet another place...
echo apply_filters( 'the_title', 'Hi there' );
// Hi there!!
}}}
By using `add_filter_once()` (in this example withouth the last parameter
as I'm not interested in where/when the callback gets fired), this would
look like so:
{{{#!php
<?php
// Somewhere in your code... Maybe!
add_filter_once( 'the_title', 'add_exclamation_mark', 20 );
// Some other place, that maybe doesn't know about the place above...
add_filter_once( 'the_title', 'add_exclamation_mark', 10 );
// Yet another place...
echo apply_filters( 'the_title', 'Hi there' );
// Hi there!
}}}
So, what do you think?
Cheers,
Thorsten
--
Ticket URL: <https://core.trac.wordpress.org/ticket/38743>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list