具有实体的Symfony2结构复合模式

时间:2014-10-11 08:30:45

标签: php symfony model-view-controller composite

我正在尝试实现一个简单的菜单组合模式。

以下是我提出的课程。

菜单项:

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

菜单包含MenuComponents并将首先渲染菜单,在每个MenuItem中调用它的build()方法。

我认为最好从我的MenuItem实体中删除渲染逻辑并将其放在其他地方,但是我无法弄清楚如何在此设计模式中正确执行此操作。

感谢任何帮助或建议。

0 个答案:

没有答案