Symfony2 структурный составной шаблон с сущностями

Я пытаюсь реализовать простой составной шаблон меню.

Это следующие классы, которые я придумал.

Пункт меню:

namespace MYNAME\MYBUNDLE\Entity;use MYNAME\MYBUNDLE\Menu\MenuComponent;

class MenuItem implements MenuComponent
{
private $id;
private $name;
private $path;
private $parent;
private $visible;
private $createdOn;
private $templating;
private $attr;
private $children;
private $website;
private $position = 1;

public function __construct($name = null, $path = null, $attr = array(), $visible = true)
{
$this->name = $name;
$this->path = $path;
$this->visible = $visible;
$this->attr = $attr;

$this->createdOn = new \DateTime;
}

public function prePersist()
{
$this->createdOn = new \DateTime;
}public function build()
{
$data['menu_item'] = $this;

$data['options'] = $this->attr;

if($this->hasChildren())
return $this->templating->render('MYBUNDLE:Menu:menu_dropdown.html.twig', $data);

if($this->isChild())
return $this->parent->getTemplating()->render('MYBUNDLE:Menu:menu_item.html.twig', $data);

return $this->templating->render('MYBUNDLE:Menu:menu_item.html.twig', $data);
}

public function __toString()
{
return $this->name;
}

public function setTemplating($templating)
{
$this->templating = $templating;
}

/**
* @return bool
*/
public function isChild()
{
return $this->hasParent();
}
/**
* @return bool
*/
public function hasParent()
{
return isset($this->parent);
}
/**
* @return bool
*/
public function hasChildren()
{
return count($this->children) > 0;
}
}

Если не использовать геттеры и сеттеры, чтобы сделать его здесь немного короче.
Как вы можете видеть, это сущность, и она содержит функцию build (), однако эта функция использует метод render, который, по моему мнению, не должен быть в сущности.

MenuController

<?php
namespace MYNAME\MYBUNDLE\Controller;use MYNAME\MYBUNDLE\Menu\Menu;
use MYNAME\MYBUNDLE\Entity\MenuItem;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;

class MenuController extends Controller
{
public function generateAction()
{
$menu = new Menu($this->get('templating'));

// load menu items
$items = $this->getDoctrine()->getRepository('MYBUNDLE:MenuItem')->findOrdered();

foreach($items as $item)
{
if(!$item->hasParent())
$menu->add($item);
}
return new Response($menu->build());
}
}

MenuController вызывается для отображения меню:

{{ render(controller('MYBUNDLE:Menu:generate')) }}

Я также хотел бы, чтобы это было по-другому, так как это выглядит неправильно. Возможно, лучше создать функцию ветки для отображения меню?

MenuComponent:

namespace MYNAME\MYBUNDLE\Menu;interface MenuComponent {
public function build();
}

Меню:

namespace MYNAME\MYBUNDLE\Menu;class Menu implements MenuComponent
{
private $children;
private $templating;

public function __construct($templating)
{
$this->templating = $templating;
}

public function add(MenuComponent $component)
{
$component->setTemplating($this->templating);
$this->children[] = $component;
}

public function build()
{
return $this->templating->render('MYBUNDLE:Menu:menu.html.twig', array("menu_items" => $this->children));
}
}

Menu Содержит MenuComponents и будет отображать меню первым, в каждом MenuItem вызывается его метод build ().

Я думаю, что лучше удалить логику рендеринга из моей сущности MenuItem и поместить ее где-нибудь еще, однако я не могу понять, как сделать это правильно в рамках этого шаблона проектирования.

Любая помощь или предложение приветствуется.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …