mirror of
https://github.com/getgrav/grav.git
synced 2026-07-07 17:21:49 +02:00
Blueprints: Move duplicated extends@ logic into BlueprintForm class
This commit is contained in:
@@ -3,9 +3,7 @@ namespace Grav\Common\Config;
|
||||
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\Data\BlueprintForm;
|
||||
use Grav\Common\File\CompiledYamlFile;
|
||||
use Grav\Common\Grav;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
/**
|
||||
* The Compiled Blueprints class.
|
||||
@@ -73,91 +71,10 @@ class CompiledBlueprints extends CompiledBase
|
||||
*/
|
||||
protected function loadFile($name, $files)
|
||||
{
|
||||
$data = $this->loadBlueprints($files);
|
||||
// Load blueprint file.
|
||||
$blueprintForm = new BlueprintForm($files);
|
||||
|
||||
// Merge all extends into a single blueprint.
|
||||
$blueprintForm = new BlueprintForm(array_shift($data));
|
||||
foreach ($data as $content) {
|
||||
$blueprintForm->extend($content, true);
|
||||
}
|
||||
$blueprintForm->init();
|
||||
|
||||
$this->object->embed($name, $blueprintForm->toArray(), '/', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function that handles loading extended blueprints.
|
||||
*
|
||||
* @param array $files
|
||||
* @return array
|
||||
*/
|
||||
protected function loadBlueprints(array $files)
|
||||
{
|
||||
$filename = array_shift($files);
|
||||
$file = CompiledYamlFile::instance($filename);
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to recursively load extended blueprints.
|
||||
*
|
||||
* @param array $parents
|
||||
* @param array $extends
|
||||
* @return array
|
||||
*/
|
||||
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;
|
||||
$this->object->embed($name, $blueprintForm->load()->toArray(), '/', true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
namespace Grav\Common\Data;
|
||||
|
||||
use Grav\Common\File\CompiledYamlFile;
|
||||
use RocketTheme\Toolbox\ArrayTraits\Constructor;
|
||||
use Grav\Common\Grav;
|
||||
use RocketTheme\Toolbox\ArrayTraits\Export;
|
||||
use RocketTheme\Toolbox\ArrayTraits\ExportInterface;
|
||||
use RocketTheme\Toolbox\ArrayTraits\NestedArrayAccessWithGetters;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
/**
|
||||
* The Config class contains configuration information.
|
||||
@@ -14,15 +15,116 @@ use RocketTheme\Toolbox\ArrayTraits\NestedArrayAccessWithGetters;
|
||||
*/
|
||||
class BlueprintForm implements \ArrayAccess, ExportInterface
|
||||
{
|
||||
use Constructor, NestedArrayAccessWithGetters, Export;
|
||||
use NestedArrayAccessWithGetters, Export;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $items;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $context = 'blueprints://';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $overrides = [];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string|array $filename
|
||||
* @param array $items
|
||||
*/
|
||||
public function __construct($filename, array $items = [])
|
||||
{
|
||||
$this->filename = $filename;
|
||||
$this->items = $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set context for import@ and extend@.
|
||||
*
|
||||
* @param $context
|
||||
* @return $this
|
||||
*/
|
||||
public function setContext($context)
|
||||
{
|
||||
$this->context = $context;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set custom overrides for import@ and extend@.
|
||||
*
|
||||
* @param array $overrides
|
||||
* @return $this
|
||||
*/
|
||||
public function setOverrides(array $overrides)
|
||||
{
|
||||
$this->overrides = $overrides;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load blueprint.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function load()
|
||||
{
|
||||
$path = $this->filename;
|
||||
|
||||
if (is_string($path) && !strpos($path, '://')) {
|
||||
// Resolve filename.
|
||||
$path = isset($this->overrides[$path]) ? $this->overrides[$path] : "{$this->context}{$path}";
|
||||
if (!preg_match('/\.yaml$/', $path)) {
|
||||
$path .= YAML_EXT;
|
||||
}
|
||||
}
|
||||
|
||||
// Only load and extend blueprint if it has not yet been loaded.
|
||||
if (empty($this->items)) {
|
||||
// Get list of parent files.
|
||||
if (is_string($path) && strpos($path, '://')) {
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
|
||||
$files = $locator->findResources($path);
|
||||
} else {
|
||||
$files = (array) $path;
|
||||
}
|
||||
|
||||
// Load and extend blueprints.
|
||||
$data = $this->doLoad($files);
|
||||
|
||||
$this->items = array_shift($data);
|
||||
foreach ($data as $content) {
|
||||
$this->extend($content, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally initialize blueprint.
|
||||
return $this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize blueprint.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
// Import blueprints.
|
||||
$this->deepInit($this->items);
|
||||
|
||||
return $this;
|
||||
@@ -209,7 +311,7 @@ class BlueprintForm implements \ArrayAccess, ExportInterface
|
||||
if (strpos($type, '://')) {
|
||||
$filename = $type;
|
||||
} elseif (empty($value['context'])) {
|
||||
$filename = "blueprints://{$type}";
|
||||
$filename = isset($this->overrides[$type]) ? $this->overrides[$type] : "{$this->context}{$type}";
|
||||
} else {
|
||||
$separator = $value['context'][strlen($value['context'])-1] === '/' ? '' : '/';
|
||||
$filename = $value['context'] . $separator . $type;
|
||||
@@ -218,15 +320,94 @@ class BlueprintForm implements \ArrayAccess, ExportInterface
|
||||
$filename .= YAML_EXT;
|
||||
}
|
||||
|
||||
|
||||
if (!is_file($filename)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$file = CompiledYamlFile::instance($filename);
|
||||
$blueprint = (new BlueprintForm($file->content()))->init();
|
||||
$blueprint = (new BlueprintForm($filename))->setContext($this->context)->setOverrides($this->overrides)->load();
|
||||
|
||||
$name = implode('/', $path);
|
||||
|
||||
$this->embed($name, $blueprint->form(), '/', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function that handles loading extended blueprints.
|
||||
*
|
||||
* @param array $files
|
||||
* @return array
|
||||
*/
|
||||
protected function doLoad(array $files)
|
||||
{
|
||||
$filename = array_shift($files);
|
||||
$file = CompiledYamlFile::instance($filename);
|
||||
$content = $file->content();
|
||||
$file->free();
|
||||
|
||||
$extends = isset($content['@extends']) ? (array) $content['@extends']
|
||||
: (isset($content['extends@']) ? (array) $content['extends@'] : null);
|
||||
|
||||
$data = isset($extends) ? $this->doExtend($files, $extends) : [];
|
||||
$data[] = $content;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to recursively load extended blueprints.
|
||||
*
|
||||
* @param array $parents
|
||||
* @param array $extends
|
||||
* @return array
|
||||
*/
|
||||
protected function doExtend(array $parents, array $extends)
|
||||
{
|
||||
if (is_string(key($extends))) {
|
||||
$extends = [$extends];
|
||||
}
|
||||
|
||||
$data = [];
|
||||
foreach ($extends as $value) {
|
||||
// Accept array of type and context or a string.
|
||||
$type = !is_string($value)
|
||||
? !isset($value['type']) ? null : $value['type'] : $value;
|
||||
|
||||
if (!$type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($type === '@parent' || $type === 'parent@') {
|
||||
$files = $parents;
|
||||
|
||||
} else {
|
||||
if (strpos($type, '://')) {
|
||||
$path = $type;
|
||||
} elseif (empty($value['context'])) {
|
||||
$path = isset($this->overrides[$type]) ? $this->overrides[$type] : "{$this->context}{$type}";
|
||||
} else {
|
||||
$separator = $value['context'][strlen($value['context'])-1] === '/' ? '' : '/';
|
||||
$path = $value['context'] . $separator . $type;
|
||||
}
|
||||
if (!preg_match('/\.yaml$/', $path)) {
|
||||
$path .= YAML_EXT;
|
||||
}
|
||||
|
||||
if (strpos($path, '://')) {
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
|
||||
$files = $locator->findResources($path);
|
||||
} else {
|
||||
$files = (array) $path;
|
||||
}
|
||||
}
|
||||
|
||||
if ($files) {
|
||||
$data = array_merge($data, $this->doLoad($files));
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
namespace Grav\Common\Data;
|
||||
|
||||
use Grav\Common\File\CompiledYamlFile;
|
||||
use Grav\Common\Grav;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
@@ -15,7 +14,7 @@ class Blueprints
|
||||
{
|
||||
protected $search;
|
||||
protected $types;
|
||||
protected $instances = array();
|
||||
protected $instances = [];
|
||||
|
||||
/**
|
||||
* @param string|array $search Search path.
|
||||
@@ -35,25 +34,7 @@ class Blueprints
|
||||
public function get($type)
|
||||
{
|
||||
if (!isset($this->instances[$type])) {
|
||||
if (!is_string($this->search)) {
|
||||
$filename = isset($this->search[$type]) ? $this->search[$type] : null;
|
||||
} else {
|
||||
$filename = $this->search . $type . YAML_EXT;
|
||||
}
|
||||
|
||||
// Check if search is a stream and resolve the path.
|
||||
if ($filename && strpos($filename, '://')) {
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
|
||||
$files = $locator->findResources($filename);
|
||||
} else {
|
||||
$files = (array) $filename;
|
||||
}
|
||||
|
||||
$blueprint = $this->loadFile($type, $files);
|
||||
|
||||
$this->instances[$type] = $blueprint->init();
|
||||
$this->instances[$type] = $this->loadFile($type);
|
||||
}
|
||||
|
||||
return $this->instances[$type];
|
||||
@@ -90,109 +71,29 @@ class Blueprints
|
||||
$this->types[$name] = ucfirst(strtr($name, '_', ' '));
|
||||
}
|
||||
}
|
||||
|
||||
return $this->types;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load single configuration file and make a blueprint.
|
||||
* Load blueprint file.
|
||||
*
|
||||
* @param string $name Name of the position.
|
||||
* @param array $files Files to be loaded.
|
||||
* @param string $name Name of the blueprint.
|
||||
* @return Blueprint
|
||||
*/
|
||||
protected function loadFile($name, $files)
|
||||
protected function loadFile($name)
|
||||
{
|
||||
$data = $this->loadBlueprints($files);
|
||||
|
||||
// Merge all extends into a single blueprint.
|
||||
$blueprintForm = new BlueprintForm(array_shift($data));
|
||||
foreach ($data as $content) {
|
||||
$blueprintForm->extend($content, true);
|
||||
$blueprintForm = new BlueprintForm($name);
|
||||
if (is_array($this->search)) {
|
||||
$blueprintForm->setOverrides($this->search);
|
||||
} else {
|
||||
$blueprintForm->setContext($this->search);
|
||||
}
|
||||
$blueprintForm->init();
|
||||
$blueprintForm->load();
|
||||
|
||||
$blueprint = new Blueprint($name, $blueprintForm->toArray(), $this);
|
||||
$blueprint = new Blueprint($name, $blueprintForm->toArray());
|
||||
|
||||
return $blueprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function that handles loading extended blueprints.
|
||||
*
|
||||
* @param array $files
|
||||
* @return array
|
||||
*/
|
||||
protected function loadBlueprints(array $files)
|
||||
{
|
||||
$filename = array_shift($files);
|
||||
$file = CompiledYamlFile::instance($filename);
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to recursively load extended blueprints.
|
||||
*
|
||||
* @param array $parents
|
||||
* @param array $extends
|
||||
* @return array
|
||||
*/
|
||||
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 = isset($this->search[$extendType]) ? $this->search[$extendType] : "blueprints://{$extendType}";
|
||||
} else {
|
||||
$separator = $extendConfig['context'][strlen($extendConfig['context'])-1] === '/' ? '' : '/';
|
||||
$path = $extendConfig['context'] . $separator . $extendType;
|
||||
}
|
||||
if (!preg_match('/\.yaml$/', $path)) {
|
||||
$path .= '.yaml';
|
||||
}
|
||||
|
||||
if (strpos($path, '://')) {
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
|
||||
$files = $locator->findResources($path);
|
||||
} else {
|
||||
$files = (array) $path;
|
||||
}
|
||||
}
|
||||
|
||||
if ($files) {
|
||||
$data = array_merge($data, $this->loadBlueprints($files));
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
return $blueprint->init();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user