Implement Module self provided configuration for menus

refs #6639
This commit is contained in:
Alexander Fuhr 2014-08-22 11:35:42 +02:00
parent f757f69bd1
commit 1886569174
2 changed files with 230 additions and 3 deletions

View File

@ -5,6 +5,7 @@
namespace Icinga\Application\Modules;
use Exception;
use Zend_Config;
use Zend_Controller_Router_Route_Abstract;
use Zend_Controller_Router_Route as Route;
use Icinga\Application\ApplicationBootstrap;
@ -13,6 +14,7 @@ use Icinga\Application\Icinga;
use Icinga\Logger\Logger;
use Icinga\Util\Translator;
use Icinga\Web\Hook;
use Icinga\Web\Menu;
use Icinga\Web\Widget;
use Icinga\Util\File;
use Icinga\Exception\ProgrammingError;
@ -136,7 +138,6 @@ class Module
*/
private $app;
/**
* Routes to add to the route chain
*
@ -146,6 +147,42 @@ class Module
*/
protected $routes = array();
/**
* A set of menu elements
*
* @var array
*/
protected $menuItems = array();
/**
* Get all Menu Items
*
* @return array
*/
public function getMenuItems()
{
$this->launchConfigScript();
return $this->menuItems;
}
/**
* Add a menu Section to the Sidebar menu
*
* @param $name
* @param array $properties
* @return mixed
*/
protected function menuSection($name, array $properties = array())
{
if (array_key_exists($name, $this->menuItems)) {
$this->menuItems[$name]->setProperties($properties);
} else {
$this->menuItems[$name] = new Menu($name, new Zend_Config($properties));
}
return $this->menuItems[$name];
}
/**
* Create a new module object
*
@ -781,4 +818,15 @@ class Module
$this->routes[$name] = $route;
return $this;
}
/**
* Translate a string with the global mt()
*
* @param $string
* @return mixed|string
*/
protected function translate($string)
{
return mt($this->name, $string);
}
}

View File

@ -4,6 +4,7 @@
namespace Icinga\Web;
use Icinga\Exception\ConfigurationError;
use Zend_Config;
use RecursiveIterator;
use Icinga\Application\Config;
@ -67,20 +68,68 @@ class Menu implements RecursiveIterator
public function __construct($id, Zend_Config $config = null)
{
$this->id = $id;
$this->setProperties($config);
}
if ($config !== null) {
foreach ($config as $key => $value) {
/**
* Set all given properties
*
* @param array|Zend_Config $props Property list
*/
public function setProperties($props = null)
{
if ($props !== null) {
foreach ($props as $key => $value) {
$method = 'set' . implode('', array_map('ucfirst', explode('_', strtolower($key))));
if (method_exists($this, $method)) {
$this->{$method}($value);
} else {
throw new ConfigurationError(
sprintf('Menu got invalid property "%s"', $key)
);
}
}
}
return $this;
}
/**
* Get Properties
*
* @return array
*/
public function getProperties()
{
$props = array();
$keys = array('url', 'icon', 'priority', 'title');
foreach ($keys as $key) {
$func = 'get' . ucfirst($key);
if (null !== ($val = $this->{$func}())) {
$props[$key] = $val;
}
}
return $props;
}
/**
* Whether this Menu conflicts with the given Menu object
*
* @param Menu $menu
* @return bool
*/
public function conflictsWith(Menu $menu)
{
if ($menu->getUrl() === null || $this->getUrl() === null) {
return false;
}
return $menu->getUrl() !== $this->getUrl();
}
/**
* Create menu from the application's menu config file plus the config files from all enabled modules
*
* THIS IS OBSOLATE. LEFT HERE FOR FUTURE USE WITH USER-SPECIFIC MODULES
*
* @return self
*/
public static function fromConfig()
@ -100,6 +149,63 @@ class Menu implements RecursiveIterator
return $menu->loadSubMenus($menu->flattenConfigs($menuConfigs));
}
/**
* Create menu from the application's menu config plus menu entries provided by all enabled modules
*
* @return self
*/
public static function load()
{
/** @var $menu \Icinga\Web\Menu */
$menu = new static('menu');
$menu->addMainMenuItems();
$manager = Icinga::app()->getModuleManager();
foreach ($manager->getLoadedModules() as $module) {
/** @var $module \Icinga\Application\Modules\Module */
$menu->mergeSubMenus($module->getMenuItems());
}
return $menu->order();
}
/**
* Add Applications Main Menu Items
*/
protected function addMainMenuItems()
{
$this->add(t('Dashboard'), array(
'url' => 'dashboard',
'icon' => 'img/icons/dashboard.png',
'priority' => 10
));
$section = $this->add(t('System'), array(
'icon' => 'img/icons/configuration.png',
'priority' => 200
));
$section->add(t('Preferences'), array(
'url' => 'preference',
'priority' => 200
));
$section->add(t('Configuration'), array(
'url' => 'config',
'priority' => 300
));
$section->add(t('Modules'), array(
'url' => 'config/modules',
'priority' => 400
));
$section->add(t('ApplicationLog'), array(
'url' => 'list/applicationlog',
'priority' => 500
));
$this->add(t('Logout'), array(
'url' => 'authentication/logout',
'icon' => 'img/icons/logout.png',
'priority' => 300
));
}
/**
* Set the id of this menu
*
@ -253,6 +359,79 @@ class Menu implements RecursiveIterator
return $subMenu;
}
/**
* Set required Permissions
*
* @param $permission
* @return $this
*/
public function requirePermission($permission)
{
// Not implemented yet
return $this;
}
/**
* Merge Sub Menus
*
* @param array $submenus
* @return $this
*/
public function mergeSubMenus(array $submenus)
{
foreach ($submenus as $menu) {
$this->mergeSubMenu($menu);
}
return $this;
}
/**
* Merge Sub Menu
*
* @param Menu $menu
* @return mixed
*/
public function mergeSubMenu(Menu $menu)
{
$name = $menu->getId();
if (array_key_exists($name, $this->subMenus)) {
/** @var $current Menu */
$current = $this->subMenus[$name];
if ($current->conflictsWith($menu)) {
while (array_key_exists($name, $this->subMenus)) {
if (preg_match('/_(\d+)$/', $name, $m)) {
$name = preg_replace('/_\d+$/', $m[1]++, $name);
} else {
$name .= '_2';
}
}
$menu->setId($name);
$this->subMenus[$name] = $menu;
} else {
$current->setProperties($menu->getProperties());
foreach ($menu->subMenus as $child) {
$current->mergeSubMenu($child);
}
}
} else {
$this->subMenus[$name] = $menu;
}
return $this->subMenus[$name];
}
/**
* Add a Menu
*
* @param $name
* @param array $config
* @return Menu
*/
public function add($name, $config = array())
{
return $this->addSubMenu($name, new Zend_Config($config));
}
/**
* Return whether a sub menu with the given id exists
*