Create a static control for the menus, the purpose was for each Bundle to register its menu item.
<?php
namespace Test\RegisterBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Doctrine\Common\Collections\ArrayCollection;
use Test\RegisterBundle\Entity\Menu;
class MenuController extends Controller {
const STANDARD_CONTAINER = '#content-wrapper';
/**
*
* @var ArrayCollection
*/
private static $menus;
public static function register(Menu $m) {
if (empty(self::$menus)) {
self::$menus = new ArrayCollection();
}
self::$menus->add($m);
}
public static function getAll() {
return self::$menus;
}
/**
*
* @param ArrayCollection $menus
* @param array $navs
* @return Menu
*/
private static function getMenuByNavFromCollection(ArrayCollection $menus, $navs) {
$e = array_shift($navs);
foreach (self::$menus as $m) {
if (!$m instanceof Menu) {
continue;
}
if ($m->getName() != $e) {
continue;
}
if (empty($navs)) {
return $m;
} else if ($m->getSubmenu()->count() == 0) {
return null;
} else {
return self::getMenuByNavFromCollection($m->getSubmenu(), $navs);
}
}
return null;
}
/**
* @param string $location
* @return Menu
*/
public static function getMenuByNav($location) {
$navs = explode('::', $location);
if (empty($navs) || empty(self::$menus)) {
return null;
}
return self::getMenuByNavFromCollection(self::$menus, $navs);
}
}
<?php
namespace Test\RegisterBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Table(name="menu")
* @ORM\Entity
*/
class Menu {
const TYPE_SIDEBAR = 'sidebar';
const TYPE_LABEL = 'label';
function __construct() {
$this->submenu = new ArrayCollection();
}
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=64, nullable=false)
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="mode", type="string", length=16, nullable=false)
*/
private $mode;
/**
* @var string
*
* @ORM\Column(name="uri", type="string", length=64, nullable=false)
*/
private $uri;
/**
* @var string
*
* @ORM\Column(name="remote", type="string", length=64, nullable=false)
*/
private $remote;
/**
* @var string
*
* @ORM\Column(name="icon", type="string", length=16, nullable=false)
*/
private $icon;
/**
* @ORM\Column(name="description", type="text", nullable=true)
* @var string
*/
private $description;
/**
* @ORM\Column(name="created", type="datetime", nullable=true)
* @var \DateTime
*/
private $created;
/**
* @ORM\Column(name="modified", type="datetime", nullable=true)
* @var \DateTime
*/
private $modified;
/**
* @ORM\OneToMany(targetEntity="Menu", mappedBy="parent")
* */
private $submenu;
/**
* @ORM\ManyToOne(targetEntity="Menu", inversedBy="submenu")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
*/
private $parent;
/**
* @ORM\ManyToMany(targetEntity="Module", inversedBy="menu")
* @ORM\JoinTable(name="menu_modules")
*/
private $module;
public function getId() {
return $this->id;
}
public function getName() {
return $this->name;
}
public function getUri() {
return $this->uri;
}
public function getMode() {
return empty($this->mode) ? self::TYPE_SIDEBAR : $this->mode;
}
public function setMode($mode) {
$this->mode = $mode;
return $this;
}
public function getIcon() {
return $this->icon;
}
public function getDescription() {
return $this->description;
}
public function getCreated() {
return $this->created;
}
public function getModified() {
return $this->modified;
}
/**
*
* @return ArrayCollection
*/
public function getSubmenu() {
return $this->submenu;
}
/**
*
* @return Menu
*/
public function getParent() {
return $this->parent;
}
public function getModule() {
return $this->module;
}
public function setId($id) {
$this->id = $id;
return $this;
}
public function setName($name) {
$this->name = $name;
return $this;
}
public function setUri($uri) {
$this->uri = $uri;
return $this;
}
public function setIcon($icon) {
$this->icon = $icon;
return $this;
}
public function setDescription($description) {
$this->description = $description;
return $this;
}
public function setCreated(\DateTime $created) {
$this->created = $created;
return $this;
}
public function setModified(\DateTime $modified) {
$this->modified = $modified;
return $this;
}
public function setSubmenu($submenu) {
$this->submenu = $submenu;
return $this;
}
public function setParent($parent) {
$this->parent = $parent;
return $this;
}
public function setModule($module) {
$this->module = $module;
return $this;
}
public function getRemote() {
return $this->remote;
}
public function setRemote($remote) {
$this->remote = $remote;
return $this;
}
public function addMenu(Menu $menu) {
$this->submenu[] = $menu;
return $this;
}
}
My intention was in the specific builder of each Bundle, to register their respective menus, however, I need to resolve the route and if possible I wanted access to Doctrine also to register these menus in persistence.
Arqui is an illustration of the problem and what I would like to do, I know that
$ this-> get ('router') -> generate ('register_profile_view')
does not exist in the context below, it's just an example of what I needed.
<?php
namespace Test\RegisterBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use SBCorp\RegisterBundle\Controller\MenuController;
use SBCorp\RegisterBundle\Entity\Menu;
class RegisterBundle extends Bundle {
function __construct() {
$mProfile = new Menu();
$mProfile->setIcon('fa-th')
->setName('My Profile')
->setRemote('#content-wrapper')
->setUri($this->get('router')->generate('register_profile_view'));
MenuController::register($mProfile);
}
}
If you have another suggestion of how to do it, I accept it, because I use Symfony very soon and it is very probable that I am reinventing the wheel.