PHP/WordPress — bind arguments to add_action call at bind time

I want to do something like this:

function activate_account_callback($user_id) {
  function footer_callback() {
     // Do some stuff with $user_id
  };

  add_action('wp_footer', footer_callback);
};

add_action('bp_core_activate_account', 'activate_account_callback');

ie., on the bp_core_activate_account event I want to attach an event to wp_footer. The problem I’m having is that the inner function footer_callback doesn’t seem to be able to access the $user_id argument passed to activate_account_callback (I’m not a PHP programmer and I’m not entirely sure how PHP scoping works).

Read More

So what I’d like to do is somehow create a new function that takes no arguments but that has access to the $user_id variable.

So the way I’d like to solve the problem boils down to wanting to do this:

function func1($arg) {
   echo($arg);
}
function func2 = some_magic($func1, 3);
func2(); // Should echo "3"

Then I could use the func2 function and pass it to the inner add_action. I just don’t know what the some_magic should be.

Or if this an inherently dumb way of doing things I’m open to other suggestions.

Related posts

Leave a Reply

1 comment

  1. Calling a function within a function like that isn’t very standard, and you don’t need to do it that way anyway. Is the activated user also the user who is logged in to WordPress? It would save some effort if you could just use wp_get_current_user().

    If you need to carry the $user_id from one function to another, between hooks, you can’t transfer it directly and the scope of the functions won’t work for you. You could use globals, or use a function with a static variable.

    Using a global variable

    function activate_account_callback($user_id) {
      global $bpcore_activated_uid;
      $bpcore_activated_uid = $user_id;
    
      add_action('wp_footer', activate_account_footer);
    };
    
    function activate_account_footer() {
      global $bpcore_activated_uid;
      if ( !$bpcore_activated_uid ) return;
    
      echo "Activated user ID: " . $bpcore_activated_uid;
    }
    
    add_action('bp_core_activate_account', 'activate_account_callback');
    

    (Update) Using a static variable

    We’ll call the target twice this way, the first time will be used just to capture the user ID. Once captured, future calls will already have the value. The only real reason you want this over a global variable is if you don’t need the user ID anywhere else.

    function activate_account_callback($user_id) {
      activate_account_footer( $user_id ); // Pass the user ID
      add_action('wp_footer', activate_account_footer);
    };
    
    function activate_account_footer($u = null) {
      static $user_id = null;
    
      if ( $u && !$user_id ) {
        $user_id = $u;
        return; // capture and abort
      }
    
      if ( !$user_id ) return; // In case we never provide the value, abort
    
      echo "Activated user ID: " . $user_id ;
    }
    
    add_action('bp_core_activate_account', 'activate_account_callback');
    

    Notes:

    1. I am not familiar with the plugin involved, but I would assume you can access the user ID through a global variable provided by the plugin. Some like $bp (which exists, but I do not know if it contains the ID).
    2. Neither option is built to work for multiple user activations at once. If this function is used for bulk actions, you may have issues. If you need multiple user support, just switch to an array (static variable