Merge branch 'master' into feature/user-and-group-management-8826
This commit is contained in:
commit
524c449649
|
@ -128,8 +128,7 @@ class ConfigController extends Controller
|
|||
$this->view->modules = Icinga::app()->getModuleManager()->select()
|
||||
->from('modules')
|
||||
->order('enabled', 'desc')
|
||||
->order('name')
|
||||
->paginate();
|
||||
->order('name');
|
||||
$this->setupLimitControl();
|
||||
$this->setupPaginationControl($this->view->modules);
|
||||
// TODO: Not working
|
||||
|
|
|
@ -51,7 +51,7 @@ class ListController extends Controller
|
|||
. 'T[0-9]{2}(?::[0-9]{2}){2}(?:[\+\-][0-9]{2}:[0-9]{2})?)' // time
|
||||
. ' - (?<loglevel>[A-Za-z]+) - (?<message>.*)(?!.)/msS' // loglevel, message
|
||||
)));
|
||||
$this->view->logData = $resource->select()->order('DESC')->paginate();
|
||||
$this->view->logData = $resource->select()->order('DESC');
|
||||
|
||||
$this->setupLimitControl();
|
||||
$this->setupPaginationControl($this->view->logData);
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||
|
||||
namespace Icinga\Data;
|
||||
|
||||
/**
|
||||
* Interface for browsing data
|
||||
*/
|
||||
interface Browsable
|
||||
{
|
||||
/**
|
||||
* Paginate data
|
||||
*
|
||||
* @param int $itemsPerPage Number of items per page
|
||||
* @param int $pageNumber Current page number
|
||||
*
|
||||
* @return Zend_Paginator
|
||||
*/
|
||||
public function paginate($itemsPerPage = null, $pageNumber = null);
|
||||
}
|
|
@ -5,4 +5,4 @@ namespace Icinga\Data;
|
|||
|
||||
use Countable;
|
||||
|
||||
interface QueryInterface extends Browsable, Fetchable, Filterable, Limitable, Sortable, Countable {};
|
||||
interface QueryInterface extends Fetchable, Filterable, Limitable, Sortable, Countable {};
|
||||
|
|
|
@ -3,14 +3,12 @@
|
|||
|
||||
namespace Icinga\Data;
|
||||
|
||||
use Icinga\Application\Icinga;
|
||||
use ArrayIterator;
|
||||
use IteratorAggregate;
|
||||
use Icinga\Data\Filter\Filter;
|
||||
use Icinga\Web\Paginator\Adapter\QueryAdapter;
|
||||
use Zend_Paginator;
|
||||
use Exception;
|
||||
use Icinga\Exception\IcingaException;
|
||||
|
||||
class SimpleQuery implements QueryInterface, Queryable
|
||||
class SimpleQuery implements QueryInterface, Queryable, IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* Query data source
|
||||
|
@ -102,6 +100,16 @@ class SimpleQuery implements QueryInterface, Queryable
|
|||
*/
|
||||
protected function init() {}
|
||||
|
||||
/**
|
||||
* Return a iterable for this query's result
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->fetchAll());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data source
|
||||
*
|
||||
|
@ -343,35 +351,6 @@ class SimpleQuery implements QueryInterface, Queryable
|
|||
return $this->limitOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate data
|
||||
*
|
||||
* Auto-detects pagination parameters from request when unset
|
||||
*
|
||||
* @param int $itemsPerPage Number of items per page
|
||||
* @param int $pageNumber Current page number
|
||||
*
|
||||
* @return Zend_Paginator
|
||||
*/
|
||||
public function paginate($itemsPerPage = null, $pageNumber = null)
|
||||
{
|
||||
if ($itemsPerPage === null || $pageNumber === null) {
|
||||
// Detect parameters from request
|
||||
$request = Icinga::app()->getFrontController()->getRequest();
|
||||
if ($itemsPerPage === null) {
|
||||
$itemsPerPage = $request->getParam('limit', 25);
|
||||
}
|
||||
if ($pageNumber === null) {
|
||||
$pageNumber = $request->getParam('page', 0);
|
||||
}
|
||||
}
|
||||
$this->limit($itemsPerPage, $pageNumber * $itemsPerPage);
|
||||
$paginator = new Zend_Paginator(new QueryAdapter($this));
|
||||
$paginator->setItemCountPerPage($itemsPerPage);
|
||||
$paginator->setCurrentPageNumber($pageNumber);
|
||||
return $paginator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an array containing all rows of the result set
|
||||
*
|
||||
|
|
|
@ -3,15 +3,13 @@
|
|||
|
||||
namespace Icinga\File;
|
||||
|
||||
use Icinga\Data\Browsable;
|
||||
|
||||
class Csv
|
||||
{
|
||||
protected $query;
|
||||
|
||||
protected function __construct() {}
|
||||
|
||||
public static function fromQuery(Browsable $query)
|
||||
public static function fromQuery($query)
|
||||
{
|
||||
$csv = new Csv();
|
||||
$csv->query = $query;
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
namespace Icinga\Web;
|
||||
|
||||
use Zend_Paginator;
|
||||
use Icinga\Web\Controller\ModuleActionController;
|
||||
use Icinga\Web\Widget\SortBox;
|
||||
use Icinga\Web\Widget\Limiter;
|
||||
use Icinga\Data\Sortable;
|
||||
use Icinga\Data\QueryInterface;
|
||||
use Icinga\Web\Paginator\Adapter\QueryAdapter;
|
||||
use Icinga\Web\Controller\ModuleActionController;
|
||||
use Icinga\Web\Widget\Limiter;
|
||||
use Icinga\Web\Widget\SortBox;
|
||||
|
||||
/**
|
||||
* This is the controller all modules should inherit from
|
||||
|
@ -22,44 +24,56 @@ class Controller extends ModuleActionController
|
|||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
$this->handleSortControlSubmit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the sort control has been submitted and redirect using GET parameters
|
||||
*/
|
||||
protected function handleSortControlSubmit()
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
$url = Url::fromRequest();
|
||||
if (! $request->isPost()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($request->isPost() && ($sort = $request->getPost('sort'))) {
|
||||
if (($sort = $request->getPost('sort'))) {
|
||||
$url = Url::fromRequest();
|
||||
$url->setParam('sort', $sort);
|
||||
if ($dir = $request->getPost('dir')) {
|
||||
if (($dir = $request->getPost('dir'))) {
|
||||
$url->setParam('dir', $dir);
|
||||
} else {
|
||||
$url->removeParam('dir');
|
||||
}
|
||||
|
||||
$this->redirectNow($url);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a SortBox widget at the `sortBox' view property
|
||||
* Create a SortBox widget and apply its sort rules on the given query
|
||||
*
|
||||
* In case the current view has been requested as compact this method does nothing.
|
||||
* The widget is set on the `sortBox' view property only if the current view has not been requested as compact
|
||||
*
|
||||
* @param array $columns An array containing the sort columns, with the
|
||||
* submit value as the key and the label as the value
|
||||
* @param Sortable $query Query to set on the newly created SortBox
|
||||
* @param Sortable $query Query to apply the user chosen sort rules on
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function setupSortControl(array $columns, Sortable $query = null)
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
$sortBox = SortBox::create('sortbox-' . $request->getActionName(), $columns);
|
||||
$sortBox->setRequest($request);
|
||||
|
||||
if ($query) {
|
||||
$sortBox->setQuery($query);
|
||||
$sortBox->handleRequest($request);
|
||||
}
|
||||
|
||||
if (! $this->view->compact) {
|
||||
$req = $this->getRequest();
|
||||
$this->view->sortBox = $sortBox = SortBox::create(
|
||||
'sortbox-' . $req->getActionName(),
|
||||
$columns
|
||||
)->setRequest($req);
|
||||
if ($query !== null) {
|
||||
$sortBox->setQuery($query);
|
||||
}
|
||||
$sortBox->handleRequest();
|
||||
$this->view->sortBox = $sortBox;
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
@ -70,29 +84,43 @@ class Controller extends ModuleActionController
|
|||
*
|
||||
* In case the current view has been requested as compact this method does nothing.
|
||||
*
|
||||
* @param int $itemsPerPage Default number of items per page
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function setupLimitControl()
|
||||
protected function setupLimitControl($itemsPerPage = 25)
|
||||
{
|
||||
if (! $this->view->compact) {
|
||||
$this->view->limiter = new Limiter();
|
||||
$this->view->limiter->setDefaultLimit($itemsPerPage);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the view property `paginator' to the given Zend_Paginator
|
||||
* Apply the given page limit and number on the given query and setup a paginator for it
|
||||
*
|
||||
* In case the current view has been requested as compact this method does nothing.
|
||||
* The $itemsPerPage and $pageNumber parameters are only applied if not available in the current request.
|
||||
* The paginator is set on the `paginator' view property only if the current view has not been requested as compact.
|
||||
*
|
||||
* @param Zend_Paginator $paginator The Zend_Paginator for which to show a pagination control
|
||||
* @param QueryInterface $query The query to create a paginator for
|
||||
* @param int $itemsPerPage Default number of items per page
|
||||
* @param int $pageNumber Default page number
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function setupPaginationControl(Zend_Paginator $paginator)
|
||||
protected function setupPaginationControl(QueryInterface $query, $itemsPerPage = 25, $pageNumber = 0)
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
$limit = $request->getParam('limit', $itemsPerPage);
|
||||
$page = $request->getParam('page', $pageNumber);
|
||||
$query->limit($limit, $page * $limit);
|
||||
|
||||
if (! $this->view->compact) {
|
||||
$paginator = new Zend_Paginator(new QueryAdapter($query));
|
||||
$paginator->setItemCountPerPage($limit);
|
||||
$paginator->setCurrentPageNumber($page);
|
||||
$this->view->paginator = $paginator;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,28 @@ class Form extends Zend_Form
|
|||
*/
|
||||
const DEFAULT_SUFFIX = '_default';
|
||||
|
||||
/**
|
||||
* The type of the notification for the error
|
||||
*/
|
||||
const NOTIFICATION_ERROR = 0;
|
||||
|
||||
/**
|
||||
* The type of the notification for the warning
|
||||
*/
|
||||
const NOTIFICATION_WARNING = 2;
|
||||
|
||||
/**
|
||||
* The type of the notification for the info
|
||||
*/
|
||||
const NOTIFICATION_INFO = 4;
|
||||
|
||||
/**
|
||||
* The notifications of the form
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $notifications = array();
|
||||
|
||||
/**
|
||||
* Whether this form has been created
|
||||
*
|
||||
|
@ -1009,6 +1031,7 @@ class Form extends Zend_Form
|
|||
}
|
||||
|
||||
$this->addDecorator('FormErrors', array('onlyCustomFormErrors' => true))
|
||||
->addDecorator('FormNotifications')
|
||||
->addDecorator('FormDescriptions')
|
||||
->addDecorator('FormElements')
|
||||
//->addDecorator('HtmlTag', array('tag' => 'dl', 'class' => 'zend_form'))
|
||||
|
@ -1208,4 +1231,57 @@ class Form extends Zend_Form
|
|||
throw new SecurityException('No permission for %s', $permission);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all form notifications
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNotifications()
|
||||
{
|
||||
return $this->notifications;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a typed message to the notifications
|
||||
*
|
||||
* @param string $message The message which would be displayed to the user
|
||||
*
|
||||
* @param int $type The type of the message notification
|
||||
*/
|
||||
public function addNotification($message, $type = self::NOTIFICATION_ERROR)
|
||||
{
|
||||
$this->notifications[$message] = $type;
|
||||
$this->markAsError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a error message to notifications
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function error($message)
|
||||
{
|
||||
$this->addNotification($message, $type = self::NOTIFICATION_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a warning message to notifications
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function warning($message)
|
||||
{
|
||||
$this->addNotification($message, $type = self::NOTIFICATION_WARNING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a info message to notifications
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function info($message)
|
||||
{
|
||||
$this->addNotification($message, $type = self::NOTIFICATION_INFO);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||
|
||||
namespace Icinga\Web\Form\Decorator;
|
||||
|
||||
use Zend_Form_Decorator_Abstract;
|
||||
use Icinga\Web\Form as Form;
|
||||
|
||||
/**
|
||||
* Decorator to add a list of notifications at the top of a form
|
||||
*/
|
||||
class FormNotifications extends Zend_Form_Decorator_Abstract
|
||||
{
|
||||
/**
|
||||
* Render form descriptions
|
||||
*
|
||||
* @param string $content The html rendered so far
|
||||
*
|
||||
* @return string The updated html
|
||||
*/
|
||||
public function render($content = '')
|
||||
{
|
||||
$form = $this->getElement();
|
||||
if (! $form instanceof Form) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
$view = $form->getView();
|
||||
if ($view === null) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
$notifications = $this->recurseForm($form);
|
||||
|
||||
if (empty($notifications)) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
$html = '<ul class="form-notifications">';
|
||||
|
||||
asort($notifications);
|
||||
foreach ($notifications as $message => $type) {
|
||||
$html .= '<li class="'.self::getNotificationTypeName($type).'">' . $view->escape($message) . '</li>';
|
||||
}
|
||||
|
||||
switch ($this->getPlacement()) {
|
||||
case self::APPEND:
|
||||
return $content . $html . '</ul>';
|
||||
case self::PREPEND:
|
||||
return $html . '</ul>' . $content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recurse the given form and return the notifications for it and all of its subforms
|
||||
*
|
||||
* @param Form $form The form to recurse
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function recurseForm(Form $form)
|
||||
{
|
||||
$notifications = $form->getNotifications();
|
||||
|
||||
foreach ($form->getSubForms() as $subForm) {
|
||||
$notifications = $notifications + $this->recurseForm($subForm);
|
||||
}
|
||||
|
||||
return $notifications;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the readable type name of the notification
|
||||
*
|
||||
* @param $type Type of the message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getNotificationTypeName($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case Form::NOTIFICATION_ERROR:
|
||||
return 'error';
|
||||
break;
|
||||
case Form::NOTIFICATION_WARNING:
|
||||
return 'warning';
|
||||
break;
|
||||
case Form::NOTIFICATION_INFO:
|
||||
return 'info';
|
||||
break;
|
||||
default:
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,6 +21,8 @@ class Limiter extends AbstractWidget
|
|||
|
||||
private $pages;
|
||||
|
||||
private $default;
|
||||
|
||||
public function setUrl(Url $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
|
@ -39,13 +41,19 @@ class Limiter extends AbstractWidget
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setDefaultLimit($limit)
|
||||
{
|
||||
$this->default = $limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
if ($this->url === null) {
|
||||
$this->url = Url::fromRequest();
|
||||
}
|
||||
|
||||
$currentLimit = (int) $this->url->getParam('limit', 25); // Default??
|
||||
$currentLimit = (int) $this->url->getParam('limit', $this->default);
|
||||
$availableLimits = array(
|
||||
10 => '10',
|
||||
25 => '25',
|
||||
|
|
|
@ -70,7 +70,7 @@ class Monitoring_AlertsummaryController extends Controller
|
|||
'notification_state'
|
||||
)
|
||||
);
|
||||
$this->view->notifications = $query->paginate();
|
||||
$this->view->notifications = $query;
|
||||
|
||||
$this->setupLimitControl();
|
||||
$this->setupPaginationControl($this->view->notifications);
|
||||
|
@ -493,7 +493,7 @@ class Monitoring_AlertsummaryController extends Controller
|
|||
|
||||
$query->order('notification_start_time', 'desc');
|
||||
|
||||
return $query->paginate(5);
|
||||
return $query->limit(5);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -97,7 +97,7 @@ class Monitoring_ListController extends Controller
|
|||
), $this->extraColumns()));
|
||||
$this->filterQuery($query);
|
||||
$this->applyRestriction('monitoring/hosts/filter', $query);
|
||||
$this->view->hosts = $query->paginate();
|
||||
$this->view->hosts = $query;
|
||||
|
||||
$this->view->stats = $this->backend->select()->from('statusSummary', array(
|
||||
'hosts_total',
|
||||
|
@ -181,7 +181,7 @@ class Monitoring_ListController extends Controller
|
|||
$query = $this->backend->select()->from('serviceStatus', $columns);
|
||||
$this->filterQuery($query);
|
||||
$this->applyRestriction('monitoring/services/filter', $query);
|
||||
$this->view->services = $query->paginate();
|
||||
$this->view->services = $query;
|
||||
|
||||
$this->setupLimitControl();
|
||||
$this->setupPaginationControl($this->view->services);
|
||||
|
@ -246,7 +246,7 @@ class Monitoring_ListController extends Controller
|
|||
'service_display_name'
|
||||
));
|
||||
$this->filterQuery($query);
|
||||
$this->view->downtimes = $query->paginate();
|
||||
$this->view->downtimes = $query;
|
||||
|
||||
$this->setupLimitControl();
|
||||
$this->setupPaginationControl($this->view->downtimes);
|
||||
|
@ -292,7 +292,7 @@ class Monitoring_ListController extends Controller
|
|||
'service_display_name'
|
||||
));
|
||||
$this->filterQuery($query);
|
||||
$this->view->notifications = $query->paginate();
|
||||
$this->view->notifications = $query;
|
||||
|
||||
$this->setupLimitControl();
|
||||
$this->setupPaginationControl($this->view->notifications);
|
||||
|
@ -326,7 +326,7 @@ class Monitoring_ListController extends Controller
|
|||
'contact_notify_host_downtime',
|
||||
));
|
||||
$this->filterQuery($query);
|
||||
$this->view->contacts = $query->paginate();
|
||||
$this->view->contacts = $query;
|
||||
|
||||
$this->setupLimitControl();
|
||||
$this->setupPaginationControl($this->view->contacts);
|
||||
|
@ -438,7 +438,7 @@ class Monitoring_ListController extends Controller
|
|||
'service_display_name'
|
||||
));
|
||||
$this->filterQuery($query);
|
||||
$this->view->comments = $query->paginate();
|
||||
$this->view->comments = $query;
|
||||
|
||||
$this->setupLimitControl();
|
||||
$this->setupPaginationControl($this->view->comments);
|
||||
|
@ -498,7 +498,7 @@ class Monitoring_ListController extends Controller
|
|||
// TODO(el): Can't default to the sort rules of the data view because it's meant for both host groups and
|
||||
// service groups. We should separate them.
|
||||
$this->filterQuery($query);
|
||||
$this->view->servicegroups = $query->paginate();
|
||||
$this->view->servicegroups = $query;
|
||||
|
||||
$this->setupLimitControl();
|
||||
$this->setupPaginationControl($this->view->servicegroups);
|
||||
|
@ -528,6 +528,12 @@ class Monitoring_ListController extends Controller
|
|||
'hosts_down_handled',
|
||||
'hosts_down_unhandled',
|
||||
'hosts_pending',
|
||||
'hosts_up_last_state_change',
|
||||
'hosts_pending_last_state_change',
|
||||
'hosts_down_last_state_change_handled',
|
||||
'hosts_unreachable_last_state_change_handled',
|
||||
'hosts_down_last_state_change_unhandled',
|
||||
'hosts_unreachable_last_state_change_unhandled',
|
||||
'services_ok',
|
||||
'services_unknown_handled',
|
||||
'services_unknown_unhandled',
|
||||
|
@ -549,7 +555,7 @@ class Monitoring_ListController extends Controller
|
|||
// TODO(el): Can't default to the sort rules of the data view because it's meant for both host groups and
|
||||
// service groups. We should separate them.
|
||||
$this->filterQuery($query);
|
||||
$this->view->hostgroups = $query->paginate();
|
||||
$this->view->hostgroups = $query;
|
||||
|
||||
$this->setupLimitControl();
|
||||
$this->setupPaginationControl($this->view->hostgroups);
|
||||
|
@ -588,7 +594,7 @@ class Monitoring_ListController extends Controller
|
|||
));
|
||||
|
||||
$this->filterQuery($query);
|
||||
$this->view->history = $query->paginate();
|
||||
$this->view->history = $query;
|
||||
|
||||
$this->setupLimitControl();
|
||||
$this->setupPaginationControl($this->view->history);
|
||||
|
|
|
@ -70,12 +70,12 @@ class Monitoring_ShowController extends Controller
|
|||
{
|
||||
$this->getTabs()->activate('history');
|
||||
$this->view->object->fetchEventHistory();
|
||||
$this->view->history = $this->view->object->eventhistory->getQuery()->paginate($this->params->get('limit', 50));
|
||||
$this->view->history = $this->view->object->eventhistory;
|
||||
$this->handleFormatRequest($this->view->object->eventhistory);
|
||||
$this->fetchHostStats();
|
||||
|
||||
$this->setupLimitControl();
|
||||
$this->setupPaginationControl($this->view->history);
|
||||
$this->setupLimitControl(50);
|
||||
$this->setupPaginationControl($this->view->history, 50);
|
||||
}
|
||||
|
||||
public function servicesAction()
|
||||
|
@ -154,7 +154,7 @@ class Monitoring_ShowController extends Controller
|
|||
'command_name'
|
||||
))->where('contact_id', $contact->contact_id);
|
||||
|
||||
$this->view->commands = $commands->paginate();
|
||||
$this->view->commands = $commands;
|
||||
|
||||
$notifications = $this->backend->select()->from('notification', array(
|
||||
'host_name',
|
||||
|
@ -168,7 +168,7 @@ class Monitoring_ShowController extends Controller
|
|||
));
|
||||
|
||||
$notifications->where('contact_object_id', $contact->contact_object_id);
|
||||
$this->view->notifications = $notifications->paginate();
|
||||
$this->view->notifications = $notifications;
|
||||
$this->setupLimitControl();
|
||||
$this->setupPaginationControl($this->view->notifications);
|
||||
}
|
||||
|
|
|
@ -215,8 +215,14 @@ class ToggleInstanceFeaturesCommandForm extends CommandForm
|
|||
->setFeature($feature)
|
||||
->setEnabled($enabled);
|
||||
$this->getTransport($this->request)->send($toggleFeature);
|
||||
|
||||
if ($this->status->{$feature} != $enabled) {
|
||||
Notification::success($enabled
|
||||
? $this->translate('Enabling feature..')
|
||||
: $this->translate('Disabling feature..')
|
||||
);
|
||||
}
|
||||
}
|
||||
Notification::success($this->translate('Toggling feature..'));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\Forms\Config;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Data\ConfigObject;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Web\Form;
|
||||
use InvalidArgumentException;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
|
@ -271,4 +275,63 @@ class BackendConfigForm extends ConfigForm
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the ido instance schema resource
|
||||
*
|
||||
* @param Form $form
|
||||
* @param ConfigObject $resourceConfig
|
||||
*
|
||||
* @return bool Whether validation succeeded or not
|
||||
*/
|
||||
public static function isValidIdoSchema(Form $form, ConfigObject $resourceConfig)
|
||||
{
|
||||
try {
|
||||
$resource = ResourceFactory::createResource($resourceConfig);
|
||||
$result = $resource->select()->from('icinga_dbversion', array('version'));
|
||||
$result->fetchOne();
|
||||
} catch (Exception $e) {
|
||||
$form->addError(
|
||||
$form->translate(
|
||||
'IDO schema validation failed, it looks like that the IDO schema is missing in the given database.'
|
||||
)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the ido instance availability
|
||||
*
|
||||
* @param Form $form
|
||||
* @param ConfigObject $resourceConfig
|
||||
*
|
||||
* @return bool Whether validation succeeded or not
|
||||
*/
|
||||
public static function isValidIdoInstance(Form $form, ConfigObject $resourceConfig)
|
||||
{
|
||||
$resource = ResourceFactory::createResource($resourceConfig);
|
||||
$result = $resource->select()->from('icinga_instances', array('instance_name'));
|
||||
$instances = $result->fetchAll();
|
||||
|
||||
if (count($instances) === 1) {
|
||||
return true;
|
||||
} elseif (count($instances) > 1) {
|
||||
$form->warning(
|
||||
$form->translate(
|
||||
'IDO instance validation failed, because there are multiple instances available.'
|
||||
)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
$form->error(
|
||||
$form->translate(
|
||||
'IDO instance validation failed, because there is no IDO instance available.'
|
||||
)
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\Forms\Setup;
|
||||
|
||||
use Icinga\Data\ConfigObject;
|
||||
use Icinga\Module\Monitoring\Forms\Config\BackendConfigForm;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Forms\Config\Resource\DbResourceForm;
|
||||
|
||||
|
@ -53,8 +55,21 @@ class IdoResourcePage extends Form
|
|||
}
|
||||
|
||||
if (false === isset($data['skip_validation']) || $data['skip_validation'] == 0) {
|
||||
if (false === DbResourceForm::isValidResource($this)) {
|
||||
$this->addSkipValidationCheckbox();
|
||||
$configObject = new ConfigObject($this->getValues());
|
||||
if (false === DbResourceForm::isValidResource($this, $configObject)) {
|
||||
$this->addSkipValidationCheckbox($this->translate(
|
||||
'Check this to not to validate connectivity with the given database server'
|
||||
));
|
||||
return false;
|
||||
} elseif (false === BackendConfigForm::isValidIdoSchema($this, $configObject)) {
|
||||
$this->addSkipValidationCheckbox($this->translate(
|
||||
'Check this to not to validate the ido schema'
|
||||
));
|
||||
return false;
|
||||
} elseif (false === BackendConfigForm::isValidIdoInstance($this, $configObject)) {
|
||||
$this->addSkipValidationCheckbox($this->translate(
|
||||
'Check this to not to validate the ido instance'
|
||||
));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -65,17 +80,21 @@ class IdoResourcePage extends Form
|
|||
/**
|
||||
* Add a checkbox to the form by which the user can skip the connection validation
|
||||
*/
|
||||
protected function addSkipValidationCheckbox()
|
||||
protected function addSkipValidationCheckbox($description = '')
|
||||
{
|
||||
if (empty($description)) {
|
||||
$description = $this->translate(
|
||||
'Proceed without any further (custom) validation'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'skip_validation',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => $this->translate('Skip Validation'),
|
||||
'description' => $this->translate(
|
||||
'Check this to not to validate connectivity with the given database server'
|
||||
)
|
||||
'description' => $description
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<?= $this->render('list/components/selectioninfo.phtml'); ?>
|
||||
</div>
|
||||
<div class="tinystatesummary">
|
||||
<?= $comments->getTotalItemCount() ?> <?= $this->translate('Comments') ?>:
|
||||
<?= count($comments) ?> <?= $this->translate('Comments') ?>:
|
||||
</div>
|
||||
<?= $this->sortBox; ?>
|
||||
<?= $this->limiter; ?>
|
||||
|
|
|
@ -9,7 +9,7 @@ if (! $this->compact): ?>
|
|||
<?= $this->render('list/components/selectioninfo.phtml'); ?>
|
||||
</div>
|
||||
<div class="tinystatesummary">
|
||||
<?= $downtimes->getTotalItemCount() ?> <?= $this->translate('Downtimes') ?>
|
||||
<?= count($downtimes) ?> <?= $this->translate('Downtimes') ?>
|
||||
</div>
|
||||
<?= $this->sortBox; ?>
|
||||
<?= $this->limiter; ?>
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<?php if (! $this->compact): ?>
|
||||
<?php
|
||||
use Icinga\Module\Monitoring\Object\Host;
|
||||
|
||||
if (! $this->compact): ?>
|
||||
<div class="controls">
|
||||
<?= $this->tabs; ?>
|
||||
<?= $this->sortBox; ?>
|
||||
|
@ -15,7 +18,7 @@ if (count($hostgroups) === 0) {
|
|||
return;
|
||||
}
|
||||
?>
|
||||
<table class="groupview" data-base-target="_next">
|
||||
<table class="groupview action" data-base-target="_next">
|
||||
<thead>
|
||||
<th><?= $this->translate('Last Problem'); ?></th>
|
||||
<th><?= $this->translate('Host Group'); ?></th>
|
||||
|
@ -23,57 +26,40 @@ if (count($hostgroups) === 0) {
|
|||
<th><?= $this->translate('Service States'); ?></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($hostgroups as $h): ?>
|
||||
<tr href="<?= $this->href('monitoring/list/hosts', array('hostgroup_name' => $h->hostgroup_name)) ?>">
|
||||
<?php if ($h->services_critical_last_state_change_unhandled): ?>
|
||||
<td class="state change critical unhandled">
|
||||
<strong><?= $this->translate('CRITICAL'); ?></strong>
|
||||
<?php foreach ($hostgroups as $h):
|
||||
if ($h->hosts_down_unhandled) {
|
||||
$handled = false;
|
||||
$state = Host::STATE_DOWN;
|
||||
$lastStateChange = $h->hosts_down_last_state_change_unhandled;
|
||||
} elseif ($h->hosts_unreachable_unhandled) {
|
||||
$handled = false;
|
||||
$state = Host::STATE_UNREACHABLE;
|
||||
$lastStateChange = $h->hosts_unreachable_last_state_change_unhandled;
|
||||
} else {
|
||||
$handled = true;
|
||||
if ($h->hosts_down_handled) {
|
||||
$state = Host::STATE_DOWN;
|
||||
$lastStateChange = $h->hosts_down_last_state_change_handled;
|
||||
} elseif ($h->hosts_unreachable_handled) {
|
||||
$state = Host::STATE_UNREACHABLE;
|
||||
$lastStateChange = $h->hosts_unreachable_last_state_change_handled;
|
||||
} elseif ($h->hosts_up) {
|
||||
$state = Host::STATE_UP;
|
||||
$lastStateChange = $h->hosts_up_last_state_change;
|
||||
} else {
|
||||
$state = Host::STATE_PENDING;
|
||||
$lastStateChange = $h->hosts_pending_last_state_change;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<tr class="state <?= Host::getStateText($state) ?><?= $handled ? ' handled' : '' ?>" href="<?=
|
||||
$this->href('monitoring/list/hosts', array('hostgroup_name' => $h->hostgroup_name))
|
||||
?>">
|
||||
<td class="state">
|
||||
<strong><?= Host::getStateText($state, true); ?></strong>
|
||||
<br>
|
||||
<?= $this->prefixedTimeSince($h->services_critical_last_state_change_unhandled); ?>
|
||||
<?= $this->prefixedTimeSince($lastStateChange); ?>
|
||||
</td>
|
||||
<?php elseif ($h->services_unknown_last_state_change_unhandled): ?>
|
||||
<td class="state change unknown unhandled">
|
||||
<strong><?= $this->translate('UNKNOWN'); ?></strong>
|
||||
<br>
|
||||
<?= $this->prefixedTimeSince($h->services_unknown_last_state_change_unhandled); ?>
|
||||
</td>
|
||||
<?php elseif ($h->services_warning_last_state_change_unhandled): ?>
|
||||
<td class="state change warning unhandled">
|
||||
<strong><?= $this->translate('WARNING'); ?></strong>
|
||||
<br>
|
||||
<?= $this->prefixedTimeSince($h->services_warning_last_state_change_unhandled); ?>
|
||||
</td>
|
||||
<?php elseif ($h->services_critical_last_state_change_handled): ?>
|
||||
<td class="state change critical">
|
||||
<strong><?= $this->translate('CRITICAL'); ?></strong>
|
||||
<br>
|
||||
<?= $this->prefixedTimeSince($h->services_critical_last_state_change_handled); ?>
|
||||
</td>
|
||||
<?php elseif ($h->services_unknown_last_state_change_handled): ?>
|
||||
<td class="state change unknown">
|
||||
<strong><?= $this->translate('UNKNOWN'); ?></strong>
|
||||
<br>
|
||||
<?= $this->prefixedTimeSince($h->services_unknown_last_state_change_handled); ?>
|
||||
</td>
|
||||
<?php elseif ($h->services_warning_last_state_change_handled): ?>
|
||||
<td class="state change warning">
|
||||
<strong><?= $this->translate('WARNING'); ?></strong>
|
||||
<br>
|
||||
<?= $this->prefixedTimeSince($h->services_warning_last_state_change_handled); ?>
|
||||
</td>
|
||||
<?php elseif ($h->services_ok_last_state_change): ?>
|
||||
<td class="state change ok">
|
||||
<strong><?= $this->translate('OK'); ?></strong>
|
||||
<br>
|
||||
<?= $this->prefixedTimeSince($h->services_ok_last_state_change); ?>
|
||||
</td>
|
||||
<?php else: ?>
|
||||
<td class="state change pending">
|
||||
<strong><?= $this->translate('PENDING'); ?></strong>
|
||||
<br>
|
||||
<?= $this->prefixedTimeSince($h->services_pending_last_state_change); ?>
|
||||
</td>
|
||||
<?php endif ?>
|
||||
<td class="groupname">
|
||||
<?= $this->qlink(
|
||||
$h->hostgroup_alias,
|
||||
|
@ -93,7 +79,7 @@ if (count($hostgroups) === 0) {
|
|||
))
|
||||
); ?>
|
||||
</td>
|
||||
<td class="state">
|
||||
<td>
|
||||
<?php if ($h->services_ok): ?>
|
||||
<span class="state ok">
|
||||
<?= $this->qlink(
|
||||
|
|
|
@ -68,7 +68,18 @@ if ($object->getType() === $object::TYPE_HOST) {
|
|||
<?php if ($object->check_execution_time): ?>
|
||||
<tr>
|
||||
<th><?= $this->translate('Check execution time') ?></th>
|
||||
<td><?= $object->check_execution_time ?>s</td>
|
||||
<td><?php
|
||||
$matches = array();
|
||||
if (preg_match(
|
||||
'/(?<!.)([0-9]+\.[0-9]{4,})(?!.)/ms',
|
||||
$object->check_execution_time,
|
||||
$matches
|
||||
)) {
|
||||
printf('%.3f', (float) $matches[1]);
|
||||
} else {
|
||||
echo $object->check_execution_time;
|
||||
}
|
||||
?>s</td>
|
||||
</tr>
|
||||
<?php endif ?>
|
||||
<?php if ($object->check_latency): ?>
|
||||
|
|
|
@ -11,17 +11,23 @@ class GroupSummaryQuery extends IdoQuery
|
|||
|
||||
protected $columnMap = array(
|
||||
'hoststatussummary' => array(
|
||||
'hosts_up' => 'SUM(CASE WHEN object_type = \'host\' AND state = 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_unreachable' => 'SUM(CASE WHEN object_type = \'host\' AND state = 2 THEN 1 ELSE 0 END)',
|
||||
'hosts_unreachable_handled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 2 AND acknowledged + in_downtime != 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_unreachable_unhandled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 2 AND acknowledged + in_downtime = 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_down' => 'SUM(CASE WHEN object_type = \'host\' AND state = 1 THEN 1 ELSE 0 END)',
|
||||
'hosts_down_handled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 1 AND acknowledged + in_downtime != 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_down_unhandled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 1 AND acknowledged + in_downtime = 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_pending' => 'SUM(CASE WHEN object_type = \'host\' AND state = 99 THEN 1 ELSE 0 END)',
|
||||
'hostgroup_name' => 'hostgroup_name',
|
||||
'hostgroup_alias' => 'hostgroup_alias',
|
||||
'hostgroup' => 'hostgroup'
|
||||
'hosts_up' => 'SUM(CASE WHEN object_type = \'host\' AND state = 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_unreachable' => 'SUM(CASE WHEN object_type = \'host\' AND state = 2 THEN 1 ELSE 0 END)',
|
||||
'hosts_unreachable_handled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 2 AND acknowledged + in_downtime != 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_unreachable_unhandled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 2 AND acknowledged + in_downtime = 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_down' => 'SUM(CASE WHEN object_type = \'host\' AND state = 1 THEN 1 ELSE 0 END)',
|
||||
'hosts_down_handled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 1 AND acknowledged + in_downtime != 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_down_unhandled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 1 AND acknowledged + in_downtime = 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_pending' => 'SUM(CASE WHEN object_type = \'host\' AND state = 99 THEN 1 ELSE 0 END)',
|
||||
'hosts_up_last_state_change' => 'MAX(CASE WHEN object_type = \'host\' AND state = 0 THEN state_change ELSE 0 END)',
|
||||
'hosts_pending_last_state_change' => 'MAX(CASE WHEN object_type = \'host\' AND state = 99 THEN state_change ELSE 0 END)',
|
||||
'hosts_down_last_state_change_handled' => 'MAX(CASE WHEN object_type = \'host\' AND state = 1 AND acknowledged + in_downtime != 0 THEN state_change ELSE 0 END)',
|
||||
'hosts_unreachable_last_state_change_handled' => 'MAX(CASE WHEN object_type = \'host\' AND state = 2 AND acknowledged + in_downtime != 0 THEN state_change ELSE 0 END)',
|
||||
'hosts_down_last_state_change_unhandled' => 'MAX(CASE WHEN object_type = \'host\' AND state = 1 AND acknowledged + in_downtime = 0 THEN state_change ELSE 0 END)',
|
||||
'hosts_unreachable_last_state_change_unhandled' => 'MAX(CASE WHEN object_type = \'host\' AND state = 2 AND acknowledged + in_downtime = 0 THEN state_change ELSE 0 END)',
|
||||
'hostgroup_name' => 'hostgroup_name',
|
||||
'hostgroup_alias' => 'hostgroup_alias',
|
||||
'hostgroup' => 'hostgroup'
|
||||
),
|
||||
'servicestatussummary' => array(
|
||||
'services_total' => 'SUM(CASE WHEN object_type = \'service\' THEN 1 ELSE 0 END)',
|
||||
|
|
|
@ -3,14 +3,13 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\DataView;
|
||||
|
||||
use Countable;
|
||||
use ArrayIterator;
|
||||
use IteratorAggregate;
|
||||
use Icinga\Data\QueryInterface;
|
||||
use Icinga\Data\Filter\Filter;
|
||||
use Icinga\Data\Filter\FilterMatch;
|
||||
use Icinga\Data\Browsable;
|
||||
use Icinga\Data\PivotTable;
|
||||
use Icinga\Data\Sortable;
|
||||
use Icinga\Data\ConnectionInterface;
|
||||
use Icinga\Data\Filterable;
|
||||
use Icinga\Exception\QueryException;
|
||||
use Icinga\Web\Request;
|
||||
use Icinga\Web\Url;
|
||||
|
@ -19,12 +18,12 @@ use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
|||
/**
|
||||
* A read-only view of an underlying query
|
||||
*/
|
||||
abstract class DataView implements Browsable, Countable, Filterable, Sortable
|
||||
abstract class DataView implements QueryInterface, IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* The query used to populate the view
|
||||
*
|
||||
* @var \Icinga\Data\SimpleQuery
|
||||
* @var QueryInterface
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
|
@ -59,6 +58,16 @@ abstract class DataView implements Browsable, Countable, Filterable, Sortable
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a iterator for all rows of the result set
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->fetchAll());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query name this data view relies on
|
||||
*
|
||||
|
@ -238,11 +247,11 @@ abstract class DataView implements Browsable, Countable, Filterable, Sortable
|
|||
};
|
||||
}
|
||||
|
||||
$order = $order === null ? (isset($sortColumns['order']) ? $sortColumns['order'] : static::SORT_ASC) : $order;
|
||||
$order = (strtoupper($order) === static::SORT_ASC) ? 'ASC' : 'DESC';
|
||||
$globalDefaultOrder = isset($sortColumns['order']) ? $sortColumns['order'] : static::SORT_ASC;
|
||||
$globalDefaultOrder = (strtoupper($globalDefaultOrder) === static::SORT_ASC) ? 'ASC' : 'DESC';
|
||||
|
||||
foreach ($sortColumns['columns'] as $column) {
|
||||
list($column, $direction) = $this->query->splitOrder($column);
|
||||
list($column, $specificDefaultOrder) = $this->query->splitOrder($column);
|
||||
if (! $this->isValidFilterTarget($column)) {
|
||||
throw new QueryException(
|
||||
mt('monitoring', 'The sort column "%s" is not allowed in "%s".'),
|
||||
|
@ -250,7 +259,10 @@ abstract class DataView implements Browsable, Countable, Filterable, Sortable
|
|||
get_class($this)
|
||||
);
|
||||
}
|
||||
$this->query->order($column, $direction !== null ? $direction : $order);
|
||||
$this->query->order(
|
||||
$column,
|
||||
$order === null && $specificDefaultOrder !== null ? $specificDefaultOrder : $globalDefaultOrder
|
||||
);
|
||||
}
|
||||
$this->isSorted = true;
|
||||
return $this;
|
||||
|
@ -400,6 +412,114 @@ abstract class DataView implements Browsable, Countable, Filterable, Sortable
|
|||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->query);
|
||||
return $this->query->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a limit count and offset
|
||||
*
|
||||
* @param int $count Number of rows to return
|
||||
* @param int $offset Start returning after this many rows
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function limit($count = null, $offset = null)
|
||||
{
|
||||
$this->query->limit($count, $offset);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a limit is set
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasLimit()
|
||||
{
|
||||
return $this->query->hasLimit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the limit if any
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getLimit()
|
||||
{
|
||||
return $this->query->getLimit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether an offset is set
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOffset()
|
||||
{
|
||||
return $this->query->hasOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the offset if any
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getOffset()
|
||||
{
|
||||
return $this->query->hasOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an array containing all rows of the result set
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAll()
|
||||
{
|
||||
return $this->getQuery()->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the first row of the result set
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchRow()
|
||||
{
|
||||
return $this->getQuery()->fetchRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a column of all rows of the result set as an array
|
||||
*
|
||||
* @param int $columnIndex Index of the column to fetch
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fetchColumn($columnIndex = 0)
|
||||
{
|
||||
return $this->getQuery()->fetchColumn($columnIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the first column of the first row of the result set
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function fetchOne()
|
||||
{
|
||||
return $this->getQuery()->fetchOne();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all rows of the result set as an array of key-value pairs
|
||||
*
|
||||
* The first column is the key, the second column is the value.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fetchPairs()
|
||||
{
|
||||
return $this->getQuery()->fetchPairs();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,12 @@ class Groupsummary extends DataView
|
|||
'hosts_down_handled',
|
||||
'hosts_down_unhandled',
|
||||
'hosts_pending',
|
||||
'hosts_up_last_state_change',
|
||||
'hosts_pending_last_state_change',
|
||||
'hosts_down_last_state_change_handled',
|
||||
'hosts_unreachable_last_state_change_handled',
|
||||
'hosts_down_last_state_change_unhandled',
|
||||
'hosts_unreachable_last_state_change_unhandled',
|
||||
'services_total',
|
||||
'services_ok',
|
||||
'services_unknown',
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
@colorUnreachableHandled: #cc77ff;
|
||||
@colorPending: #77aaff;
|
||||
@colorInvalid: #999;
|
||||
@colorFormNotificationInfo: #77aaff;
|
||||
@colorFormNotificationWarning: #ffaa44;
|
||||
@colorFormNotificationError: #ff5566;
|
||||
|
||||
/* Mixins */
|
||||
|
||||
|
|
|
@ -87,6 +87,10 @@ button::-moz-focus-inner {
|
|||
outline: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select::-moz-focus-inner {
|
||||
border: 0;
|
||||
outline: 0;
|
||||
|
@ -165,6 +169,32 @@ form ul.form-errors {
|
|||
}
|
||||
}
|
||||
|
||||
form ul.form-notifications {
|
||||
.non-list-like-list;
|
||||
margin-bottom: 1em;
|
||||
padding: 0em;
|
||||
|
||||
li.info {
|
||||
background: @colorFormNotificationInfo;
|
||||
}
|
||||
|
||||
li.warning {
|
||||
background: @colorFormNotificationWarning;
|
||||
}
|
||||
|
||||
li.error {
|
||||
background: @colorFormNotificationError;
|
||||
}
|
||||
|
||||
li {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
line-height: 1.5em;
|
||||
padding: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
form div.element {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue