mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-07-23 22:04:25 +02:00
Merge branch 'bugfix/separate-configuration-files-for-navigation-items-10246'
fixes #10246
This commit is contained in:
commit
ff25c24825
@ -5,13 +5,13 @@ namespace Icinga\Controllers;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Data\DataArray\ArrayDatasource;
|
||||
use Icinga\Forms\ConfirmRemovalForm;
|
||||
use Icinga\Forms\Navigation\NavigationConfigForm;
|
||||
use Icinga\Web\Controller;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Navigation\Navigation;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
@ -21,11 +21,11 @@ use Icinga\Web\Url;
|
||||
class NavigationController extends Controller
|
||||
{
|
||||
/**
|
||||
* The default item types provided by Icinga Web 2
|
||||
* The global navigation item type configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $defaultItemTypes;
|
||||
protected $itemTypeConfig;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@ -33,11 +33,19 @@ class NavigationController extends Controller
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
$this->itemTypeConfig = Navigation::getItemTypeConfiguration();
|
||||
}
|
||||
|
||||
$this->defaultItemTypes = array(
|
||||
'menu-item' => $this->translate('Menu Entry'),
|
||||
'dashlet' => 'Dashlet'
|
||||
);
|
||||
/**
|
||||
* Return the label for the given navigation item type
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return string $type if no label can be found
|
||||
*/
|
||||
protected function getItemLabel($type)
|
||||
{
|
||||
return isset($this->itemTypeConfig[$type]['label']) ? $this->itemTypeConfig[$type]['label'] : $type;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,33 +55,71 @@ class NavigationController extends Controller
|
||||
*/
|
||||
protected function listItemTypes()
|
||||
{
|
||||
$moduleManager = Icinga::app()->getModuleManager();
|
||||
|
||||
$types = $this->defaultItemTypes;
|
||||
foreach ($moduleManager->getLoadedModules() as $module) {
|
||||
if ($this->hasPermission($moduleManager::MODULE_PERMISSION_NS . $module->getName())) {
|
||||
$moduleTypes = $module->getNavigationItems();
|
||||
if (! empty($moduleTypes)) {
|
||||
$types = array_merge($types, $moduleTypes);
|
||||
}
|
||||
}
|
||||
$types = array();
|
||||
foreach ($this->itemTypeConfig as $type => $options) {
|
||||
$types[$type] = isset($options['label']) ? $options['label'] : $type;
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all shared navigation item configurations
|
||||
*
|
||||
* @param string $owner A username if only items shared by a specific user are desired
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function fetchSharedNavigationItemConfigs($owner = null)
|
||||
{
|
||||
$configs = array();
|
||||
foreach ($this->itemTypeConfig as $type => $_) {
|
||||
$config = Config::navigation($type);
|
||||
$config->getConfigObject()->setKeyColumn('name');
|
||||
$query = $config->select();
|
||||
if ($owner !== null) {
|
||||
$query->where('owner', $owner);
|
||||
}
|
||||
|
||||
foreach ($query as $itemConfig) {
|
||||
$configs[] = $itemConfig;
|
||||
}
|
||||
}
|
||||
|
||||
return $configs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all user navigation item configurations
|
||||
*
|
||||
* @param string $username
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function fetchUserNavigationItemConfigs($username)
|
||||
{
|
||||
$configs = array();
|
||||
foreach ($this->itemTypeConfig as $type => $_) {
|
||||
$config = Config::navigation($type, $username);
|
||||
$config->getConfigObject()->setKeyColumn('name');
|
||||
foreach ($config->select() as $itemConfig) {
|
||||
$configs[] = $itemConfig;
|
||||
}
|
||||
}
|
||||
|
||||
return $configs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the current user a list of his/her navigation items
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
$user = $this->Auth()->getUser();
|
||||
|
||||
$ds = new ArrayDatasource(array_merge(
|
||||
Config::app('navigation')->select()->where('owner', $user->getUsername())->fetchAll(),
|
||||
iterator_to_array($user->loadNavigationConfig())
|
||||
$this->fetchSharedNavigationItemConfigs($user->getUsername()),
|
||||
$this->fetchUserNavigationItemConfigs($user->getUsername())
|
||||
));
|
||||
$ds->setKeyColumn('name');
|
||||
$query = $ds->select();
|
||||
|
||||
$this->view->types = $this->listItemTypes();
|
||||
@ -91,7 +137,7 @@ class NavigationController extends Controller
|
||||
array(
|
||||
'type' => $this->translate('Type'),
|
||||
'owner' => $this->translate('Shared'),
|
||||
'name' => $this->translate('Shared Navigation')
|
||||
'name' => $this->translate('Navigation')
|
||||
),
|
||||
$query
|
||||
);
|
||||
@ -103,13 +149,11 @@ class NavigationController extends Controller
|
||||
public function sharedAction()
|
||||
{
|
||||
$this->assertPermission('config/application/navigation');
|
||||
$config = Config::app('navigation');
|
||||
$config->getConfigObject()->setKeyColumn('name');
|
||||
$query = $config->select();
|
||||
$ds = new ArrayDatasource($this->fetchSharedNavigationItemConfigs());
|
||||
$query = $ds->select();
|
||||
|
||||
$removeForm = new Form();
|
||||
$removeForm->setUidDisabled();
|
||||
$removeForm->setAction(Url::fromPath('navigation/unshare'));
|
||||
$removeForm->addElement('hidden', 'name', array(
|
||||
'decorators' => array('ViewHelper')
|
||||
));
|
||||
@ -156,11 +200,10 @@ class NavigationController extends Controller
|
||||
{
|
||||
$form = new NavigationConfigForm();
|
||||
$form->setRedirectUrl('navigation');
|
||||
$form->setUser($this->Auth()->getUser());
|
||||
$form->setItemTypes($this->listItemTypes());
|
||||
$form->setTitle($this->translate('Create New Navigation Item'));
|
||||
$form->addDescription($this->translate('Create a new navigation item, such as a menu entry or dashlet.'));
|
||||
$form->setUser($this->Auth()->getUser());
|
||||
$form->setShareConfig(Config::app('navigation'));
|
||||
$form->setOnSuccess(function (NavigationConfigForm $form) {
|
||||
$data = array_filter($form->getValues());
|
||||
|
||||
@ -172,7 +215,7 @@ class NavigationController extends Controller
|
||||
}
|
||||
|
||||
if ($form->save()) {
|
||||
if (isset($data['type']) && $data['type'] === 'menu-item') {
|
||||
if ($data['type'] === 'menu-item') {
|
||||
$form->getResponse()->setRerenderLayout();
|
||||
}
|
||||
|
||||
@ -194,14 +237,22 @@ class NavigationController extends Controller
|
||||
public function editAction()
|
||||
{
|
||||
$itemName = $this->params->getRequired('name');
|
||||
$itemType = $this->params->getRequired('type');
|
||||
$referrer = $this->params->get('referrer', 'index');
|
||||
|
||||
$user = $this->Auth()->getUser();
|
||||
if ($user->can('config/application/navigation')) {
|
||||
$itemOwner = $this->params->get('owner', $user->getUsername());
|
||||
} else {
|
||||
$itemOwner = $user->getUsername();
|
||||
}
|
||||
|
||||
$form = new NavigationConfigForm();
|
||||
$form->setUser($user);
|
||||
$form->setShareConfig(Config::navigation($itemType));
|
||||
$form->setUserConfig(Config::navigation($itemType, $itemOwner));
|
||||
$form->setRedirectUrl($referrer === 'shared' ? 'navigation/shared' : 'navigation');
|
||||
$form->setItemTypes($this->listItemTypes());
|
||||
$form->setTitle(sprintf($this->translate('Edit Navigation Item %s'), $itemName));
|
||||
$form->setUser($this->Auth()->getUser());
|
||||
$form->setShareConfig(Config::app('navigation'));
|
||||
$form->setTitle(sprintf($this->translate('Edit %s %s'), $this->getItemLabel($itemType), $itemName));
|
||||
$form->setOnSuccess(function (NavigationConfigForm $form) use ($itemName) {
|
||||
$data = array_map(
|
||||
function ($v) {
|
||||
@ -248,13 +299,17 @@ class NavigationController extends Controller
|
||||
public function removeAction()
|
||||
{
|
||||
$itemName = $this->params->getRequired('name');
|
||||
$itemType = $this->params->getRequired('type');
|
||||
$user = $this->Auth()->getUser();
|
||||
|
||||
$navigationConfigForm = new NavigationConfigForm();
|
||||
$navigationConfigForm->setUser($this->Auth()->getUser());
|
||||
$navigationConfigForm->setShareConfig(Config::app('navigation'));
|
||||
$navigationConfigForm->setUser($user);
|
||||
$navigationConfigForm->setShareConfig(Config::navigation($itemType));
|
||||
$navigationConfigForm->setUserConfig(Config::navigation($itemType, $user->getUsername()));
|
||||
|
||||
$form = new ConfirmRemovalForm();
|
||||
$form->setRedirectUrl('navigation');
|
||||
$form->setTitle(sprintf($this->translate('Remove Navigation Item %s'), $itemName));
|
||||
$form->setTitle(sprintf($this->translate('Remove %s %s'), $this->getItemLabel($itemType), $itemName));
|
||||
$form->setOnSuccess(function (ConfirmRemovalForm $form) use ($itemName, $navigationConfigForm) {
|
||||
try {
|
||||
$itemConfig = $navigationConfigForm->delete($itemName);
|
||||
@ -291,9 +346,14 @@ class NavigationController extends Controller
|
||||
$this->assertPermission('config/application/navigation');
|
||||
$this->assertHttpMethod('POST');
|
||||
|
||||
// TODO: I'd like these being form fields
|
||||
$itemType = $this->params->getRequired('type');
|
||||
$itemOwner = $this->params->getRequired('owner');
|
||||
|
||||
$navigationConfigForm = new NavigationConfigForm();
|
||||
$navigationConfigForm->setUser($this->Auth()->getUser());
|
||||
$navigationConfigForm->setShareConfig(Config::app('navigation'));
|
||||
$navigationConfigForm->setShareConfig(Config::navigation($itemType));
|
||||
$navigationConfigForm->setUserConfig(Config::navigation($itemType, $itemOwner));
|
||||
|
||||
$form = new Form(array(
|
||||
'onSuccess' => function ($form) use ($navigationConfigForm) {
|
||||
|
@ -123,12 +123,18 @@ class NavigationConfigForm extends ConfigForm
|
||||
/**
|
||||
* Return the user's navigation configuration
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public function getUserConfig()
|
||||
public function getUserConfig($type = null)
|
||||
{
|
||||
if ($this->userConfig === null) {
|
||||
$this->setUserConfig($this->getUser()->loadNavigationConfig());
|
||||
if ($type === null) {
|
||||
throw new ProgrammingError('You need to pass a type if no user configuration is set');
|
||||
}
|
||||
|
||||
$this->setUserConfig(Config::navigation($type, $this->getUser()->getUsername()));
|
||||
}
|
||||
|
||||
return $this->userConfig;
|
||||
@ -151,10 +157,20 @@ class NavigationConfigForm extends ConfigForm
|
||||
/**
|
||||
* Return the shared navigation configuration
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public function getShareConfig()
|
||||
public function getShareConfig($type = null)
|
||||
{
|
||||
if ($this->shareConfig === null) {
|
||||
if ($type === null) {
|
||||
throw new ProgrammingError('You need to pass a type if no share configuration is set');
|
||||
}
|
||||
|
||||
$this->setShareConfig(Config::navigation($type));
|
||||
}
|
||||
|
||||
return $this->shareConfig;
|
||||
}
|
||||
|
||||
@ -194,10 +210,9 @@ class NavigationConfigForm extends ConfigForm
|
||||
$children = $this->itemToLoad ? $this->getFlattenedChildren($this->itemToLoad) : array();
|
||||
|
||||
$names = array();
|
||||
foreach ($this->getShareConfig() as $sectionName => $sectionConfig) {
|
||||
foreach ($this->getShareConfig($type) as $sectionName => $sectionConfig) {
|
||||
if (
|
||||
$sectionName !== $this->itemToLoad
|
||||
&& $sectionConfig->type === $type
|
||||
&& $sectionConfig->owner === ($owner ?: $this->getUser()->getUsername())
|
||||
&& !in_array($sectionName, $children, true)
|
||||
) {
|
||||
@ -205,10 +220,9 @@ class NavigationConfigForm extends ConfigForm
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->getUserConfig() as $sectionName => $sectionConfig) {
|
||||
foreach ($this->getUserConfig($type) as $sectionName => $sectionConfig) {
|
||||
if (
|
||||
$sectionName !== $this->itemToLoad
|
||||
&& $sectionConfig->type === $type
|
||||
&& !in_array($sectionName, $children, true)
|
||||
) {
|
||||
$names[] = $sectionName;
|
||||
@ -271,29 +285,31 @@ class NavigationConfigForm extends ConfigForm
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException In case $data does not contain a navigation item name
|
||||
* @throws InvalidArgumentException In case $data does not contain a navigation item name or type
|
||||
* @throws IcingaException In case a navigation item with the same name already exists
|
||||
*/
|
||||
public function add(array $data)
|
||||
{
|
||||
if (! isset($data['name'])) {
|
||||
throw new InvalidArgumentException('Key \'name\' missing');
|
||||
} elseif (! isset($data['type'])) {
|
||||
throw new InvalidArgumentException('Key \'type\' missing');
|
||||
}
|
||||
|
||||
$shared = false;
|
||||
$config = $this->getUserConfig();
|
||||
$config = $this->getUserConfig($data['type']);
|
||||
if ((isset($data['users']) && $data['users']) || (isset($data['groups']) && $data['groups'])) {
|
||||
if ($this->getUser()->can('application/share/navigation')) {
|
||||
$data['owner'] = $this->getUser()->getUsername();
|
||||
$config = $this->getShareConfig();
|
||||
$config = $this->getShareConfig($data['type']);
|
||||
$shared = true;
|
||||
} else {
|
||||
unset($data['users']);
|
||||
unset($data['groups']);
|
||||
}
|
||||
} elseif (isset($data['parent']) && $data['parent'] && $this->hasBeenShared($data['parent'])) {
|
||||
} elseif (isset($data['parent']) && $data['parent'] && $this->hasBeenShared($data['parent'], $data['type'])) {
|
||||
$data['owner'] = $this->getUser()->getUsername();
|
||||
$config = $this->getShareConfig();
|
||||
$config = $this->getShareConfig($data['type']);
|
||||
$shared = true;
|
||||
}
|
||||
|
||||
@ -301,9 +317,9 @@ class NavigationConfigForm extends ConfigForm
|
||||
$exists = $config->hasSection($itemName);
|
||||
if (! $exists) {
|
||||
if ($shared) {
|
||||
$exists = $this->getUserConfig()->hasSection($itemName);
|
||||
$exists = $this->getUserConfig($data['type'])->hasSection($itemName);
|
||||
} else {
|
||||
$exists = (bool) $this->getShareConfig()
|
||||
$exists = (bool) $this->getShareConfig($data['type'])
|
||||
->select()
|
||||
->where('name', $itemName)
|
||||
->where('owner', $this->getUser()->getUsername())
|
||||
@ -385,8 +401,7 @@ class NavigationConfigForm extends ConfigForm
|
||||
if ($ownerName === $this->getUser()->getUsername()) {
|
||||
$exists = $this->getUserConfig()->hasSection($name);
|
||||
} else {
|
||||
$owner = new User($ownerName);
|
||||
$exists = $owner->loadNavigationConfig()->hasSection($name);
|
||||
$exists = Config::navigation($itemConfig->type, $ownerName)->hasSection($name);
|
||||
}
|
||||
} else {
|
||||
$exists = (bool) $this->getShareConfig()
|
||||
@ -521,8 +536,7 @@ class NavigationConfigForm extends ConfigForm
|
||||
if (! $itemConfig->owner || $itemConfig->owner === $this->getUser()->getUsername()) {
|
||||
$config = $this->getUserConfig();
|
||||
} else {
|
||||
$owner = new User($itemConfig->owner);
|
||||
$config = $owner->loadNavigationConfig();
|
||||
$config = Config::navigation($itemConfig->type, $itemConfig->owner);
|
||||
}
|
||||
|
||||
foreach ($children as $child) {
|
||||
@ -549,6 +563,13 @@ class NavigationConfigForm extends ConfigForm
|
||||
$shared = false;
|
||||
$itemTypes = $this->getItemTypes();
|
||||
$itemType = isset($formData['type']) ? $formData['type'] : key($itemTypes);
|
||||
if ($itemType === null) {
|
||||
throw new ProgrammingError(
|
||||
'This should actually not happen. Create a bug report at dev.icinga.org'
|
||||
. ' or remove this assertion if you know what you\'re doing'
|
||||
);
|
||||
}
|
||||
|
||||
$itemForm = $this->getItemForm($itemType);
|
||||
|
||||
$this->addElement(
|
||||
@ -606,17 +627,27 @@ class NavigationConfigForm extends ConfigForm
|
||||
}
|
||||
}
|
||||
|
||||
$this->addElement(
|
||||
'select',
|
||||
'type',
|
||||
array(
|
||||
'required' => true,
|
||||
'autosubmit' => true,
|
||||
'label' => $this->translate('Type'),
|
||||
'description' => $this->translate('The type of this navigation item'),
|
||||
'multiOptions' => $itemTypes
|
||||
)
|
||||
);
|
||||
if (empty($itemTypes) || count($itemTypes) === 1) {
|
||||
$this->addElement(
|
||||
'hidden',
|
||||
'type',
|
||||
array(
|
||||
'value' => $itemType
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->addElement(
|
||||
'select',
|
||||
'type',
|
||||
array(
|
||||
'required' => true,
|
||||
'autosubmit' => true,
|
||||
'label' => $this->translate('Type'),
|
||||
'description' => $this->translate('The type of this navigation item'),
|
||||
'multiOptions' => $itemTypes
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (! $shared && $itemForm->requiresParentSelection()) {
|
||||
if ($this->itemToLoad && $this->hasBeenShared($this->itemToLoad)) {
|
||||
@ -767,12 +798,13 @@ class NavigationConfigForm extends ConfigForm
|
||||
* Return whether the given navigation item has been shared
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasBeenShared($name)
|
||||
protected function hasBeenShared($name, $type = null)
|
||||
{
|
||||
return $this->getConfigForItem($name) === $this->getShareConfig();
|
||||
return $this->getShareConfig($type) === $this->getConfigForItem($name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,14 +22,17 @@
|
||||
<th style="width: 5em"><?= $this->translate('Remove'); ?></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($items as $name => $item): ?>
|
||||
<?php foreach ($items as $item): ?>
|
||||
<tr>
|
||||
<td><?= $this->qlink(
|
||||
$name,
|
||||
$item->name,
|
||||
'navigation/edit',
|
||||
array('name' => $name),
|
||||
array(
|
||||
'title' => sprintf($this->translate('Edit navigation item %s'), $name)
|
||||
'name' => $item->name,
|
||||
'type' => $item->type
|
||||
),
|
||||
array(
|
||||
'title' => sprintf($this->translate('Edit navigation item %s'), $item->name)
|
||||
)
|
||||
); ?></td>
|
||||
<td><?= $item->type && isset($types[$item->type])
|
||||
@ -39,10 +42,13 @@
|
||||
<td><?= $this->qlink(
|
||||
'',
|
||||
'navigation/remove',
|
||||
array('name' => $name),
|
||||
array(
|
||||
'name' => $item->name,
|
||||
'type' => $item->type
|
||||
),
|
||||
array(
|
||||
'icon' => 'trash',
|
||||
'title' => sprintf($this->translate('Remove navigation item %s'), $name)
|
||||
'title' => sprintf($this->translate('Remove navigation item %s'), $item->name)
|
||||
)
|
||||
); ?></td>
|
||||
</tr>
|
||||
|
@ -1,4 +1,8 @@
|
||||
<?php if (! $this->compact): ?>
|
||||
<?php
|
||||
|
||||
use Icinga\Web\Url;
|
||||
|
||||
if (! $this->compact): ?>
|
||||
<div class="controls">
|
||||
<?= $this->tabs; ?>
|
||||
<?= $this->sortBox; ?>
|
||||
@ -19,17 +23,19 @@
|
||||
<th style="width: 5em"><?= $this->translate('Unshare'); ?></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($items as $name => $item): ?>
|
||||
<?php foreach ($items as $item): ?>
|
||||
<tr>
|
||||
<td><?= $this->qlink(
|
||||
$name,
|
||||
$item->name,
|
||||
'navigation/edit',
|
||||
array(
|
||||
'name' => $name,
|
||||
'name' => $item->name,
|
||||
'type' => $item->type,
|
||||
'owner' => $item->owner,
|
||||
'referrer' => 'shared'
|
||||
),
|
||||
array(
|
||||
'title' => sprintf($this->translate('Edit shared navigation item %s'), $name)
|
||||
'title' => sprintf($this->translate('Edit shared navigation item %s'), $item->name)
|
||||
)
|
||||
); ?></td>
|
||||
<td><?= $item->type && isset($types[$item->type])
|
||||
@ -48,7 +54,12 @@
|
||||
)
|
||||
); ?></td>
|
||||
<?php else: ?>
|
||||
<td data-base-target="_self"><?= $removeForm->setDefault('name', $name); ?></td>
|
||||
<td data-base-target="_self"><?= $removeForm
|
||||
->setDefault('name', $item->name)
|
||||
->setAction(Url::fromPath(
|
||||
'navigation/unshare',
|
||||
array('type' => $item->type, 'owner' => $item->owner)
|
||||
)); ?></td>
|
||||
<?php endif ?>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
|
@ -13,7 +13,9 @@ use Icinga\Data\Selectable;
|
||||
use Icinga\Data\SimpleQuery;
|
||||
use Icinga\File\Ini\IniWriter;
|
||||
use Icinga\File\Ini\IniParser;
|
||||
use Icinga\Exception\IcingaException;
|
||||
use Icinga\Exception\NotReadableError;
|
||||
use Icinga\Web\Navigation\Navigation;
|
||||
|
||||
/**
|
||||
* Container for INI like configuration and global registry of application and module related configuration.
|
||||
@ -41,6 +43,13 @@ class Config implements Countable, Iterator, Selectable
|
||||
*/
|
||||
protected static $modules = array();
|
||||
|
||||
/**
|
||||
* Navigation config instances per type
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $navigation = array();
|
||||
|
||||
/**
|
||||
* The internal ConfigObject
|
||||
*
|
||||
@ -416,6 +425,60 @@ class Config implements Countable, Iterator, Selectable
|
||||
return $moduleConfigs[$configname];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a navigation config
|
||||
*
|
||||
* @param string $type The type identifier of the navigation item for which to return its config
|
||||
* @param string $username A user's name or null if the shared config is desired
|
||||
* @param bool $fromDisk If true, the configuration will be read from disk
|
||||
*
|
||||
* @return Config The requested configuration
|
||||
*/
|
||||
public static function navigation($type, $username = null, $fromDisk = false)
|
||||
{
|
||||
if (! isset(self::$navigation[$type])) {
|
||||
self::$navigation[$type] = array();
|
||||
}
|
||||
|
||||
$branch = $username ?: 'shared';
|
||||
$typeConfigs = self::$navigation[$type];
|
||||
if (! isset($typeConfigs[$branch]) || $fromDisk) {
|
||||
$typeConfigs[$branch] = static::fromIni(static::getNavigationConfigPath($type, $username));
|
||||
}
|
||||
|
||||
return $typeConfigs[$branch];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the path to the configuration file for the given navigation item type and user
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $username
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws IcingaException In case the given type is unknown
|
||||
*/
|
||||
protected static function getNavigationConfigPath($type, $username = null)
|
||||
{
|
||||
$itemTypeConfig = Navigation::getItemTypeConfiguration();
|
||||
if (! isset($itemTypeConfig[$type])) {
|
||||
throw new IcingaException('Invalid navigation item type %s provided', $type);
|
||||
}
|
||||
|
||||
if (isset($itemTypeConfig[$type]['config'])) {
|
||||
$filename = $itemTypeConfig[$type]['config'] . '.ini';
|
||||
} else {
|
||||
$filename = $type . 's.ini';
|
||||
}
|
||||
|
||||
return static::resolvePath(
|
||||
($username ? 'preferences' . DIRECTORY_SEPARATOR . $username : 'navigation')
|
||||
. DIRECTORY_SEPARATOR
|
||||
. $filename
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this config rendered as a INI structured string
|
||||
*
|
||||
|
@ -1014,16 +1014,21 @@ class Module
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a new type of configurable navigation item with a optional label
|
||||
* Provide a new type of configurable navigation item with a optional label and config filename
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $label
|
||||
* @param string $config
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function provideNavigationItem($type, $label = null)
|
||||
protected function provideNavigationItem($type, $label = null, $config = null)
|
||||
{
|
||||
$this->navigationItems[$type] = $label ?: $type;
|
||||
$this->navigationItems[$type] = array(
|
||||
'label' => $label,
|
||||
'config' => $config
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -179,12 +179,11 @@ class Web extends EmbeddedWeb
|
||||
*/
|
||||
public function getSharedNavigation($type)
|
||||
{
|
||||
$config = Config::app('navigation')->getConfigObject();
|
||||
$config->setKeyColumn('name');
|
||||
$config = Config::navigation($type === 'dashboard-pane' ? 'dashlet' : $type);
|
||||
|
||||
if ($type === 'dashboard-pane') {
|
||||
$panes = array();
|
||||
foreach ($config->select()->where('type', 'dashlet') as $dashletName => $dashletConfig) {
|
||||
foreach ($config as $dashletName => $dashletConfig) {
|
||||
if ($this->hasAccessToSharedNavigationItem($dashletConfig)) {
|
||||
// TODO: Throw ConfigurationError if pane or url is missing
|
||||
$panes[$dashletConfig->pane][$dashletName] = $dashletConfig->url;
|
||||
@ -203,7 +202,7 @@ class Web extends EmbeddedWeb
|
||||
}
|
||||
} else {
|
||||
$items = array();
|
||||
foreach ($config->select()->where('type', $type) as $name => $typeConfig) {
|
||||
foreach ($config as $name => $typeConfig) {
|
||||
if ($this->hasAccessToSharedNavigationItem($typeConfig)) {
|
||||
$items[$name] = $typeConfig;
|
||||
}
|
||||
|
@ -479,22 +479,6 @@ class User
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and return this user's navigation configuration
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public function loadNavigationConfig()
|
||||
{
|
||||
return Config::fromIni(
|
||||
Config::resolvePath('preferences')
|
||||
. DIRECTORY_SEPARATOR
|
||||
. $this->getUsername()
|
||||
. DIRECTORY_SEPARATOR
|
||||
. 'navigation.ini'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and return this user's configured navigation of the given type
|
||||
*
|
||||
@ -504,12 +488,11 @@ class User
|
||||
*/
|
||||
public function getNavigation($type)
|
||||
{
|
||||
$config = $this->loadNavigationConfig();
|
||||
$config->getConfigObject()->setKeyColumn('name');
|
||||
$config = Config::navigation($type === 'dashboard-pane' ? 'dashlet' : $type, $this->getUsername());
|
||||
|
||||
if ($type === 'dashboard-pane') {
|
||||
$panes = array();
|
||||
foreach ($config->select()->where('type', 'dashlet') as $dashletName => $dashletConfig) {
|
||||
foreach ($config as $dashletName => $dashletConfig) {
|
||||
// TODO: Throw ConfigurationError if pane or url is missing
|
||||
$panes[$dashletConfig->pane][$dashletName] = $dashletConfig->url;
|
||||
}
|
||||
@ -525,7 +508,7 @@ class User
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$navigation = Navigation::fromConfig($config->select()->where('type', $type));
|
||||
$navigation = Navigation::fromConfig($config);
|
||||
}
|
||||
|
||||
return $navigation;
|
||||
|
@ -451,6 +451,39 @@ class Navigation implements ArrayAccess, Countable, IteratorAggregate
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the global navigation item type configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getItemTypeConfiguration()
|
||||
{
|
||||
$defaultItemTypes = array(
|
||||
'menu-item' => array(
|
||||
'label' => t('Menu Entry'),
|
||||
'config' => 'menu'
|
||||
),
|
||||
'dashlet' => array(
|
||||
'label' => 'Dashlet',
|
||||
'config' => 'dashboard'
|
||||
)
|
||||
);
|
||||
|
||||
$moduleItemTypes = array();
|
||||
$moduleManager = Icinga::app()->getModuleManager();
|
||||
foreach ($moduleManager->getLoadedModules() as $module) {
|
||||
if (Auth::getInstance()->hasPermission($moduleManager::MODULE_PERMISSION_NS . $module->getName())) {
|
||||
foreach ($module->getNavigationItems() as $type => $options) {
|
||||
if (! isset($moduleItemTypes[$type])) {
|
||||
$moduleItemTypes[$type] = $options;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge($defaultItemTypes, $moduleItemTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new set of navigation items for the given configuration
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user