From be297677e8940b27aaa32a12dbdc212ab88162de Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 18 Feb 2016 14:16:37 +0200 Subject: [PATCH] Blueprint extend: Fix extending blueprints for configuration --- composer.lock | 8 +- .../Grav/Common/Config/CompiledBlueprints.php | 105 +++++++++++++++++- 2 files changed, 106 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index 527905e1b..093ff4a34 100644 --- a/composer.lock +++ b/composer.lock @@ -637,12 +637,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "a88015f9e6e473e5ddf4294f747d8fe434de3857" + "reference": "2c6f703d6da8570ec2ab51d5111189e284d5a12e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/a88015f9e6e473e5ddf4294f747d8fe434de3857", - "reference": "a88015f9e6e473e5ddf4294f747d8fe434de3857", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/2c6f703d6da8570ec2ab51d5111189e284d5a12e", + "reference": "2c6f703d6da8570ec2ab51d5111189e284d5a12e", "shasum": "" }, "require": { @@ -677,7 +677,7 @@ "php", "rockettheme" ], - "time": "2016-02-16 10:01:59" + "time": "2016-02-18 12:10:06" }, { "name": "symfony/console", diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php index d35bbbd45..bd028c0c3 100644 --- a/system/src/Grav/Common/Config/CompiledBlueprints.php +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -4,6 +4,7 @@ namespace Grav\Common\Config; use Grav\Common\File\CompiledYamlFile; use Grav\Common\Grav; use RocketTheme\Toolbox\Blueprints\Blueprints; +use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; /** * The Compiled Blueprints class. @@ -46,6 +47,11 @@ class CompiledBlueprints extends CompiledBase $this->object = (new Blueprints($data))->setTypes($this->getTypes()); } + /** + * Get list of form field types. + * + * @return array + */ protected function getTypes() { return Grav::instance()['plugins']->formFieldTypes; @@ -63,12 +69,105 @@ class CompiledBlueprints extends CompiledBase * Load single configuration file and append it to the correct position. * * @param string $name Name of the position. - * @param string $filename File to be loaded. + * @param array $files Files to be loaded. */ - protected function loadFile($name, $filename) + protected function loadFile($name, $files) { + $data = $this->loadBlueprints($files); + + // Merge all extends into a single blueprint. + foreach ($data as $content) { + $this->object->embed($name, $content, '/', 1); + } + } + + protected function loadBlueprints(array $files) + { + $filename = array_shift($files); $file = CompiledYamlFile::instance($filename); - $this->object->embed($name, $file->content(), '/'); + $content = $file->content(); $file->free(); + + $extends = isset($content['@extends']) ? (array) $content['@extends'] + : (isset($content['extends@']) ? (array) $content['extends@'] : null); + + $data = isset($extends) ? $this->extendBlueprint($files, $extends) : []; + $data[] = $content; + + return $data; + } + + protected function extendBlueprint(array $parents, array $extends) + { + if (is_string(key($extends))) { + $extends = [$extends]; + } + + $data = []; + foreach ($extends as $extendConfig) { + // Accept array of type and context or a string. + $extendType = !is_string($extendConfig) + ? !isset($extendConfig['type']) ? null : $extendConfig['type'] : $extendConfig; + + if (!$extendType) { + continue; + } + + if ($extendType === '@parent' || $extendType === 'parent@') { + $files = $parents; + + } else { + if (strpos($extendType, '://')) { + $path = $extendType; + } elseif (empty($extendConfig['context'])) { + $path = "blueprints://{$extendType}"; + } else { + $separator = $extendConfig['context'][strlen($extendConfig['context'])-1] === '/' ? '' : '/'; + $path = $extendConfig['context'] . $separator . $extendType; + } + if (!preg_match('/\.yaml$/', $path)) { + $path .= '.yaml'; + } + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + $files = $locator->findResources($path); + } + + if ($files) { + $data = array_merge($data, $this->loadBlueprints($files)); + } + } + + return $data; + } + + /** + * Load and join all configuration files. + * + * @return bool + * @internal + */ + protected function loadFiles() + { + $this->createObject(); + + // Convert file list into parent list. + $list = []; + foreach ($this->files as $files) { + foreach ($files as $name => $item) { + $list[$name][] = $this->path . $item['file']; + } + } + + // Load files. + foreach ($list as $name => $files) { + $this->loadFile($name, $files); + } + + $this->finalizeObject(); + + return true; } }