varuog
varuog

Reputation: 3081

restrict method of an class while calling from another class

abstract class User
{
  protected $content; // $content object will be assigned here


}

class Member extends User
{

}


abstract class Content
{
 function create()
 {
  //create some content
 }
}

class Text extends Content
{

}

class Image extends Content
{
}

Abstract User can extend to other classes based on rolls which are customizable. Each roll has a different permission to use Content class, and it's child classes method. I can write manually each permission for each method, but I want to do that dynamically.

How can I do that?

Upvotes: 0

Views: 154

Answers (1)

Elias Van Ootegem
Elias Van Ootegem

Reputation: 76395

UPDATE

On reading your question a second time, I've just thought of another way that is a better fit for what you need. Though php doesn't support multiple inheritance, and traits require php >= 5.4, you might want to consider adding a second "generation" (another level of children). The abstract class contains only those methods that are available to all, preferably with final keyword, or that only have 1 variation somewhere down the line (in which case, drop the final keyword and override the member function).

As I've said before, I'm not that good in explaining this stuff, So I went on ahead an put together an example of how your classes could look like:

abstract class User
{
    public function __construct()
    {
        echo get_class($this).'<br/>';
    }
    final function forAll()
    {
        echo 'access for all';
    }
}
class TxtGroup extends User
{
    public function __construct()
    {
        parent::__construct();
    }
    public function abstr()
    {
        echo 'TxtGroup specific';
    }
}
class ImgGroup extends User
{
    public function __construct()
    {
        echo 'Same, but different for ImgGroup<br/>';
        parent::__construct();
    }
    public function abstr()
    {
        echo 'ImgGroup specific';
    }
}
class inst1 extends TxtGroup
{
    public function __construct()
    {
        parent::__construct();
        if ($this instanceof TxtGroup)
        {
            echo 'Child member of: TxtGroup<br/>';
        }
        if ($this instanceof inst1)
        {
            echo 'Child instance of inst1 (itself)<br/>';
        }
        if ($this instanceof User)
        {
            echo 'grand-Child of User<br/>';
        }
    }
    public function objSpecific()
    {
        echo 'self explanatory<br/>';
    }
}
class inst2 extends ImgGroup
{
    public function __construct()
    {
        parent::__construct();
        if ($this instanceof ImgGroup)
        {
            echo 'Child member of: ImgGroup<br/>';
        }
        if ($this instanceof inst2)
        {
            echo 'Child insance of inst2 (itself)<br/>';
        }
        if ($this instanceof User)
        {
            echo 'grand-Child of User<br/>';
        }
    }
}
$foo = new inst1();
$bar = new inst2();

See what I mean? Output:

inst1
Child member of: TxtGroup
Child instance of inst1 (itself)
grand-Child of User
Same, but different for ImgGroup
inst2
Child member of: ImgGroup
Child insance of inst1 (itself)
grand-Child of User


If you're using the latest version of PHP, you have traits for that. There's a lot of ways you can check which class is invoking the memberfunction. The easiest, IMO, is by starting your methods by checking the value of get_class($this);:

abstract class Foo
{
    public function who()
    {
        echo get_class($this);
    }
}
class bar extends Foo
{
    public function __construct()
    {
        $this->who();
    }
}
$f = new bar();

echo's bar, so you can alter the abstract methods, and throw exceptions if necessary.

The same construction can be used to overload certain methods, like this (terrible) example (tries to show/) shows:

abstract class Foo
{
    public function who()
    {
        $child =  explode('_',get_class($this));
        if (end($child) === 'whoExec')
        {
            return $this->whoExec();
        }
        echo 'this isn\'t for bar the bar instance';
        return $this;
    }
    private function whoExec()
    {
        if(!strstr('whoExec',get_class($this)))
        {
            return $this->who();
        }
        echo 'This methods mimics overloading -sort of';
        return $this;
    }
}
class bar_whoExec extends Foo
{
    public function __construct()
    {
        $this->who();
    }
}
$f = new bar(); 

Upvotes: 1

Related Questions