Home > front end >  How to encapsulate WP_User in a new class and access directly both properties and methods?
How to encapsulate WP_User in a new class and access directly both properties and methods?

Time:03-27

I am developing a WordPress theme and I am faced with a problem that I cannot solve. I need to "extend" the WP_User class objects with a number of new methods and properties. At first I thought about extending the class by inheritance, but I always start from an already existing WP_User object so if I used an extension I would actually create a new object that would not remain aligned in case of changes to the original one. So I decided to encapsulate the already existing WP_User type object. Then I wrote the following class:

class My_User {
    protected WP_User $wp_user;

    public function __construct($user) {
        $this->wp_user = $user;
    }

    public function __get( $key ) {
        if ( isset( $this->$key ) ) { // I have all My_User properties set
            $value = $this->$key;
        } else {
            $value = $this->wp_user->$key;
        }
        return $value;
    }
}

An example of usage is

$wp_user = wp_get_current_user();
$my_user = new My_User($wp_user);

Thanks to the magic function __get() I can directly access the properties of the encapsulated object as if they were properties of My_User, but how can I do the same thing for the methods too? For example, is there a way to call $wp_user->exists() by writing $my_user->exists() without overriding all methods one by one? A magic function similar to __get() but for methods and not for properties?

CodePudding user response:

What you search is the __call magic method. See the php doc about this.

It's pretty straightforward to use :

class My_User {
    protected WP_User $wp_user;

    public function __construct($user) {
        $this->wp_user = $user;
    }

    public function __call( $method, $args ) {
         return $this->wp_user->$method(...$args);
    }
}

You don't need to do any test on $this because __call will only be invoked if a not found method is invoked on an object.

  • Related