object = $object; } #[\ReturnTypeWillChange] public function count() { return count($this->imports); } #[\ReturnTypeWillChange] public function rewind() { $this->position = 0; } public function setModified() { $this->modified = true; return $this; } public function hasBeenModified() { return $this->modified; } /** * @return IcingaObject|null * @throws \Icinga\Exception\NotFoundError */ #[\ReturnTypeWillChange] public function current() { if (! $this->valid()) { return null; } return $this->getObject( $this->imports[$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); } /** * @param $key * @return IcingaObject|null * @throws \Icinga\Exception\NotFoundError */ public function get($key) { if (array_key_exists($key, $this->imports)) { return $this->getObject($this->imports[$key]); } return null; } public function set($import) { if (empty($import)) { if (empty($this->imports)) { return $this; } else { return $this->clear(); } } if (! is_array($import)) { $import = [$import]; } $existing = $this->listImportNames(); $new = $this->listNamesForGivenImports($import); if ($existing === $new) { return $this; } $this->imports = []; return $this->add($import); } protected function listNamesForGivenImports($imports) { $list = []; $class = $this->getImportClass(); foreach ($imports as $i) { if ($i instanceof $class) { $list[] = $i->object_name; } else { $list[] = $i; } } return $list; } /** * Magic isset check * * @param string $import * * @return boolean */ public function __isset($import) { return array_key_exists($import, $this->imports); } public function clear() { if ($this->imports === []) { return $this; } $this->imports = []; $this->modified = true; return $this->refreshIndex(); } public function remove($import) { if (array_key_exists($import, $this->imports)) { unset($this->imports[$import]); } $this->modified = true; return $this->refreshIndex(); } protected function refreshIndex() { $this->idx = array_keys($this->imports); // $this->object->templateResolver()->refreshObject($this->object); return $this; } public function add($import) { $class = $this->getImportClass(); if (is_array($import)) { foreach ($import as $i) { // Gracefully ignore null members or empty strings if (! $i instanceof $class && ($i === null || strlen($i) === 0)) { continue; } $this->add($i); } return $this; } if ($import instanceof $class) { $name = $import->object_name; if (array_key_exists($name, $this->imports)) { return $this; } $this->imports[$name] = $name; $this->objects[$name] = $import; } elseif (is_string($import)) { if (array_key_exists($import, $this->imports)) { return $this; } $this->imports[$import] = $import; } $this->modified = true; $this->refreshIndex(); return $this; } /** * @return IcingaObject[] * @throws \Icinga\Exception\NotFoundError */ public function getObjects() { $list = []; foreach ($this->listImportNames() as $name) { $name = (string) $name; $list[$name] = $this->getObject($name); } return $list; } /** * @param $name * @return IcingaObject * @throws \Icinga\Exception\NotFoundError */ protected function getObject($name) { if (array_key_exists($name, $this->objects)) { return $this->objects[$name]; } $connection = $this->object->getConnection(); /** @var IcingaObject $class */ $class = $this->getImportClass(); try { if (is_array($this->object->getKeyName())) { // Services only $import = $class::load([ 'object_name' => $name, 'object_type' => 'template' ], $connection); } else { $import = $class::load($name, $connection); } } catch (NotFoundError $e) { throw new NotFoundError(sprintf( 'Unable to load parent referenced from %s "%s", %s', $this->object->getShortTableName(), $this->object->getObjectName(), lcfirst($e->getMessage()) ), $e->getCode(), $e); } return $this->objects[$import->getObjectName()] = $import; } protected function getImportTableName() { return $this->object->getTableName() . '_inheritance'; } public function listImportNames() { return array_keys($this->imports); } public function listOriginalImportNames() { return $this->storedNames; } public function getType() { return $this->object->getShortTableName(); } protected function loadFromDb() { // $resolver = $this->object->templateResolver(); // $this->objects = $resolver->fetchParents(); $this->objects = IcingaTemplateRepository::instanceByObject($this->object) ->getTemplatesIndexedByNameFor($this->object); if (empty($this->objects)) { $this->imports = []; } else { $keys = array_keys($this->objects); $this->imports = array_combine($keys, $keys); } $this->setBeingLoadedFromDb(); return $this; } /** * @return bool * @throws \Zend_Db_Adapter_Exception * @throws \Icinga\Exception\NotFoundError */ public function store() { if (! $this->hasBeenModified()) { return true; } $objectId = $this->object->get('id'); if ($objectId === null) { throw new RuntimeException( 'Cannot store imports for unstored object with no ID' ); } else { $objectId = (int) $objectId; } $type = $this->getType(); $objectCol = $type . '_id'; $importCol = 'parent_' . $type . '_id'; $table = $this->getImportTableName(); $db = $this->object->getDb(); if ($this->object->hasBeenLoadedFromDb()) { $db->delete( $table, $objectCol . ' = ' . $objectId ); } $weight = 1; foreach ($this->getObjects() as $import) { $db->insert($table, [ $objectCol => $objectId, $importCol => $import->get('id'), 'weight' => $weight++ ]); } $this->setBeingLoadedFromDb(); return true; } public function setBeingLoadedFromDb() { $this->storedNames = $this->listImportNames(); $this->modified = false; } protected function getImportClass() { return get_class($this->object); } public static function loadForStoredObject(IcingaObject $object) { $obj = new static($object); return $obj->loadFromDb(); } public function toConfigString() { $ret = ''; foreach ($this->listImportNames() as $name) { $ret .= ' import ' . c::renderString($name) . "\n"; } if ($ret !== '') { $ret .= "\n"; } return $ret; } public function toLegacyConfigString() { $ret = ''; foreach ($this->listImportNames() as $name) { $ret .= c1::renderKeyValue('use', c1::renderString($name)) . "\n"; } if ($ret !== '') { $ret .= "\n"; } return $ret; } 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()); } } } public function __destruct() { unset($this->object); unset($this->objects); } }