162 lines
4.1 KiB
PHP
162 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace App\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;
|
|
|
|
public function __construct(RouterInterface $router, string $cache_dir, string $config_dir)
|
|
{
|
|
$this->index = new Collection();
|
|
$this->menu = new Collection();
|
|
$this->router = $router;
|
|
$this->cache_dir = $cache_dir;
|
|
$this->config_dir = $config_dir;
|
|
}
|
|
|
|
public function getMenu($menu_key)
|
|
{
|
|
// initialize
|
|
$menu_data = [
|
|
'menu' => [],
|
|
'index' => []
|
|
];
|
|
|
|
// cache config
|
|
$cache_file = $this->cache_dir . '/' . $menu_key . '.serial';
|
|
$menu_cache = new ConfigCache($cache_file, true);
|
|
|
|
// cache not fresh
|
|
if (!$menu_cache->isFresh())
|
|
{
|
|
$files = [];
|
|
$resources = [];
|
|
|
|
try
|
|
{
|
|
// get location of menu.yaml
|
|
$path = $this->config_dir . '/menu.yaml';
|
|
$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;
|
|
}
|
|
}
|