neanderslob
neanderslob

Reputation: 2693

Writing a class to pass add_action arguments in wordpress

I'm using the hook user_register that writes to the variable $user_id. I want to call this hook inside a function and pass the variable $pass from the parent function to the function register_pass. Once there, $pass and user_id will be sent to third party software as per their protocol.

The key goal is to get both $pass and $user_id into the same array to be sent out via SOAP.

function random_pass_save($pass){

    add_action( 'user_register', 'regiser_pass')
    function register_pass($user_id){
        .
        .
        .
        code that processes both the $user_id, AND $pass and sends it to another piece of software
        .
        .
        .
    }

}

Now I have done a bit of reading on this and I keep having people recommend using classes to pass variables around from add_action calls to parent functions and so on. In principle this makes sense; as I understand it, you can pretty much access the class everywhere (sort of like a global variable but a lot less precarious). However, I'm just not understanding how to apply the examples that I've seen to my situation. I haven't used classes before and so I was wondering if anyone would be kind enough to walk me through this particular application.

Upvotes: 2

Views: 3252

Answers (2)

brasofilo
brasofilo

Reputation: 26065

If I'm understanding this right, you simply need to call a custom function when a user is created. The functions don't have to be nested and it doesn't matter if this is a class or not.

Add the hook and inside its callback, you call your function passing the data:

add_action( 'user_register', 'register_pass' );

function register_pass( $user_id )
{
    $password = get_the_password_somehow_with( $user_id ); // <--- problem
    random_pass_save( $user_id, $password );
}

function random_pass_save( $user_id, $password )
{
    // do your thing
}

That problem can be solved with the hook check_passwords, that happens before user_register and that contains both the user name and the password.

But ok, let's do it in a Class, it's based in this skeleton that I always use. All the explanation is in the code comments.

<?php
/**
 * Plugin Name: Testing a Singleton
 * Plugin URI:  http://stackoverflow.com/questions/19306582
 * Version:     0.1
 * Author:      brasofilo 
 * Author URI:  http://wordpress.stackexchange.com/users/12615/brasofilo
 */

# Start the plugin in a safe point
add_action( 
    'plugins_loaded',
    array( B5F_Demo_SO_19306582::get_instance(), 'plugin_setup' )
    );

class B5F_Demo_SO_19306582 
{
    # Singleton
    protected static $instance = NULL;  

    # Store new user data (id, name, password)
    private $user_data;  

    # Leave empty
    public function __construct() {}

    # Singleton
    public static function get_instance() 
    {
        NULL === self::$instance and self::$instance = new self;
        return self::$instance;
    }

    # Start our action hooks
    public function plugin_setup() 
    {
        add_action( 'check_passwords', array( $this, 'check_pass' ), 10, 3 );
        add_action( 'user_register',  array( $this, 'user_register_action' ) );
    }

    # Confirms that passwords match when registering a new user
    public function check_pass( $user, $pass1, $pass2 ) 
    {   
        // They match, let's add data to our private property
        if( $pass1 == $pass2 )
            $this->user_data = array( 'user' => $user, 'pass' => $pass1 );
    }

    # Add the ID of a newly registered user to our private property
    # Now we have all the data and can call our final method
    public function user_register_action( $user_id )
    {
        $this->user_data['user_id'] = $user_id;
        $this->external_save();
    }

    # In this method we do our thing with all the information 
    # previously stored in the private property
    public function external_save()
    {
        var_dump( $this->user_data );
        die();
    }
}

Upvotes: 3

acobster
acobster

Reputation: 1657

You don't need a function within a function; as others have stated, you can accomplish this with classes.

I'd suggest reading up on the Singleton pattern. Basically, you want an object that guarantees the presence of only one instance of itself. So let's say the class you use to store the new user's info is called UserCredentials. Once it's implemented as a Singleton, along with getters/setters for user/pass as appropriate, you can do:

function random_pass_save($pass) {
    UserCredentials::getSingleton()->savePass($pass);
}

add_action( 'user_register', 'regiser_pass')
function register_pass($user_id){
    $pass = UserCredentials::getSingleton()->getPass();
    // $user_id and $pass are now both in scope
}

As you inferred, the same thing can be accomplished by storing to $GLOBALS['whatever'], but this is cleaner.

Upvotes: 2

Related Questions