summaryrefslogtreecommitdiffstats
path: root/library/Icinga/Web/Announcement
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 12:39:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 12:39:39 +0000
commit8ca6cc32b2c789a3149861159ad258f2cb9491e3 (patch)
tree2492de6f1528dd44eaa169a5c1555026d9cb75ec /library/Icinga/Web/Announcement
parentInitial commit. (diff)
downloadicingaweb2-8ca6cc32b2c789a3149861159ad258f2cb9491e3.tar.xz
icingaweb2-8ca6cc32b2c789a3149861159ad258f2cb9491e3.zip
Adding upstream version 2.11.4.upstream/2.11.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/Icinga/Web/Announcement')
-rw-r--r--library/Icinga/Web/Announcement/AnnouncementCookie.php138
-rw-r--r--library/Icinga/Web/Announcement/AnnouncementIniRepository.php152
2 files changed, 290 insertions, 0 deletions
diff --git a/library/Icinga/Web/Announcement/AnnouncementCookie.php b/library/Icinga/Web/Announcement/AnnouncementCookie.php
new file mode 100644
index 0000000..f4398ba
--- /dev/null
+++ b/library/Icinga/Web/Announcement/AnnouncementCookie.php
@@ -0,0 +1,138 @@
+<?php
+/* Icinga Web 2 | (c) 2016 Icinga Development Team | GPLv2+ */
+
+namespace Icinga\Web\Announcement;
+
+use Icinga\Util\Json;
+use Icinga\Web\Cookie;
+
+/**
+ * Handle acknowledged announcements via cookie
+ */
+class AnnouncementCookie extends Cookie
+{
+ /**
+ * Array of hashes representing acknowledged announcements
+ *
+ * @var string[]
+ */
+ protected $acknowledged = array();
+
+ /**
+ * ETag of the last known announcements.ini
+ *
+ * @var string
+ */
+ protected $etag;
+
+ /**
+ * Timestamp of the next active acknowledgement, if any
+ *
+ * @var int|null
+ */
+ protected $nextActive;
+
+ /**
+ * AnnouncementCookie constructor
+ */
+ public function __construct()
+ {
+ parent::__construct('icingaweb2-announcements');
+ $this->setExpire(2147483648);
+ if (isset($_COOKIE['icingaweb2-announcements'])) {
+ $cookie = json_decode($_COOKIE['icingaweb2-announcements'], true);
+ if ($cookie !== null) {
+ if (isset($cookie['acknowledged'])) {
+ $this->setAcknowledged($cookie['acknowledged']);
+ }
+ if (isset($cookie['etag'])) {
+ $this->setEtag($cookie['etag']);
+ }
+ if (isset($cookie['next'])) {
+ $this->setNextActive($cookie['next']);
+ }
+ }
+ }
+ }
+
+ /**
+ * Get the hashes of the acknowledged announcements
+ *
+ * @return string[]
+ */
+ public function getAcknowledged()
+ {
+ return $this->acknowledged;
+ }
+
+ /**
+ * Set the hashes of the acknowledged announcements
+ *
+ * @param string[] $acknowledged
+ *
+ * @return $this
+ */
+ public function setAcknowledged(array $acknowledged)
+ {
+ $this->acknowledged = $acknowledged;
+ return $this;
+ }
+
+ /**
+ * Get the ETag
+ *
+ * @return string
+ */
+ public function getEtag()
+ {
+ return $this->etag;
+ }
+
+ /**
+ * Set the ETag
+ *
+ * @param string $etag
+ *
+ * @return $this
+ */
+ public function setEtag($etag)
+ {
+ $this->etag = $etag;
+ return $this;
+ }
+
+ /**
+ * Get the timestamp of the next active announcement
+ *
+ * @return int
+ */
+ public function getNextActive()
+ {
+ return $this->nextActive;
+ }
+
+ /**
+ * Set the timestamp of the next active announcement
+ *
+ * @param int $nextActive
+ *
+ * @return $this
+ */
+ public function setNextActive($nextActive)
+ {
+ $this->nextActive = $nextActive;
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getValue()
+ {
+ return Json::encode(array(
+ 'acknowledged' => $this->getAcknowledged(),
+ 'etag' => $this->getEtag(),
+ 'next' => $this->getNextActive()
+ ));
+ }
+}
diff --git a/library/Icinga/Web/Announcement/AnnouncementIniRepository.php b/library/Icinga/Web/Announcement/AnnouncementIniRepository.php
new file mode 100644
index 0000000..d972a1d
--- /dev/null
+++ b/library/Icinga/Web/Announcement/AnnouncementIniRepository.php
@@ -0,0 +1,152 @@
+<?php
+/* Icinga Web 2 | (c) 2016 Icinga Development Team | GPLv2+ */
+
+namespace Icinga\Web\Announcement;
+
+use DateTime;
+use Icinga\Data\ConfigObject;
+use Icinga\Data\Filter\Filter;
+use Icinga\Data\Filter\FilterAnd;
+use Icinga\Data\SimpleQuery;
+use Icinga\Repository\IniRepository;
+use Icinga\Web\Announcement;
+
+/**
+ * A collection of announcements stored in an INI file
+ */
+class AnnouncementIniRepository extends IniRepository
+{
+ protected $queryColumns = array('announcement' => array('id', 'author', 'message', 'hash', 'start', 'end'));
+
+ protected $triggers = array('announcement');
+
+ protected $configs = array('announcement' => array(
+ 'name' => 'announcements',
+ 'keyColumn' => 'id'
+ ));
+
+ protected $conversionRules = array('announcement' => array(
+ 'start' => 'timestamp',
+ 'end' => 'timestamp'
+ ));
+
+ /**
+ * Get a DateTime's timestamp
+ *
+ * @param DateTime $datetime
+ *
+ * @return int|null
+ */
+ protected function persistTimestamp(DateTime $datetime)
+ {
+ return $datetime === null ? null : $datetime->getTimestamp();
+ }
+
+ /**
+ * Before-insert trigger (per row)
+ *
+ * @param ConfigObject $new The original data to insert
+ *
+ * @return ConfigObject The eventually modified data to insert
+ */
+ protected function onInsertAnnouncement(ConfigObject $new)
+ {
+ if (! isset($new->id)) {
+ $new->id = uniqid();
+ }
+
+ if (! isset($new->hash)) {
+ $announcement = new Announcement($new->toArray());
+ $new->hash = $announcement->getHash();
+ }
+
+ return $new;
+ }
+
+ /**
+ * Before-update trigger (per row)
+ *
+ * @param ConfigObject $old The original data as currently stored
+ * @param ConfigObject $new The original data to update
+ *
+ * @return ConfigObject The eventually modified data to update
+ */
+ protected function onUpdateAnnouncement(ConfigObject $old, ConfigObject $new)
+ {
+ if ($new->message !== $old->message) {
+ $announcement = new Announcement($new->toArray());
+ $new->hash = $announcement->getHash();
+ }
+
+ return $new;
+ }
+
+ /**
+ * Get the ETag of the announcements.ini file
+ *
+ * @return string
+ */
+ public function getEtag()
+ {
+ $file = $this->getDataSource('announcement')->getConfigFile();
+
+ if (@is_readable($file)) {
+ $mtime = filemtime($file);
+ $size = filesize($file);
+
+ return hash('crc32', $mtime . $size);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the query for all active announcements
+ *
+ * @return SimpleQuery
+ */
+ public function findActive()
+ {
+ $now = new DateTime();
+
+ $query = $this
+ ->select(array('hash', 'message', 'start'))
+ ->setFilter(new FilterAnd(array(
+ Filter::expression('start', '<=', $now),
+ Filter::expression('end', '>=', $now)
+ )))
+ ->order('start');
+
+ return $query;
+ }
+
+ /**
+ * Get the timestamp of the next active announcement
+ *
+ * @return int|null
+ */
+ public function findNextActive()
+ {
+ $now = new DateTime();
+
+ $query = $this
+ ->select(array('start', 'end'))
+ ->setFilter(Filter::matchAny(array(
+ Filter::expression('start', '>', $now), Filter::expression('end', '>', $now)
+ )));
+
+ $refresh = null;
+
+ foreach ($query as $row) {
+ $min = min($row->start, $row->end);
+
+ if ($refresh === null) {
+ $refresh = $min;
+ } else {
+ $refresh = min($refresh, $min);
+ }
+ }
+
+ return $refresh;
+ }
+}