summaryrefslogtreecommitdiffstats
path: root/library/Director/Objects/IcingaRanges.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Director/Objects/IcingaRanges.php')
-rw-r--r--library/Director/Objects/IcingaRanges.php321
1 files changed, 321 insertions, 0 deletions
diff --git a/library/Director/Objects/IcingaRanges.php b/library/Director/Objects/IcingaRanges.php
new file mode 100644
index 0000000..c14c588
--- /dev/null
+++ b/library/Director/Objects/IcingaRanges.php
@@ -0,0 +1,321 @@
+<?php
+
+namespace Icinga\Module\Director\Objects;
+
+use Exception;
+use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
+
+abstract class IcingaRanges
+{
+ /** @var IcingaTimePeriodRange[]|IcingaScheduledDowntimeRange[] */
+ protected $storedRanges = [];
+
+ /** @var IcingaTimePeriodRange[]|IcingaScheduledDowntimeRange[] */
+ protected $ranges = [];
+
+ protected $modified = false;
+
+ protected $object;
+
+ private $position = 0;
+
+ protected $idx = array();
+
+ public function __construct(IcingaObject $object)
+ {
+ $this->object = $object;
+ }
+
+ #[\ReturnTypeWillChange]
+ public function count()
+ {
+ return count($this->ranges);
+ }
+
+ #[\ReturnTypeWillChange]
+ public function rewind()
+ {
+ $this->position = 0;
+ }
+
+ public function hasBeenModified()
+ {
+ return $this->modified;
+ }
+
+ #[\ReturnTypeWillChange]
+ public function current()
+ {
+ if (! $this->valid()) {
+ return null;
+ }
+
+ return $this->ranges[$this->idx[$this->position]];
+ }
+
+ #[\ReturnTypeWillChange]
+ public function key()
+ {
+ return $this->idx[$this->position];
+ }
+
+ #[\ReturnTypeWillChange]
+ public function next()
+ {
+ ++$this->position;
+ }
+
+ #[\ReturnTypeWillChange]
+ public function valid()
+ {
+ return array_key_exists($this->position, $this->idx);
+ }
+
+ public function get($key)
+ {
+ if (array_key_exists($key, $this->ranges)) {
+ return $this->ranges[$key];
+ }
+
+ return null;
+ }
+
+ public function getValues()
+ {
+ $res = array();
+ foreach ($this->ranges as $key => $range) {
+ $res[$key] = $range->range_value;
+ }
+
+ return (object) $res;
+ }
+
+ public function getOriginalValues()
+ {
+ $res = array();
+ foreach ($this->storedRanges as $key => $range) {
+ $res[$key] = $range->range_value;
+ }
+
+ return (object) $res;
+ }
+
+ public function getRanges()
+ {
+ return $this->ranges;
+ }
+
+ protected function modify($range, $value)
+ {
+ $this->ranges[$range]->range_key = $value;
+ }
+
+ public function set($ranges)
+ {
+ foreach ($ranges as $range => $value) {
+ $this->setRange($range, $value);
+ }
+
+ $toDelete = array_diff(array_keys($this->ranges), array_keys($ranges));
+ foreach ($toDelete as $range) {
+ $this->remove($range);
+ }
+
+ return $this;
+ }
+
+ public function setRange($range, $value)
+ {
+ if ($value === null && array_key_exists($range, $this->ranges)) {
+ $this->remove($range);
+ return $this;
+ }
+
+ if (array_key_exists($range, $this->ranges)) {
+ if ($this->ranges[$range]->range_value === $value) {
+ return $this;
+ } else {
+ $this->ranges[$range]->range_value = $value;
+ $this->modified = true;
+ }
+ } else {
+ $class = $this->getRangeClass();
+ $this->ranges[$range] = $class::create([
+ $this->objectIdColumn => $this->object->get('id'),
+ 'range_key' => $range,
+ 'range_value' => $value,
+ ]);
+ $this->modified = true;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Magic isset check
+ *
+ * @return boolean
+ */
+ public function __isset($range)
+ {
+ return array_key_exists($range, $this->ranges);
+ }
+
+ public function remove($range)
+ {
+ if (array_key_exists($range, $this->ranges)) {
+ unset($this->ranges[$range]);
+ }
+
+ $this->modified = true;
+ $this->refreshIndex();
+ }
+
+ public function clear()
+ {
+ $this->ranges = [];
+ $this->modified = true;
+ $this->refreshIndex();
+ }
+
+ protected function refreshIndex()
+ {
+ ksort($this->ranges);
+ $this->idx = array_keys($this->ranges);
+ }
+
+ public function listRangesNames()
+ {
+ return array_keys($this->ranges);
+ }
+
+ public function getType()
+ {
+ return $this->object->getShortTableName();
+ }
+
+ public function getRangeTableName()
+ {
+ return $this->object->getTableName() . '_range';
+ }
+
+ protected function loadFromDb()
+ {
+ $db = $this->object->getDb();
+ $connection = $this->object->getConnection();
+
+ $table = $this->getRangeTableName();
+
+ $query = $db->select()
+ ->from(['o' => $table])
+ ->where('o.' . $this->objectIdColumn . ' = ?', (int) $this->object->get('id'))
+ ->order('o.range_key');
+
+ $class = $this->getRangeClass();
+ $this->ranges = $class::loadAll($connection, $query, 'range_key');
+ $this->setBeingLoadedFromDb();
+
+ return $this;
+ }
+
+ public function setBeingLoadedFromDb()
+ {
+ $this->storedRanges = [];
+
+ foreach ($this->ranges as $key => $range) {
+ $range->setBeingLoadedFromDb();
+ $this->storedRanges[$key] = clone($range);
+ }
+ $this->refreshIndex();
+ $this->modified = false;
+ }
+
+ public function store()
+ {
+ $db = $this->object->getConnection();
+ if (! $this->hasBeenModified()) {
+ return false;
+ }
+
+ $table = $this->getRangeTableName();
+ $objectId = (int) $this->object->get('id');
+ $idColumn = $this->objectIdColumn;
+ foreach ($this->ranges as $range) {
+ if ($range->hasBeenModified()) {
+ $range->setConnection($db);
+ if ((int) $range->get($idColumn) !== $objectId) {
+ $range->set($idColumn, $objectId);
+ }
+ }
+ }
+
+ foreach (array_diff(array_keys($this->storedRanges), array_keys($this->ranges)) as $delete) {
+ $range = $this->storedRanges[$delete];
+ $range->setConnection($db);
+ $range->set($idColumn, $objectId);
+ $db->getDbAdapter()->delete($table, $range->createWhere());
+ unset($this->ranges[$delete]);
+ }
+ foreach ($this->ranges as $range) {
+ $range->store();
+ }
+ $this->setBeingLoadedFromDb();
+
+ return true;
+ }
+
+ /**
+ * @return IcingaTimePeriodRange|IcingaScheduledDowntimeRange|string IDE hint
+ */
+ protected function getRangeClass()
+ {
+ return $this->rangeClass;
+ }
+
+ public static function loadForStoredObject(IcingaObject $object)
+ {
+ $ranges = new static($object);
+ return $ranges->loadFromDb();
+ }
+
+ public function toConfigString()
+ {
+ if (empty($this->ranges) && $this->object->object_type === 'template') {
+ return '';
+ }
+
+ $string = " ranges = {\n";
+
+ foreach ($this->ranges as $range) {
+ $string .= sprintf(
+ " %s\t= %s\n",
+ c::renderString($range->range_key),
+ c::renderString($range->range_value)
+ );
+ }
+
+ return $string . " }\n";
+ }
+
+ abstract public function toLegacyConfigString();
+
+ public function __toString()
+ {
+ try {
+ return $this->toConfigString();
+ } catch (Exception $e) {
+ trigger_error($e);
+ $previousHandler = set_exception_handler(
+ function () {
+ }
+ );
+ restore_error_handler();
+ if ($previousHandler !== null) {
+ call_user_func($previousHandler, $e);
+ die();
+ } else {
+ die($e->getMessage());
+ }
+ }
+ }
+}