diff --git a/library/Director/Objects/IcingaCommandArgument.php b/library/Director/Objects/IcingaCommandArgument.php index be4db155..5de6d235 100644 --- a/library/Director/Objects/IcingaCommandArgument.php +++ b/library/Director/Objects/IcingaCommandArgument.php @@ -48,7 +48,8 @@ class IcingaCommandArgument extends IcingaObject // No log right now, we have to handle "sub-objects" } - public function replaceWith(IcingaObject $object) + // Preserve is not supported + public function replaceWith(IcingaObject $object, $preserve = null) { $this->setProperties((array) $object->toPlainObject( false, diff --git a/library/Director/Objects/IcingaObject.php b/library/Director/Objects/IcingaObject.php index b7e5da44..e4a467e3 100644 --- a/library/Director/Objects/IcingaObject.php +++ b/library/Director/Objects/IcingaObject.php @@ -339,6 +339,15 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer } } + if (substr($key, 0, 5) === 'vars.') { + $var = $this->vars()->get(substr($key, 5)); + if ($var === null) { + return $var; + } else { + return $var->getValue(); + } + } + if ($this->hasRelation($key)) { if ($id = $this->get($key . '_id')) { $class = $this->getRelationClass($key); @@ -1495,9 +1504,21 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer return static::create((array) $plain, $connection); } - public function replaceWith(IcingaObject $object) + public function replaceWith(IcingaObject $object, $preserve = null) { - $this->setProperties((array) $object->toPlainObject()); + if ($preserve === null) { + $this->setProperties((array) $object->toPlainObject()); + } else { + $plain = (array) $object->toPlainObject(); + foreach ($preserve as $k) { + $v = $this->$k; + if ($v !== null) { + $plain[$k] = $v; + } + } + + $this->setProperties($plain); + } return $this; } diff --git a/test/php/library/Director/Objects/IcingaHostTest.php b/test/php/library/Director/Objects/IcingaHostTest.php index 942a6639..ccf7a584 100644 --- a/test/php/library/Director/Objects/IcingaHostTest.php +++ b/test/php/library/Director/Objects/IcingaHostTest.php @@ -84,6 +84,73 @@ class IcingaHostTest extends BaseTestCase ); } + public function testPropertiesCanBePreservedWhenBeingReplaced() + { + if ($this->skipForMissingDb()) { + return; + } + + $db = $this->getDb(); + $this->host()->store($db); + $host = IcingaHost::load($this->testHostName, $db); + + $newHost = IcingaHost::create( + array( + 'display_name' => 'Replaced display', + 'address' => '1.2.2.3', + 'vars' => array( + 'test1' => 'newstring', + 'test2' => 18, + 'initially' => 'set and then preserved', + ) + ) + ); + + $preserve = array('address', 'vars.test1', 'vars.initially'); + $host->replaceWith($newHost, $preserve); + $this->assertEquals( + $host->address, + '127.0.0.127' + ); + + $this->assertEquals( + $host->{'vars.test2'}, + 18 + ); + + $this->assertEquals( + $host->vars()->test2->getValue(), + 18 + ); + + $this->assertEquals( + $host->{'vars.initially'}, + 'set and then preserved' + ); + + $this->assertFalse( + array_key_exists('address', $host->getModifiedProperties()), + 'Preserved property stays unmodified' + ); + + $newHost->set('vars.initially', 'changed later on'); + $newHost->set('vars.test2', 19); + + $host->replaceWith($newHost, $preserve); + $this->assertEquals( + $host->{'vars.initially'}, + 'set and then preserved' + ); + + $this->assertEquals( + $host->get('vars.test2'), + 19 + ); + + + $host->delete(); + } + public function testDistinctCustomVarsCanBeSetWithoutSideEffects() { $host = $this->host();