Skip to content
Snippets Groups Projects
Commit 8d1e828d authored by André Lahmann's avatar André Lahmann Committed by Demian Katz
Browse files

Config inheritance array merge setting (#921)

parent 2687898c
No related merge requests found
...@@ -1135,6 +1135,12 @@ skip_numeric = true ...@@ -1135,6 +1135,12 @@ skip_numeric = true
; any sections not listed here will be merged on a section-by-section basis. ; any sections not listed here will be merged on a section-by-section basis.
;override_full_sections = "Languages,AlphaBrowse_Types" ;override_full_sections = "Languages,AlphaBrowse_Types"
; This setting is for allowing arrays to be merged with the values of their parents
; arrays. If override_full_sections is set for a section the arrays will always be
; overridden.
; For legacy reasons merging of arrays is disabled by default.
;merge_array_settings = false
; This section controls which language options are available to your users. ; This section controls which language options are available to your users.
; If you offer more than one option, a control will appear in the user ; If you offer more than one option, a control will appear in the user
; interface to allow user selection. If you only activate one language, ; interface to allow user selection. If you only activate one language,
......
...@@ -113,6 +113,11 @@ class PluginFactory implements AbstractFactoryInterface ...@@ -113,6 +113,11 @@ class PluginFactory implements AbstractFactoryInterface
) )
: []; : [];
foreach ($child as $section => $contents) { foreach ($child as $section => $contents) {
// Check if arrays in the current config file should be merged with
// preceding arrays from config files defined as Parent_Config.
$mergeArraySettings
= !empty($child->Parent_Config->merge_array_settings);
// Omit Parent_Config from the returned configuration; it is only // Omit Parent_Config from the returned configuration; it is only
// needed during loading, and its presence will cause problems in // needed during loading, and its presence will cause problems in
// config files that iterate through all of the sections (e.g. // config files that iterate through all of the sections (e.g.
...@@ -126,7 +131,21 @@ class PluginFactory implements AbstractFactoryInterface ...@@ -126,7 +131,21 @@ class PluginFactory implements AbstractFactoryInterface
$config->$section = $child->$section; $config->$section = $child->$section;
} else { } else {
foreach (array_keys($contents->toArray()) as $key) { foreach (array_keys($contents->toArray()) as $key) {
$config->$section->$key = $child->$section->$key; // If a key is defined as key[] in the config file the key
// remains a Zend\Config\Config object. If the current
// section is not configured as an override section we try to
// merge the key[] values instead of overwriting them.
if (is_object($config->$section->$key)
&& is_object($child->$section->$key)
&& $mergeArraySettings
) {
$config->$section->$key = array_merge(
$config->$section->$key->toArray(),
$child->$section->$key->toArray()
);
} else {
$config->$section->$key = $child->$section->$key;
}
} }
} }
} }
......
...@@ -75,20 +75,36 @@ class PluginFactoryTest extends \VuFindTest\Unit\TestCase ...@@ -75,20 +75,36 @@ class PluginFactoryTest extends \VuFindTest\Unit\TestCase
. "[Section2]\n" . "[Section2]\n"
. "d=4\ne=5\nf=6\n" . "d=4\ne=5\nf=6\n"
. "[Section3]\n" . "[Section3]\n"
. "g=7\nh=8\ni=9\n"; . "g=7\nh=8\ni=9\n"
. "[Section4]\n"
. "j[] = 1\nj[] = 2\nk[a] = 1\nk[b] = 2\n";
$childPath = Locator::getLocalConfigPath('unit-test-child.ini', null, true); $childPath = Locator::getLocalConfigPath('unit-test-child.ini', null, true);
$child = "[Section1]\n" $child = "[Section1]\n"
. "j=10\nk=11\nl=12\n" . "j=10\nk=11\nl=12\n"
. "[Section2]\n" . "[Section2]\n"
. "m=13\nn=14\no=15\n" . "m=13\nn=14\no=15\n"
. "[Section4]\n"
. "j[] = 3\nk[c] = 3\n"
. "[Parent_Config]\n" . "[Parent_Config]\n"
. "path=\"{$parentPath}\"\n" . "path=\"{$parentPath}\"\n"
. "override_full_sections=Section1\n"; . "override_full_sections=Section1\n";
$child2Path = Locator::getLocalConfigPath('unit-test-child2.ini', null, true);
$child2 = "[Section1]\n"
. "j=10\nk=11\nl=12\n"
. "[Section2]\n"
. "m=13\nn=14\no=15\n"
. "[Section4]\n"
. "j[] = 3\nk[c] = 3\n"
. "[Parent_Config]\n"
. "path=\"{$parentPath}\"\n"
. "override_full_sections=Section1\n"
. "merge_array_settings=true\n";
// Fail if we are unable to write files: // Fail if we are unable to write files:
if (null === $parentPath || null === $childPath if (null === $parentPath || null === $childPath || null === $child2Path
|| !file_put_contents($parentPath, $parent) || !file_put_contents($parentPath, $parent)
|| !file_put_contents($childPath, $child) || !file_put_contents($childPath, $child)
|| !file_put_contents($child2Path, $child2)
) { ) {
self::$writeFailed = true; self::$writeFailed = true;
return; return;
...@@ -175,6 +191,45 @@ class PluginFactoryTest extends \VuFindTest\Unit\TestCase ...@@ -175,6 +191,45 @@ class PluginFactoryTest extends \VuFindTest\Unit\TestCase
// Make sure Section 3 was inherited; values from parent should exist. // Make sure Section 3 was inherited; values from parent should exist.
$this->assertEquals('7', $config->Section3->g); $this->assertEquals('7', $config->Section3->g);
// Make sure Section 4 arrays were overwritten.
$this->assertEquals([3], $config->Section4->j->toArray());
$this->assertEquals(['c' => 3], $config->Section4->k->toArray());
}
/**
* Test inheritance features with array merging turned on.
*
* @return void
*/
public function testInheritanceWithArrayMerging()
{
if (self::$writeFailed) {
$this->markTestSkipped('Could not write test configurations.');
}
// Make sure load succeeds:
$config = $this->getConfig('unit-test-child2');
$this->assertTrue(is_object($config));
// Make sure Section 1 was overridden; values from parent should not be
// present.
$this->assertTrue(!isset($config->Section1->a));
$this->assertEquals('10', $config->Section1->j);
// Make sure Section 2 was merged; values from parent and child should
// both be present.
$this->assertEquals('4', $config->Section2->d);
$this->assertEquals('13', $config->Section2->m);
// Make sure Section 3 was inherited; values from parent should exist.
$this->assertEquals('7', $config->Section3->g);
// Make sure Section 4 arrays were overwritten.
$this->assertEquals([1, 2, 3], $config->Section4->j->toArray());
$this->assertEquals(
['a' => 1, 'b' => 2, 'c' => 3], $config->Section4->k->toArray()
);
} }
/** /**
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment