1

While building an object-based menu component i ran into a problem.

Imagine:

abstract class key {}
class key_main extends key {}
class key_submenu extends key_main {}
class key_navpoint extends key_submenu {}

These menu items can render themselves:

abstract class key {
    public function render(){
        return template::get('key', '/tpl/menu/');
    }
}

The according templates are stored in a structurally similar scheme:

/tpl/menu/main/template.key.php
/tpl/menu/main/submenu/template.key.php
/tpl/menu/main/submenu/navpoint/template.key.php

In order for the render functions to access the correct templates, i want to introduce a function buildTemplatePath() that basically calls itself for inherited-from class up the tree, chaining classnames together:

abstract class key {
    public function buildTemplatePath(){
        return get_class($this) . '/' . parent::buildTemplatePath();
    }
}

This function should return the correct path:

$navpoint=new key_navpoint();
$path=$navpoint->buildTemplatePath();
/* $path should be 'main/submenu/navpoint' */

The problem is that this only works if i place the buildTemplatePath() function within each child class separately. Since it contains the same code, it seems kind of a shady workaround to me, to do that.

Therefore my question is:

How do i modify buildTemplatePath() so that it works as desired without having to be defined in each subclass?

I tried various things, including using get_parent_class($this), but i cannot get this to work.

1 Answer 1

1

Use recursion, but you may manually remove the "key_" and namespace prefixes returned from get_parent_class and get_class.

abstract class key {
    public function buildTemplatePath(){
        return self::buildTemplatePathRecursion(get_class($this));
    }
    private static function buildTemplatePathRecursion(string $clz){
        $parentClz = get_parent_class($clz);
        return $parentClz ?
            self::buildTemplatePathRecursion($parentClz).'/'.$clz :
            '';
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.