123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- <?php
- /**
- * @package Grav.Common.Config
- *
- * @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
- * @license MIT License; see LICENSE file for details.
- */
- namespace Grav\Common\Config;
- use Grav\Common\File\CompiledYamlFile;
- use Grav\Common\Data\Data;
- use Grav\Common\Utils;
- use Pimple\Container;
- use RocketTheme\Toolbox\File\YamlFile;
- use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
- class Setup extends Data
- {
- public static $environment;
- protected $streams = [
- 'system' => [
- 'type' => 'ReadOnlyStream',
- 'prefixes' => [
- '' => ['system'],
- ]
- ],
- 'user' => [
- 'type' => 'ReadOnlyStream',
- 'force' => true,
- 'prefixes' => [
- '' => ['user'],
- ]
- ],
- 'environment' => [
- 'type' => 'ReadOnlyStream'
- // If not defined, environment will be set up in the constructor.
- ],
- 'asset' => [
- 'type' => 'ReadOnlyStream',
- 'prefixes' => [
- '' => ['assets'],
- ]
- ],
- 'blueprints' => [
- 'type' => 'ReadOnlyStream',
- 'prefixes' => [
- '' => ['environment://blueprints', 'user://blueprints', 'system/blueprints'],
- ]
- ],
- 'config' => [
- 'type' => 'ReadOnlyStream',
- 'prefixes' => [
- '' => ['environment://config', 'user://config', 'system/config'],
- ]
- ],
- 'plugins' => [
- 'type' => 'ReadOnlyStream',
- 'prefixes' => [
- '' => ['user://plugins'],
- ]
- ],
- 'plugin' => [
- 'type' => 'ReadOnlyStream',
- 'prefixes' => [
- '' => ['user://plugins'],
- ]
- ],
- 'themes' => [
- 'type' => 'ReadOnlyStream',
- 'prefixes' => [
- '' => ['user://themes'],
- ]
- ],
- 'languages' => [
- 'type' => 'ReadOnlyStream',
- 'prefixes' => [
- '' => ['environment://languages', 'user://languages', 'system/languages'],
- ]
- ],
- 'cache' => [
- 'type' => 'Stream',
- 'force' => true,
- 'prefixes' => [
- '' => ['cache'],
- 'images' => ['images']
- ]
- ],
- 'log' => [
- 'type' => 'Stream',
- 'force' => true,
- 'prefixes' => [
- '' => ['logs']
- ]
- ],
- 'backup' => [
- 'type' => 'Stream',
- 'force' => true,
- 'prefixes' => [
- '' => ['backup']
- ]
- ],
- 'tmp' => [
- 'type' => 'Stream',
- 'force' => true,
- 'prefixes' => [
- '' => ['tmp']
- ]
- ],
- 'image' => [
- 'type' => 'ReadOnlyStream',
- 'prefixes' => [
- '' => ['user://images', 'system://images']
- ]
- ],
- 'page' => [
- 'type' => 'ReadOnlyStream',
- 'prefixes' => [
- '' => ['user://pages']
- ]
- ],
- 'account' => [
- 'type' => 'ReadOnlyStream',
- 'prefixes' => [
- '' => ['user://accounts']
- ]
- ],
- ];
- /**
- * @param Container|array $container
- */
- public function __construct($container)
- {
- $environment = null !== static::$environment ? static::$environment : ($container['uri']->environment() ?: 'localhost');
- // Pre-load setup.php which contains our initial configuration.
- // Configuration may contain dynamic parts, which is why we need to always load it.
- // If "GRAVE_SETUP_PATH" has been defined, use it, otherwise use defaults.
- $file = defined('GRAV_SETUP_PATH') ? GRAV_SETUP_PATH : GRAV_ROOT . '/setup.php';
- $setup = is_file($file) ? (array) include $file : [];
- // Add default streams defined in beginning of the class.
- if (!isset($setup['streams']['schemes'])) {
- $setup['streams']['schemes'] = [];
- }
- $setup['streams']['schemes'] += $this->streams;
- // Initialize class.
- parent::__construct($setup);
- // Set up environment.
- $this->def('environment', $environment ?: 'cli');
- $this->def('streams.schemes.environment.prefixes', ['' => $environment ? ["user://{$this->environment}"] : []]);
- }
- /**
- * @return $this
- * @throws \RuntimeException
- * @throws \InvalidArgumentException
- */
- public function init()
- {
- $locator = new UniformResourceLocator(GRAV_ROOT);
- $files = [];
- $guard = 5;
- do {
- $check = $files;
- $this->initializeLocator($locator);
- $files = $locator->findResources('config://streams.yaml');
- if ($check === $files) {
- break;
- }
- // Update streams.
- foreach (array_reverse($files) as $path) {
- $file = CompiledYamlFile::instance($path);
- $content = (array)$file->content();
- if (!empty($content['schemes'])) {
- $this->items['streams']['schemes'] = $content['schemes'] + $this->items['streams']['schemes'];
- }
- }
- } while (--$guard);
- if (!$guard) {
- throw new \RuntimeException('Setup: Configuration reload loop detected!');
- }
- // Make sure we have valid setup.
- $this->check($locator);
- return $this;
- }
- /**
- * Initialize resource locator by using the configuration.
- *
- * @param UniformResourceLocator $locator
- * @throws \BadMethodCallException
- */
- public function initializeLocator(UniformResourceLocator $locator)
- {
- $locator->reset();
- $schemes = (array) $this->get('streams.schemes', []);
- foreach ($schemes as $scheme => $config) {
- if (isset($config['paths'])) {
- $locator->addPath($scheme, '', $config['paths']);
- }
- $override = isset($config['override']) ? $config['override'] : false;
- $force = isset($config['force']) ? $config['force'] : false;
- if (isset($config['prefixes'])) {
- foreach ((array)$config['prefixes'] as $prefix => $paths) {
- $locator->addPath($scheme, $prefix, $paths, $override, $force);
- }
- }
- }
- }
- /**
- * Get available streams and their types from the configuration.
- *
- * @return array
- */
- public function getStreams()
- {
- $schemes = [];
- foreach ((array) $this->get('streams.schemes') as $scheme => $config) {
- $type = !empty($config['type']) ? $config['type'] : 'ReadOnlyStream';
- if ($type[0] !== '\\') {
- $type = '\\RocketTheme\\Toolbox\\StreamWrapper\\' . $type;
- }
- $schemes[$scheme] = $type;
- }
- return $schemes;
- }
- /**
- * @param UniformResourceLocator $locator
- * @throws \InvalidArgumentException
- * @throws \BadMethodCallException
- * @throws \RuntimeException
- */
- protected function check(UniformResourceLocator $locator)
- {
- $streams = isset($this->items['streams']['schemes']) ? $this->items['streams']['schemes'] : null;
- if (!is_array($streams)) {
- throw new \InvalidArgumentException('Configuration is missing streams.schemes!');
- }
- $diff = array_keys(array_diff_key($this->streams, $streams));
- if ($diff) {
- throw new \InvalidArgumentException(
- sprintf('Configuration is missing keys %s from streams.schemes!', implode(', ', $diff))
- );
- }
- try {
- if (!$locator->findResource('environment://config', true)) {
- // If environment does not have its own directory, remove it from the lookup.
- $this->set('streams.schemes.environment.prefixes', ['config' => []]);
- $this->initializeLocator($locator);
- }
- // Create security.yaml if it doesn't exist.
- $filename = $locator->findResource('config://security.yaml', true, true);
- $file = YamlFile::instance($filename);
- if (!$file->exists()) {
- $file->save(['salt' => Utils::generateRandomString(14)]);
- $file->free();
- }
- } catch (\RuntimeException $e) {
- throw new \RuntimeException(sprintf('Grav failed to initialize: %s', $e->getMessage()), 500, $e);
- }
- }
- }
|