Sign in
Log inSign up

PHP: Component that extends other component, without changing original component

Emil Moe's photo
Emil Moe
·Dec 6, 2018

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);