Merge branch 'master' into feature/svg-chart-tooltips-7024
This commit is contained in:
commit
da85112538
|
@ -4,6 +4,7 @@
|
|||
|
||||
// namespace Icinga\Application\Controllers;
|
||||
|
||||
use Icinga\Logger\Logger;
|
||||
use Icinga\Web\Controller\ActionController;
|
||||
use Icinga\Application\Icinga;
|
||||
|
||||
|
@ -21,6 +22,10 @@ class ErrorController extends ActionController
|
|||
{
|
||||
$error = $this->_getParam('error_handler');
|
||||
$exception = $error->exception;
|
||||
|
||||
Logger::error($exception);
|
||||
Logger::error('Stacktrace: %s', $exception->getTraceAsString());
|
||||
|
||||
switch ($error->type) {
|
||||
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
|
||||
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
use Zend_Controller_Action_Exception as ActionException;
|
||||
use Icinga\Web\Controller\ActionController;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Logger\Logger;
|
||||
use Icinga\Web\FileCache;
|
||||
use Zend_Controller_Action_Exception as ActionException;
|
||||
|
||||
/**
|
||||
* Delivery static content to clients
|
||||
|
@ -30,8 +31,25 @@ class StaticController extends ActionController
|
|||
|
||||
public function gravatarAction()
|
||||
{
|
||||
$cache = FileCache::instance();
|
||||
$filename = md5(strtolower(trim($this->_request->getParam('email'))));
|
||||
$cacheFile = 'gravatar-' . $filename;
|
||||
header('Cache-Control: public');
|
||||
header('Pragma: cache');
|
||||
if ($etag = $cache->etagMatchesCachedFile($cacheFile)) {
|
||||
header("HTTP/1.1 304 Not Modified");
|
||||
return;
|
||||
}
|
||||
|
||||
header('Content-Type: image/jpg');
|
||||
$img = file_get_contents('http://www.gravatar.com/avatar/' . md5(strtolower(trim($this->_request->getParam('email')))) . '?s=200&d=mm');
|
||||
if ($cache->has($cacheFile)) {
|
||||
header('ETag: "' . $cache->etagForCachedFile($cacheFile) . '"');
|
||||
$cache->send($cacheFile);
|
||||
return;
|
||||
}
|
||||
$img = file_get_contents('http://www.gravatar.com/avatar/' . $filename . '?s=200&d=mm');
|
||||
$cache->store($cacheFile, $img);
|
||||
header('ETag: "' . $cache->etagForCachedFile($cacheFile) . '"');
|
||||
echo $img;
|
||||
}
|
||||
|
||||
|
|
|
@ -452,9 +452,8 @@ abstract class ApplicationBootstrap
|
|||
*/
|
||||
protected function setupInternationalization()
|
||||
{
|
||||
$localeDir = $this->getApplicationDir('locale');
|
||||
if (file_exists($localeDir) && is_dir($localeDir)) {
|
||||
Translator::registerDomain(Translator::DEFAULT_DOMAIN, $localeDir);
|
||||
if ($this->hasLocales()) {
|
||||
Translator::registerDomain(Translator::DEFAULT_DOMAIN, $this->getLocaleDir());
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -469,4 +468,48 @@ abstract class ApplicationBootstrap
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Our locale directory
|
||||
*/
|
||||
public function getLocaleDir()
|
||||
{
|
||||
return $this->getApplicationDir('locale');
|
||||
}
|
||||
|
||||
/**
|
||||
* return bool Whether Icinga Web has translations
|
||||
*/
|
||||
public function hasLocales()
|
||||
{
|
||||
$localedir = $this->getLocaleDir();
|
||||
return file_exists($localedir) && is_dir($localedir);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all available locales
|
||||
*
|
||||
* NOTE: Might be a candidate for a static function in Translator
|
||||
*
|
||||
* return array Locale list
|
||||
*/
|
||||
public function listLocales()
|
||||
{
|
||||
$locales = array();
|
||||
if (! $this->hasLocales()) {
|
||||
return $locales;
|
||||
}
|
||||
$localedir = $this->getLocaleDir();
|
||||
|
||||
$dh = opendir($localedir);
|
||||
while (false !== ($file = readdir($dh))) {
|
||||
$filename = $localedir . DIRECTORY_SEPARATOR . $file;
|
||||
if (preg_match('/^[a-z]{2}_[A-Z]{2}$/', $file) && is_dir($filename)) {
|
||||
$locales[] = $file;
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
sort($locales);
|
||||
return $locales;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,6 +85,18 @@ class Config extends Zend_Config
|
|||
return self::$app[$configname];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set module config
|
||||
*
|
||||
* @param string $moduleName
|
||||
* @param string $configName
|
||||
* @param Zend_Config $config
|
||||
*/
|
||||
public static function setModuleConfig($moduleName, $configName, Zend_Config $config)
|
||||
{
|
||||
self::$modules[$moduleName][$configName] = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a module config instance
|
||||
*
|
||||
|
|
|
@ -177,7 +177,6 @@ class Module
|
|||
/**
|
||||
* Add a pane to dashboard
|
||||
*
|
||||
* @param $id
|
||||
* @param $name
|
||||
* @return Pane
|
||||
*/
|
||||
|
@ -201,21 +200,19 @@ class Module
|
|||
/**
|
||||
* Add a menu Section to the Sidebar menu
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $name
|
||||
* @param $name
|
||||
* @param array $properties
|
||||
* @return mixed
|
||||
*/
|
||||
protected function menuSection($id, $name, array $properties = array())
|
||||
protected function menuSection($name, array $properties = array())
|
||||
{
|
||||
if (array_key_exists($id, $this->menuItems)) {
|
||||
$this->menuItems[$id]->setProperties($properties);
|
||||
if (array_key_exists($name, $this->menuItems)) {
|
||||
$this->menuItems[$name]->setProperties($properties);
|
||||
} else {
|
||||
$this->menuItems[$id] = new Menu($id, new Zend_Config($properties));
|
||||
$this->menuItems[$id]->setTitle($name);
|
||||
$this->menuItems[$name] = new Menu($name, new Zend_Config($properties));
|
||||
}
|
||||
|
||||
return $this->menuItems[$id];
|
||||
return $this->menuItems[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -711,12 +708,44 @@ class Module
|
|||
*/
|
||||
protected function registerLocales()
|
||||
{
|
||||
if (file_exists($this->localedir) && is_dir($this->localedir)) {
|
||||
if ($this->hasLocales()) {
|
||||
Translator::registerDomain($this->name, $this->localedir);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* return bool Whether this module has translations
|
||||
*/
|
||||
public function hasLocales()
|
||||
{
|
||||
return file_exists($this->localedir) && is_dir($this->localedir);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all available locales
|
||||
*
|
||||
* return array Locale list
|
||||
*/
|
||||
public function listLocales()
|
||||
{
|
||||
$locales = array();
|
||||
if (! $this->hasLocales()) {
|
||||
return $locales;
|
||||
}
|
||||
|
||||
$dh = opendir($this->localedir);
|
||||
while (false !== ($file = readdir($dh))) {
|
||||
$filename = $this->localedir . DIRECTORY_SEPARATOR . $file;
|
||||
if (preg_match('/^[a-z]{2}_[A-Z]{2}$/', $file) && is_dir($filename)) {
|
||||
$locales[] = $file;
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
sort($locales);
|
||||
return $locales;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register web integration
|
||||
*
|
||||
|
|
|
@ -13,8 +13,6 @@ use Icinga\Logger\Logger;
|
|||
use Icinga\Web\Request;
|
||||
use Icinga\Web\Response;
|
||||
use Icinga\Web\View;
|
||||
use Icinga\Web\Session\Session as BaseSession;
|
||||
use Icinga\Web\Session;
|
||||
use Icinga\User;
|
||||
use Icinga\Util\Translator;
|
||||
use Icinga\Util\DateTimeFactory;
|
||||
|
@ -59,13 +57,6 @@ class Web extends ApplicationBootstrap
|
|||
*/
|
||||
private $request;
|
||||
|
||||
/**
|
||||
* Session object
|
||||
*
|
||||
* @var BaseSession
|
||||
*/
|
||||
private $session;
|
||||
|
||||
/**
|
||||
* User object
|
||||
*
|
||||
|
@ -92,7 +83,6 @@ class Web extends ApplicationBootstrap
|
|||
->setupErrorHandling()
|
||||
->loadConfig()
|
||||
->setupResourceFactory()
|
||||
->setupSession()
|
||||
->setupUser()
|
||||
->setupTimezone()
|
||||
->setupLogger()
|
||||
|
@ -172,7 +162,6 @@ class Web extends ApplicationBootstrap
|
|||
|
||||
$this->setupFrontController();
|
||||
$this->setupViewRenderer();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -192,17 +181,6 @@ class Web extends ApplicationBootstrap
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a session provider
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
private function setupSession()
|
||||
{
|
||||
$this->session = Session::create();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject dependencies into request
|
||||
*
|
||||
|
|
|
@ -89,6 +89,17 @@ class DbQuery extends SimpleQuery
|
|||
public function getSelectQuery()
|
||||
{
|
||||
$select = $this->dbSelect();
|
||||
|
||||
// Add order fields to select for postgres distinct queries (#6351)
|
||||
if ($this->hasOrder()
|
||||
&& $this->getDatasource()->getDbType() === 'pgsql'
|
||||
&& $select->getPart(Zend_Db_Select::DISTINCT) === true) {
|
||||
foreach ($this->getOrder() as $fieldAndDirection) {
|
||||
list($alias, $field) = explode('.', $fieldAndDirection[0]);
|
||||
$this->columns[$field] = $fieldAndDirection[0];
|
||||
}
|
||||
}
|
||||
|
||||
$select->columns($this->columns);
|
||||
$this->applyFilterSql($select);
|
||||
|
||||
|
@ -102,6 +113,7 @@ class DbQuery extends SimpleQuery
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $select;
|
||||
}
|
||||
|
||||
|
|
|
@ -132,12 +132,12 @@ abstract class Filter
|
|||
public static function expression($col, $op, $expression)
|
||||
{
|
||||
switch ($op) {
|
||||
case '=': return new FilterEqual($col, $op, $expression);
|
||||
case '=': return new FilterMatch($col, $op, $expression);
|
||||
case '<': return new FilterLessThan($col, $op, $expression);
|
||||
case '>': return new FilterGreaterThan($col, $op, $expression);
|
||||
case '>=': return new FilterEqualOrGreaterThan($col, $op, $expression);
|
||||
case '<=': return new FilterEqualOrLessThan($col, $op, $expression);
|
||||
case '!=': return new FilterNotEqual($col, $op, $expression);
|
||||
case '!=': return new FilterMatchNot($col, $op, $expression);
|
||||
default: throw new ProgrammingError(
|
||||
'There is no such filter sign: %s',
|
||||
$op
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Data\Filter;
|
||||
|
||||
class FilterMatch extends FilterExpression
|
||||
{
|
||||
public function matches($row)
|
||||
{
|
||||
$expression = (string) $this->expression;
|
||||
if (strpos($expression, '*') === false) {
|
||||
return (string) $row->{$this->column} === $expression;
|
||||
} else {
|
||||
$parts = array();
|
||||
foreach (preg_split('/\*/', $expression) as $part) {
|
||||
$parts[] = preg_quote($part);
|
||||
}
|
||||
return preg_match('/^' . implode('.*', $parts) . '$/', $row->{$this->column});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Data\Filter;
|
||||
|
||||
class FilterMatchNot extends FilterExpression
|
||||
{
|
||||
public function matches($row)
|
||||
{
|
||||
$expression = (string) $this->expression;
|
||||
if (strpos($expression, '*') === false) {
|
||||
return (string) $row->{$this->column} !== $expression;
|
||||
} else {
|
||||
$parts = array();
|
||||
foreach (preg_split('/\*/', $expression) as $part) {
|
||||
$parts[] = preg_quote($part);
|
||||
}
|
||||
return ! preg_match('/^' . implode('.*', $parts) . '$/', $row->{$this->column});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Data\Filter;
|
||||
|
||||
class FilterNotEqual extends FilterExpression
|
||||
{
|
||||
public function matches($row)
|
||||
{
|
||||
return (string) $row->{$this->column} !== (string) $this->expression;
|
||||
}
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace Icinga\Protocol\File;
|
||||
|
||||
use RuntimeException;
|
||||
use Icinga\Exception\IcingaException;
|
||||
|
||||
/**
|
||||
* Exception thrown if a file reader specific error occurs
|
||||
*/
|
||||
class FileReaderException extends RuntimeException {}
|
||||
class FileReaderException extends IcingaException {}
|
||||
|
|
|
@ -40,7 +40,7 @@ class Reader extends FilterIterator
|
|||
{
|
||||
foreach (array('filename', 'fields') as $key) {
|
||||
if (! isset($config->{$key})) {
|
||||
throw new FileReaderException('The directive `' . $key . '\' is required');
|
||||
throw new FileReaderException('The directive `%s\' is required', $key);
|
||||
}
|
||||
}
|
||||
$this->fields = $config->fields;
|
||||
|
|
|
@ -307,7 +307,7 @@ class Connection
|
|||
$results = @ldap_search(
|
||||
$this->ds,
|
||||
$base,
|
||||
(string) $query,
|
||||
$query->create(),
|
||||
$fields,
|
||||
0, // Attributes and values
|
||||
0 // No limit - at least where possible
|
||||
|
@ -619,7 +619,7 @@ class Connection
|
|||
$result = @ldap_read(
|
||||
$ds,
|
||||
'',
|
||||
(string) $query,
|
||||
$query->create(),
|
||||
$query->listFields()
|
||||
);
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
namespace Icinga\Protocol\Ldap;
|
||||
|
||||
use Icinga\Exception\IcingaException;
|
||||
|
||||
/**
|
||||
* Search class
|
||||
*
|
||||
|
@ -84,7 +82,7 @@ class Query
|
|||
public function limit($count = null, $offset = null)
|
||||
{
|
||||
if (! preg_match('~^\d+~', $count . $offset)) {
|
||||
throw new IcingaException(
|
||||
throw new Exception(
|
||||
'Got invalid limit: %s, %s',
|
||||
$count,
|
||||
$offset
|
||||
|
@ -302,21 +300,11 @@ class Query
|
|||
*
|
||||
* @string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the LDAP filter that will be applied
|
||||
*
|
||||
* @string
|
||||
*/
|
||||
protected function render()
|
||||
public function create()
|
||||
{
|
||||
$parts = array();
|
||||
if (! isset($this->filters['objectClass']) || $this->filters['objectClass'] === null) {
|
||||
// throw new IcingaException('Object class is mandatory');
|
||||
throw new Exception('Object class is mandatory');
|
||||
}
|
||||
foreach ($this->filters as $key => $value) {
|
||||
$parts[] = sprintf(
|
||||
|
|
|
@ -348,7 +348,9 @@ class ActionController extends Zend_Controller_Action
|
|||
// Cast preference app.show_benchmark to bool because preferences loaded from a preferences storage are
|
||||
// always strings
|
||||
if ((bool) $user->getPreferences()->get('app.show_benchmark', false) === true) {
|
||||
$layout->benchmark = $this->renderBenchmark();
|
||||
if (!$this->_helper->viewRenderer->getNoRender()) {
|
||||
$layout->benchmark = $this->renderBenchmark();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,275 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Web;
|
||||
|
||||
class FileCache
|
||||
{
|
||||
/**
|
||||
* FileCache singleton instances
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $instances = array();
|
||||
|
||||
/**
|
||||
* Cache instance base directory
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $basedir;
|
||||
|
||||
/**
|
||||
* Instance name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Whether the cache is enabled
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $enabled = false;
|
||||
|
||||
/**
|
||||
* The protected constructor creates a new instance with the given name
|
||||
*
|
||||
* @param string $name Cache instance name
|
||||
*/
|
||||
protected function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
$tmpdir = sys_get_temp_dir();
|
||||
$basedir = $tmpdir . '/FileCache_' . $name;
|
||||
|
||||
if (file_exists($basedir) && is_writeable($basedir)) {
|
||||
|
||||
$this->basedir = $basedir;
|
||||
$this->enabled = true;
|
||||
|
||||
} elseif (file_exists($tmpdir) && is_writeable($tmpdir)) {
|
||||
|
||||
if (mkdir($basedir, '0750', true)) {
|
||||
$this->enabled = true;
|
||||
$this->basedir = $basedir;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the given content to the desired file name
|
||||
*
|
||||
* @param string $file new (relative) filename
|
||||
* @param string $content the content to be stored
|
||||
*
|
||||
* @return bool whether the file has been stored
|
||||
*/
|
||||
public function store($file, $content)
|
||||
{
|
||||
if (! $this->enabled) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return file_put_contents($this->filename($file), $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out whether a given file exists
|
||||
*
|
||||
* @param string $file the (relative) filename
|
||||
* @param int $newerThan optional timestamp to compare against
|
||||
*
|
||||
* @return bool whether such file exists
|
||||
*/
|
||||
public function has($file, $newerThan = null)
|
||||
{
|
||||
if (! $this->enabled) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$filename = $this->filename($file);
|
||||
|
||||
if (! file_exists($filename) || ! is_readable($filename)) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($newerThan === null) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$info = stat($file);
|
||||
|
||||
if ($info === false) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return (int) $newerThan < $info['mtime'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific file or false if no such file available
|
||||
*
|
||||
* @param string $file the disired file name
|
||||
*
|
||||
* @return string|bool Filename content or false
|
||||
*/
|
||||
public function get($file)
|
||||
{
|
||||
if ($this->has($file)) {
|
||||
return file_get_contents($this->filename($file));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a specific file to the browser (output)
|
||||
*
|
||||
* @param string $file the disired file name
|
||||
*
|
||||
* @return bool Whether the file has been sent
|
||||
*/
|
||||
public function send($file)
|
||||
{
|
||||
if ($this->has($file)) {
|
||||
readfile($this->filename($file));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get absolute filename for a given file
|
||||
*
|
||||
* @param string $file the disired file name
|
||||
*
|
||||
* @return string absolute filename
|
||||
*/
|
||||
protected function filename($file)
|
||||
{
|
||||
return $this->basedir . '/' . $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the given ETag matches a cached file
|
||||
*
|
||||
* If no ETag is given we'll try to fetch the one from the current
|
||||
* HTTP request.
|
||||
*
|
||||
* @param string $file The cached file you want to check
|
||||
* @param string $match The ETag to match against
|
||||
*
|
||||
* @return string|bool ETag on match, otherwise false
|
||||
*/
|
||||
public function etagMatchesCachedFile($file, $match = null)
|
||||
{
|
||||
return self::etagMatchesFiles($this->filename($file), $match);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ETag for the given file
|
||||
*
|
||||
* @param string $file The desired cache file
|
||||
*
|
||||
* @return string your ETag
|
||||
*/
|
||||
public function etagForCachedFile($file)
|
||||
{
|
||||
return self::etagForFiles($this->filename($file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the given ETag matchesspecific file(s) on disk
|
||||
*
|
||||
* If no ETag is given we'll try to fetch the one from the current
|
||||
* HTTP request.
|
||||
*
|
||||
* @param string|array $files file(s) to check
|
||||
* @param string $match ETag to match against
|
||||
*
|
||||
* @return string|bool ETag on match, otherwise false
|
||||
*/
|
||||
public static function etagMatchesFiles($files, $match = null)
|
||||
{
|
||||
if ($match === null) {
|
||||
$match = isset($_SERVER['HTTP_IF_NONE_MATCH'])
|
||||
? trim($_SERVER['HTTP_IF_NONE_MATCH'], '"')
|
||||
: false;
|
||||
}
|
||||
if (! $match) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$etag = self::etagForFiles($files);
|
||||
return $match === $etag ? $etag : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create ETag for the given files
|
||||
*
|
||||
* Custom algorithm creating an ETag based on filenames, mtimes
|
||||
* and file sizes. Supports single files or a list of files. This
|
||||
* way we are able to create ETags for virtual files depending on
|
||||
* multiple source files (e.g. compressed JS, CSS).
|
||||
*
|
||||
* @param string|array $files Single file or a list of such
|
||||
*
|
||||
* @return string The generated ETag
|
||||
*/
|
||||
public static function etagForFiles($files)
|
||||
{
|
||||
if (is_string($files)) {
|
||||
$files = array($files);
|
||||
}
|
||||
|
||||
$sizes = array();
|
||||
$mtimes = array();
|
||||
|
||||
foreach ($files as $file) {
|
||||
$file = realpath($file);
|
||||
if ($file !== false && $info = stat($file)) {
|
||||
$mtimes[] = $info['mtime'];
|
||||
$sizes[] = $info['size'];
|
||||
} else {
|
||||
$mtimes[] = time();
|
||||
$sizes[] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'%s-%s-%s',
|
||||
hash('crc32', implode('|', $files)),
|
||||
hash('crc32', implode('|', $sizes)),
|
||||
hash('crc32', implode('|', $mtimes))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory creating your cache instance
|
||||
*
|
||||
* @param string $name Instance name
|
||||
*
|
||||
* @return FileCache
|
||||
*/
|
||||
public static function instance($name = 'icingaweb')
|
||||
{
|
||||
if ($name !== 'icingaweb') {
|
||||
$name = 'icingaweb/modules/' . $name;
|
||||
}
|
||||
|
||||
if (!array_key_exists($name, self::$instances)) {
|
||||
self::$instances[$name] = new static($name);
|
||||
}
|
||||
|
||||
return self::$instances[$name];
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
namespace Icinga\Web;
|
||||
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Web\FileCache;
|
||||
use JShrink\Minifier;
|
||||
|
||||
class JavaScript
|
||||
|
@ -64,36 +65,58 @@ class JavaScript
|
|||
$js = $out = '';
|
||||
$min = $minified ? '.min' : '';
|
||||
|
||||
// TODO: Cache header
|
||||
header('Content-Type: application/javascript');
|
||||
$cacheFile = '/tmp/cache_icinga' . $min . '.js';
|
||||
if (file_exists($cacheFile)) {
|
||||
readfile($cacheFile);
|
||||
exit;
|
||||
}
|
||||
|
||||
// We do not minify vendor files
|
||||
// Prepare vendor file list
|
||||
$vendorFiles = array();
|
||||
foreach (self::$vendorFiles as $file) {
|
||||
$out .= file_get_contents($basedir . '/' . $file . $min . '.js');
|
||||
$vendorFiles[] = $basedir . '/' . $file . $min . '.js';
|
||||
}
|
||||
|
||||
// Prepare Icinga JS file list
|
||||
$jsFiles = array();
|
||||
foreach (self::$jsFiles as $file) {
|
||||
$js .= file_get_contents($basedir . '/' . $file);
|
||||
$jsFiles[] = $basedir . '/' . $file;
|
||||
}
|
||||
|
||||
foreach (Icinga::app()->getModuleManager()->getLoadedModules() as $name => $module) {
|
||||
if ($module->hasJs()) {
|
||||
$js .= file_get_contents($module->getJsFilename());
|
||||
$jsFiles[] = $module->getJsFilename();
|
||||
}
|
||||
}
|
||||
$files = array_merge($vendorFiles, $jsFiles);
|
||||
|
||||
if ($etag = FileCache::etagMatchesFiles($files)) {
|
||||
header("HTTP/1.1 304 Not Modified");
|
||||
return;
|
||||
} else {
|
||||
$etag = FileCache::etagForFiles($files);
|
||||
}
|
||||
header('Cache-Control: public');
|
||||
header('ETag: "' . $etag . '"');
|
||||
header('Content-Type: application/javascript');
|
||||
|
||||
$cacheFile = 'icinga-' . $etag . $min . '.js';
|
||||
$cache = FileCache::instance();
|
||||
if ($cache->has($cacheFile)) {
|
||||
$cache->send($cacheFile);
|
||||
return;
|
||||
}
|
||||
|
||||
// We do not minify vendor files
|
||||
foreach ($vendorFiles as $file) {
|
||||
$out .= file_get_contents($file);
|
||||
}
|
||||
|
||||
foreach ($jsFiles as $file) {
|
||||
$js .= file_get_contents($file);
|
||||
}
|
||||
|
||||
if ($minified) {
|
||||
require_once 'IcingaVendor/JShrink/Minifier.php';
|
||||
$out .= Minifier::minify($js, array('flaggedComments' => false));
|
||||
} else {
|
||||
$out .= $js;
|
||||
}
|
||||
// Not yet, this is for tests only. Waiting for Icinga\Web\Cache
|
||||
// file_put_contents($cacheFile, $out);
|
||||
$cache->store($cacheFile, $out);
|
||||
echo $out;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
namespace Icinga\Web;
|
||||
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Logger\Logger;
|
||||
use Zend_Config;
|
||||
use RecursiveIterator;
|
||||
use Icinga\Application\Config;
|
||||
|
@ -173,34 +172,34 @@ class Menu implements RecursiveIterator
|
|||
*/
|
||||
protected function addMainMenuItems()
|
||||
{
|
||||
$this->add('dashboard', t('Dashboard'), array(
|
||||
$this->add(t('Dashboard'), array(
|
||||
'url' => 'dashboard',
|
||||
'icon' => 'img/icons/dashboard.png',
|
||||
'priority' => 10
|
||||
));
|
||||
|
||||
$section = $this->add('system', t('System'), array(
|
||||
$section = $this->add(t('System'), array(
|
||||
'icon' => 'img/icons/configuration.png',
|
||||
'priority' => 200
|
||||
));
|
||||
$section->add('preferences', t('Preferences'), array(
|
||||
$section->add(t('Preferences'), array(
|
||||
'url' => 'preference',
|
||||
'priority' => 200
|
||||
));
|
||||
$section->add('configuration', t('Configuration'), array(
|
||||
$section->add(t('Configuration'), array(
|
||||
'url' => 'config',
|
||||
'priority' => 300
|
||||
));
|
||||
$section->add('modules', t('Modules'), array(
|
||||
$section->add(t('Modules'), array(
|
||||
'url' => 'config/modules',
|
||||
'priority' => 400
|
||||
));
|
||||
$section->add('applicationlog', t('ApplicationLog'), array(
|
||||
$section->add(t('ApplicationLog'), array(
|
||||
'url' => 'list/applicationlog',
|
||||
'priority' => 500
|
||||
));
|
||||
|
||||
$this->add('logout', t('Logout'), array(
|
||||
$this->add(t('Logout'), array(
|
||||
'url' => 'authentication/logout',
|
||||
'icon' => 'img/icons/logout.png',
|
||||
'priority' => 300
|
||||
|
@ -428,10 +427,9 @@ class Menu implements RecursiveIterator
|
|||
* @param array $config
|
||||
* @return Menu
|
||||
*/
|
||||
public function add($id, $name, $config = array())
|
||||
public function add($name, $config = array())
|
||||
{
|
||||
$config['title'] = $name;
|
||||
return $this->addSubMenu($id, new Zend_Config($config));
|
||||
return $this->addSubMenu($name, new Zend_Config($config));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,7 +47,7 @@ class Session
|
|||
public static function getSession()
|
||||
{
|
||||
if (self::$session === null) {
|
||||
throw new ProgrammingError('No session created yet');
|
||||
self::create();
|
||||
}
|
||||
|
||||
return self::$session;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
namespace Icinga\Web;
|
||||
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Web\FileCache;
|
||||
use Icinga\Web\LessCompiler;
|
||||
|
||||
class StyleSheet
|
||||
|
@ -46,28 +47,45 @@ class StyleSheet
|
|||
|
||||
public static function send($minified = false)
|
||||
{
|
||||
$app = Icinga::app();
|
||||
$basedir = $app->getBootstrapDirecory();
|
||||
foreach (self::$lessFiles as $file) {
|
||||
$lessFiles[] = $basedir . '/' . $file;
|
||||
}
|
||||
$files = $lessFiles;
|
||||
foreach ($app->getModuleManager()->getLoadedModules() as $name => $module) {
|
||||
if ($module->hasCss()) {
|
||||
$files[] = $module->getCssFilename();
|
||||
}
|
||||
}
|
||||
|
||||
if ($etag = FileCache::etagMatchesFiles($files)) {
|
||||
header("HTTP/1.1 304 Not Modified");
|
||||
return;
|
||||
} else {
|
||||
$etag = FileCache::etagForFiles($files);
|
||||
}
|
||||
header('Cache-Control: public');
|
||||
header('ETag: "' . $etag . '"');
|
||||
header('Content-Type: text/css');
|
||||
|
||||
$min = $minified ? '.min' : '';
|
||||
$cacheFile = '/tmp/cache_icinga' . $min . '.css';
|
||||
if (file_exists($cacheFile)) {
|
||||
readfile($cacheFile);
|
||||
exit;
|
||||
$cacheFile = 'icinga-' . $etag . $min . '.css';
|
||||
$cache = FileCache::instance();
|
||||
if ($cache->has($cacheFile)) {
|
||||
$cache->send($cacheFile);
|
||||
return;
|
||||
}
|
||||
|
||||
$less = new LessCompiler();
|
||||
$basedir = Icinga::app()->getBootstrapDirecory();
|
||||
foreach (self::$lessFiles as $file) {
|
||||
$less->addFile($basedir . '/' . $file);
|
||||
foreach ($lessFiles as $file) {
|
||||
$less->addFile($file);
|
||||
}
|
||||
$less->addLoadedModules();
|
||||
if ($minified) {
|
||||
$less->compress();
|
||||
}
|
||||
$out = $less->compile();
|
||||
// Not yet, this is for tests only. Waiting for Icinga\Web\Cache
|
||||
// file_put_contents($cacheFile, $out);
|
||||
$cache->store($cacheFile, $out);
|
||||
echo $out;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use Icinga\Application\Icinga;
|
|||
use Icinga\Application\Config as IcingaConfig;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Web\Widget\AbstractWidget;
|
||||
use Icinga\Web\Widget\Dashboard\Pane;
|
||||
use Icinga\Web\Widget\Dashboard\Component as DashboardComponent;
|
||||
use Icinga\Web\Url;
|
||||
|
@ -96,7 +95,7 @@ class Dashboard extends AbstractWidget
|
|||
$current = $this->panes[$pane->getName()];
|
||||
$current->addComponents($pane->getComponents());
|
||||
} else {
|
||||
$this->panes = array_filter(array_merge($this->panes, $panes));
|
||||
$this->panes[$pane->getName()] = $pane;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,6 +127,16 @@ class Dashboard extends AbstractWidget
|
|||
return $this->tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all panes of this dashboard
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPanes()
|
||||
{
|
||||
return $this->panes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate this dashboard via the given configuration file
|
||||
*
|
||||
|
@ -164,9 +173,9 @@ class Dashboard extends AbstractWidget
|
|||
*
|
||||
* @TODO: Should only allow component objects to be added directly as soon as we store more information
|
||||
*
|
||||
* @param string $pane The pane to add the component to
|
||||
* @param Component|string $component The component to add or the title of the newly created component
|
||||
* @param $url The url to use for the component
|
||||
* @param string $pane The pane to add the component to
|
||||
* @param Component|string $component The component to add or the title of the newly created component
|
||||
* @param string|null $url The url to use for the component
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
|
@ -198,20 +207,14 @@ class Dashboard extends AbstractWidget
|
|||
}
|
||||
|
||||
/**
|
||||
* Return true if a pane doesn't exist or doesn't have any components in it
|
||||
*
|
||||
* @param string $pane The name of the pane to check for emptyness
|
||||
* Check if this dashboard has a specific pane
|
||||
*
|
||||
* @param $pane string The name of the pane
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmptyPane($pane)
|
||||
public function hasPane($pane)
|
||||
{
|
||||
$paneObj = $this->getPane($pane);
|
||||
if ($paneObj === null) {
|
||||
return true;
|
||||
}
|
||||
$cmps = $paneObj->getComponents();
|
||||
return !empty($cmps);
|
||||
return array_key_exists($pane, $this->panes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -305,11 +308,11 @@ class Dashboard extends AbstractWidget
|
|||
return $active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see determineActivePane()
|
||||
*/
|
||||
public function getActivePane()
|
||||
{
|
||||
if ($active = $this->getTabs()->getActiveName()) {
|
||||
return $this->getPane($active);
|
||||
}
|
||||
return $this->determineActivePane();
|
||||
}
|
||||
|
||||
|
@ -323,10 +326,12 @@ class Dashboard extends AbstractWidget
|
|||
$active = $this->getTabs()->getActiveName();
|
||||
if (! $active) {
|
||||
if ($active = Url::fromRequest()->getParam($this->tabParam)) {
|
||||
if ($this->isEmptyPane($active)) {
|
||||
$active = $this->setDefaultPane();
|
||||
} else {
|
||||
if ($this->hasPane($active)) {
|
||||
$this->activate($active);
|
||||
} else {
|
||||
throw new ProgrammingError(
|
||||
'Try to get an inexistent pane.'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$active = $this->setDefaultPane();
|
||||
|
|
|
@ -30,13 +30,6 @@ class Component extends AbstractWidget
|
|||
*/
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* The id of this Component
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* The title being displayed on top of the component
|
||||
* @var
|
||||
|
@ -49,6 +42,13 @@ class Component extends AbstractWidget
|
|||
*/
|
||||
private $pane;
|
||||
|
||||
/**
|
||||
* The disabled option is used to "delete" default dashlets provided by modules
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $disabled = false;
|
||||
|
||||
/**
|
||||
* The template string used for rendering this widget
|
||||
*
|
||||
|
@ -67,14 +67,12 @@ EOD;
|
|||
/**
|
||||
* Create a new component displaying the given url in the provided pane
|
||||
*
|
||||
* @param string $id The id to use for this component
|
||||
* @param string $title The title to use for this component
|
||||
* @param Url|string $url The url this component uses for displaying information
|
||||
* @param Pane $pane The pane this Component will be added to
|
||||
*/
|
||||
public function __construct($id, $title, $url, Pane $pane)
|
||||
public function __construct($title, $url, Pane $pane)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->title = $title;
|
||||
$this->pane = $pane;
|
||||
if ($url instanceof Url) {
|
||||
|
@ -126,6 +124,26 @@ EOD;
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the disabled property
|
||||
*
|
||||
* @param boolean $disabled
|
||||
*/
|
||||
public function setDisabled($disabled)
|
||||
{
|
||||
$this->disabled = $disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the disabled property
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getDisabled()
|
||||
{
|
||||
return $this->disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this component's structure as array
|
||||
*
|
||||
|
@ -145,6 +163,10 @@ EOD;
|
|||
*/
|
||||
public function render()
|
||||
{
|
||||
if ($this->disabled === true) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$view = $this->view();
|
||||
$url = clone($this->url);
|
||||
$url->setParam('view', 'compact');
|
||||
|
@ -195,14 +217,14 @@ EOD;
|
|||
|
||||
/**
|
||||
* Create a @see Component instance from the given Zend config, using the provided title
|
||||
* @param $id The id for this component
|
||||
*
|
||||
* @param $title The title for this component
|
||||
* @param Zend_Config $config The configuration defining url, parameters, height, width, etc.
|
||||
* @param Pane $pane The pane this component belongs to
|
||||
*
|
||||
* @return Component A newly created Component for use in the Dashboard
|
||||
*/
|
||||
public static function fromIni($id, $title, Zend_Config $config, Pane $pane)
|
||||
public static function fromIni($title, Zend_Config $config, Pane $pane)
|
||||
{
|
||||
$height = null;
|
||||
$width = null;
|
||||
|
@ -210,27 +232,7 @@ EOD;
|
|||
$parameters = $config->toArray();
|
||||
unset($parameters['url']); // otherwise there's an url = parameter in the Url
|
||||
|
||||
$cmp = new Component($id, $title, Url::fromPath($url, $parameters), $pane);
|
||||
$cmp = new Component($title, Url::fromPath($url, $parameters), $pane);
|
||||
return $cmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the components id
|
||||
*
|
||||
* @param $id string
|
||||
*/
|
||||
public function setId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the components id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ class Pane extends AbstractWidget
|
|||
/**
|
||||
* Create a new pane
|
||||
*
|
||||
* @param $name The pane to create
|
||||
* @param string $name The pane to create
|
||||
*/
|
||||
public function __construct($name)
|
||||
{
|
||||
|
@ -83,44 +83,54 @@ class Pane extends AbstractWidget
|
|||
/**
|
||||
* Return true if a component with the given title exists in this pane
|
||||
*
|
||||
* @param string $id The id of the component to check for existence
|
||||
* @param string $title The title of the component to check for existence
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasComponent($id)
|
||||
public function hasComponent($title)
|
||||
{
|
||||
return array_key_exists($id, $this->components);
|
||||
return array_key_exists($title, $this->components);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current pane has any components
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasComponents()
|
||||
{
|
||||
return ! empty($this->components);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a component with the given name if existing
|
||||
*
|
||||
* @param string $id The id of the component to return
|
||||
* @param string $title The title of the component to return
|
||||
*
|
||||
* @return Component The component with the given title
|
||||
* @throws ProgrammingError If the component doesn't exist
|
||||
*/
|
||||
public function getComponent($id)
|
||||
public function getComponent($title)
|
||||
{
|
||||
if ($this->hasComponent($id)) {
|
||||
return $this->components[$id];
|
||||
if ($this->hasComponent($title)) {
|
||||
return $this->components[$title];
|
||||
}
|
||||
throw new ProgrammingError(
|
||||
'Trying to access invalid component: %s',
|
||||
$id
|
||||
$title
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the component with the given id if it exists in this pane
|
||||
* Removes the component with the given title if it exists in this pane
|
||||
*
|
||||
* @param string $id The pane
|
||||
* @param string $title The pane
|
||||
* @return Pane $this
|
||||
*/
|
||||
public function removeComponent($id)
|
||||
public function removeComponent($title)
|
||||
{
|
||||
if ($this->hasComponent($id)) {
|
||||
unset($this->components[$id]);
|
||||
if ($this->hasComponent($title)) {
|
||||
unset($this->components[$title]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
@ -146,7 +156,6 @@ class Pane extends AbstractWidget
|
|||
/**
|
||||
* Add a component to this pane, optionally creating it if $component is a string
|
||||
*
|
||||
* @param string $id An unique Identifier
|
||||
* @param string|Component $component The component object or title
|
||||
* (if a new component will be created)
|
||||
* @param string|null $url An Url to be used when component is a string
|
||||
|
@ -154,12 +163,12 @@ class Pane extends AbstractWidget
|
|||
* @return self
|
||||
* @throws \Icinga\Exception\ConfigurationError
|
||||
*/
|
||||
public function addComponent($id, $component, $url = null)
|
||||
public function addComponent($component, $url = null)
|
||||
{
|
||||
if ($component instanceof Component) {
|
||||
$this->components[$component->getId()] = $component;
|
||||
} elseif (is_string($id) && is_string($component) && $url !== null) {
|
||||
$this->components[$id] = new Component($id, $component, $url, $this);
|
||||
$this->components[$component->getTitle()] = $component;
|
||||
} elseif (is_string($component) && $url !== null) {
|
||||
$this->components[$component] = new Component($component, $url, $this);
|
||||
} else {
|
||||
throw new ConfigurationError('Invalid component added: %s', $component);
|
||||
}
|
||||
|
@ -176,15 +185,15 @@ class Pane extends AbstractWidget
|
|||
{
|
||||
/* @var $component Component */
|
||||
foreach ($components as $component) {
|
||||
if (array_key_exists($component->getId(), $this->components)) {
|
||||
if (preg_match('/-(\d+)$/', $component->getId(), $m)) {
|
||||
$name = preg_replace('/-\d+$/', $m[1]++, $component->getId());
|
||||
if (array_key_exists($component->getTitle(), $this->components)) {
|
||||
if (preg_match('/_(\d+)$/', $component->getTitle(), $m)) {
|
||||
$name = preg_replace('/_\d+$/', $m[1]++, $component->getTitle());
|
||||
} else {
|
||||
$name = $component->getId() . '-2';
|
||||
$name = $component->getTitle() . '_2';
|
||||
}
|
||||
$this->components[$name] = $component;
|
||||
} else {
|
||||
$this->components[$component->getId()] = $component;
|
||||
$this->components[$component->getTitle()] = $component;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,18 +203,17 @@ class Pane extends AbstractWidget
|
|||
/**
|
||||
* Add a component to the current pane
|
||||
*
|
||||
* @param $id
|
||||
* @param $title
|
||||
* @param null $url
|
||||
* @return mixed
|
||||
* @param $url
|
||||
* @return Component
|
||||
*
|
||||
* @see addComponent()
|
||||
*/
|
||||
public function add($id, $title, $url = null)
|
||||
public function add($title, $url = null)
|
||||
{
|
||||
$this->addComponent($id, $title, $url);
|
||||
$this->addComponent($title, $url);
|
||||
|
||||
return $this->components[$id];
|
||||
return $this->components[$title];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -183,9 +183,10 @@ class FilterEditor extends AbstractWidget
|
|||
{
|
||||
$name = 'sign_' . $filter->getId();
|
||||
$signs = array(
|
||||
'=' => '=',
|
||||
'>' => '>',
|
||||
'<' => '<',
|
||||
'=' => '=',
|
||||
'!=' => '!=',
|
||||
'>' => '>',
|
||||
'<' => '<',
|
||||
'>=' => '>=',
|
||||
'<=' => '<=',
|
||||
);
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
/* @var $this \Icinga\Application\Modules\Module */
|
||||
|
||||
$section = $this->menuSection('documentation', $this->translate('Documentation'), array(
|
||||
$section = $this->menuSection($this->translate('Documentation'), array(
|
||||
'title' => 'Documentation',
|
||||
'icon' => 'img/icons/comment.png',
|
||||
'url' => 'doc',
|
||||
'priority' => 80
|
||||
|
|
|
@ -34,8 +34,21 @@ class Monitoring_ListController extends Controller
|
|||
|
||||
protected function hasBetterUrl()
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
$url = clone($this->url);
|
||||
|
||||
if ($this->getRequest()->isPost()) {
|
||||
|
||||
if ($request->getPost('sort')) {
|
||||
$url->setParam('sort', $request->getPost('sort'));
|
||||
if ($request->getPost('dir')) {
|
||||
$url->setParam('dir', $request->getPost('dir'));
|
||||
} else {
|
||||
$url->removeParam('dir');
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
$q = $this->getRequest()->getPost('q');
|
||||
} else {
|
||||
$q = $url->shift('q');
|
||||
|
@ -488,15 +501,8 @@ class Monitoring_ListController extends Controller
|
|||
$request = $this->getRequest();
|
||||
|
||||
$limit = $params->shift('limit');
|
||||
|
||||
$sort = null;
|
||||
$dir = null;
|
||||
if ($request->isPost()) {
|
||||
$sort = $request->getPost('sort', null);
|
||||
$dir = $request->getPost('dir', null);
|
||||
}
|
||||
$sort = $params->shift('sort', $sort);
|
||||
$dir = $params->shift('dir', $dir);
|
||||
$sort = $params->shift('sort');
|
||||
$dir = $params->shift('dir');
|
||||
$page = $params->shift('page');
|
||||
$format = $params->shift('format');
|
||||
$view = $params->shift('view');
|
||||
|
@ -533,7 +539,9 @@ class Monitoring_ListController extends Controller
|
|||
$query->applyFilter($filter);
|
||||
}
|
||||
$this->view->filter = $filter;
|
||||
$query->order($sort, $dir);
|
||||
if ($sort) {
|
||||
$query->order($sort, $dir);
|
||||
}
|
||||
$this->applyRestrictions($query);
|
||||
$this->handleFormatRequest($query);
|
||||
return $query;
|
||||
|
|
|
@ -89,9 +89,8 @@ class Monitoring_ShowController extends Controller
|
|||
$this->getTabs()->activate('history');
|
||||
//$this->view->object->populate();
|
||||
$this->view->object->fetchEventHistory();
|
||||
$this->view->history = $this->view->object->eventhistory->paginate($this->params->get('limit', 50));
|
||||
$this->handleFormatRequest($this->view->object->eventhistory);
|
||||
$this->view->history = $this->view->object->eventhistory
|
||||
->paginate($this->params->get('limit', 50));
|
||||
}
|
||||
|
||||
public function servicesAction()
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
use DateTime;
|
||||
use DateInterval;
|
||||
use Zend_Config;
|
||||
use \DateTime;
|
||||
use \DateInterval;
|
||||
use \Zend_Config;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Util\Format;
|
||||
use Icinga\Application\Config;
|
||||
|
|
|
@ -1,284 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
use Icinga\Module\Monitoring\Object\AbstractObject;
|
||||
|
||||
/**
|
||||
* Class Zend_View_Helper_MonitoringProperties
|
||||
*/
|
||||
class Zend_View_Helper_MonitoringProperties extends Zend_View_Helper_Abstract
|
||||
{
|
||||
/**
|
||||
* Value for check type active
|
||||
*/
|
||||
const CHECK_ACTIVE = 'ACTIVE';
|
||||
|
||||
/**
|
||||
* Value for check type passive
|
||||
*/
|
||||
const CHECK_PASSIVE = 'PASSIVE';
|
||||
|
||||
/**
|
||||
* Value for check type disabled
|
||||
*/
|
||||
const CHECK_DISABLED = 'DISABLED';
|
||||
|
||||
/**
|
||||
* Return value for not available
|
||||
*/
|
||||
const VALUE_NA = 'N/A';
|
||||
|
||||
/**
|
||||
* Return value for "YES"
|
||||
*/
|
||||
const VALUE_YES = 'YES';
|
||||
|
||||
/**
|
||||
* Return value for "NO"
|
||||
*/
|
||||
const VALUE_NO = 'NO';
|
||||
|
||||
/**
|
||||
* Label / value mapping for object keys
|
||||
*
|
||||
* Keys can be callables in this object
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $keys = array(
|
||||
'buildAttempt' => 'Current Attempt',
|
||||
'buildCheckType' => 'Check Type',
|
||||
'buildLatency' => 'Check Latency / Duration',
|
||||
'buildLastStateChange' => 'Last State Change',
|
||||
'buildLastNotification' => 'Last Notification',
|
||||
'buildFlapping' => 'Is This %s Flapping?',
|
||||
'buildScheduledDowntime' => 'In Scheduled Downtime?',
|
||||
'status_update_time' => 'Last Update'
|
||||
);
|
||||
|
||||
private static $notificationReasons = array(
|
||||
0 => 'NORMAL',
|
||||
1 => 'ACKNOWLEDGEMENT',
|
||||
2 => 'FLAPPING START',
|
||||
3 => 'FLAPPING STOP',
|
||||
4 => 'FLAPPING DISABLED',
|
||||
5 => 'DOWNTIME START',
|
||||
6 => 'DOWNTIME END',
|
||||
7 => 'DOWNTIME CANCELLED',
|
||||
8 => 'CUSTOM',
|
||||
9 => 'STALKING'
|
||||
);
|
||||
|
||||
/**
|
||||
* Return the object type
|
||||
* @param stdClass $object
|
||||
* @return mixed
|
||||
*/
|
||||
private function getObjectType($object)
|
||||
{
|
||||
$keys = array_keys(get_object_vars($object));
|
||||
$keyParts = explode('_', array_shift($keys), 2);
|
||||
return array_shift($keyParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop all object specific attribute prefixes
|
||||
* @param stdClass $object
|
||||
* @param $type
|
||||
* @return object
|
||||
*/
|
||||
private function dropObjectType($object, $type)
|
||||
{
|
||||
$vars = get_object_vars($object);
|
||||
$out = array();
|
||||
foreach ($vars as $name => $value) {
|
||||
$name = str_replace($type. '_', '', $name);
|
||||
$out[$name] = $value;
|
||||
}
|
||||
return (object)$out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string for attempt
|
||||
* @param stdClass $object
|
||||
* @return string
|
||||
*/
|
||||
private function buildAttempt($object)
|
||||
{
|
||||
return sprintf(
|
||||
'%s/%s (%s state)',
|
||||
$object->current_check_attempt,
|
||||
$object->max_check_attempts,
|
||||
($object->state_type === '1') ? 'HARD' : 'SOFT'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic fomatter for float values
|
||||
* @param $value
|
||||
* @return string
|
||||
*/
|
||||
private function floatFormatter($value)
|
||||
{
|
||||
return sprintf('%.4f', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string for check type
|
||||
* @param stdClass $object
|
||||
* @return string
|
||||
*/
|
||||
private function buildCheckType($object)
|
||||
{
|
||||
if ($object->passive_checks_enabled === '1' && $object->active_checks_enabled === '0') {
|
||||
return self::CHECK_PASSIVE;
|
||||
} elseif ($object->passive_checks_enabled === '0' && $object->active_checks_enabled === '0') {
|
||||
return self::CHECK_DISABLED;
|
||||
}
|
||||
|
||||
return self::CHECK_ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string for latency
|
||||
* @param stdClass $object
|
||||
* @return string
|
||||
*/
|
||||
private function buildLatency($object)
|
||||
{
|
||||
$val = '';
|
||||
if ($this->buildCheckType($object) === self::CHECK_PASSIVE) {
|
||||
$val .= self::VALUE_NA;
|
||||
} else {
|
||||
$val .= $this->floatFormatter(
|
||||
(isset($object->check_latency)) ? $object->check_latency : 0
|
||||
);
|
||||
}
|
||||
|
||||
$val .= ' / '. $this->floatFormatter(
|
||||
isset($object->check_execution_time) ? $object->check_execution_time : 0
|
||||
). ' seconds';
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string for next check
|
||||
* @param stdClass $object
|
||||
* @return string
|
||||
*/
|
||||
private function buildNextCheck($object)
|
||||
{
|
||||
if ($this->buildCheckType($object) === self::CHECK_PASSIVE) {
|
||||
return self::VALUE_NA;
|
||||
} else {
|
||||
return $object->next_check;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get date for last state change
|
||||
* @param stdClass $object
|
||||
* @return string
|
||||
*/
|
||||
private function buildLastStateChange($object)
|
||||
{
|
||||
return strftime('%Y-%m-%d %H:%M:%S', $object->last_state_change);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string for "last notification"
|
||||
* @param stdClass $object
|
||||
* @return string
|
||||
*/
|
||||
private function buildLastNotification($object)
|
||||
{
|
||||
$val = '';
|
||||
|
||||
if ($object->last_notification === '0000-00-00 00:00:00') {
|
||||
$val .= self::VALUE_NA;
|
||||
} else {
|
||||
$val .= $object->last_notification;
|
||||
}
|
||||
|
||||
$val .= sprintf(' (notification %d)', $object->current_notification_number);
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string for "is flapping"
|
||||
* @param stdClass $object
|
||||
* @return string
|
||||
*/
|
||||
private function buildFlapping($object)
|
||||
{
|
||||
$val = '';
|
||||
|
||||
if ($object->is_flapping === '0') {
|
||||
$val .= self::VALUE_NO;
|
||||
} else {
|
||||
$val .= self::VALUE_YES;
|
||||
}
|
||||
|
||||
$val .= sprintf(' (%.2f%% state change)', $object->percent_state_change);
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string for scheduled downtime
|
||||
* @param stdClass $object
|
||||
* @return string
|
||||
*/
|
||||
private function buildScheduledDowntime($object)
|
||||
{
|
||||
if ($object->in_downtime === '1') {
|
||||
return self::VALUE_YES;
|
||||
}
|
||||
|
||||
return self::VALUE_NO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array which represent monitoring properties
|
||||
*
|
||||
* @param stdClass $object
|
||||
* @return array
|
||||
*/
|
||||
public function monitoringProperties($object)
|
||||
{
|
||||
$type = $this->getObjectType($object);
|
||||
//$object = $this->dropObjectType($object, $type);
|
||||
|
||||
$out = array();
|
||||
foreach (self::$keys as $property => $label) {
|
||||
$label = sprintf($label, ucfirst($type));
|
||||
if (is_callable(array(&$this, $property))) {
|
||||
$out[$label] = $this->$property($object);
|
||||
} elseif (isset($object->{$property})) {
|
||||
$out[$label] = $object->{$property};
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function getNotificationType($notification)
|
||||
{
|
||||
$reason = intval($notification->notification_reason);
|
||||
if (!isset(self::$notificationReasons[$reason])) {
|
||||
return 'N/A';
|
||||
}
|
||||
$type = self::$notificationReasons[$reason];
|
||||
if ($reason === 8) {
|
||||
if (intval($notification->notification_type) === 0) {
|
||||
$type .= '(UP)';
|
||||
} else {
|
||||
$type .= '(OK)';
|
||||
}
|
||||
}
|
||||
return $type;
|
||||
}
|
||||
}
|
|
@ -22,73 +22,72 @@ $this->provideConfigTab('security', array(
|
|||
/*
|
||||
* Problems Section
|
||||
*/
|
||||
$section = $this->menuSection('problems', $this->translate('Problems'), array(
|
||||
$section = $this->menuSection($this->translate('Problems'), array(
|
||||
'icon' => 'img/icons/error.png',
|
||||
'priority' => 20
|
||||
));
|
||||
$section->add('unhandled hosts', $this->translate('Unhandled Hosts'), array(
|
||||
$section->add($this->translate('Unhandled Hosts'), array(
|
||||
'url' => 'monitoring/list/hosts?host_problem=1&host_handled=0',
|
||||
'priority' => 40
|
||||
));
|
||||
$section->add('unhandled services', $this->translate('Unhandled Services'), array(
|
||||
$section->add($this->translate('Unhandled Services'), array(
|
||||
'url' => 'monitoring/list/services?service_problem=1&service_handled=0&sort=service_severity',
|
||||
'priority' => 40
|
||||
));
|
||||
$section->add('host problems', $this->translate('Host Problems'), array(
|
||||
$section->add($this->translate('Host Problems'), array(
|
||||
'url' => 'monitoring/list/hosts?host_problem=1&sort=host_severity',
|
||||
'priority' => 50
|
||||
));
|
||||
$section->add('service prolems', $this->translate('Service Problems'), array(
|
||||
$section->add($this->translate('Service Problems'), array(
|
||||
'url' => 'monitoring/list/services?service_problem=1&sort=service_severity&dir=desc',
|
||||
'priority' => 50
|
||||
));
|
||||
$section->add('current downtimes', $this->translate('Current Downtimes'))
|
||||
->setUrl('monitoring/list/downtimes?downtime_is_in_effect=1');
|
||||
$section->add($this->translate('Current Downtimes'))->setUrl('monitoring/list/downtimes?downtime_is_in_effect=1');
|
||||
|
||||
/*
|
||||
* Overview Section
|
||||
*/
|
||||
$section = $this->menuSection('overview', $this->translate('Overview'), array(
|
||||
$section = $this->menuSection($this->translate('Overview'), array(
|
||||
'icon' => 'img/icons/hostgroup.png',
|
||||
'priority' => 30
|
||||
));
|
||||
$section->add('tactical overview', $this->translate('Tactical Overview'), array(
|
||||
$section->add($this->translate('Tactical Overview'), array(
|
||||
'url' => 'monitoring/tactical',
|
||||
'priority' => 40
|
||||
));
|
||||
$section->add('hosts', $this->translate('Hosts'), array(
|
||||
$section->add($this->translate('Hosts'), array(
|
||||
'url' => 'monitoring/list/hosts',
|
||||
'priority' => 50
|
||||
));
|
||||
$section->add('services', $this->translate('Services'), array(
|
||||
$section->add($this->translate('Services'), array(
|
||||
'url' => 'monitoring/list/services',
|
||||
'priority' => 50
|
||||
));
|
||||
$section->add('servicematrix', $this->translate('Servicematrix'), array(
|
||||
$section->add($this->translate('Servicematrix'), array(
|
||||
'url' => 'monitoring/list/servicematrix?service_problem=1',
|
||||
'priority' => 51
|
||||
));
|
||||
$section->add('servicegroups', $this->translate('Servicegroups'), array(
|
||||
$section->add($this->translate('Servicegroups'), array(
|
||||
'url' => 'monitoring/list/servicegroups',
|
||||
'priority' => 60
|
||||
));
|
||||
$section->add('hostgroups', $this->translate('Hostgroups'), array(
|
||||
$section->add($this->translate('Hostgroups'), array(
|
||||
'url' => 'monitoring/list/hostgroups',
|
||||
'priority' => 60
|
||||
));
|
||||
$section->add('contactgroups', $this->translate('Contactgroups'), array(
|
||||
$section->add($this->translate('Contactgroups'), array(
|
||||
'url' => 'monitoring/list/contactgroups',
|
||||
'priority' => 61
|
||||
));
|
||||
$section->add('downtimes', $this->translate('Downtimes'), array(
|
||||
$section->add($this->translate('Downtimes'), array(
|
||||
'url' => 'monitoring/list/downtimes',
|
||||
'priority' => 71
|
||||
));
|
||||
$section->add('comments', $this->translate('Comments'), array(
|
||||
$section->add($this->translate('Comments'), array(
|
||||
'url' => 'monitoring/list/comments?comment_type=(comment|ack)',
|
||||
'priority' => 70
|
||||
));
|
||||
$section->add('contacts', $this->translate('Contacts'), array(
|
||||
$section->add($this->translate('Contacts'), array(
|
||||
'url' => 'monitoring/list/contacts',
|
||||
'priority' => 70
|
||||
));
|
||||
|
@ -96,33 +95,31 @@ $section->add('contacts', $this->translate('Contacts'), array(
|
|||
/*
|
||||
* History Section
|
||||
*/
|
||||
$section = $this->menuSection('history', $this->translate('History'), array(
|
||||
'title' => $this->translate('History'),
|
||||
$section = $this->menuSection($this->translate('History'), array(
|
||||
'icon' => 'img/icons/history.png'
|
||||
));
|
||||
$section->add('critical events', $this->translate('Critical Events'), array(
|
||||
'title' => $this->translate('Critical Events'),
|
||||
$section->add($this->translate('Critical Events'), array(
|
||||
'url' => 'monitoring/list/statehistorysummary',
|
||||
'priority' => 50
|
||||
));
|
||||
$section->add('notifications', $this->translate('Notifications'), array(
|
||||
$section->add($this->translate('Notifications'), array(
|
||||
'url' => 'monitoring/list/notifications'
|
||||
));
|
||||
$section->add('events', $this->translate('Events'), array(
|
||||
$section->add($this->translate('Events'), array(
|
||||
'title' => $this->translate('All Events'),
|
||||
'url' => 'monitoring/list/eventhistory?timestamp>=-7%20days'
|
||||
));
|
||||
$section->add('timeline', $this->translate('Timeline'))->setUrl('monitoring/timeline');
|
||||
$section->add($this->translate('Timeline'))->setUrl('monitoring/timeline');
|
||||
|
||||
/*
|
||||
* System Section
|
||||
*/
|
||||
$section = $this->menuSection('system', $this->translate('System'));
|
||||
$section->add('process info', $this->translate('Process Info'), array(
|
||||
$section = $this->menuSection($this->translate('System'));
|
||||
$section->add($this->translate('Process Info'), array(
|
||||
'url' => 'monitoring/process/info',
|
||||
'priority' => 120
|
||||
));
|
||||
$section->add('performance info', $this->translate('Performance Info'), array(
|
||||
$section->add($this->translate('Performance Info'), array(
|
||||
'url' => 'monitoring/process/performance',
|
||||
'priority' => 130
|
||||
));
|
||||
|
@ -130,19 +127,16 @@ $section->add('performance info', $this->translate('Performance Info'), array(
|
|||
/*
|
||||
* Dashboard
|
||||
*/
|
||||
$dashboard = $this->dashboard('current incidents')->setTitle($this->translate('Current Incidents'));
|
||||
$dashboard = $this->dashboard($this->translate('Current Incidents'));
|
||||
$dashboard->add(
|
||||
'service problems',
|
||||
$this->translate('Service Problems'),
|
||||
'monitoring/list/services?service_problem=1&limit=10&sort=service_severity'
|
||||
);
|
||||
$dashboard->add(
|
||||
'recently recovered services',
|
||||
$this->translate('Recently Recovered Services'),
|
||||
'monitoring/list/services?service_state=0&limit=10&sort=service_last_state_change&dir=desc'
|
||||
);
|
||||
$dashboard->add(
|
||||
'host problems',
|
||||
$this->translate('Host Problems'),
|
||||
'monitoring/list/hosts?host_problem=1&sort=host_severity'
|
||||
);
|
||||
|
|
|
@ -69,33 +69,31 @@ class Backend implements Selectable, Queryable, ConnectionInterface
|
|||
*/
|
||||
public static function createBackend($backendName = null)
|
||||
{
|
||||
$allBackends = array();
|
||||
$defaultBackend = null;
|
||||
foreach (IcingaConfig::module('monitoring', 'backends') as $name => $config) {
|
||||
if (!(bool) $config->get('disabled', false) && $defaultBackend === null) {
|
||||
$defaultBackend = $config;
|
||||
}
|
||||
$allBackends[$name] = $config;
|
||||
$config = IcingaConfig::module('monitoring', 'backends');
|
||||
if ($config->count() === 0) {
|
||||
throw new ConfigurationError(t('No backend has been configured'));
|
||||
}
|
||||
if (empty($allBackends)) {
|
||||
throw new ConfigurationError('No backend has been configured');
|
||||
}
|
||||
if ($defaultBackend === null) {
|
||||
throw new ConfigurationError('All backends are disabled');
|
||||
}
|
||||
if ($backendName === null) {
|
||||
$backendConfig = $defaultBackend;
|
||||
} else {
|
||||
if (!array_key_exists($backendName, $allBackends)) {
|
||||
if ($backendName !== null) {
|
||||
$backendConfig = $config->get($backendName);
|
||||
if ($backendConfig === null) {
|
||||
throw new ConfigurationError('No configuration for backend %s', $backendName);
|
||||
}
|
||||
$backendConfig = $allBackends[$backendName];
|
||||
if ((bool) $backendConfig->get('disabled', false)) {
|
||||
if ((bool) $backendConfig->get('disabled', false) === true) {
|
||||
throw new ConfigurationError(
|
||||
'Configuration for backend %s available but backend is disabled',
|
||||
t('Configuration for backend %s available but backend is disabled'),
|
||||
$backendName
|
||||
);
|
||||
}
|
||||
} else {
|
||||
foreach ($config as $name => $backendConfig) {
|
||||
if ((bool) $backendConfig->get('disabled', false) === false) {
|
||||
$backendName = $name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($backendName === null) {
|
||||
throw new ConfigurationError(t('All backends are disabled'));
|
||||
}
|
||||
}
|
||||
$resource = ResourceFactory::create($backendConfig->resource);
|
||||
if ($backendConfig->type === 'ido' && $resource->getDbType() !== 'oracle') {
|
||||
|
|
|
@ -51,10 +51,12 @@ class CommandQuery extends IdoQuery
|
|||
{
|
||||
$this->select->join(
|
||||
array('cnc' => $this->prefix . 'contact_notificationcommands'),
|
||||
'cnc.command_object_id = co.object_id'
|
||||
'cnc.command_object_id = co.object_id',
|
||||
array()
|
||||
)->join(
|
||||
array('con' => $this->prefix . 'contacts'),
|
||||
'con.contact_id = cnc.contact_id'
|
||||
'con.contact_id = cnc.contact_id',
|
||||
array()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -45,7 +45,7 @@ class CommentdeletionhistoryQuery extends IdoQuery
|
|||
array()
|
||||
)->join(
|
||||
array('h' => $this->prefix . 'commenthistory'),
|
||||
'o.' . $this->object_id . ' = h.' . $this->object_id . " AND o.is_active = 1 AND h.deletion_time > '1970-01-01 00:00:00' AND h.entry_type <> 2",
|
||||
'o.' . $this->object_id . ' = h.' . $this->object_id . " AND o.is_active = 1 AND h.deletion_time > '1970-01-02 00:00:00' AND h.entry_type <> 2",
|
||||
array()
|
||||
);
|
||||
$this->joinedVirtualTables = array('commenthistory' => true);
|
||||
|
|
|
@ -23,8 +23,8 @@ class DowntimeQuery extends IdoQuery
|
|||
'downtime_triggered_by_id' => 'sd.triggered_by_id',
|
||||
'downtime_scheduled_start' => 'UNIX_TIMESTAMP(sd.scheduled_start_time)',
|
||||
'downtime_scheduled_end' => 'UNIX_TIMESTAMP(sd.scheduled_end_time)',
|
||||
'downtime_start' => "UNIX_TIMESTAMP(CASE WHEN sd.trigger_time != '0000-00-00 00:00:00' then sd.trigger_time ELSE sd.scheduled_start_time END)",
|
||||
'downtime_end' => 'CASE WHEN sd.is_fixed THEN UNIX_TIMESTAMP(sd.scheduled_end_time) ELSE UNIX_TIMESTAMP(sd.trigger_time) + sd.duration END',
|
||||
'downtime_start' => "UNIX_TIMESTAMP(CASE WHEN UNIX_TIMESTAMP(sd.trigger_time) > 0 then sd.trigger_time ELSE sd.scheduled_start_time END)",
|
||||
'downtime_end' => 'CASE WHEN sd.is_fixed > 0 THEN UNIX_TIMESTAMP(sd.scheduled_end_time) ELSE UNIX_TIMESTAMP(sd.trigger_time) + sd.duration END',
|
||||
'downtime_duration' => 'sd.duration',
|
||||
'downtime_is_in_effect' => 'sd.is_in_effect',
|
||||
'downtime_internal_id' => 'sd.internal_downtime_id',
|
||||
|
|
|
@ -47,7 +47,7 @@ class DowntimeendhistoryQuery extends IdoQuery
|
|||
array('h' => $this->prefix . 'downtimehistory'),
|
||||
'o.' . $this->object_id . ' = h.' . $this->object_id . ' AND o.is_active = 1',
|
||||
array()
|
||||
)->where('h.actual_end_time > ?', '1970-01-01 00:00:00');
|
||||
)->where('h.actual_end_time > ?', '1970-01-02 00:00:00');
|
||||
$this->joinedVirtualTables = array('downtimehistory' => true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ class DowntimestarthistoryQuery extends IdoQuery
|
|||
array('h' => $this->prefix . 'downtimehistory'),
|
||||
'o.' . $this->object_id . ' = h.' . $this->object_id . ' AND o.is_active = 1',
|
||||
array()
|
||||
)->where('h.actual_start_time > ?', '1970-01-01 00:00:00');
|
||||
)->where('h.actual_start_time > ?', '1970-01-02 00:00:00');
|
||||
$this->joinedVirtualTables = array('downtimehistory' => true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
||||
|
||||
use Icinga\Logger\Logger;
|
||||
use Zend_Db_Select;
|
||||
|
||||
class GroupSummaryQuery extends IdoQuery
|
||||
|
@ -69,8 +70,15 @@ class GroupSummaryQuery extends IdoQuery
|
|||
)
|
||||
);
|
||||
|
||||
$groupColumn = 'hostgroup';
|
||||
|
||||
if (in_array('servicegroup', $this->desiredColumns)) {
|
||||
$groupColumn = 'servicegroup';
|
||||
}
|
||||
|
||||
$union = $this->db->select()->union(array($hosts, $services), Zend_Db_Select::SQL_UNION_ALL);
|
||||
$this->select->from(array('statussummary' => $union), '*')->group($columns[0]);
|
||||
$this->select->from(array('statussummary' => $union), array($groupColumn))->group(array($groupColumn));
|
||||
|
||||
$this->joinedVirtualTables = array(
|
||||
'servicestatussummary' => true,
|
||||
'hoststatussummary' => true
|
||||
|
|
|
@ -85,7 +85,8 @@ class NotificationhistoryQuery extends IdoQuery
|
|||
$this->select->group('n.object_id')
|
||||
->group('n.start_time')
|
||||
->group('n.output')
|
||||
->group('n.state');
|
||||
->group('n.state')
|
||||
->group('o.objecttype_id');
|
||||
}
|
||||
|
||||
$this->joinedVirtualTables = array('history' => true);
|
||||
|
|
|
@ -41,7 +41,7 @@ class StatusQuery extends IdoQuery
|
|||
'host_next_check' => 'CASE hs.should_be_scheduled WHEN 1 THEN UNIX_TIMESTAMP(hs.next_check) ELSE NULL END',
|
||||
'host_check_execution_time' => 'hs.execution_time',
|
||||
'host_check_latency' => 'hs.latency',
|
||||
'host_problem' => 'CASE WHEN hs.current_state = 0 THEN 0 ELSE 1 END',
|
||||
'host_problem' => 'CASE WHEN COALESCE(hs.current_state, 0) = 0 THEN 0 ELSE 1 END',
|
||||
|
||||
'host_notifications_enabled' => 'hs.notifications_enabled',
|
||||
|
||||
|
@ -278,20 +278,41 @@ class StatusQuery extends IdoQuery
|
|||
ELSE 0
|
||||
END'
|
||||
),
|
||||
|
||||
'serviceproblemsummary' => array(
|
||||
'host_unhandled_services' => 'sps.unhandled_services_count'
|
||||
),
|
||||
'lasthostcomment' => array(
|
||||
'host_last_comment' => 'hlc.last_comment_data',
|
||||
'host_last_downtime' => 'hlc.last_downtime_data',
|
||||
'host_last_flapping' => 'hlc.last_flapping_data',
|
||||
'host_last_ack' => 'hlc.last_ack_data',
|
||||
|
||||
'lasthostcommentgeneric' => array(
|
||||
'host_last_comment' => 'hlcg.last_comment_data'
|
||||
),
|
||||
'lastservicecomment' => array(
|
||||
'service_last_comment' => 'slc.last_comment_data',
|
||||
'service_last_downtime' => 'slc.last_downtime_data',
|
||||
'service_last_flapping' => 'slc.last_flapping_data',
|
||||
'service_last_ack' => 'slc.last_ack_data',
|
||||
|
||||
'lasthostcommentdowntime' => array(
|
||||
'host_last_downtime' => 'hlcd.last_downtime_data'
|
||||
),
|
||||
|
||||
'lasthostcommentflapping' => array(
|
||||
'host_last_flapping' => 'hlcf.last_flapping_data'
|
||||
),
|
||||
|
||||
'lasthostcommentack' => array(
|
||||
'host_last_ack' => 'hlca.last_ack_data'
|
||||
),
|
||||
|
||||
'lastservicecommentgeneric' => array(
|
||||
'service_last_comment' => 'slcg.last_comment_data'
|
||||
),
|
||||
|
||||
'lastservicecommentdowntime' => array(
|
||||
'service_last_downtime' => 'slcd.last_downtime_data'
|
||||
),
|
||||
|
||||
'lastservicecommentflapping' => array(
|
||||
'service_last_flapping' => 'slcf.last_flapping_data'
|
||||
),
|
||||
|
||||
'lastservicecommentack' => array(
|
||||
'service_last_ack' => 'slca.last_ack_data'
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -483,41 +504,117 @@ class StatusQuery extends IdoQuery
|
|||
);
|
||||
}
|
||||
|
||||
protected function getLastCommentSubQuery()
|
||||
/**
|
||||
* Create a subquery to join comments into status query
|
||||
* @param int $entryType
|
||||
* @param string $fieldName
|
||||
* @return Zend_Db_Expr
|
||||
*/
|
||||
protected function getLastCommentSubQuery($entryType, $fieldName)
|
||||
{
|
||||
$sub = '(SELECT'
|
||||
. ' lc.object_id,'
|
||||
. " CASE WHEN lc.entry_type = 1 THEN CONCAT('[' || c.author_name || '] ' || c.comment_data) ELSE NULL END AS last_comment_data,"
|
||||
. " CASE WHEN lc.entry_type = 2 THEN CONCAT('[' || c.author_name || '] ' || c.comment_data) ELSE NULL END AS last_downtime_data,"
|
||||
. " CASE WHEN lc.entry_type = 3 THEN CONCAT('[' || c.author_name || '] ' || c.comment_data) ELSE NULL END AS last_flapping_data,"
|
||||
. " CASE WHEN lc.entry_type = 4 THEN CONCAT('[' || c.author_name || '] ' || c.comment_data) ELSE NULL END AS last_ack_data"
|
||||
. ' FROM icinga_comments c'
|
||||
. ' JOIN (SELECT'
|
||||
. ' MAX(comment_id) as comment_id,'
|
||||
. ' object_id,'
|
||||
. ' entry_type'
|
||||
. ' FROM icinga_comments'
|
||||
. ' WHERE entry_type = 1 OR entry_type = 4'
|
||||
. ' GROUP BY object_id, entry_type'
|
||||
. ') lc ON lc.comment_id = c.comment_id GROUP BY lc.object_id)';
|
||||
. ' c.object_id,'
|
||||
. " '[' || c.author_name || '] ' || c.comment_data AS $fieldName"
|
||||
. ' FROM icinga_comments c JOIN ('
|
||||
. ' SELECT MAX(comment_id) AS comment_id, object_id FROM icinga_comments'
|
||||
. ' WHERE entry_type = ' . $entryType . ' GROUP BY object_id'
|
||||
. ' ) lc ON c.comment_id = lc.comment_id)';
|
||||
|
||||
return new Zend_Db_Expr($sub);
|
||||
}
|
||||
|
||||
protected function joinLasthostcomment()
|
||||
/**
|
||||
* Join last host comment
|
||||
*/
|
||||
protected function joinLasthostcommentgeneric()
|
||||
{
|
||||
$this->select->joinLeft(
|
||||
array('hlc' => $this->getLastCommentSubQuery()),
|
||||
'hlc.object_id = hs.host_object_id',
|
||||
array('hlcg' => $this->getLastCommentSubQuery(1, 'last_comment_data')),
|
||||
'hlcg.object_id = hs.host_object_id',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: Terribly slow. As I have no idea of how to fix this we should remove it.
|
||||
protected function joinLastservicecomment()
|
||||
/**
|
||||
* Join last host downtime comment
|
||||
*/
|
||||
protected function joinLasthostcommentdowntime()
|
||||
{
|
||||
$this->select->joinLeft(
|
||||
array('slc' => $this->getLastCommentSubQuery()),
|
||||
'slc.object_id = ss.service_object_id',
|
||||
array('hlcd' => $this->getLastCommentSubQuery(2, 'last_downtime_data')),
|
||||
'hlcg.object_id = hs.host_object_id',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Join last host flapping comment
|
||||
*/
|
||||
protected function joinLastHostcommentflapping()
|
||||
{
|
||||
$this->select->joinLeft(
|
||||
array('hlcf' => $this->getLastCommentSubQuery(3, 'last_flapping_data')),
|
||||
'hlcg.object_id = hs.host_object_id',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Join last host acknowledgement comment
|
||||
*/
|
||||
protected function joinLasthostcommentack()
|
||||
{
|
||||
$this->select->joinLeft(
|
||||
array('hlca' => $this->getLastCommentSubQuery(4, 'last_ack_data')),
|
||||
'hlca.object_id = hs.host_object_id',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Join last service comment
|
||||
*/
|
||||
protected function joinLastservicecommentgeneric()
|
||||
{
|
||||
$this->select->joinLeft(
|
||||
array('slcg' => $this->getLastCommentSubQuery(1, 'last_comment_data')),
|
||||
'slcg.object_id = ss.service_object_id',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Join last service downtime comment
|
||||
*/
|
||||
protected function joinLastservicecommentdowntime()
|
||||
{
|
||||
$this->select->joinLeft(
|
||||
array('slcd' => $this->getLastCommentSubQuery(2, 'last_downtime_data')),
|
||||
'slcd.object_id = ss.service_object_id',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Join last service flapping comment
|
||||
*/
|
||||
protected function joinLastservicecommentflapping()
|
||||
{
|
||||
$this->select->joinLeft(
|
||||
array('slcf' => $this->getLastCommentSubQuery(3, 'last_flapping_data')),
|
||||
'slcf.object_id = ss.service_object_id',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Join last service acknowledgement comment
|
||||
*/
|
||||
protected function joinLastservicecommentack()
|
||||
{
|
||||
$this->select->joinLeft(
|
||||
array('slca' => $this->getLastCommentSubQuery(4, 'last_ack_data')),
|
||||
'slca.object_id = ss.service_object_id',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -33,23 +33,27 @@ class StatusSummaryQuery extends IdoQuery
|
|||
'hosts_flapping' => 'SUM(CASE WHEN object_type = \'host\' AND is_flapping = 1 THEN 1 ELSE 0 END)'
|
||||
),
|
||||
'servicestatussummary' => array(
|
||||
'services_total' => 'SUM(CASE WHEN object_type = \'service\' THEN 1 ELSE 0 END)',
|
||||
'services_problem' => 'SUM(CASE WHEN object_type = \'service\' AND state > 0 THEN 1 ELSE 0 END)',
|
||||
'services_problem_handled' => 'SUM(CASE WHEN object_type = \'service\' AND state > 0 AND (acknowledged + in_downtime + host_problem) > 0 THEN 1 ELSE 0 END)',
|
||||
'services_problem_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state > 0 AND (acknowledged + in_downtime + host_problem) = 0 THEN 1 ELSE 0 END)',
|
||||
'services_ok' => 'SUM(CASE WHEN object_type = \'service\' AND state = 0 THEN 1 ELSE 0 END)',
|
||||
'services_ok_not_checked' => 'SUM(CASE WHEN object_type = \'service\' AND state = 0 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)',
|
||||
'services_pending' => 'SUM(CASE WHEN object_type = \'service\' AND state = 99 THEN 1 ELSE 0 END)',
|
||||
'services_pending_not_checked' => 'SUM(CASE WHEN object_type = \'service\' AND state = 99 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)',
|
||||
'services_warning' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 THEN 1 ELSE 0 END)',
|
||||
'services_warning_handled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) > 0 THEN 1 ELSE 0 END)',
|
||||
'services_warning_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) = 0 THEN 1 ELSE 0 END)',
|
||||
'services_warning_handled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 AND (acknowledged + in_downtime + host_problem) > 0 THEN 1 ELSE 0 END)',
|
||||
'services_warning_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 AND (acknowledged + in_downtime + host_problem) = 0 THEN 1 ELSE 0 END)',
|
||||
'services_warning_passive' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 AND is_passive_checked = 1 THEN 1 ELSE 0 END)',
|
||||
'services_warning_not_checked' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)',
|
||||
'services_critical' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 THEN 1 ELSE 0 END)',
|
||||
'services_critical_handled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) > 0 THEN 1 ELSE 0 END)',
|
||||
'services_critical_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) = 0 THEN 1 ELSE 0 END)',
|
||||
'services_critical_handled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 AND (acknowledged + in_downtime + host_problem) > 0 THEN 1 ELSE 0 END)',
|
||||
'services_critical_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 AND (acknowledged + in_downtime + host_problem) = 0 THEN 1 ELSE 0 END)',
|
||||
'services_critical_passive' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 AND is_passive_checked = 1 THEN 1 ELSE 0 END)',
|
||||
'services_critical_not_checked' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)',
|
||||
'services_unknown' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 THEN 1 ELSE 0 END)',
|
||||
'services_unknown_handled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) > 0 THEN 1 ELSE 0 END)',
|
||||
'services_unknown_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) = 0 THEN 1 ELSE 0 END)',
|
||||
'services_unknown_handled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 AND (acknowledged + in_downtime + host_problem) > 0 THEN 1 ELSE 0 END)',
|
||||
'services_unknown_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 AND (acknowledged + in_downtime + host_problem) = 0 THEN 1 ELSE 0 END)',
|
||||
'services_unknown_passive' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 AND is_passive_checked = 1 THEN 1 ELSE 0 END)',
|
||||
'services_unknown_not_checked' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)',
|
||||
'services_active' => 'SUM(CASE WHEN object_type = \'service\' AND is_active_checked = 1 THEN 1 ELSE 0 END)',
|
||||
|
@ -131,6 +135,7 @@ class StatusSummaryQuery extends IdoQuery
|
|||
'acknowledged' => 'hs.problem_has_been_acknowledged',
|
||||
'in_downtime' => 'CASE WHEN (hs.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END',
|
||||
'host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END',
|
||||
'host_problem' => 'CASE WHEN COALESCE(hs.current_state, 0) = 0 THEN 0 ELSE 1 END',
|
||||
'is_passive_checked' => 'CASE WHEN hs.active_checks_enabled = 0 AND hs.passive_checks_enabled = 1 THEN 1 ELSE 0 END',
|
||||
'is_active_checked' => 'hs.active_checks_enabled',
|
||||
'is_processing_events' => 'hs.event_handler_enabled',
|
||||
|
@ -144,6 +149,7 @@ class StatusSummaryQuery extends IdoQuery
|
|||
'acknowledged' => 'ss.problem_has_been_acknowledged',
|
||||
'in_downtime' => 'CASE WHEN (ss.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END',
|
||||
'host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END',
|
||||
'host_problem' => 'CASE WHEN COALESCE(hs.current_state, 0) = 0 THEN 0 ELSE 1 END',
|
||||
'is_passive_checked' => 'CASE WHEN ss.active_checks_enabled = 0 AND ss.passive_checks_enabled = 1 THEN 1 ELSE 0 END',
|
||||
'is_active_checked' => 'ss.active_checks_enabled',
|
||||
'is_processing_events' => 'ss.event_handler_enabled',
|
||||
|
|
|
@ -31,6 +31,8 @@ abstract class DataView implements Browsable, Filterable, Sortable
|
|||
|
||||
protected $connection;
|
||||
|
||||
protected $isSorted = false;
|
||||
|
||||
/**
|
||||
* Create a new view
|
||||
*
|
||||
|
@ -99,6 +101,7 @@ public function dump()
|
|||
protected function applyUrlFilter($request = null)
|
||||
{
|
||||
$url = Url::fromRequest();
|
||||
|
||||
$limit = $url->shift('limit');
|
||||
$sort = $url->shift('sort');
|
||||
$dir = $url->shift('dir');
|
||||
|
@ -132,20 +135,19 @@ public function dump()
|
|||
}
|
||||
}
|
||||
|
||||
$order = isset($params['order']) ? $params['order'] : null;
|
||||
if ($order !== null) {
|
||||
if (strtolower($order) === 'desc') {
|
||||
$order = self::SORT_DESC;
|
||||
} else {
|
||||
$order = self::SORT_ASC;
|
||||
if (isset($params['sort'])) {
|
||||
|
||||
$order = isset($params['order']) ? $params['order'] : null;
|
||||
if ($order !== null) {
|
||||
if (strtolower($order) === 'desc') {
|
||||
$order = self::SORT_DESC;
|
||||
} else {
|
||||
$order = self::SORT_ASC;
|
||||
}
|
||||
}
|
||||
|
||||
$view->sort($params['sort'], $order);
|
||||
}
|
||||
|
||||
$view->sort(
|
||||
isset($params['sort']) ? $params['sort'] : null,
|
||||
$order
|
||||
);
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
|
@ -226,6 +228,7 @@ public function dump()
|
|||
foreach ($sortColumns['columns'] as $column) {
|
||||
$this->query->order($column, $order);
|
||||
}
|
||||
$this->isSorted = true;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
@ -285,6 +288,7 @@ public function dump()
|
|||
*/
|
||||
public function getQuery()
|
||||
{
|
||||
if (! $this->isSorted) { $this->sort(); }
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Test\Modules\Monitoring\Application\Views\Helpers;
|
||||
|
||||
use Zend_View_Helper_MonitoringProperties;
|
||||
use Icinga\Test\BaseTestCase;
|
||||
|
||||
require_once realpath(BaseTestCase::$moduleDir . '/monitoring/application/views/helpers/MonitoringProperties.php');
|
||||
|
||||
class HostStruct4Properties
|
||||
{
|
||||
public $host_name = 'localhost';
|
||||
public $host_address = '127.0.0.1';
|
||||
public $host_state = '1';
|
||||
public $host_handled = '1';
|
||||
public $in_downtime = '1';
|
||||
public $acknowledged = '1';
|
||||
public $check_command = 'check-host-alive';
|
||||
public $last_state_change = '1372937083';
|
||||
public $host_alias = 'localhost';
|
||||
public $output = 'DDD';
|
||||
public $long_output = '';
|
||||
public $perfdata = '';
|
||||
public $current_check_attempt = '1';
|
||||
public $max_check_attempts = '10';
|
||||
public $attempt = '1/10';
|
||||
public $last_check = '2013-07-04 11:24:42';
|
||||
public $next_check = '2013-07-04 11:29:43';
|
||||
public $heck_type = '1';
|
||||
public $last_hard_state_change = '2013-07-04 11:24:43';
|
||||
public $last_hard_state = '0';
|
||||
public $last_time_up = '2013-07-04 11:20:23';
|
||||
public $last_time_down = '2013-07-04 11:24:43';
|
||||
public $last_time_unreachable = '0000-00-00 00:00:00';
|
||||
public $state_type = '1';
|
||||
public $last_notification = '0000-00-00 00:00:00';
|
||||
public $next_notification = '0000-00-00 00:00:00';
|
||||
public $no_more_notifications = '0';
|
||||
public $host_notifications_enabled = '1';
|
||||
public $host_problem_has_been_acknowledged = '1';
|
||||
public $host_acknowledgement_type = '2';
|
||||
public $current_notification_number = '0';
|
||||
public $passive_checks_enabled = '1';
|
||||
public $active_checks_enabled = '0';
|
||||
public $event_handler_enabled = '0';
|
||||
public $flap_detection_enabled = '1';
|
||||
public $is_flapping = '0';
|
||||
public $percent_state_change = '12.36842';
|
||||
public $check_latency = '0.12041';
|
||||
public $check_execution_time = '0';
|
||||
public $scheduled_downtime_depth = '1';
|
||||
public $host_failure_prediction_enabled = '1';
|
||||
public $host_process_performance_data = '1';
|
||||
public $host_obsessing = '1';
|
||||
public $host_modified_host_attributes = '14';
|
||||
public $host_event_handler = '';
|
||||
public $host_normal_check_interval = '5';
|
||||
public $host_retry_check_interval = '1';
|
||||
public $host_check_timeperiod_object_id = '27';
|
||||
public $host_status_update_time = '2013-07-08 10:10:10';
|
||||
}
|
||||
|
||||
/**
|
||||
* @TODO(el): This test is subject to bug #4679
|
||||
*/
|
||||
class MonitoringPropertiesTest extends BaseTestCase
|
||||
{
|
||||
public function testOutput1()
|
||||
{
|
||||
$host = new HostStruct4Properties();
|
||||
$host->current_check_attempt = '5';
|
||||
|
||||
$propertyHelper = new Zend_View_Helper_MonitoringProperties();
|
||||
$items = $propertyHelper->monitoringProperties($host);
|
||||
|
||||
$this->assertEquals('5/10 (HARD state)', $items['Current Attempt']);
|
||||
}
|
||||
|
||||
public function testOutput2()
|
||||
{
|
||||
$host = new HostStruct4Properties();
|
||||
$host->current_check_attempt = '5';
|
||||
$host->active_checks_enabled = '1';
|
||||
$host->passive_checks_enabled = '0';
|
||||
$host->is_flapping = '1';
|
||||
|
||||
$propertyHelper = new Zend_View_Helper_MonitoringProperties();
|
||||
$items = $propertyHelper->monitoringProperties($host);
|
||||
|
||||
$test = array(
|
||||
'Current Attempt' => "5/10 (HARD state)",
|
||||
'Check Type' => "ACTIVE",
|
||||
'Check Latency / Duration' => "0.1204 / 0.0000 seconds",
|
||||
'Last State Change' => "2013-07-04 11:24:43",
|
||||
'Last Notification' => "N/A (notification 0)",
|
||||
'Is This Host Flapping?' => "YES (12.37% state change)",
|
||||
'In Scheduled Downtime?' => "YES"
|
||||
);
|
||||
|
||||
$this->assertEquals($test, $items);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Icinga\Module\Monitoring\Regression;
|
||||
|
||||
// Necessary as some of these tests disable phpunit's preservation
|
||||
// of the global state (e.g. autoloaders are in the global state)
|
||||
require_once realpath(dirname(__FILE__) . '/../../../../../test/php/bootstrap.php');
|
||||
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Module\Monitoring\Backend;
|
||||
use Icinga\Test\BaseTestCase;
|
||||
use Mockery;
|
||||
use Zend_Config;
|
||||
|
||||
class Bug7043Test extends BaseTestCase
|
||||
{
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
Mockery::close(); // Necessary because some tests run in a separate process
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
*/
|
||||
public function testBackendDefaultName()
|
||||
{
|
||||
Mockery::mock('alias:Icinga\Data\ResourceFactory')
|
||||
->shouldReceive('create')
|
||||
->andReturn(
|
||||
Mockery::mock('Icinga\Data\Db\DbConnection')
|
||||
->shouldReceive('getDbType')
|
||||
->andReturn('mysql')
|
||||
->shouldReceive('setTablePrefix')
|
||||
->getMock()
|
||||
);
|
||||
|
||||
Config::setModuleConfig('monitoring', 'backends', new Zend_Config(array(
|
||||
'backendName' => array(
|
||||
'type' => 'ido',
|
||||
'resource' => 'ido'
|
||||
)
|
||||
)));
|
||||
|
||||
$defaultBackend = Backend::createBackend();
|
||||
|
||||
$this->assertEquals('backendName', $defaultBackend->getName(), 'Default backend has name set');
|
||||
}
|
||||
}
|
|
@ -329,8 +329,7 @@
|
|||
this.icinga.ui.reloadCss();
|
||||
}
|
||||
|
||||
var redirect = req.getResponseHeader('X-Icinga-Redirect');
|
||||
if (this.processRedirectHeader(req)) return;
|
||||
if (req.getResponseHeader('X-Icinga-Redirect')) return;
|
||||
|
||||
// div helps getting an XML tree
|
||||
var $resp = $('<div>' + req.responseText + '</div>');
|
||||
|
@ -567,6 +566,7 @@
|
|||
delete this.requests[req.$target.attr('id')];
|
||||
this.icinga.ui.fadeNotificationsAway();
|
||||
|
||||
this.processRedirectHeader(req);
|
||||
|
||||
if (typeof req.loadNext !== 'undefined') {
|
||||
if ($('#col2').length) {
|
||||
|
@ -665,7 +665,11 @@
|
|||
var self = this;
|
||||
var containerId = $container.attr('id');
|
||||
if (typeof containerId !== 'undefined') {
|
||||
scrollPos = $container.scrollTop();
|
||||
if (autorefresh) {
|
||||
scrollPos = $container.scrollTop();
|
||||
} else {
|
||||
scrollPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var origFocus = document.activeElement;
|
||||
|
|
|
@ -26,10 +26,10 @@ class DbBackendFormTest extends BaseTestCase
|
|||
*/
|
||||
public function testValidBackendIsValid()
|
||||
{
|
||||
$this->setUpUserBackendMock()
|
||||
$this->setUpResourceFactoryMock();
|
||||
Mockery::mock('overload:Icinga\Authentication\Backend\DbUserBackend')
|
||||
->shouldReceive('count')
|
||||
->andReturn(2);
|
||||
$this->setUpResourceFactoryMock();
|
||||
|
||||
$form = new DbBackendForm();
|
||||
$form->setBackendName('test');
|
||||
|
@ -49,10 +49,10 @@ class DbBackendFormTest extends BaseTestCase
|
|||
*/
|
||||
public function testInvalidBackendIsNotValid()
|
||||
{
|
||||
$this->setUpUserBackendMock()
|
||||
$this->setUpResourceFactoryMock();
|
||||
Mockery::mock('overload:Icinga\Authentication\Backend\DbUserBackend')
|
||||
->shouldReceive('count')
|
||||
->andReturn(0);
|
||||
$this->setUpResourceFactoryMock();
|
||||
|
||||
$form = new DbBackendForm();
|
||||
$form->setBackendName('test');
|
||||
|
@ -66,18 +66,10 @@ class DbBackendFormTest extends BaseTestCase
|
|||
);
|
||||
}
|
||||
|
||||
protected function setUpUserBackendMock()
|
||||
{
|
||||
return Mockery::mock('overload:Icinga\Authentication\Backend\DbUserBackend');
|
||||
}
|
||||
|
||||
protected function setUpResourceFactoryMock()
|
||||
{
|
||||
Mockery::mock('alias:Icinga\Data\ResourceFactory')
|
||||
->shouldReceive('getResourceConfig')
|
||||
->andReturn(new \Zend_Config(array()))
|
||||
->shouldReceive('createResource')
|
||||
->with(Mockery::type('\Zend_Config'))
|
||||
->shouldReceive('create')
|
||||
->andReturn(Mockery::mock('Icinga\Data\Db\DbConnection'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ class FilterTest extends BaseTestCase
|
|||
|
||||
public function testComplexFilterFromQueryString()
|
||||
{
|
||||
$q = 'host=localhost|nohost*&problem&service=*www*|ups*&state!=1&!handled';
|
||||
$q = '(host=localhost|host=nohost*)&problem&(service=*www*|service=ups*)&state!=1&!handled';
|
||||
$filter = Filter::fromQueryString($q);
|
||||
$this->assertFalse($filter->matches($this->row(0)));
|
||||
$this->assertTrue($filter->matches($this->row(1)));
|
||||
|
|
|
@ -109,10 +109,10 @@ class QueryTest extends BaseTestCase
|
|||
$this->assertEquals('testIntColumn', $cols[0][0]);
|
||||
}
|
||||
|
||||
public function test__toString()
|
||||
public function testCreateQuery()
|
||||
{
|
||||
$select = $this->prepareSelect();
|
||||
$res = '(&(objectClass=dummyClass)(testIntColumn=1)(testStringColumn=test)(testWildcard=abc*))';
|
||||
$this->assertEquals($res, (string) $select);
|
||||
$this->assertEquals($res, $select->create());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ class TranslatorTest extends BaseTestCase
|
|||
public function testWhetherGetAvailableLocaleCodesReturnsAllAvailableLocaleCodes()
|
||||
{
|
||||
$this->assertEquals(
|
||||
array('de_DE', 'fr_FR'),
|
||||
array(Translator::DEFAULT_LOCALE, 'de_DE', 'fr_FR'),
|
||||
Translator::getAvailableLocaleCodes(),
|
||||
'Translator::getAvailableLocaleCodes does not return all available locale codes'
|
||||
);
|
||||
|
|
|
@ -0,0 +1,509 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Tests\Icinga\Web;
|
||||
|
||||
// Necessary as some of these tests disable phpunit's preservation
|
||||
// of the global state (e.g. autoloaders are in the global state)
|
||||
require_once realpath(dirname(__FILE__) . '/../../../../bootstrap.php');
|
||||
|
||||
use Mockery;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Web\Widget\Dashboard;
|
||||
use Icinga\Web\Widget\Dashboard\Pane;
|
||||
use Icinga\Web\Widget\Dashboard\Component;
|
||||
use Icinga\Test\BaseTestCase;
|
||||
|
||||
class ComponentWithMockedView extends Component
|
||||
{
|
||||
public function view()
|
||||
{
|
||||
$mock = Mockery::mock('Icinga\Web\View');
|
||||
$mock->shouldReceive('escape');
|
||||
|
||||
return $mock;
|
||||
}
|
||||
}
|
||||
|
||||
class DashboardWithPredefinableActiveName extends Dashboard
|
||||
{
|
||||
public $activeName = '';
|
||||
|
||||
public function getTabs()
|
||||
{
|
||||
return Mockery::mock('Icinga\Web\Widget\Tabs')
|
||||
->shouldReceive('getActiveName')->andReturn($this->activeName)
|
||||
->shouldReceive('activate')
|
||||
->getMock();
|
||||
}
|
||||
}
|
||||
|
||||
class DashboardTest extends BaseTestCase
|
||||
{
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
Mockery::close(); // Necessary because some tests run in a separate process
|
||||
}
|
||||
|
||||
protected function setupIcingaMock(\Zend_Controller_Request_Abstract $request)
|
||||
{
|
||||
$moduleMock = Mockery::mock('Icinga\Application\Modules\Module');
|
||||
$moduleMock->shouldReceive('getPaneItems')->andReturn(array(
|
||||
'test-pane' => new Pane('Test Pane')
|
||||
));
|
||||
|
||||
$moduleManagerMock = Mockery::mock('Icinga\Application\Modules\Manager');
|
||||
$moduleManagerMock->shouldReceive('getLoadedModules')->andReturn(array(
|
||||
'test-module' => $moduleMock
|
||||
));
|
||||
|
||||
$bootstrapMock = Mockery::mock('Icinga\Application\ApplicationBootstrap')->shouldDeferMissing();
|
||||
$bootstrapMock->shouldReceive('getFrontController->getRequest')->andReturnUsing(
|
||||
function () use ($request) { return $request; }
|
||||
)->shouldReceive('getApplicationDir')->andReturn(self::$appDir);
|
||||
|
||||
$bootstrapMock->shouldReceive('getModuleManager')->andReturn($moduleManagerMock);
|
||||
|
||||
Icinga::setApp($bootstrapMock, true);
|
||||
}
|
||||
|
||||
public function testWhetherCreatePaneCreatesAPane()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$pane = $dashboard->createPane('test')->getPane('test');
|
||||
|
||||
$this->assertEquals('test', $pane->getTitle(), 'Dashboard::createPane() could not create a pane');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherCreatePaneCreatesAPane
|
||||
*/
|
||||
public function testMergePanesWithDifferentPaneName()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1');
|
||||
$dashboard->createPane('test2');
|
||||
|
||||
$panes = array(
|
||||
new Pane('test1a'),
|
||||
new Pane('test2a')
|
||||
);
|
||||
|
||||
$dashboard->mergePanes($panes);
|
||||
|
||||
$this->assertCount(4, $dashboard->getPanes(), 'Dashboard::mergePanes() could not merge different panes');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherCreatePaneCreatesAPane
|
||||
*/
|
||||
public function testMergePanesWithSamePaneName()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1');
|
||||
$dashboard->createPane('test2');
|
||||
|
||||
$panes = array(
|
||||
new Pane('test1'),
|
||||
new Pane('test3')
|
||||
);
|
||||
|
||||
$dashboard->mergePanes($panes);
|
||||
|
||||
$this->assertCount(3, $dashboard->getPanes(), 'Dashboard::mergePanes() could not merge same panes');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherCreatePaneCreatesAPane
|
||||
*/
|
||||
public function testWhetherGetPaneReturnsAPaneByName()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1');
|
||||
|
||||
$pane = $dashboard->getPane('test1');
|
||||
|
||||
$this->assertEquals(
|
||||
'test1',
|
||||
$pane->getName(),
|
||||
'Dashboard:getPane() could not return pane by name'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherCreatePaneCreatesAPane
|
||||
*/
|
||||
public function testLoadPaneItemsProvidedByEnabledModules()
|
||||
{
|
||||
$dashboard = Dashboard::load();
|
||||
|
||||
$this->assertCount(
|
||||
1,
|
||||
$dashboard->getPanes(),
|
||||
'Dashboard::load() could not load panes from enabled modules'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Icinga\Exception\ProgrammingError
|
||||
* @depends testWhetherCreatePaneCreatesAPane
|
||||
*/
|
||||
public function testWhetherGetPaneThrowsAnExceptionOnNotExistentPaneName()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1');
|
||||
|
||||
$dashboard->getPane('test2');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherGetPaneReturnsAPaneByName
|
||||
*/
|
||||
public function testWhetherRenderNotRendersPanesDisabledComponent()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1');
|
||||
$pane = $dashboard->getPane('test1');
|
||||
$component = new ComponentWithMockedView('test', 'test', $pane);
|
||||
$component->setDisabled(true);
|
||||
$pane->addComponent($component);
|
||||
|
||||
$rendered = $dashboard->render();
|
||||
|
||||
$greaterThanOne = strlen($rendered) > 1;
|
||||
|
||||
$this->assertFalse(
|
||||
$greaterThanOne,
|
||||
'Dashboard::render() disabled component is rendered, but should not'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherGetPaneReturnsAPaneByName
|
||||
*/
|
||||
public function testWhetherRenderRendersPanesEnabledComponent()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1');
|
||||
$pane = $dashboard->getPane('test1');
|
||||
$component = new ComponentWithMockedView('test', 'test', $pane);
|
||||
$pane->addComponent($component);
|
||||
|
||||
$rendered = $dashboard->render();
|
||||
|
||||
$greaterThanOne = strlen($rendered) > 1;
|
||||
|
||||
$this->assertTrue(
|
||||
$greaterThanOne,
|
||||
'Dashboard::render() could not render enabled component'
|
||||
);
|
||||
}
|
||||
|
||||
public function testWhetherRenderNotRendersNotExistentPane()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
|
||||
$rendered = $dashboard->render();
|
||||
|
||||
$greaterThanOne = strlen($rendered) > 1;
|
||||
|
||||
$this->assertFalse(
|
||||
$greaterThanOne,
|
||||
'Dashboard::render() not existent pane ist rendered, but should not'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherGetPaneReturnsAPaneByName
|
||||
*/
|
||||
public function testWhetherGetPaneKeyTitleArrayReturnFormedArray()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1')->getPane('test1')->setTitle('Test1');
|
||||
$dashboard->createPane('test2')->getPane('test2')->setTitle('Test2');
|
||||
|
||||
$result = $dashboard->getPaneKeyTitleArray();
|
||||
|
||||
$expected = array(
|
||||
'test1' => 'Test1',
|
||||
'test2' => 'Test2'
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
$result,
|
||||
'Dashboard::getPaneKeyTitleArray() could not return valid expectation'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherCreatePaneCreatesAPane
|
||||
*/
|
||||
public function testWhetherHasPanesHasPanes()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1');
|
||||
$dashboard->createPane('test2');
|
||||
|
||||
$hasPanes = $dashboard->hasPanes();
|
||||
|
||||
$this->assertTrue($hasPanes, 'Dashboard::hasPanes() could not return valid expectation');
|
||||
}
|
||||
|
||||
public function testWhetherHasPanesHasNoPanes()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
|
||||
$hasPanes = $dashboard->hasPanes();
|
||||
|
||||
$this->assertFalse($hasPanes, 'Dashboard::hasPanes() has panes but should not');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherGetPaneReturnsAPaneByName
|
||||
*/
|
||||
public function testWhetherRemoveComponentRemovesComponent()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1');
|
||||
$pane = $dashboard->getPane('test1');
|
||||
|
||||
$component = new Component('test', 'test', $pane);
|
||||
$pane->addComponent($component);
|
||||
|
||||
$component2 = new Component('test2', 'test2', $pane);
|
||||
$pane->addComponent($component2);
|
||||
|
||||
$dashboard->removeComponent('test1', 'test');
|
||||
|
||||
$result = $dashboard->getPane('test1')->hasComponent('test');
|
||||
|
||||
$this->assertFalse(
|
||||
$result,
|
||||
'Dashboard::removeComponent() could not remove component from the pane'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherGetPaneReturnsAPaneByName
|
||||
*/
|
||||
public function testWhetherRemoveComponentRemovesComponentByConcatenation()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1');
|
||||
$pane = $dashboard->getPane('test1');
|
||||
|
||||
$component = new Component('test', 'test', $pane);
|
||||
$pane->addComponent($component);
|
||||
|
||||
$component2 = new Component('test2', 'test2', $pane);
|
||||
$pane->addComponent($component2);
|
||||
|
||||
$dashboard->removeComponent('test1.test', null);
|
||||
|
||||
$result = $dashboard->getPane('test1')->hasComponent('test');
|
||||
|
||||
$this->assertFalse(
|
||||
$result,
|
||||
'Dashboard::removeComponent() could not remove component from the pane'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherGetPaneReturnsAPaneByName
|
||||
*/
|
||||
public function testWhetherToArrayReturnsDashboardStructureAsArray()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1');
|
||||
$pane = $dashboard->getPane('test1');
|
||||
|
||||
$component = new Component('test', 'test', $pane);
|
||||
$pane->addComponent($component);
|
||||
|
||||
$result = $dashboard->toArray();
|
||||
|
||||
$expected = array(
|
||||
'test1' => array(
|
||||
'title' => 'test1'
|
||||
),
|
||||
'test1.test' => array(
|
||||
'url' => 'test'
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
$result,
|
||||
'Dashboard::toArray() could not return valid expectation'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherGetPaneReturnsAPaneByName
|
||||
*/
|
||||
public function testWhetherSetComponentUrlUpdatesTheComponentUrl()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1');
|
||||
$pane = $dashboard->getPane('test1');
|
||||
$component = new Component('test', 'test', $pane);
|
||||
$pane->addComponent($component);
|
||||
|
||||
$dashboard->setComponentUrl('test1', 'test', 'new');
|
||||
|
||||
$this->assertEquals(
|
||||
'new',
|
||||
$component->getUrl()->getPath(),
|
||||
'Dashboard::setComponentUrl() could not return valid expectation'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherGetPaneReturnsAPaneByName
|
||||
*/
|
||||
public function testWhetherSetComponentUrlUpdatesTheComponentUrlConcatenation()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1');
|
||||
$pane = $dashboard->getPane('test1');
|
||||
$component = new Component('test', 'test', $pane);
|
||||
$pane->addComponent($component);
|
||||
|
||||
$dashboard->setComponentUrl('test1.test', null, 'new');
|
||||
|
||||
$this->assertEquals(
|
||||
'new',
|
||||
$component->getUrl()->getPath(),
|
||||
'Dashboard::setComponentUrl() could not return valid expectation'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherGetPaneReturnsAPaneByName
|
||||
*/
|
||||
public function testWhetherSetComponentUrlUpdatesTheComponentUrlNotExistentPane()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->createPane('test1');
|
||||
$pane = $dashboard->getPane('test1');
|
||||
$component = new Component('test', 'test', $pane);
|
||||
$pane->addComponent($component);
|
||||
|
||||
$dashboard->setComponentUrl('test3.test', null, 'new');
|
||||
|
||||
$result = $dashboard->getPane('test3')->getComponent('test');
|
||||
|
||||
$this->assertEquals(
|
||||
'new',
|
||||
$result->getUrl()->getPath(),
|
||||
'Dashboard::setComponentUrl() could not return valid expectation'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Icinga\Exception\ConfigurationError
|
||||
*/
|
||||
public function testWhetherDetermineActivePaneThrowsAnExceptionIfCouldNotDetermine()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->determineActivePane();
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
* @expectedException \Icinga\Exception\ProgrammingError
|
||||
* @depends testWhetherCreatePaneCreatesAPane
|
||||
*/
|
||||
public function testWhetherDetermineActivePaneThrowsAnExceptionIfCouldNotDetermineInvalidPane()
|
||||
{
|
||||
$dashboard = new DashboardWithPredefinableActiveName();
|
||||
$dashboard->createPane('test1');
|
||||
|
||||
Mockery::mock('alias:Icinga\Web\Url')
|
||||
->shouldReceive('fromRequest->getParam')->andReturn('test2');
|
||||
|
||||
$dashboard->determineActivePane();
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherCreatePaneCreatesAPane
|
||||
*/
|
||||
public function testWhetherDetermineActivePaneDeterminesActivePane()
|
||||
{
|
||||
$dashboard = new DashboardWithPredefinableActiveName();
|
||||
$dashboard->activeName = 'test2';
|
||||
$dashboard->createPane('test1');
|
||||
$dashboard->createPane('test2');
|
||||
|
||||
$activePane = $dashboard->determineActivePane();
|
||||
|
||||
$this->assertEquals(
|
||||
'test2',
|
||||
$activePane->getTitle(),
|
||||
'Dashboard::determineActivePane() could not determine active pane'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
* @depends testWhetherCreatePaneCreatesAPane
|
||||
*/
|
||||
public function testWhetherDetermineActivePaneDeterminesActiveValidPane()
|
||||
{
|
||||
$dashboard = new DashboardWithPredefinableActiveName();
|
||||
$dashboard->createPane('test1');
|
||||
$dashboard->createPane('test2');
|
||||
|
||||
Mockery::mock('alias:Icinga\Web\Url')
|
||||
->shouldReceive('fromRequest->getParam')->andReturn('test2');
|
||||
|
||||
$activePane = $dashboard->determineActivePane();
|
||||
|
||||
$this->assertEquals(
|
||||
'test2',
|
||||
$activePane->getTitle(),
|
||||
'Dashboard::determineActivePane() could not determine active pane'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherCreatePaneCreatesAPane
|
||||
*/
|
||||
public function testWhetherGetActivePaneReturnsActivePane()
|
||||
{
|
||||
$dashboard = new DashboardWithPredefinableActiveName();
|
||||
$dashboard->activeName = 'test2';
|
||||
$dashboard->createPane('test1');
|
||||
$dashboard->createPane('test2');
|
||||
|
||||
$activePane = $dashboard->getActivePane();
|
||||
|
||||
$this->assertEquals(
|
||||
'test2',
|
||||
$activePane->getTitle(),
|
||||
'Dashboard::determineActivePane() could not get expected active pane'
|
||||
);
|
||||
}
|
||||
|
||||
public function testWhetherLoadConfigPanes()
|
||||
{
|
||||
$this->markTestIncomplete(
|
||||
'Dashboard::loadConfigPanes() is not fully implemented yet or rather not used'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherLoadConfigPanes
|
||||
*/
|
||||
public function testWhetherReadConfigPopulatesDashboard()
|
||||
{
|
||||
$this->markTestIncomplete(
|
||||
'Dashboard::readConfig() is not fully implemented yet or rather not used'
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue