summaryrefslogtreecommitdiffstats
path: root/library/Director/DirectorObject/Automation/BasketSnapshotFieldResolver.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Director/DirectorObject/Automation/BasketSnapshotFieldResolver.php')
-rw-r--r--library/Director/DirectorObject/Automation/BasketSnapshotFieldResolver.php226
1 files changed, 226 insertions, 0 deletions
diff --git a/library/Director/DirectorObject/Automation/BasketSnapshotFieldResolver.php b/library/Director/DirectorObject/Automation/BasketSnapshotFieldResolver.php
new file mode 100644
index 0000000..4653255
--- /dev/null
+++ b/library/Director/DirectorObject/Automation/BasketSnapshotFieldResolver.php
@@ -0,0 +1,226 @@
+<?php
+
+namespace Icinga\Module\Director\DirectorObject\Automation;
+
+use Icinga\Module\Director\Db;
+use Icinga\Module\Director\Objects\DirectorDatafield;
+use Icinga\Module\Director\Objects\IcingaObject;
+
+class BasketSnapshotFieldResolver
+{
+ /** @var BasketSnapshot */
+ protected $snapshot;
+
+ /** @var \Icinga\Module\Director\Data\Db\DbConnection */
+ protected $targetDb;
+
+ /** @var array|null */
+ protected $requiredIds;
+
+ protected $objects;
+
+ /** @var int */
+ protected $nextNewId = 1;
+
+ /** @var array|null */
+ protected $idMap;
+
+ /** @var DirectorDatafield[]|null */
+ protected $targetFields;
+
+ public function __construct($objects, Db $targetDb)
+ {
+ $this->objects = $objects;
+ $this->targetDb = $targetDb;
+ }
+
+ /**
+ * @param Db $db
+ * @return DirectorDatafield[]
+ * @throws \Icinga\Exception\NotFoundError
+ */
+ public function loadCurrentFields(Db $db)
+ {
+ $fields = [];
+ foreach ($this->getRequiredIds() as $id) {
+ $fields[$id] = DirectorDatafield::loadWithAutoIncId((int) $id, $db);
+ }
+
+ return $fields;
+ }
+
+ /**
+ * @throws \Icinga\Exception\NotFoundError
+ * @throws \Icinga\Module\Director\Exception\DuplicateKeyException
+ */
+ public function storeNewFields()
+ {
+ $this->targetFields = null; // Clear Cache
+ foreach ($this->getTargetFields() as $id => $field) {
+ if ($field->hasBeenModified()) {
+ $field->store();
+ $this->idMap[$id] = $field->get('id');
+ }
+ }
+ }
+
+ /**
+ * @param IcingaObject $new
+ * @param $object
+ * @throws \Icinga\Exception\NotFoundError
+ * @throws \Zend_Db_Adapter_Exception
+ */
+ public function relinkObjectFields(IcingaObject $new, $object)
+ {
+ if (! $new->supportsFields() || ! isset($object->fields)) {
+ return;
+ }
+ $fieldMap = $this->getIdMap();
+
+ $objectId = (int) $new->get('id');
+ $table = $new->getTableName() . '_field';
+ $objectKey = $new->getShortTableName() . '_id';
+ $existingFields = [];
+
+ $db = $this->targetDb->getDbAdapter();
+
+ foreach ($db->fetchAll(
+ $db->select()->from($table)->where("$objectKey = ?", $objectId)
+ ) as $mapping) {
+ $existingFields[(int) $mapping->datafield_id] = $mapping;
+ }
+ foreach ($object->fields as $field) {
+ $id = $fieldMap[(int) $field->datafield_id];
+ if (isset($existingFields[$id])) {
+ unset($existingFields[$id]);
+ } else {
+ $db->insert($table, [
+ $objectKey => $objectId,
+ 'datafield_id' => $id,
+ 'is_required' => $field->is_required,
+ 'var_filter' => $field->var_filter,
+ ]);
+ }
+ }
+ if (! empty($existingFields)) {
+ $db->delete(
+ $table,
+ $db->quoteInto(
+ "$objectKey = $objectId AND datafield_id IN (?)",
+ array_keys($existingFields)
+ )
+ );
+ }
+ }
+
+ /**
+ * @param object $object
+ * @throws \Icinga\Exception\NotFoundError
+ */
+ public function tweakTargetIds($object)
+ {
+ $forward = $this->getIdMap();
+ $map = array_flip($forward);
+ if (isset($object->fields)) {
+ foreach ($object->fields as $field) {
+ $id = $field->datafield_id;
+ if (isset($map[$id])) {
+ $field->datafield_id = $map[$id];
+ } else {
+ $field->datafield_id = "(NEW)";
+ }
+ }
+ }
+ }
+
+ /**
+ * @return int
+ */
+ protected function getNextNewId()
+ {
+ return $this->nextNewId++;
+ }
+
+ protected function getRequiredIds()
+ {
+ if ($this->requiredIds === null) {
+ if (isset($this->objects['Datafield'])) {
+ $this->requiredIds = array_keys($this->objects['Datafield']);
+ } else {
+ $ids = [];
+ foreach ($this->objects as $typeName => $objects) {
+ foreach ($objects as $key => $object) {
+ if (isset($object->fields)) {
+ foreach ($object->fields as $field) {
+ $ids[$field->datafield_id] = true;
+ }
+ }
+ }
+ }
+
+ $this->requiredIds = array_keys($ids);
+ }
+ }
+
+ return $this->requiredIds;
+ }
+
+ /**
+ * @param $type
+ * @return object[]
+ */
+ protected function getObjectsByType($type)
+ {
+ if (isset($this->objects->$type)) {
+ return (array) $this->objects->$type;
+ } else {
+ return [];
+ }
+ }
+
+ /**
+ * @return DirectorDatafield[]
+ * @throws \Icinga\Exception\NotFoundError
+ */
+ protected function getTargetFields()
+ {
+ if ($this->targetFields === null) {
+ $this->calculateIdMap();
+ }
+
+ return $this->targetFields;
+ }
+
+ /**
+ * @throws \Icinga\Exception\NotFoundError
+ */
+ protected function getIdMap()
+ {
+ if ($this->idMap === null) {
+ $this->calculateIdMap();
+ }
+
+ return $this->idMap;
+ }
+
+ /**
+ * @throws \Icinga\Exception\NotFoundError
+ */
+ protected function calculateIdMap()
+ {
+ $this->idMap = [];
+ $this->targetFields = [];
+ foreach ($this->getObjectsByType('Datafield') as $id => $object) {
+ unset($object->category_id); // Fix old baskets
+ // Hint: import() doesn't store!
+ $new = DirectorDatafield::import($object, $this->targetDb);
+ if ($new->hasBeenLoadedFromDb()) {
+ $newId = (int) $new->get('id');
+ } else {
+ $newId = sprintf('NEW(%s)', $this->getNextNewId());
+ }
+ $this->idMap[$id] = $newId;
+ $this->targetFields[$id] = $new;
+ }
+ }
+}