I'm propably too tired but I've been wrestling with this one for a while. A container can either have a layout on its own, or it can have a parent somewhere up the hierarchy that has a layout. I need to find that layout no matter how far up the line it is.
The object $container has a property $parent which, if not null, references another $container object (same type).
I think this code has a problem in the while condition?
private function findInheritedLayout($container) {
do {
if ( $container->getLayoutTemplate() ) {
return $container->getLayoutTemplate();
}
else {
if ( $container->getParent() ) {
$container = $container->getParent();
}
else {
return null;
}
}
} while ( $container->getParent() ); //flawed? looks for a parent one step too far?
}
Your assumption is correct. The while condition checks if the current $container
has a parent, without checking for a layout.
Try the following:
while (!$container->getLayoutTemplate() && $container->getParent()) {
$container = $container->getParent();
}
$template = $container->getLayoutTemplate();
return $template ?: null;
The Test:
$test = new View('A');
$test->assign('A', new View('B'));
$test->assign('B', $test2 = new View('C'));
$test2->assign('D', $test3 = new View('E'));
$test3->assign('F', $searchTarget = new View('G'));
$root = RootViewIterator::findRootOf($searchTarget);
var_dump($root->getName());
The Result:
string(1) "A"
The Iterator:
class RootViewIterator
implements Iterator
{
protected $view;
protected $startView;
protected $key = 0;
public function __construct(View $view)
{
$this->view = $view;
$this->startView = $view;
}
public function next()
{
$this->view = $this->view->getParent();
$this->key++;
}
public function key()
{
return $this->key;
}
public function current()
{
return $this->view;
}
public function rewind()
{
$this->view = $this->startView;
$this->key = 0;
}
public function valid()
{
return null !== $this->view;
}
public static function findRootOf(View $view)
{
$result = iterator_to_array(new static($view));
end($result);
return current($result);
}
}
The View:
class View
{
protected $name;
protected $items;
protected $parent;
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
public function assign($key, $content)
{
if ( $content instanceof View ) {
$content->setParent($this);
}
$this->items[$key] = $content;
}
public function setParent(View $view)
{
$this->parent = $view;
}
public function getParent()
{
return $this->parent;
}
public function hasParent()
{
return !empty($this->parent);
}
}