diff --git a/application/forms/Config/Resource/LdapResourceForm.php b/application/forms/Config/Resource/LdapResourceForm.php index c6e452d2c..d20ec55af 100644 --- a/application/forms/Config/Resource/LdapResourceForm.php +++ b/application/forms/Config/Resource/LdapResourceForm.php @@ -81,22 +81,6 @@ class LdapResourceForm extends Form ) ); - if (isset($formData['encryption']) && $formData['encryption'] !== 'none') { - // TODO(jom): Do not show this checkbox unless the connection is actually failing due to certificate errors - $this->addElement( - 'checkbox', - 'reqcert', - array( - 'required' => true, - 'label' => $this->translate('Require Certificate'), - 'description' => $this->translate( - 'When checked, the LDAP server must provide a valid and known (trusted) certificate.' - ), - 'value' => 1 - ) - ); - } - $this->addElement( 'text', 'root_dn', diff --git a/library/Icinga/Protocol/Ldap/LdapConnection.php b/library/Icinga/Protocol/Ldap/LdapConnection.php index 841e855da..13036f847 100644 --- a/library/Icinga/Protocol/Ldap/LdapConnection.php +++ b/library/Icinga/Protocol/Ldap/LdapConnection.php @@ -122,13 +122,6 @@ class LdapConnection implements Selectable, Inspectable */ protected $rootDn; - /** - * Whether to load the configuration for strict certificate validation or the one for non-strict validation - * - * @var bool - */ - protected $validateCertificate; - /** * Whether the bind on this connection has already been performed * @@ -176,7 +169,6 @@ class LdapConnection implements Selectable, Inspectable $this->bindPw = $config->bind_pw; $this->rootDn = $config->root_dn; $this->port = $config->get('port', 389); - $this->validateCertificate = (bool) $config->get('reqcert', true); $this->encryption = $config->encryption; if ($this->encryption !== null) { @@ -957,16 +949,9 @@ class LdapConnection implements Selectable, Inspectable $info = new Inspection(''); } - if ($this->encryption === static::STARTTLS || $this->encryption === static::LDAPS) { - $this->prepareTlsEnvironment(); - } - $hostname = $this->hostname; if ($this->encryption === static::LDAPS) { $info->write('Connect using LDAPS'); - if (! $this->validateCertificate) { - $info->write('Skip certificate validation'); - } $hostname = 'ldaps://' . $hostname; } @@ -983,9 +968,6 @@ class LdapConnection implements Selectable, Inspectable if ($this->encryption === static::STARTTLS) { $this->encrypted = true; $info->write('Connect using STARTTLS'); - if (! $this->validateCertificate) { - $info->write('Skip certificate validation'); - } if (! ldap_start_tls($ds)) { throw new LdapException('LDAP STARTTLS failed: %s', ldap_error($ds)); } @@ -998,30 +980,6 @@ class LdapConnection implements Selectable, Inspectable return $ds; } - /** - * Set up how to handle StartTLS connections - * - * @throws LdapException In case the LDAPRC environment variable cannot be set - */ - protected function prepareTlsEnvironment() - { - // TODO: allow variable known CA location (system VS Icinga) - if (Platform::isWindows()) { - putenv('LDAPTLS_REQCERT=never'); - } else { - if ($this->validateCertificate) { - $ldap_conf = $this->getConfigDir('ldap_ca.conf'); - } else { - $ldap_conf = $this->getConfigDir('ldap_nocert.conf'); - } - - putenv('LDAPRC=' . $ldap_conf); // TODO: Does not have any effect - if (getenv('LDAPRC') !== $ldap_conf) { - throw new LdapException('putenv failed'); - } - } - } - /** * Create an LDAP entry * @@ -1103,6 +1061,13 @@ class LdapConnection implements Selectable, Inspectable try { $ds = $this->prepareNewConnection($insp); } catch (Exception $e) { + if ($this->encryption === 'starttls') { + // The Exception does not return any proper error messages in case of certificate errors. Connecting + // by STARTTLS will usually fail at this point when the certificate is unknown, + // so at least try to give some hints. + $insp->write('NOTE: There might be an issue with the chosen encryption. Ensure that the LDAP-Server ' . + 'supports STARTTLS and that the LDAP-Client is configured to accept its certificate.'); + } return $insp->error($e->getMessage()); } @@ -1116,6 +1081,13 @@ class LdapConnection implements Selectable, Inspectable '***' /* $this->bindPw */ ); if (! $success) { + // ldap_error does not return any proper error messages in case of certificate errors. Connecting + // by LDAPS will usually fail at this point when the certificate is unknown, so at least try to give + // some hints. + if ($this->encryption === 'ldaps') { + $insp->write('NOTE: There might be an issue with the chosen encryption. Ensure that the LDAP-Server ' . + ' supports LDAPS and that the LDAP-Client is configured to accept its certificate.'); + } return $insp->error(sprintf('%s failed: %s', $msg, ldap_error($ds))); } $insp->write(sprintf($msg . ' successful')); @@ -1137,12 +1109,4 @@ class LdapConnection implements Selectable, Inspectable } return $insp; } - - /** - * Reset the environment variables set by self::prepareTlsEnvironment() - */ - public function __destruct() - { - putenv('LDAPRC'); - } } diff --git a/library/Icinga/Web/Menu.php b/library/Icinga/Web/Menu.php index 7992364b9..7124a4776 100644 --- a/library/Icinga/Web/Menu.php +++ b/library/Icinga/Web/Menu.php @@ -117,9 +117,19 @@ class Menu implements RecursiveIterator foreach ($props as $key => $value) { $method = 'set' . implode('', array_map('ucfirst', explode('_', strtolower($key)))); if ($key === 'renderer') { + // nested configuration is used to pass multiple arguments to the item renderer + if ($value instanceof ConfigObject) { + $args = $value; + $value = $value->get('0'); + } + $value = '\\' . ltrim($value, '\\'); if (class_exists($value)) { - $value = new $value; + if (isset($args)) { + $value = new $value($args); + } else { + $value = new $value; + } } else { $class = '\Icinga\Web\Menu' . $value; if (!class_exists($class)) { @@ -127,7 +137,11 @@ class Menu implements RecursiveIterator sprintf('ItemRenderer with class "%s" does not exist', $class) ); } - $value = new $class; + if (isset($args)) { + $value = new $class($args); + } else { + $value = new $class; + } } } if (method_exists($this, $method)) { @@ -226,7 +240,6 @@ class Menu implements RecursiveIterator $auth = Auth::getInstance(); if ($auth->isAuthenticated()) { - $this->add(t('Dashboard'), array( 'url' => 'dashboard', 'icon' => 'dashboard', @@ -236,7 +249,10 @@ class Menu implements RecursiveIterator $section = $this->add(t('System'), array( 'icon' => 'services', 'priority' => 700, - 'renderer' => 'ProblemMenuItemRenderer' + 'renderer' => array( + 'SummaryMenuItemRenderer', + 'state' => 'critical' + ) )); $section->add(t('About'), array( 'url' => 'about', @@ -297,7 +313,10 @@ class Menu implements RecursiveIterator $section->add(t('Logout'), array( 'url' => 'authentication/logout', 'priority' => 990, - 'renderer' => 'ForeignMenuItemRenderer' + 'renderer' => array( + 'MenuItemRenderer', + 'target' => '_self' + ) )); } } diff --git a/library/Icinga/Web/Menu/BadgeMenuItemRenderer.php b/library/Icinga/Web/Menu/BadgeMenuItemRenderer.php new file mode 100644 index 000000000..ebde0b38f --- /dev/null +++ b/library/Icinga/Web/Menu/BadgeMenuItemRenderer.php @@ -0,0 +1,65 @@ +renderBadge() . $this->createLink($menu); + } + + /** + * Render the badge + * + * @return string + */ + protected function renderBadge() + { + if ($count = $this->getCount()) { + return sprintf( + '
%s
', + $this->getView()->escape($this->getTitle()), + $this->getView()->escape($this->getState()), + $count + ); + } + return ''; + } +} diff --git a/library/Icinga/Web/Menu/ForeignMenuItemRenderer.php b/library/Icinga/Web/Menu/ForeignMenuItemRenderer.php deleted file mode 100644 index b898b4d08..000000000 --- a/library/Icinga/Web/Menu/ForeignMenuItemRenderer.php +++ /dev/null @@ -1,17 +0,0 @@ - '_self' - ); -} diff --git a/library/Icinga/Web/Menu/MenuItemRenderer.php b/library/Icinga/Web/Menu/MenuItemRenderer.php index d40650d91..27abcc94a 100644 --- a/library/Icinga/Web/Menu/MenuItemRenderer.php +++ b/library/Icinga/Web/Menu/MenuItemRenderer.php @@ -7,6 +7,7 @@ use Icinga\Application\Icinga; use Icinga\Web\Menu; use Icinga\Web\Url; use Icinga\Web\View; +use Icinga\Data\ConfigObject; /** * Default MenuItemRenderer class @@ -14,38 +15,39 @@ use Icinga\Web\View; class MenuItemRenderer { /** - * Contains element specific attributes - * - * @var array - */ - protected $attributes = array(); - - /** - * View + * The view this menu item is being rendered to * * @var View|null */ - protected $view; + protected $view = null; /** - * Set the view + * The link target * - * @param View $view - * - * @return $this + * @var string */ - public function setView(View $view) + protected $target = null; + + /** + * Create a new instance of MenuItemRenderer + * + * Is is possible to configure the link target using the option 'target' + * + * @param ConfigObject|null $configuration + */ + public function __construct(ConfigObject $configuration = null) { - $this->view = $view; - return $this; + if ($configuration !== null) { + $this->target = $configuration->get('target', null); + } } /** - * Get the view + * Get the view this menu item is being rendered to * * @return View */ - public function getView() + protected function getView() { if ($this->view === null) { $this->view = Icinga::app()->getViewRenderer()->view; @@ -53,6 +55,36 @@ class MenuItemRenderer return $this->view; } + /** + * Creates a menu item link element + * + * @param Menu $menu + * + * @return string + */ + public function createLink(Menu $menu) + { + $attributes = isset($this->target) ? sprintf(' target="%s"', $this->getView()->escape($this->target)) : ''; + + if ($menu->getIcon() && strpos($menu->getIcon(), '.') === false) { + return sprintf( + '%s', + $menu->getUrl() ? : '#', + $attributes, + $menu->getIcon(), + $this->getView()->escape($menu->getTitle()) + ); + } + + return sprintf( + '%s%s', + $menu->getUrl() ? : '#', + $attributes, + $menu->getIcon() ? ' ' : '', + $this->getView()->escape($menu->getTitle()) + ); + } + /** * Renders the html content of a single menu item * @@ -64,47 +96,4 @@ class MenuItemRenderer { return $this->createLink($menu); } - - /** - * Creates a menu item link element - * - * @param Menu $menu - * - * @return string - */ - public function createLink(Menu $menu) - { - if ($menu->getIcon() && strpos($menu->getIcon(), '.') === false) { - return sprintf( - '%s', - $menu->getUrl() ? : '#', - $this->getAttributes(), - $menu->getIcon(), - $this->getView()->escape($menu->getTitle()) - ); - } - - return sprintf( - '%s%s', - $menu->getUrl() ? : '#', - $this->getAttributes(), - $menu->getIcon() ? ' ' : '', - $this->getView()->escape($menu->getTitle()) - ); - } - - /** - * Returns element specific attributes if present - * - * @return string - */ - protected function getAttributes() - { - $attributes = ''; - $view = $this->getView(); - foreach ($this->attributes as $attribute => $value) { - $attributes .= ' ' . $view->escape($attribute) . '="' . $view->escape($value) . '"'; - } - return $attributes; - } } diff --git a/library/Icinga/Web/Menu/ProblemMenuItemRenderer.php b/library/Icinga/Web/Menu/ProblemMenuItemRenderer.php deleted file mode 100644 index 010bdc034..000000000 --- a/library/Icinga/Web/Menu/ProblemMenuItemRenderer.php +++ /dev/null @@ -1,64 +0,0 @@ -getParent() !== null && $menu->hasSubMenus()) { - /** @var $submenu Menu */ - foreach ($menu->getSubMenus() as $submenu) { - $renderer = $submenu->getRenderer(); - if (method_exists($renderer, 'getSummary')) { - if ($renderer->getSummary() !== null) { - $this->summary[] = $renderer->getSummary(); - } - } - } - } - return $this->getBadge() . $this->createLink($menu); - } - - /** - * Get the problem badge - * - * @return string - */ - protected function getBadge() - { - if (count($this->summary) > 0) { - $problems = 0; - $titles = array(); - - foreach ($this->summary as $summary) { - $problems += $summary['problems']; - $titles[] = $summary['title']; - } - - return sprintf( - '
%s
', - implode(', ', $titles), - $problems - ); - } - return ''; - } -} diff --git a/library/Icinga/Web/Menu/SummaryMenuItemRenderer.php b/library/Icinga/Web/Menu/SummaryMenuItemRenderer.php new file mode 100644 index 000000000..942ddbc09 --- /dev/null +++ b/library/Icinga/Web/Menu/SummaryMenuItemRenderer.php @@ -0,0 +1,94 @@ +state = $configuration->get('state', self::STATE_CRITICAL); + } + + /** + * Renders the html content of a single menu item and summarized sub-menus + * + * @param Menu $menu + * + * @return string + */ + public function render(Menu $menu) + { + /** @var $submenu Menu */ + foreach ($menu->getSubMenus() as $submenu) { + $renderer = $submenu->getRenderer(); + if ($renderer instanceof BadgeMenuItemRenderer) { + if ($renderer->getState() === $this->state) { + $this->titles[] = $renderer->getTitle(); + $this->count += $renderer->getCount(); + } + } + } + return $this->renderBadge() . $this->createLink($menu); + } + + /** + * The amount of items to display in the badge + * + * @return int + */ + public function getCount() + { + return $this->count; + } + + /** + * Defines the color of the badge + * + * @return string + */ + public function getState() + { + return $this->state; + } + + /** + * The tooltip title + * + * @return string + */ + public function getTitle() + { + return implode(', ', $this->titles); + } +} diff --git a/library/Icinga/Web/Request.php b/library/Icinga/Web/Request.php index b4d7e92d4..5d11798a0 100644 --- a/library/Icinga/Web/Request.php +++ b/library/Icinga/Web/Request.php @@ -119,6 +119,11 @@ class Request extends Zend_Controller_Request_Http return $id . '-' . $this->uniqueId; } + /** + * Detect whether cookies are enabled + * + * @return bool + */ public function hasCookieSupport() { $cookie = new Cookie($this); diff --git a/modules/monitoring/application/views/scripts/list/comments.phtml b/modules/monitoring/application/views/scripts/list/comments.phtml index 3287f08e9..44b452f42 100644 --- a/modules/monitoring/application/views/scripts/list/comments.phtml +++ b/modules/monitoring/application/views/scripts/list/comments.phtml @@ -67,7 +67,7 @@ ) : $this->translate('This comment does not expire.'); ?> - + populate( diff --git a/modules/monitoring/application/views/scripts/list/downtimes.phtml b/modules/monitoring/application/views/scripts/list/downtimes.phtml index 1125aa9ba..a45bd0499 100644 --- a/modules/monitoring/application/views/scripts/list/downtimes.phtml +++ b/modules/monitoring/application/views/scripts/list/downtimes.phtml @@ -126,7 +126,7 @@ if (! $this->compact): ?> - + populate( diff --git a/modules/monitoring/configuration.php b/modules/monitoring/configuration.php index 8844c3247..fa95c3785 100644 --- a/modules/monitoring/configuration.php +++ b/modules/monitoring/configuration.php @@ -89,17 +89,34 @@ $this->provideSearchUrl($this->translate('Servicegroups'), 'monitoring/list/serv * Problems Section */ $section = $this->menuSection($this->translate('Problems'), array( - 'renderer' => 'Icinga\Module\Monitoring\Web\Menu\ProblemMenuItemRenderer', + 'renderer' => array( + 'SummaryMenuItemRenderer', + 'state' => 'critical' + ), 'icon' => 'block', 'priority' => 20 )); $section->add($this->translate('Unhandled Hosts'), array( - 'renderer' => 'Icinga\Module\Monitoring\Web\Menu\UnhandledHostMenuItemRenderer', + 'renderer' => array( + 'Icinga\Module\Monitoring\Web\Menu\MonitoringBadgeMenuItemRenderer', + 'columns' => array( + 'hosts_down_unhandled' => $this->translate('%d unhandled hosts down') + ), + 'state' => 'critical', + 'dataView' => 'statussummary' + ), 'url' => 'monitoring/list/hosts?host_problem=1&host_handled=0', 'priority' => 30 )); $section->add($this->translate('Unhandled Services'), array( - 'renderer' => 'Icinga\Module\Monitoring\Web\Menu\UnhandledServiceMenuItemRenderer', + 'renderer' => array( + 'Icinga\Module\Monitoring\Web\Menu\MonitoringBadgeMenuItemRenderer', + 'columns' => array( + 'services_critical_unhandled' => $this->translate('%d unhandled services critical') + ), + 'state' => 'critical', + 'dataView' => 'statussummary' + ), 'url' => 'monitoring/list/services?service_problem=1&service_handled=0&sort=service_severity', 'priority' => 40 )); @@ -204,7 +221,7 @@ $section = $this->menuSection($this->translate('System')); $section->add($this->translate('Monitoring Health'), array( 'url' => 'monitoring/process/info', 'priority' => 720, - 'renderer' => 'Icinga\Module\Monitoring\Web\Menu\BackendAvailabilityMenuItemRenderer' + 'renderer' => 'Icinga\Module\Monitoring\Web\Menu\BackendAvailabilityMenuItemRenderer' )); /* diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/IdoQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/IdoQuery.php index 85d9169a9..c8d2e3140 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/IdoQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/IdoQuery.php @@ -479,8 +479,12 @@ abstract class IdoQuery extends DbQuery } } + /** + * {@inheritdoc} + */ public function addFilter(Filter $filter) { + $filter = clone $filter; $this->requireFilterColumns($filter); return parent::addFilter($filter); } diff --git a/modules/monitoring/library/Monitoring/Web/Menu/BackendAvailabilityMenuItemRenderer.php b/modules/monitoring/library/Monitoring/Web/Menu/BackendAvailabilityMenuItemRenderer.php index f65f25993..ca589d3cb 100644 --- a/modules/monitoring/library/Monitoring/Web/Menu/BackendAvailabilityMenuItemRenderer.php +++ b/modules/monitoring/library/Monitoring/Web/Menu/BackendAvailabilityMenuItemRenderer.php @@ -4,10 +4,10 @@ namespace Icinga\Module\Monitoring\Web\Menu; use Icinga\Web\Menu; -use Icinga\Web\Menu\MenuItemRenderer; +use Icinga\Web\Menu\BadgeMenuItemRenderer; use Icinga\Module\Monitoring\Backend\MonitoringBackend; -class BackendAvailabilityMenuItemRenderer extends MenuItemRenderer +class BackendAvailabilityMenuItemRenderer extends BadgeMenuItemRenderer { /** * Get whether or not the monitoring backend is currently running @@ -27,47 +27,39 @@ class BackendAvailabilityMenuItemRenderer extends MenuItemRenderer } /** - * {@inheritdoc} - */ - public function render(Menu $menu) - { - return $this->getBadge() . $this->createLink($menu); - } - - /** - * Get the problem badge HTML + * The css class of the badge * * @return string */ - protected function getBadge() + public function getState() { - if (! $this->isCurrentlyRunning()) { - return sprintf( - '
%d
', - sprintf( - mt('monitoring', 'Monitoring backend %s is not running'), MonitoringBackend::instance()->getName() - ), - 1 - ); - } - return ''; + return self::STATE_CRITICAL; } /** - * Get the problem data for the summary + * The amount of items to display in the badge * - * @return array|null + * @return int */ - public function getSummary() + public function getCount() { if (! $this->isCurrentlyRunning()) { - return array( - 'problems' => 1, - 'title' => sprintf( - mt('monitoring', 'Monitoring backend %s is not running'), MonitoringBackend::instance()->getName() - ) - ); + return 1; } - return null; + return 0; + } + + /** + * The tooltip title + * + * @return string + * @throws \Icinga\Exception\ConfigurationError + */ + public function getTitle() + { + return sprintf( + mt('monitoring', 'Monitoring backend %s is not running'), + MonitoringBackend::instance()->getName() + ); } } diff --git a/modules/monitoring/library/Monitoring/Web/Menu/MonitoringBadgeMenuItemRenderer.php b/modules/monitoring/library/Monitoring/Web/Menu/MonitoringBadgeMenuItemRenderer.php new file mode 100644 index 000000000..90d02fe52 --- /dev/null +++ b/modules/monitoring/library/Monitoring/Web/Menu/MonitoringBadgeMenuItemRenderer.php @@ -0,0 +1,183 @@ +columns = $configuration->get('columns'); + $this->state = $configuration->get('state'); + $this->dataView = $configuration->get('dataView'); + + // clear the outdated summary cache, since new columns are being added. Optimally all menu item are constructed + // before any rendering is going on to avoid trashing too man old requests + if (isset(self::$summaries[$this->dataView])) { + unset(self::$summaries[$this->dataView]); + } + + // add the new columns to this view + if (! isset(self::$dataViews[$this->dataView])) { + self::$dataViews[$this->dataView] = array(); + } + foreach ($this->columns as $column => $title) { + if (! array_search($column, self::$dataViews[$this->dataView])) { + self::$dataViews[$this->dataView][] = $column; + } + $this->titles[$column] = $title; + } + } + + /** + * Apply a restriction on the given data view + * + * @param string $restriction The name of restriction + * @param Filterable $filterable The filterable to restrict + * + * @return Filterable The filterable + */ + protected static function applyRestriction($restriction, Filterable $filterable) + { + $restrictions = Filter::matchAny(); + foreach (Auth::getInstance()->getRestrictions($restriction) as $filter) { + $restrictions->addFilter(Filter::fromQueryString($filter)); + } + $filterable->applyFilter($restrictions); + return $filterable; + } + + /** + * Fetch the response from the database or access cache + * + * @param $view + * + * @return null + * @throws \Icinga\Exception\ConfigurationError + */ + protected static function summary($view) + { + if (! isset(self::$summaries[$view])) { + $summary = MonitoringBackend::instance()->select()->from( + $view, + self::$dataViews[$view] + ); + static::applyRestriction('monitoring/filter/objects', $summary); + self::$summaries[$view] = $summary->fetchRow(); + } + return isset(self::$summaries[$view]) ? self::$summaries[$view] : null; + } + + /** + * Defines the color of the badge + * + * @return string + */ + public function getState() + { + return $this->state; + } + + /** + * The amount of items to display in the badge + * + * @return int + */ + public function getCount() + { + $sum = self::summary($this->dataView); + $count = 0; + + foreach ($this->columns as $col => $title) { + if (isset($sum->$col)) { + $count += $sum->$col; + } + } + return $count; + } + + /** + * The tooltip title + * + * @return string + */ + public function getTitle() + { + $titles = array(); + $sum = $this->summary($this->dataView); + foreach ($this->columns as $column => $value) { + if (isset($sum->$column) && $sum->$column > 0) { + $titles[] = sprintf($this->titles[$column], $sum->$column); + } + } + return implode(', ', $titles); + } +} diff --git a/modules/monitoring/library/Monitoring/Web/Menu/MonitoringMenuItemRenderer.php b/modules/monitoring/library/Monitoring/Web/Menu/MonitoringMenuItemRenderer.php deleted file mode 100644 index df901b165..000000000 --- a/modules/monitoring/library/Monitoring/Web/Menu/MonitoringMenuItemRenderer.php +++ /dev/null @@ -1,109 +0,0 @@ -getRestrictions($restriction) as $filter) { - $restrictions->addFilter(Filter::fromQueryString($filter)); - } - $filterable->applyFilter($restrictions); - return $filterable; - } - - protected static function summary($column = null) - { - if (self::$summary === null) { - $summary = MonitoringBackend::instance()->select()->from( - 'statussummary', - array( - 'hosts_down_unhandled', - 'services_critical_unhandled' - ) - ); - static::applyRestriction('monitoring/filter/objects', $summary); - self::$summary = $summary->fetchRow(); - } - - if ($column === null) { - return self::$summary; - } elseif (isset(self::$summary->$column)) { - return self::$summary->$column; - } else { - return null; - } - } - - protected function getBadgeTitle() - { - $translations = array( - 'hosts_down_unhandled' => mt('monitoring', '%d unhandled hosts down'), - 'services_critical_unhandled' => mt('monitoring', '%d unhandled services critical') - ); - - $titles = array(); - $sum = $this->summary(); - - foreach ($this->columns as $col) { - if (isset($sum->$col) && $sum->$col > 0) { - $titles[] = sprintf($translations[$col], $sum->$col); - } - } - - return implode(', ', $titles); - } - - protected function countItems() - { - $sum = self::summary(); - $count = 0; - - foreach ($this->columns as $col) { - if (isset($sum->$col)) { - $count += $sum->$col; - } - } - - return $count; - } - - public function render(Menu $menu) - { - return $this->getBadge() . $this->createLink($menu); - } - - protected function getBadge() - { - if ($count = $this->countItems()) { - return sprintf( - '
%s
', - $this->getBadgeTitle(), - $count - ); - } - return ''; - } -} diff --git a/modules/monitoring/library/Monitoring/Web/Menu/ProblemMenuItemRenderer.php b/modules/monitoring/library/Monitoring/Web/Menu/ProblemMenuItemRenderer.php deleted file mode 100644 index d17431398..000000000 --- a/modules/monitoring/library/Monitoring/Web/Menu/ProblemMenuItemRenderer.php +++ /dev/null @@ -1,12 +0,0 @@ -