From 920c0279900423a09a905b3586456cd850b08e9a Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Tue, 1 Jul 2014 14:55:45 +0200 Subject: [PATCH] Ensure that the ini writer deletes properties properly The fix for #5958 introduced with commit 6aaff6b3 caused the property deletion of the PreservingIniWriter be even more faulty than before. The actual fix for this issue is an improved procedure for how properties are deleted as the initial implementation suffered from a few misunderstandings in how properties in Zend_Ini files need to be handled. fixes #6599 fixes #6601 fixes #6600 fixes #6598 fixes #6614 --- library/Icinga/Config/PreservingIniWriter.php | 55 ++++++++++++------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/library/Icinga/Config/PreservingIniWriter.php b/library/Icinga/Config/PreservingIniWriter.php index 159a52fdd..a89cf268c 100644 --- a/library/Icinga/Config/PreservingIniWriter.php +++ b/library/Icinga/Config/PreservingIniWriter.php @@ -177,29 +177,42 @@ class PreservingIniWriter extends Zend_Config_Writer_FileAbstract // Iterate over all properties in the old configuration file and search for deleted properties foreach ($oldconfig as $key => $value) { - $nextParents = array_merge($parents, array($key)); - $newvalue = $newconfig->get($key); - $keyIdentifier = empty($parents) ? array($key) : array_slice($nextParents, 1, null, true); - - if ($newvalue === null) { - if ($value instanceof Zend_Config) { - // The deleted value is a nested Zend_Config, handle it recursively - $this->diffConfigs($value, new Zend_Config(array()), $editor, $nextParents); - if ($section === null) { - $editor->removeSection($key); - } - } else { - // The deleted value is a plain value, use the editor to delete it - if (is_numeric($key)) { - $editor->resetArrayElement($keyIdentifier, $section); - } elseif (!empty($parents)) { - // Drop nested properties, fixes #5958 - $editor->resetArrayElement($nextParents, $section); - } else { - $editor->reset($keyIdentifier, $section); - } + if ($newconfig->get($key) === null) { + $nextParents = array_merge($parents, array($key)); + $keyIdentifier = empty($parents) ? array($key) : array_slice($nextParents, 1, null, true); + foreach ($this->getPropertyIdentifiers($value, $keyIdentifier) as $propertyIdentifier) { + $editor->reset($propertyIdentifier, $section); } } } } + + /** + * Return all possible combinations of property identifiers for the given value + * + * @param mixed $value The value to return all combinations for + * @param array $key The root property identifier, if any + * + * @return array All property combinations that are possible + * + * @todo Cannot handle array properties yet (e.g. a.b[]='c') + */ + protected function getPropertyIdentifiers($value, array $key = null) + { + $combinations = array(); + $rootProperty = $key !== null ? $key : array(); + + if ($value instanceof Zend_Config) { + foreach ($value as $subProperty => $subValue) { + $combinations = array_merge( + $combinations, + $this->getPropertyIdentifiers($subValue, array_merge($rootProperty, array($subProperty))) + ); + } + } elseif (is_string($value)) { + $combinations[] = $rootProperty; + } + + return $combinations; + } }