diff options
Diffstat (limited to 'library/Director/Objects/IcingaRanges.php')
-rw-r--r-- | library/Director/Objects/IcingaRanges.php | 321 |
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()); + } + } + } +} |