Upgrade to 3.6.0
This commit is contained in:
250
kirby/src/Cms/Loader.php
Executable file
250
kirby/src/Cms/Loader.php
Executable file
@@ -0,0 +1,250 @@
|
||||
<?php
|
||||
|
||||
namespace Kirby\Cms;
|
||||
|
||||
use Closure;
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Filesystem\F;
|
||||
|
||||
/**
|
||||
* The Loader class is an internal loader for
|
||||
* core parts, like areas, components, sections, etc.
|
||||
*
|
||||
* It's exposed in the `$kirby->load()` and the
|
||||
* `$kirby->core()->load()` methods.
|
||||
*
|
||||
* With `$kirby->load()` you get access to core parts
|
||||
* that might be overwritten by plugins.
|
||||
*
|
||||
* With `$kirby->core()->load()` you get access to
|
||||
* untouched core parts. This is useful if you want to
|
||||
* reuse or fall back to core features in your plugins.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link https://getkirby.com
|
||||
* @copyright Bastian Allgeier GmbH
|
||||
* @license https://getkirby.com/license
|
||||
*/
|
||||
class Loader
|
||||
{
|
||||
/**
|
||||
* @var \Kirby\Cms\App
|
||||
*/
|
||||
protected $kirby;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $withPlugins;
|
||||
|
||||
/**
|
||||
* @param \Kirby\Cms\App $kirby
|
||||
* @param bool $withPlugins
|
||||
*/
|
||||
public function __construct(App $kirby, bool $withPlugins = true)
|
||||
{
|
||||
$this->kirby = $kirby;
|
||||
$this->withPlugins = $withPlugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the area definition
|
||||
*
|
||||
* @param string $name
|
||||
* @return array|null
|
||||
*/
|
||||
public function area(string $name): ?array
|
||||
{
|
||||
return $this->areas()[$name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all areas and makes sure that plugins
|
||||
* are injected properly
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function areas(): array
|
||||
{
|
||||
$areas = [];
|
||||
$extensions = $this->withPlugins === true ? $this->kirby->extensions('areas') : [];
|
||||
|
||||
// load core areas and extend them with elements from plugins if they exist
|
||||
foreach ($this->kirby->core()->areas() as $id => $area) {
|
||||
$area = $this->resolveArea($area);
|
||||
|
||||
if (isset($extensions[$id]) === true) {
|
||||
foreach ($extensions[$id] as $areaExtension) {
|
||||
$extension = $this->resolveArea($areaExtension);
|
||||
$area = array_replace_recursive($area, $extension);
|
||||
}
|
||||
|
||||
unset($extensions[$id]);
|
||||
}
|
||||
|
||||
$areas[$id] = $area;
|
||||
}
|
||||
|
||||
// add additional areas from plugins
|
||||
foreach ($extensions as $id => $areaExtensions) {
|
||||
foreach ($areaExtensions as $areaExtension) {
|
||||
$areas[$id] = $this->resolve($areaExtension);
|
||||
}
|
||||
}
|
||||
|
||||
return $areas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a core component closure
|
||||
*
|
||||
* @param string $name
|
||||
* @return \Closure|null
|
||||
*/
|
||||
public function component(string $name): ?Closure
|
||||
{
|
||||
return $this->extension('components', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all core component closures
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function components(): array
|
||||
{
|
||||
return $this->extensions('components');
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a particular extension
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function extension(string $type, string $name)
|
||||
{
|
||||
return $this->extensions($type)[$name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all defined extensions
|
||||
*
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
public function extensions(string $type): array
|
||||
{
|
||||
return $this->withPlugins === false ? $this->kirby->core()->$type() : $this->kirby->extensions($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* The resolver takes a string, array or closure.
|
||||
*
|
||||
* 1.) a string is supposed to be a path to an existing file.
|
||||
* The file will either be included when it's a PHP file and
|
||||
* the array contents will be read. Or it will be parsed with
|
||||
* the Data class to read yml or json data into an array
|
||||
*
|
||||
* 2.) arrays are untouched and returned
|
||||
*
|
||||
* 3.) closures will be called and the Kirby instance will be
|
||||
* passed as first argument
|
||||
*
|
||||
* @param mixed $item
|
||||
* @return mixed
|
||||
*/
|
||||
public function resolve($item)
|
||||
{
|
||||
if (is_string($item) === true) {
|
||||
if (F::extension($item) !== 'php') {
|
||||
$item = Data::read($item);
|
||||
} else {
|
||||
$item = require $item;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_callable($item)) {
|
||||
$item = $item($this->kirby);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls `static::resolve()` on all items
|
||||
* in the given array
|
||||
*
|
||||
* @param array $items
|
||||
* @return array
|
||||
*/
|
||||
public function resolveAll(array $items): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($items as $key => $value) {
|
||||
$result[$key] = $this->resolve($value);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Areas need a bit of special treatment
|
||||
* when they are being loaded
|
||||
*
|
||||
* @param string|array|Closure $area
|
||||
* @return array
|
||||
*/
|
||||
public function resolveArea($area): array
|
||||
{
|
||||
$area = $this->resolve($area);
|
||||
$dropdowns = $area['dropdowns'] ?? [];
|
||||
|
||||
// convert closure dropdowns to an array definition
|
||||
// otherwise they cannot be merged properly later
|
||||
foreach ($dropdowns as $key => $dropdown) {
|
||||
if (is_a($dropdown, 'Closure') === true) {
|
||||
$area['dropdowns'][$key] = [
|
||||
'options' => $dropdown
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $area;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a particular section definition
|
||||
*
|
||||
* @param string $name
|
||||
* @return array|null
|
||||
*/
|
||||
public function section(string $name): ?array
|
||||
{
|
||||
return $this->resolve($this->extension('sections', $name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all section defintions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function sections(): array
|
||||
{
|
||||
return $this->resolveAll($this->extensions('sections'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status flag, which shows
|
||||
* if plugins are loaded as well.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function withPlugins(): bool
|
||||
{
|
||||
return $this->withPlugins;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user