summaryrefslogtreecommitdiffstats
path: root/library/Icingadb/Web/Navigation/Renderer/ProblemsBadge.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Icingadb/Web/Navigation/Renderer/ProblemsBadge.php')
-rw-r--r--library/Icingadb/Web/Navigation/Renderer/ProblemsBadge.php173
1 files changed, 173 insertions, 0 deletions
diff --git a/library/Icingadb/Web/Navigation/Renderer/ProblemsBadge.php b/library/Icingadb/Web/Navigation/Renderer/ProblemsBadge.php
new file mode 100644
index 0000000..658fa1c
--- /dev/null
+++ b/library/Icingadb/Web/Navigation/Renderer/ProblemsBadge.php
@@ -0,0 +1,173 @@
+<?php
+
+/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
+
+namespace Icinga\Module\Icingadb\Web\Navigation\Renderer;
+
+use Exception;
+use Icinga\Application\Logger;
+use Icinga\Module\Icingadb\Common\Database;
+use Icinga\Web\Navigation\NavigationItem;
+use Icinga\Web\Navigation\Renderer\NavigationItemRenderer;
+use ipl\Html\HtmlDocument;
+use ipl\Html\HtmlString;
+use ipl\Web\Widget\Link;
+use ipl\Web\Widget\StateBadge;
+
+abstract class ProblemsBadge extends NavigationItemRenderer
+{
+ use Database;
+
+ const STATE_CRITICAL = 'critical';
+ const STATE_UNKNOWN = 'unknown';
+
+ /** @var int Count cache */
+ protected $count;
+
+ /** @var string State text */
+ protected $state;
+
+ /** @var string Title */
+ protected $title;
+
+ protected $linkDisabled;
+
+ abstract protected function fetchProblemsCount();
+
+ abstract protected function getUrl();
+
+ public function getProblemsCount()
+ {
+ if ($this->count === null) {
+ try {
+ $count = $this->fetchProblemsCount();
+ } catch (Exception $e) {
+ Logger::debug($e);
+
+ $this->count = 1;
+
+ $this->setState(static::STATE_UNKNOWN);
+ $this->setTitle($e->getMessage());
+
+ return $this->count;
+ }
+
+ $this->count = $this->round($count);
+
+ $this->setState(static::STATE_CRITICAL);
+ }
+
+ return $this->count;
+ }
+
+ /**
+ * Set the state text
+ *
+ * @param string $state
+ *
+ * @return $this
+ */
+ public function setState(string $state): self
+ {
+ $this->state = $state;
+
+ return $this;
+ }
+
+ /**
+ * Get the state text
+ *
+ * @return string
+ */
+ public function getState(): string
+ {
+ if ($this->state === null) {
+ throw new \LogicException(
+ 'You are accessing an unset property. Please make sure to set it beforehand.'
+ );
+ }
+
+ return $this->state;
+ }
+
+ /**
+ * Set the title
+ *
+ * @param string $title
+ *
+ * @return $this
+ */
+ public function setTitle(string $title): self
+ {
+ $this->title = $title;
+
+ return $this;
+ }
+
+ /**
+ * Get the title
+ *
+ * @return ?string
+ */
+ public function getTitle()
+ {
+ return $this->title;
+ }
+
+ public function render(NavigationItem $item = null): string
+ {
+ if ($item === null) {
+ $item = $this->getItem();
+ }
+
+ $item->setCssClass('badge-nav-item icinga-module module-icingadb');
+
+ $html = new HtmlDocument();
+
+ $badge = $this->createBadge();
+ if ($badge !== null) {
+ if ($this->linkDisabled) {
+ $badge->addAttributes(['class' => 'disabled']);
+ $this->setEscapeLabel(false);
+ $label = $this->view()->escape($item->getLabel());
+ $item->setLabel($badge . $label);
+ } else {
+ $html->add(new Link($badge, $this->getUrl(), ['title' => $this->getTitle()]));
+ }
+ }
+
+ return $html
+ ->prepend(new HtmlString(parent::render($item)))
+ ->render();
+ }
+
+ protected function createBadge()
+ {
+ $count = $this->getProblemsCount();
+
+ if ($count) {
+ return (new StateBadge($count, $this->getState()))
+ ->addAttributes(['class' => 'badge', 'title' => $this->getTitle()]);
+ }
+
+ return null;
+ }
+
+ protected function round($count)
+ {
+ if ($count > 1000000) {
+ $count = round($count, -6) / 1000000 . 'M';
+ } elseif ($count > 1000) {
+ $count = round($count, -3) / 1000 . 'k';
+ }
+
+ return $count;
+ }
+
+ public function disableLink()
+ {
+ $this->linkDisabled = true;
+
+ return $this;
+ }
+}