Basket/Datafield: map best candidate, fix bindings
This commit is contained in:
parent
2e37758336
commit
eb789162cb
|
@ -178,6 +178,10 @@ class BasketController extends ActionController
|
|||
$this->addSingleTab($this->translate('Snapshot'));
|
||||
$all = Json::decode($json);
|
||||
foreach ($all as $type => $objects) {
|
||||
if ($type === 'Datafield') {
|
||||
// $this->content()->add(Html::tag('h2', sprintf('+%d Datafield(s)', count($objects))));
|
||||
continue;
|
||||
}
|
||||
$table = new NameValueTable();
|
||||
$table->setAttribute('data-base-target', '_next');
|
||||
foreach ($objects as $key => $object) {
|
||||
|
@ -225,6 +229,7 @@ class BasketController extends ActionController
|
|||
$this->content()->add(Html::tag('h2', $type));
|
||||
$this->content()->add($table);
|
||||
}
|
||||
$this->content()->add(Html::tag('div', ['style' => 'height: 5em']));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,6 +9,7 @@ use Icinga\Module\Director\Objects\DirectorDatafield;
|
|||
use Icinga\Module\Director\Objects\IcingaCommand;
|
||||
use Icinga\Module\Director\Objects\IcingaObject;
|
||||
use RuntimeException;
|
||||
use Zend_Db_Adapter_Abstract as ZfDbAdapter;
|
||||
|
||||
class BasketSnapshot extends DbObject
|
||||
{
|
||||
|
@ -70,6 +71,12 @@ class BasketSnapshot extends DbObject
|
|||
return $types[$type];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Basket $basket
|
||||
* @param Db $db
|
||||
* @return BasketSnapshot
|
||||
* @throws \Icinga\Exception\NotFoundError
|
||||
*/
|
||||
public static function createForBasket(Basket $basket, Db $db)
|
||||
{
|
||||
$snapshot = static::create([
|
||||
|
@ -102,7 +109,7 @@ class BasketSnapshot extends DbObject
|
|||
$this->objects['Datafield'] = [];
|
||||
}
|
||||
$fields = & $this->objects['Datafield'];
|
||||
foreach ($requiredIds as $id) {
|
||||
foreach (array_keys($requiredIds) as $id) {
|
||||
if (! isset($fields[$id])) {
|
||||
$fields[$id] = DirectorDatafield::loadWithAutoIncId((int) $id, $connection)->export();
|
||||
}
|
||||
|
@ -148,19 +155,21 @@ class BasketSnapshot extends DbObject
|
|||
* @param bool $replace
|
||||
* @throws \Icinga\Module\Director\Exception\DuplicateKeyException
|
||||
* @throws \Icinga\Exception\NotFoundError
|
||||
* @throws \Zend_Db_Adapter_Exception
|
||||
*/
|
||||
public function restoreTo(Db $connection, $replace = true)
|
||||
{
|
||||
$all = Json::decode($this->getJsonDump());
|
||||
$db = $connection->getDbAdapter();
|
||||
$db->beginTransaction();
|
||||
$fieldMap = [];
|
||||
foreach ($this->restoreOrder as $typeName) {
|
||||
if (isset($all->$typeName)) {
|
||||
$objects = $all->$typeName;
|
||||
$class = static::getClassForType($typeName);
|
||||
|
||||
$changed = [];
|
||||
foreach ($objects as $object) {
|
||||
foreach ($objects as $key => $object) {
|
||||
/** @var DbObject $new */
|
||||
$new = $class::import($object, $connection, $replace);
|
||||
if ($new->hasBeenModified()) {
|
||||
|
@ -170,6 +179,13 @@ class BasketSnapshot extends DbObject
|
|||
$new->store();
|
||||
}
|
||||
}
|
||||
if ($new instanceof DirectorDatafield) {
|
||||
$fieldMap[(int) $key] = (int) $new->get('id');
|
||||
}
|
||||
|
||||
if ($new instanceof IcingaObject) {
|
||||
$this->relinkObjectFields($db, $new, $object, $fieldMap);
|
||||
}
|
||||
}
|
||||
|
||||
/** @var IcingaObject $object */
|
||||
|
@ -181,6 +197,53 @@ class BasketSnapshot extends DbObject
|
|||
$db->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ZfDbAdapter $db
|
||||
* @param IcingaObject $new
|
||||
* @param $object
|
||||
* @param $fieldMap
|
||||
* @throws \Zend_Db_Adapter_Exception
|
||||
*/
|
||||
protected function relinkObjectFields(ZfDbAdapter $db, IcingaObject $new, $object, $fieldMap)
|
||||
{
|
||||
if (! $new->supportsFields() || ! isset($object->fields)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$objectId = (int) $new->get('id');
|
||||
$table = $new->getTableName() . '_field';
|
||||
$objectKey = $new->getShortTableName() . '_id';
|
||||
$existingFields = [];
|
||||
|
||||
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 IcingaObject $object
|
||||
* @param $list
|
||||
|
|
|
@ -93,17 +93,32 @@ class DirectorDatafield extends DbObjectWithSettings
|
|||
$id = null;
|
||||
}
|
||||
|
||||
$encoded = Json::encode($properties);
|
||||
if ($id) {
|
||||
if (static::exists($id, $db)) {
|
||||
$existing = static::loadWithAutoIncId($id, $db);
|
||||
$existingProperties = (array) $existing->export();
|
||||
unset($existingProperties['originalId']);
|
||||
if (Json::encode($properties) === Json::encode($existingProperties)) {
|
||||
if ($encoded === Json::encode($existingProperties)) {
|
||||
return $existing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$dba = $db->getDbAdapter();
|
||||
$query = $dba->select()
|
||||
->from('director_datafield')
|
||||
->where('varname = ?', $plain->varname);
|
||||
$candidates = DirectorDatafield::loadAll($db, $query);
|
||||
|
||||
foreach ($candidates as $candidate) {
|
||||
$export = $candidate->export();
|
||||
unset($export->originalId);
|
||||
if (Json::encode($export) === $encoded) {
|
||||
return $candidate;
|
||||
}
|
||||
}
|
||||
|
||||
return static::create($properties, $db);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue