PHP: Component that extends other component, without changing original component
I have a scenario where I'm having 2 components. Let's say:
- Users
- Permissions
I can choose to just install Users
then there's basic authentication, 1 role only. If I choose to also install Permissions
then the option of different roles would be added to the system.
I want Permissions
to add some extra features to the users, like $user->hasRole('admin')
, but I don't want to modify in the Users
package nor do I want to have to create a parent class for both.
How would you solve this?
I have a few ideas, I haven't tested any of them out.
1: The first one gives a better code when using, but is breaking semantics, and I'm not 100% sure if it works:
Having an Extender
parent observer, that any class can add a method to. Then Permissions
would have to do something like:
Extender::add(
Addons\User::class,
function($role) {
// $user = Somehow obtain user class when called from there
// Check if $user has $role
});
The User class must have a magic method:
function __call($method, $params)
{
return Extender(Addons\User::class, $method($params));
}
The idea is the ability to call the user directly:
$user->hasRole($role);
I hope you get the idea, but I don't think this is an optimal solution.
2: Permissions
gets feeded an user object
The idea is that a user object is injected into the permission:
class Permission
{
public function __construct(User $user)
{
$this->user = $user;
}
public function hasRole($role)
{
return Role::user($user)->has($role);
}
}
That would of course be called from:
Permission($user)->hasRole($role);