Copy over menu classes from main app #222
This commit is contained in:
parent
841011d3d0
commit
682bf7ede2
3 changed files with 373 additions and 0 deletions
71
catalyst/menu-bundle/Menu/Collection.php
Normal file
71
catalyst/menu-bundle/Menu/Collection.php
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace Catalyst\MenuBundle\Menu;
|
||||
|
||||
use Iterator;
|
||||
|
||||
// iterable collection of menu items
|
||||
class Collection implements Iterator
|
||||
{
|
||||
protected $position = 0;
|
||||
protected $array;
|
||||
protected $index_array;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->position = 0;
|
||||
$this->array = array();
|
||||
$this->index_array = array();
|
||||
}
|
||||
|
||||
// iterator stuff
|
||||
public function rewind()
|
||||
{
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
public function current()
|
||||
{
|
||||
return $this->array[$this->index_array[$this->position]];
|
||||
}
|
||||
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function next()
|
||||
{
|
||||
return ++$this->position;
|
||||
}
|
||||
|
||||
public function valid()
|
||||
{
|
||||
return isset($this->index_array[$this->position]);
|
||||
}
|
||||
// end of iterator stuff
|
||||
|
||||
public function add(Item $mi)
|
||||
{
|
||||
$id = $mi->getID();
|
||||
$this->array[$id] = $mi;
|
||||
$this->index_array[] = $id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function get($id)
|
||||
{
|
||||
if (isset($this->array[$id]))
|
||||
return $this->array[$id];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function unselectAll()
|
||||
{
|
||||
foreach ($this->array as $mi)
|
||||
$mi->setSelected(false, false);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
164
catalyst/menu-bundle/Menu/Generator.php
Normal file
164
catalyst/menu-bundle/Menu/Generator.php
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
|
||||
namespace Catalyst\MenuBundle\Menu;
|
||||
|
||||
use Symfony\Component\Routing\Exception\RouteNotFoundException;
|
||||
use Symfony\Component\Yaml\Parser as YamlParser;
|
||||
use Symfony\Component\Config\ConfigCache;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
class Generator
|
||||
{
|
||||
protected $index;
|
||||
protected $menu;
|
||||
protected $router;
|
||||
protected $cache_dir;
|
||||
protected $config_dir;
|
||||
protected $config_file;
|
||||
|
||||
public function __construct(RouterInterface $router, string $cache_dir, string $config_dir, $config_file = 'menu.yaml')
|
||||
{
|
||||
$this->index = new Collection();
|
||||
$this->menu = new Collection();
|
||||
$this->router = $router;
|
||||
$this->cache_dir = $cache_dir;
|
||||
$this->config_dir = $config_dir;
|
||||
$this->config_file = $config_file;
|
||||
}
|
||||
|
||||
public function getMenu($menu_key)
|
||||
{
|
||||
// initialize
|
||||
$menu_data = [
|
||||
'menu' => [],
|
||||
'index' => []
|
||||
];
|
||||
|
||||
// cache config
|
||||
$cache_file = $this->cache_dir . '/' . $this->config_file . '.' . $menu_key . '.serial';
|
||||
$menu_cache = new ConfigCache($cache_file, true);
|
||||
|
||||
// cache not fresh
|
||||
if (!$menu_cache->isFresh())
|
||||
{
|
||||
$files = [];
|
||||
$resources = [];
|
||||
|
||||
try
|
||||
{
|
||||
// get location of menu config file
|
||||
$path = $this->config_dir . '/' . $this->config_file;
|
||||
$files[] = $path;
|
||||
$resources[] = new FileResource($path);
|
||||
|
||||
// TODO: handle routes changes as well
|
||||
// NOTE: need to figure out how to handle route changes or require
|
||||
// a cache clear for every route change
|
||||
|
||||
// process bundle menu
|
||||
$this->parseMenu($path, $menu_key);
|
||||
}
|
||||
catch (\InvalidArgumentException $e)
|
||||
{
|
||||
error_log($e->getMessage());
|
||||
error_log($menu_key . ' menu not found.');
|
||||
return $menu_data;
|
||||
}
|
||||
|
||||
$menu_data = [
|
||||
'menu' => $this->menu,
|
||||
'index' => $this->index,
|
||||
];
|
||||
$menu_serial = serialize($menu_data);
|
||||
$menu_cache->write($menu_serial, $resources);
|
||||
}
|
||||
else
|
||||
{
|
||||
$menu_serial = file_get_contents($cache_file);
|
||||
$menu_data = unserialize($menu_serial);
|
||||
$this->menu = $menu_data['menu'];
|
||||
$this->index = $menu_data['index'];
|
||||
}
|
||||
|
||||
return $menu_data;
|
||||
}
|
||||
|
||||
protected function parseMenu($path, $menu_key)
|
||||
{
|
||||
$parser = new YamlParser();
|
||||
$menu_config = $parser->parse(file_get_contents($path));
|
||||
|
||||
// check if we have menu items
|
||||
if (!isset($menu_config[$menu_key]))
|
||||
{
|
||||
error_log('No ' . $menu_key . ' found for ' . $path);
|
||||
return;
|
||||
}
|
||||
|
||||
// go through each one
|
||||
foreach ($menu_config[$menu_key] as $mi_data)
|
||||
{
|
||||
// check params
|
||||
if (!isset($mi_data['icon']))
|
||||
$mi_data['icon'] = null;
|
||||
|
||||
// instantiate
|
||||
$mi = $this->newItem($mi_data['id'], $mi_data['label'], $mi_data['icon']);
|
||||
|
||||
// acl
|
||||
if (isset($mi_data['acl']))
|
||||
$mi->setACLKey($mi_data['acl']);
|
||||
|
||||
// check parent
|
||||
if (isset($mi_data['parent']) && $mi_data['parent'] != null)
|
||||
{
|
||||
$parent = $this->index->get($mi_data['parent']);
|
||||
if ($parent == null)
|
||||
continue;
|
||||
|
||||
$parent->addChild($mi);
|
||||
}
|
||||
else
|
||||
$this->menu->add($mi);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected function newItem($id, $label, $icon = null)
|
||||
{
|
||||
$mi = new Item();
|
||||
$mi->setID($id)
|
||||
->setLabel($label);
|
||||
|
||||
try
|
||||
{
|
||||
$mi->setLink($this->router->generate($id));
|
||||
}
|
||||
catch (RouteNotFoundException $e)
|
||||
{
|
||||
// no route, set to #
|
||||
$mi->setLink('#');
|
||||
}
|
||||
|
||||
if ($icon != null)
|
||||
$mi->setIcon($icon);
|
||||
|
||||
$this->index->add($mi);
|
||||
|
||||
return $mi;
|
||||
}
|
||||
|
||||
public function generate()
|
||||
{
|
||||
$this->getAllBundleMenus();
|
||||
|
||||
return $this->menu;
|
||||
}
|
||||
|
||||
public function getIndex()
|
||||
{
|
||||
return $this->index;
|
||||
}
|
||||
}
|
||||
138
catalyst/menu-bundle/Menu/Item.php
Normal file
138
catalyst/menu-bundle/Menu/Item.php
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
namespace Catalyst\MenuBundle\Menu;
|
||||
|
||||
class Item
|
||||
{
|
||||
protected $id;
|
||||
protected $icon;
|
||||
protected $link;
|
||||
protected $label;
|
||||
protected $children;
|
||||
protected $selected;
|
||||
protected $parent;
|
||||
protected $acl_key;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->id = '';
|
||||
$this->icon = null;
|
||||
$this->link = null;
|
||||
$this->label = '';
|
||||
$this->children = [];
|
||||
$this->selected = false;
|
||||
$this->parent = null;
|
||||
$this->acl_key = null;
|
||||
}
|
||||
|
||||
// setters
|
||||
public function setID($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setIcon($icon)
|
||||
{
|
||||
$this->icon = $icon;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setLink($link)
|
||||
{
|
||||
$this->link = $link;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setLabel($label)
|
||||
{
|
||||
$this->label = $label;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setParent(self $parent)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addChild(self $child)
|
||||
{
|
||||
$child->setParent($this);
|
||||
|
||||
// check if selected
|
||||
if ($child->isSelected())
|
||||
$this->setSelected();
|
||||
|
||||
$this->children[] = $child;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSelected($sel = true, $to_bubble = true)
|
||||
{
|
||||
if ($sel)
|
||||
{
|
||||
$this->selected = true;
|
||||
// bubble up to parents
|
||||
if ($this->parent != null && $to_bubble)
|
||||
$this->parent->setSelected(true, true);
|
||||
}
|
||||
else
|
||||
$this->selected = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setACLKey($key)
|
||||
{
|
||||
$this->acl_key = $key;
|
||||
return $this;
|
||||
}
|
||||
|
||||
// getters
|
||||
public function getID()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getIcon()
|
||||
{
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
public function getLink()
|
||||
{
|
||||
return $this->link;
|
||||
}
|
||||
|
||||
public function getLabel()
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
public function hasChildren()
|
||||
{
|
||||
if (count($this->children) > 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isSelected()
|
||||
{
|
||||
return $this->selected;
|
||||
}
|
||||
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
public function getACLKey()
|
||||
{
|
||||
return $this->acl_key;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue