From b9fa0ff3f47718e115c799fb2976969f40678b87 Mon Sep 17 00:00:00 2001 From: Demian Katz <demian.katz@villanova.edu> Date: Wed, 31 Aug 2016 14:45:42 -0400 Subject: [PATCH] Add @parent_yaml support. --- config/vufind/searchspecs.yaml | 13 +++ .../src/VuFind/Config/SearchSpecsReader.php | 7 ++ .../Config/SearchSpecsReaderTest.php | 79 ++++++++++++++++++- 3 files changed, 98 insertions(+), 1 deletion(-) diff --git a/config/vufind/searchspecs.yaml b/config/vufind/searchspecs.yaml index e945c79ad98..62e12e5d243 100644 --- a/config/vufind/searchspecs.yaml +++ b/config/vufind/searchspecs.yaml @@ -148,6 +148,19 @@ # [uppercase] - Convert string to uppercase # # See the CallNumber search below for an example of custom munging in action. +# +#----------------------------------------------------------------------------------- +# +# Note that you may create a "@parent_yaml" entry at the very top of the file to +# inherit sections from another file. For example: +# +# @parent_yaml: "/path/to/my/file.yaml" +# +# Only sections not found in this file will be loaded in from the parent file. +# In some complex scenarios, this can be a useful way of sharing settings +# between multiple configured VuFind instances. You can create a chain of parent +# files if necessary. +# #----------------------------------------------------------------------------------- # These searches use Dismax when possible: diff --git a/module/VuFind/src/VuFind/Config/SearchSpecsReader.php b/module/VuFind/src/VuFind/Config/SearchSpecsReader.php index 8bc6b752e9f..d772c346e30 100644 --- a/module/VuFind/src/VuFind/Config/SearchSpecsReader.php +++ b/module/VuFind/src/VuFind/Config/SearchSpecsReader.php @@ -134,6 +134,13 @@ class SearchSpecsReader $results = (!empty($file) && file_exists($file)) ? Yaml::parse(file_get_contents($file)) : []; + // Override default parent with explicitly-defined parent, if present: + if (isset($results['@parent_yaml'])) { + $defaultParent = $results['@parent_yaml']; + // Swallow the directive after processing it: + unset($results['@parent_yaml']); + } + // Now load in missing sections from parent, if applicable: if (null !== $defaultParent) { foreach ($this->parseYaml($defaultParent) as $section => $contents) { diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/SearchSpecsReaderTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/SearchSpecsReaderTest.php index ce7e7fdf408..52d8c0f2947 100644 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/SearchSpecsReaderTest.php +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/SearchSpecsReaderTest.php @@ -26,7 +26,7 @@ * @link https://vufind.org/wiki/development:testing:unit_tests Wiki */ namespace VuFindTest\Config; -use VuFind\Config\SearchSpecsReader; +use VuFind\Config\Locator, VuFind\Config\SearchSpecsReader; /** * Config SearchSpecsReader Test Class @@ -40,6 +40,49 @@ use VuFind\Config\SearchSpecsReader; */ class SearchSpecsReaderTest extends \VuFindTest\Unit\TestCase { + /** + * Flag -- did writing config files fail? + * + * @var bool + */ + protected static $writeFailed = false; + + /** + * Array of files to clean up after test. + * + * @var array + */ + protected static $filesToDelete = []; + + /** + * Standard setup method. + * + * @return void + */ + public static function setUpBeforeClass() + { + // Create test files: + $parentPath = Locator::getLocalConfigPath('top.yaml', null, true); + $parent = "top: foo"; + $childPath = Locator::getLocalConfigPath('middle.yaml', null, true); + $child = "@parent_yaml: $parentPath\nmiddle: bar"; + $grandchildPath = Locator::getLocalConfigPath('bottom.yaml', null, true); + $grandchild = "@parent_yaml: $childPath\nbottom: baz"; + + // Fail if we are unable to write files: + if (null === $parentPath || null === $childPath || null === $grandchildPath + || !file_put_contents($parentPath, $parent) + || !file_put_contents($childPath, $child) + || !file_put_contents($grandchildPath, $grandchild) + ) { + self::$writeFailed = true; + return; + } + + // Mark for cleanup: + self::$filesToDelete = [$parentPath, $childPath, $grandchildPath]; + } + /** * Test loading of a YAML file. * @@ -114,4 +157,38 @@ class SearchSpecsReaderTest extends \VuFindTest\Unit\TestCase $this->callMethod($reader, 'getFromPaths', [$core, $local]) ); } + + /** + * Test @parent_yaml directive. + * + * @return void + */ + public function testParentYaml() + { + if (self::$writeFailed) { + $this->markTestSkipped('Could not write test configurations.'); + } + $reader = new SearchSpecsReader(); + $core = Locator::getLocalConfigPath('middle.yaml', null, true); + $local = Locator::getLocalConfigPath('bottom.yaml', null, true); + $this->assertEquals( + [ + 'top' => 'foo', + 'middle' => 'bar', + 'bottom' => 'baz', + ], + $this->callMethod($reader, 'getFromPaths', [$core, $local]) + ); + } + + /** + * Standard teardown method. + * + * @return void + */ + public static function tearDownAfterClass() + { + // Clean up test files: + array_map('unlink', self::$filesToDelete); + } } -- GitLab