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()); } } } }