6

I have an add_filter function for the auth_cookie_expiration hook. This hook accepts three parameters. However, I am interested in passing it more parameters. For example:

add_filter( 'auth_cookie_expiration', 'get_expiration', 10, 5 );

This would be possible with apply_filter, but the add_filter function is called once, which makes it throw an error:

PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments to function get_expiration(), 3 passed in ... and exactly 5 expected

I got around this using closures, but it seems like a completely ridiculous way to do this:

add_filter( 'auth_cookie_expiration', function() use ($param1, $param2) { return get_expiration(null, null, null, $param1, $param2); } , 10, 3 );

Is there a proper/more elegant way to make it accept additional parameters (even better, the params I want in place of the default ones)? Am I misunderstanding how add_filter is supposed to work?

For the sake of example, suppose get_expiration looks like this:

function get_expiration( $length, $user_id, $remember, $param1, $param2 )
{
    return $param1 + $param2;
}
3
  • 1
    you cannot modify the argument numbers then the use of use looks like the better solution.
    – mmm
    Jan 3, 2018 at 16:06
  • 1
    what is not elegant about closures? by miles better than creating an object for this or using globals. Jan 3, 2018 at 16:15
  • They're not inelegant in principle (on the contrary), just in this case: basically I'm creating a function within a one-liner just to call another function. It's a pretty dirty workaround for having to use a hook that doesn't handle such cases. But here I suspect I am simply missing something, and that WordPress has thought of such a scenario. Could be wrong though.
    – Ynhockey
    Jan 3, 2018 at 16:19

3 Answers 3

5

The second parameter in add_filter is a function with accepted arguments, not returned values.

This is an example how I pass my custom array $args to change an existing array $filter_args:

add_filter( 'woocommerce_dropdown_variation_attribute_options_args', function( $filter_args ) use ( $args ) {
        return eswc_var_dropdown_args( $filter_args, $args );
    }
);

function eswc_var_dropdown_args( $filter_args, $args ) {
    $filter_args['show_option_none'] = $args['var_select_text'];
    return $filter_args;
}
3

Am I misunderstanding how add_filter is supposed to work?

Yes, you are.

The function ( aka callback function ), specified by name, in the second parameter of add_filter(), NEVER passes ANY parameters. It accepts parameters passed by apply_filters(). The number of these parameters, and their meaning is defined by apply_filters(). The callback function MUST accept at least the first parameter, past the hook name. It MUST, also, return modified ( or not ) value for this first parameter.

1
  • 4
    What would be a good way for this user to access an additional variable ( not originally passed to the function ) inside the callback?
    – Howdy_McGee
    Jan 3, 2018 at 22:07
0

After just using my original "solution" for a while, I have returned to this problem with a bit more time to figure out what WordPress actually does.

Firstly it should be noted that to directly pass a parameter to an add_filter function, the only reasonable way is the one in my original question.

However, more often than not, it is possible to solve the larger problem better by passing a parameter to the function calling apply_filters in WordPress or the plugin you're trying to hook into.

For example, apply_filters( 'auth_cookie_expiration' ), in any meaningful way for hooking, is called in WordPress inside wp_set_auth_cookie, which accepts the same parameters ( $user_id, $remember ), so calling wp_set_auth_cookie() (likely done anyway for any session manipulation) allows the eventual passing of parameters to add_filter. For example:

add_filter( 'auth_cookie_expiration', array( 'get_session_expiration' ), 10, 3 );

// ...

wp_set_auth_cookie( $user_id, $is_remember_me );

// ...

function get_session_expiration( $expiration, $user_id, $remember ) {
    // ...
    return $some_calculated_expiration;
}

This works in multiple cases I have found where filter hooks are available.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.