Basket: fix various little issues

fixes #1691
This commit is contained in:
Thomas Gelf 2018-12-10 17:52:56 +01:00
parent ac69d022b6
commit 0c2e3fe1b1
5 changed files with 187 additions and 56 deletions

View File

@ -282,6 +282,14 @@ class BasketController extends ActionController
} }
$currentExport = $current->export(); $currentExport = $current->export();
$fieldResolver->tweakTargetIds($currentExport); $fieldResolver->tweakTargetIds($currentExport);
// Ignore originalId
if (isset($currentExport->originalId)) {
unset($currentExport->originalId);
}
if (isset($object->originalId)) {
unset($object->originalId);
}
$hasChanged = Json::encode($currentExport) !== Json::encode($object); $hasChanged = Json::encode($currentExport) !== Json::encode($object);
$table->addNameValueRow( $table->addNameValueRow(
$key, $key,

View File

@ -24,6 +24,8 @@ class Basket extends DbObject implements ExportInterface
protected $chosenObjects = []; protected $chosenObjects = [];
protected $protectedFormerChosenObjects;
protected $defaultProperties = [ protected $defaultProperties = [
'uuid' => null, 'uuid' => null,
'basket_name' => null, 'basket_name' => null,
@ -118,6 +120,7 @@ class Basket extends DbObject implements ExportInterface
if (empty($objects)) { if (empty($objects)) {
$this->chosenObjects = []; $this->chosenObjects = [];
} else { } else {
$this->protectedFormerChosenObjects = $this->chosenObjects;
$this->chosenObjects = []; $this->chosenObjects = [];
foreach ((array) $objects as $type => $object) { foreach ((array) $objects as $type => $object) {
$this->addObjects($type, $object); $this->addObjects($type, $object);
@ -142,13 +145,17 @@ class Basket extends DbObject implements ExportInterface
} elseif ($objects === null || $objects === 'IGNORE') { } elseif ($objects === null || $objects === 'IGNORE') {
return; return;
} elseif ($objects === '[]' || is_array($objects)) { } elseif ($objects === '[]' || is_array($objects)) {
if (isset($this->chosenObjects[$type])) {
if (! is_array($this->chosenObjects[$type])) { if (! is_array($this->chosenObjects[$type])) {
$this->chosenObjects[$type] = []; $this->chosenObjects[$type] = [];
} }
if (isset($this->protectedFormerChosenObjects[$type])) {
if (is_array($this->protectedFormerChosenObjects[$type])) {
$this->chosenObjects[$type] = $this->protectedFormerChosenObjects;
} else { } else {
$this->chosenObjects[$type] = []; $this->chosenObjects[$type] = [];
} }
}
if ($objects === '[]') { if ($objects === '[]') {
$objects = []; $objects = [];
} }

View File

@ -54,7 +54,6 @@ class BasketSnapshot extends DbObject
'ServiceSet', 'ServiceSet',
'Notification', 'Notification',
'Dependency', 'Dependency',
'DataList',
'ImportSource', 'ImportSource',
'SyncRule', 'SyncRule',
'DirectorJob', 'DirectorJob',
@ -213,10 +212,36 @@ class BasketSnapshot extends DbObject
$db = $connection->getDbAdapter(); $db = $connection->getDbAdapter();
$db->beginTransaction(); $db->beginTransaction();
$fieldResolver = new BasketSnapshotFieldResolver($all, $connection); $fieldResolver = new BasketSnapshotFieldResolver($all, $connection);
$this->restoreType($all, 'DataList', $fieldResolver, $connection, $replace);
$fieldResolver->storeNewFields(); $fieldResolver->storeNewFields();
foreach ($this->restoreOrder as $typeName) { foreach ($this->restoreOrder as $typeName) {
$this->restoreType($all, $typeName, $fieldResolver, $connection, $replace);
}
$db->commit();
}
/**
* @param $all
* @param $typeName
* @param BasketSnapshotFieldResolver $fieldResolver
* @param Db $connection
* @param $replace
* @throws \Icinga\Exception\NotFoundError
* @throws \Icinga\Module\Director\Exception\DuplicateKeyException
* @throws \Zend_Db_Adapter_Exception
*/
protected function restoreType(
& $all,
$typeName,
BasketSnapshotFieldResolver $fieldResolver,
Db $connection,
$replace
) {
if (isset($all->$typeName)) { if (isset($all->$typeName)) {
$objects = (array) $all->$typeName; $objects = (array) $all->$typeName;
} else {
return;
}
$class = static::getClassForType($typeName); $class = static::getClassForType($typeName);
$changed = []; $changed = [];
@ -250,15 +275,12 @@ class BasketSnapshot extends DbObject
} }
foreach ($changed as $key => $new) { foreach ($changed as $key => $new) {
// Store related fields. As objects might have formerly been // Store related fields. As objects might have formerly been
// unstored, let's to it right here // un-stored, let's to it right here
if ($new instanceof IcingaObject) { if ($new instanceof IcingaObject) {
$fieldResolver->relinkObjectFields($new, $objects[$key]); $fieldResolver->relinkObjectFields($new, $objects[$key]);
} }
} }
} }
}
$db->commit();
}
/** /**
* @param IcingaObject $object * @param IcingaObject $object

View File

@ -93,12 +93,13 @@ class DirectorDatafield extends DbObjectWithSettings
} }
if (isset($properties['settings']->datalist)) { if (isset($properties['settings']->datalist)) {
// Just try to load the list, import should fail if missing
$list = DirectorDatalist::load( $list = DirectorDatalist::load(
$properties['settings']->datalist, $properties['settings']->datalist,
$db $db
); );
$properties['settings']->datalist_id = $list->get('id'); } else {
unset($properties['settings']->datalist); $list = null;
} }
$encoded = Json::encode($properties); $encoded = Json::encode($properties);
@ -113,6 +114,11 @@ class DirectorDatafield extends DbObjectWithSettings
} }
} }
if ($list) {
unset($properties['settings']->datalist);
$properties['settings']->datalist_id = $list->get('id');
}
$dba = $db->getDbAdapter(); $dba = $db->getDbAdapter();
$query = $dba->select() $query = $dba->select()
->from('director_datafield') ->from('director_datafield')

View File

@ -21,6 +21,9 @@ class DirectorDatalist extends DbObject implements ExportInterface
'owner' => null 'owner' => null
); );
/** @var DirectorDatalistEntry[] */
protected $storedEntries;
public function getUniqueIdentifier() public function getUniqueIdentifier()
{ {
return $this->get('list_name'); return $this->get('list_name');
@ -38,7 +41,6 @@ class DirectorDatalist extends DbObject implements ExportInterface
{ {
$properties = (array) $plain; $properties = (array) $plain;
if (isset($properties['originalId'])) { if (isset($properties['originalId'])) {
$id = $properties['originalId'];
unset($properties['originalId']); unset($properties['originalId']);
} else { } else {
$id = null; $id = null;
@ -56,13 +58,83 @@ class DirectorDatalist extends DbObject implements ExportInterface
$object = static::create([], $db); $object = static::create([], $db);
} }
$object->setProperties($properties); $object->setProperties($properties);
if ($id !== null) {
$object->reallySet('id', $id);
}
return $object; return $object;
} }
public function setEntries($entries)
{
$existing = $this->getStoredEntries();
$new = [];
$seen = [];
$modified = false;
foreach ($entries as $entry) {
$name = $entry->entry_name;
$entry = DirectorDatalistEntry::create((array) $entry);
$seen[$name] = true;
if (isset($existing[$name])) {
$existing[$name]->replaceWith($entry);
if (! $modified && $existing[$name]->hasBeenModified()) {
$modified = true;
}
} else {
$modified = true;
$new[] = $entry;
}
}
foreach (array_keys($existing) as $key) {
if (! isset($seen[$key])) {
$existing[$key]->markForRemoval();
$modified = true;
}
}
foreach ($new as $entry) {
$existing[$entry->get('entry_name')] = $entry;
}
if ($modified) {
$this->hasBeenModified = true;
}
$this->storedEntries = $existing;
ksort($this->storedEntries);
return $this;
}
/**
* @throws DuplicateKeyException
*/
public function onStore()
{
if ($this->storedEntries) {
$db = $this->getConnection();
$removedKeys = [];
$myId = $this->get('id');
foreach ($this->storedEntries as $key => $entry) {
if ($entry->shouldBeRemoved()) {
$entry->delete();
$removedKeys[] = $key;
} else {
if (! $entry->hasBeenLoadedFromDb()) {
$entry->set('list_id', $myId);
}
$entry->set('list_id', $myId);
$entry->store($db);
}
}
foreach ($removedKeys as $key) {
unset($this->storedEntries[$key]);
}
}
}
public function export() public function export()
{ {
$plain = (object) $this->getProperties(); $plain = (object) $this->getProperties();
@ -70,8 +142,10 @@ class DirectorDatalist extends DbObject implements ExportInterface
unset($plain->id); unset($plain->id);
$plain->entries = []; $plain->entries = [];
$entries = DirectorDatalistEntry::loadAllForList($this); foreach ($this->getStoredEntries() as $key => $entry) {
foreach ($entries as $key => $entry) { if ($entry->shouldBeRemoved()) {
continue;
}
$plainEntry = (object) $entry->getProperties(); $plainEntry = (object) $entry->getProperties();
unset($plainEntry->list_id); unset($plainEntry->list_id);
@ -80,4 +154,18 @@ class DirectorDatalist extends DbObject implements ExportInterface
return $plain; return $plain;
} }
protected function getStoredEntries()
{
if ($this->storedEntries === null) {
if ($id = $this->get('id')) {
$this->storedEntries = DirectorDatalistEntry::loadAllForList($this);
ksort($this->storedEntries);
} else {
$this->storedEntries = [];
}
}
return $this->storedEntries;
}
} }