Extensible configuration system
Add configuration tab builder parts to register free configuration tab items refs #4300
This commit is contained in:
parent
b403721c11
commit
1ede8df2af
|
@ -4,35 +4,35 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
use \Icinga\Web\ActionController;
|
||||
use Icinga\Application\Benchmark;
|
||||
use Icinga\Authentication\Manager;
|
||||
use Icinga\Web\ActionController;
|
||||
use Icinga\Web\Hook\Configuration\ConfigurationTab;
|
||||
use Icinga\Web\Hook\Configuration\ConfigurationTabBuilder;
|
||||
|
||||
/**
|
||||
* Class ConfigurationController
|
||||
*/
|
||||
class ConfigurationController extends ActionController
|
||||
{
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Index action
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->tabs = $this->createTabs();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Icinga\Web\Widget
|
||||
*/
|
||||
protected function createTabs()
|
||||
{
|
||||
$tabs = $this->widget('tabs')->add(
|
||||
'configuration',
|
||||
array(
|
||||
'title' => $this->translate('Overview'),
|
||||
'url' => 'configuration/index',
|
||||
)
|
||||
$tabBuilder = new ConfigurationTabBuilder(
|
||||
$this->widget('tabs')
|
||||
);
|
||||
|
||||
return $tabs;
|
||||
$tabBuilder->build();
|
||||
|
||||
$this->view->tabs = $tabBuilder->getTabs();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
|
||||
# namespace Icinga\Application\Controllers;
|
||||
|
||||
|
||||
use Icinga\Web\ActionController;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Web\Hook\Configuration\ConfigurationTabBuilder;
|
||||
|
||||
class ModulesController extends ActionController
|
||||
{
|
||||
|
@ -20,6 +20,14 @@ class ModulesController extends ActionController
|
|||
|
||||
public function indexAction()
|
||||
{
|
||||
$tabBuilder = new ConfigurationTabBuilder(
|
||||
$this->widget('tabs')
|
||||
);
|
||||
|
||||
$tabBuilder->build();
|
||||
|
||||
$this->view->tabs = $tabBuilder->getTabs();
|
||||
|
||||
$this->view->modules = $this->manager->select()
|
||||
->from('modules')
|
||||
->order('name');
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?= $this->tabs; ?>
|
||||
<h2>Configuration</h2>
|
||||
<h3>Configuration</h3>
|
||||
|
||||
<p>
|
||||
This is the configuration over page. Modules can register their handler to
|
||||
|
|
|
@ -3,6 +3,7 @@ $this->modules->limit(10);
|
|||
$modules = $this->modules->paginate();
|
||||
|
||||
?>
|
||||
<?= $this->tabs; ?>
|
||||
<h3>Installed Modules</h3>
|
||||
<?= $this->paginationControl($modules, null, null, array(
|
||||
'preserve' => $this->preserve
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Web\Hook\Configuration;
|
||||
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
|
||||
/**
|
||||
* Class ConfigurationTab
|
||||
*
|
||||
* Hook to represent configuration tabs
|
||||
*
|
||||
* @package Icinga\Web\Hook\Configuration
|
||||
*/
|
||||
class ConfigurationTab implements ConfigurationTabInterface
|
||||
{
|
||||
/**
|
||||
* Module name
|
||||
* @var string
|
||||
*/
|
||||
private $moduleName;
|
||||
|
||||
/**
|
||||
* Url segment to invoke controller
|
||||
* @var string
|
||||
*/
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* Title of the tab
|
||||
* @var string
|
||||
*/
|
||||
private $title;
|
||||
|
||||
function __construct($name = null, $url = null, $title = null)
|
||||
{
|
||||
if ($name !== null) {
|
||||
$this->setModuleName($name);
|
||||
|
||||
if ($title === null) {
|
||||
$this->setTitle($name);
|
||||
}
|
||||
}
|
||||
|
||||
if ($url !== null) {
|
||||
$this->setUrl($url);
|
||||
}
|
||||
|
||||
if ($title !== null) {
|
||||
$this->setTitle($title);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter for title
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for title
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for url
|
||||
* @param string $url
|
||||
*/
|
||||
public function setUrl($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for url
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for module name
|
||||
* @param string $moduleName
|
||||
*/
|
||||
public function setModuleName($moduleName)
|
||||
{
|
||||
$this->moduleName = $moduleName;
|
||||
}
|
||||
|
||||
private function assertConfiguration()
|
||||
{
|
||||
if (!$this->moduleName) {
|
||||
throw new ProgrammingError('moduleName is missing');
|
||||
}
|
||||
|
||||
if (!$this->getUrl()) {
|
||||
throw new ProgrammingError('url is missing');
|
||||
}
|
||||
|
||||
if (!$this->getTitle()) {
|
||||
throw new ProgrammingError('title is missing');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a tab configuration to build configuration links
|
||||
* @return array
|
||||
*/
|
||||
public function getTab()
|
||||
{
|
||||
$this->assertConfiguration();
|
||||
|
||||
return array(
|
||||
'title' => $this->getTitle(),
|
||||
'url' => $this->getUrl()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the tab key
|
||||
* @return string
|
||||
*/
|
||||
public function getModuleName()
|
||||
{
|
||||
$this->assertConfiguration();
|
||||
return $this->moduleName;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Web\Hook\Configuration;
|
||||
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Web\Hook;
|
||||
use Icinga\Web\Widget\Tabs;
|
||||
|
||||
/**
|
||||
* Class ConfigurationTabBuilder
|
||||
*
|
||||
* Glue config tabs together
|
||||
*
|
||||
* @package Icinga\Web\Hook\Configuration
|
||||
*/
|
||||
class ConfigurationTabBuilder
|
||||
{
|
||||
/**
|
||||
* Namespace for configuration tabs
|
||||
*/
|
||||
const HOOK_NAMESPACE = 'Configuration/Tabs';
|
||||
|
||||
/**
|
||||
* Tabs widget
|
||||
* @var Tabs
|
||||
*/
|
||||
private $tabs;
|
||||
|
||||
/**
|
||||
* Create a new instance
|
||||
* @param Tabs $tabs
|
||||
*/
|
||||
public function __construct(Tabs $tabs)
|
||||
{
|
||||
$this->setTabs($tabs);
|
||||
|
||||
$this->initializeSystemConfigurationTabs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for tabs
|
||||
* @param \Icinga\Web\Widget\Tabs $tabs
|
||||
*/
|
||||
public function setTabs($tabs)
|
||||
{
|
||||
$this->tabs = $tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for tabs
|
||||
* @return \Icinga\Web\Widget\Tabs
|
||||
*/
|
||||
public function getTabs()
|
||||
{
|
||||
return $this->tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the tabs
|
||||
*
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
/** @var ConfigurationTab $configTab */
|
||||
$configTab = null;
|
||||
foreach (Hook::all(self::HOOK_NAMESPACE) as $configTab) {
|
||||
if (!$configTab instanceof ConfigurationTabInterface) {
|
||||
throw new ProgrammingError('tab not instance of ConfigTabInterface');
|
||||
}
|
||||
|
||||
$this->getTabs()->add($configTab->getModuleName(), $configTab->getTab());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize system configuration tabs
|
||||
*/
|
||||
public function initializeSystemConfigurationTabs()
|
||||
{
|
||||
$configurationTab = new ConfigurationTab(
|
||||
'configuration',
|
||||
'configuration/index',
|
||||
'Configuration'
|
||||
);
|
||||
|
||||
// Display something about us
|
||||
Hook::registerObject(
|
||||
ConfigurationTabBuilder::HOOK_NAMESPACE,
|
||||
$configurationTab->getModuleName(),
|
||||
$configurationTab
|
||||
);
|
||||
|
||||
$modulesOverviewTab = new ConfigurationTab(
|
||||
'modules',
|
||||
'modules/overview',
|
||||
'Modules'
|
||||
);
|
||||
|
||||
Hook::registerObject(
|
||||
ConfigurationTabBuilder::HOOK_NAMESPACE,
|
||||
$modulesOverviewTab->getModuleName(),
|
||||
$modulesOverviewTab
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Web\Hook\Configuration;
|
||||
|
||||
/**
|
||||
* Interface ConfigurationTabInterface
|
||||
*
|
||||
* Used to register configuration tab settings
|
||||
*
|
||||
* @package Icinga\Web\Hook\Configuration
|
||||
*/
|
||||
interface ConfigurationTabInterface
|
||||
{
|
||||
/**
|
||||
* Returns a tab configuration to build configuration links
|
||||
* @return array
|
||||
*/
|
||||
public function getTab();
|
||||
|
||||
/**
|
||||
* Return the tab key
|
||||
* @return string
|
||||
*/
|
||||
public function getModuleName();
|
||||
}
|
|
@ -17,7 +17,7 @@ use Icinga\Web\Url;
|
|||
* @author Icinga-Web Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
|
||||
*/
|
||||
class Tabs extends AbstractWidget
|
||||
class Tabs extends AbstractWidget implements \Countable
|
||||
{
|
||||
/**
|
||||
* This is where single tabs added to this container will be stored
|
||||
|
@ -240,4 +240,18 @@ class Tabs extends AbstractWidget
|
|||
$html .= "</ul>\n";
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counting registered tabs
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->tabs);
|
||||
}
|
||||
|
||||
public function getTabs()
|
||||
{
|
||||
return $this->tabs;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Icinga\Web\Hook\Configuration;
|
||||
|
||||
require_once '../../library/Icinga/Web/Hook/Configuration/ConfigurationTabInterface.php';
|
||||
require_once '../../library/Icinga/Web/Hook/Configuration/ConfigurationTab.php';
|
||||
require_once '../../library/Icinga/Web/Hook/Configuration/ConfigurationTabBuilder.php';
|
||||
require_once '../../library/Icinga/Web/Hook.php';
|
||||
require_once '../../library/Icinga/Web/Widget/AbstractWidget.php';
|
||||
require_once '../../library/Icinga/Web/Widget/Tabs.php';
|
||||
require_once '../../library/Icinga/Web/Widget/Tab.php';
|
||||
require_once '../../library/Icinga/Exception/ProgrammingError.php';
|
||||
|
||||
use Icinga\Web\Hook\Configuration\ConfigurationTab;
|
||||
use Icinga\Web\Hook;
|
||||
use Icinga\Web\Widget\Tabs;
|
||||
use PHPUnit_Framework_TestResult;
|
||||
|
||||
|
||||
class ConfigurationTabBuilderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Hook::clean();
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
Hook::clean();
|
||||
}
|
||||
|
||||
public function testDefaultTabs()
|
||||
{
|
||||
$widget = new Tabs();
|
||||
$builder = new Hook\Configuration\ConfigurationTabBuilder($widget);
|
||||
|
||||
$array = $builder->build();
|
||||
$tabs = $builder->getTabs();
|
||||
|
||||
$this->assertInstanceOf('Icinga\\Web\\Widget\\Tab', $tabs->get('configuration'));
|
||||
}
|
||||
|
||||
public function testTabCreation1()
|
||||
{
|
||||
$widget = new Tabs();
|
||||
$builder = new Hook\Configuration\ConfigurationTabBuilder($widget);
|
||||
|
||||
$tab1 = new ConfigurationTab('test1', '/test1', 'TEST1');
|
||||
$tab2 = new ConfigurationTab('test2', '/test2', 'TEST2');
|
||||
$tab3 = new ConfigurationTab('test3', '/test3', 'TEST3');
|
||||
|
||||
Hook::registerObject(Hook\Configuration\ConfigurationTabBuilder::HOOK_NAMESPACE, 'test1', $tab1);
|
||||
Hook::registerObject(Hook\Configuration\ConfigurationTabBuilder::HOOK_NAMESPACE, 'test2', $tab2);
|
||||
Hook::registerObject(Hook\Configuration\ConfigurationTabBuilder::HOOK_NAMESPACE, 'test3', $tab3);
|
||||
|
||||
$builder->build();
|
||||
|
||||
$this->assertCount(5, $builder->getTabs());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Icinga\Exception\ProgrammingError
|
||||
* @expectedExceptionMessage tab not instance of ConfigTabInterface
|
||||
*/
|
||||
public function testTabCreation2()
|
||||
{
|
||||
$widget = new Tabs();
|
||||
$builder = new Hook\Configuration\ConfigurationTabBuilder($widget);
|
||||
|
||||
$tab = new \stdClass();
|
||||
Hook::registerObject(Hook\Configuration\ConfigurationTabBuilder::HOOK_NAMESPACE, 'misc', $tab);
|
||||
$builder->build();
|
||||
|
||||
$this->assertCount(5, $builder->getTabs());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Icinga\Web\Hook\Configuration;
|
||||
|
||||
require_once '../../library/Icinga/Web/Hook/Configuration/ConfigurationTabInterface.php';
|
||||
require_once '../../library/Icinga/Web/Hook/Configuration/ConfigurationTab.php';
|
||||
require_once '../../library/Icinga/Exception/ProgrammingError.php';
|
||||
|
||||
use Icinga\Web\Hook\Configuration\ConfigurationTab;
|
||||
|
||||
class ConfigurationTabTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testCreate1()
|
||||
{
|
||||
$tab = new ConfigurationTab(
|
||||
'test1',
|
||||
'/test/$555',
|
||||
'TEST_TITLE'
|
||||
);
|
||||
|
||||
$this->assertEquals('test1', $tab->getModuleName());
|
||||
|
||||
$testArray = array(
|
||||
'title' => 'TEST_TITLE',
|
||||
'url' => '/test/$555'
|
||||
);
|
||||
|
||||
$this->assertEquals($testArray, $tab->getTab());
|
||||
}
|
||||
|
||||
public function testCreate2()
|
||||
{
|
||||
$tab = new ConfigurationTab(
|
||||
'test2',
|
||||
'/test/$666'
|
||||
);
|
||||
|
||||
$this->assertEquals('test2', $tab->getModuleName());
|
||||
|
||||
$testArray = array(
|
||||
'title' => 'test2',
|
||||
'url' => '/test/$666'
|
||||
);
|
||||
|
||||
$this->assertEquals($testArray, $tab->getTab());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Icinga\Exception\ProgrammingError
|
||||
* @expectedExceptionMessage moduleName is missing
|
||||
*/
|
||||
public function testException1()
|
||||
{
|
||||
$tab = new ConfigurationTab();
|
||||
$tab->getTab();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Icinga\Exception\ProgrammingError
|
||||
* @expectedExceptionMessage url is missing
|
||||
*/
|
||||
public function testException2()
|
||||
{
|
||||
$tab = new ConfigurationTab();
|
||||
$tab->setModuleName('DING1');
|
||||
$tab->getTab();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Icinga\Exception\ProgrammingError
|
||||
* @expectedExceptionMessage title is missing
|
||||
*/
|
||||
public function testException3()
|
||||
{
|
||||
$tab = new ConfigurationTab();
|
||||
$tab->setModuleName('DING1');
|
||||
$tab->setUrl('/ding/dong');
|
||||
$tab->getTab();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue