Opened 20 years ago
Closed 20 years ago
#768 closed enhancement (fixed)
Add support for additional arguments to filters
Reported by: |
|
Owned by: |
|
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 1.5 |
Component: | General | Keywords: | |
Focuses: | Cc: |
Description
It is often difficult or impossible within a filter to discover the context with which the function being filtered was called. For example, get_permalink() takes an optional $id argument; when this argument is used, it is unknown to the filter which post id has been passed. Suggest adding support for passing additional arguments to filters, and passing useful information to apply_filters() where appropriate.
Attachments (1)
Change History (13)
#2
@
20 years ago
- Summary changed from Add support to filters for additional arguments to Add support for additional arguments to filters
#5
@
20 years ago
I just committed a close version of this. I got rid of the $filter argument to apply_filters since it was used only by do_action. Factoring some things out of apply_filters and into merge_filters and copying the remaining filter logic into do_action allowed me to get rid of $filter and also give do_action a more suitable call signature. BTW, when we want to do call time pass by reference, we must use the array trick on the call to do_action. Ex:
do_action('generate_rewrite_rules', array(&$this)); Works
Directly specifying &$this will result in the call time pass by reference error.
do_action('generate_rewrite_rules', &$this); Won't work.
I thought about making the call signature for do_action be do_action($tag, &$arg = NULL) and changing all calls to accommodate that sig, but do_action is used in templates in a manner incompatible with that sig. I'd rather not break templates. Perhaps we should have had a user space do_template_action() wrapper, but it's too late for that.
Thanks morganiq. Another fine patch. Now we need to pass extra args where they are needed. We can take care of that in another bug.
edited on: 02-01-05 09:42
#7
@
20 years ago
Great Ryan, thanks so much. This will really take the plugin API to the next level, I think.
By the way, I wasn't aware of the call time pass by reference error, but in your illustration you used the same example for what will work and what won't. Just to clarify, did you mean:
do_action('generate_rewrite_rules', array(&$this)); Works
do_action('generate_rewrite_rules', &$this); Won't work.
Is this a PHP bug? Or is it a logical anomaly that can't be repaired?
#8
@
20 years ago
I fixed the examples.
PHP no longer allows call time pass by reference. You must declare an arg as being a reference at the function definition rather than at function call time. We would have to update the function definition of do_action to accept a reference, but doing so would require updating all templates in the wild since they contain do_action('wp_footer', ). You can't make a reference to a literal string, only a variable.
#9
@
20 years ago
Gotcha, thanks for the explanation.
I'll start compiling extra arguments and submit another bug for their addition.
#10
@
20 years ago
Found one minor error, on line 940 of function.php:
$args = array($action) + array_slice(func_get_args(), 2);
$action should be $arg.
#11
@
20 years ago
Maybe I was a little heavy on the rhetoric -- "taking the plugin API to the next level." Looking through the filters and actions, there are far fewer places where multiple arguments are useful than I figured there would be.
Oh well, it's still useful in many places. :-)
Not also that call_user_func_array() could be called in place of call_user_func(), to pass additional arguments into filter functions as normal list of arguments rather than as a single array.
+
+ if ($filter)
+ $args = array($string) + array_slice(func_get_args(), 3);
+ else
+ $args = array($string) + func_get_arg(3);
+
! $string = call_user_func_array($function, $args);
! call_user_func_array($function, $args);
Note also that call_user_func_array() can pass values by reference, whereas call_user_func() cannot.