Ejemplo n.º 1
0
 /**
  * Get theme or throw exception if it cannot be found.
  *
  * @param string $name
  * @return Data
  * @throws \RuntimeException
  */
 public function get($name)
 {
     if (!$name) {
         throw new \RuntimeException('Theme name not provided.');
     }
     $blueprints = new Blueprints("theme:///{$name}");
     $blueprint = $blueprints->get('blueprints');
     $blueprint->name = $name;
     /** @var Config $config */
     $config = $this->grav['config'];
     // Find thumbnail.
     $thumb = "theme:///{$name}/thumbnail.jpg";
     if (file_exists($thumb)) {
         $blueprint->set('thumbnail', $config->get('system.base_url_relative') . "/user/themes/{$name}/thumbnail.jpg");
     }
     // Load default configuration.
     $file = Yaml::instance("theme:///{$name}/{$name}.yaml");
     $obj = new Data($file->content(), $blueprint);
     // Override with user configuration.
     $file = Yaml::instance("user://config/themes/{$name}.yaml");
     $obj->merge($file->content());
     // Save configuration always to user/config.
     $obj->file($file);
     return $obj;
 }
Ejemplo n.º 2
0
 public function __construct(Data $package, $package_type = null)
 {
     $data = new Data($package->blueprints()->toArray());
     parent::__construct($data, $package_type);
     $this->settings = $package->toArray();
     $html_description = \Parsedown::instance()->line($this->description);
     $this->data->set('slug', $package->slug);
     $this->data->set('description_html', $html_description);
     $this->data->set('description_plain', strip_tags($html_description));
     $this->data->set('symlink', is_link(USER_DIR . $package_type . DS . $this->slug));
 }
Ejemplo n.º 3
0
 /**
  * @param Data $package
  * @param bool $package_type
  */
 public function __construct(Data $package, $package_type = false)
 {
     $this->data = $package;
     $this->blueprints = $this->data->blueprints();
     if ($package_type) {
         $html_description = \Parsedown::instance()->line($this->blueprints->get('description'));
         $this->blueprints->set('package_type', $package_type);
         $this->blueprints->set('description_html', $html_description);
         $this->blueprints->set('description_plain', strip_tags($html_description));
         $this->blueprints->set('symlink', is_link(USER_DIR . $package_type . DS . $this->blueprints->name));
     }
 }
Ejemplo n.º 4
0
 public function __construct(array $items = array(), Grav $grav = null, $environment = null)
 {
     $this->grav = $grav ?: Grav::instance();
     $this->finder = new ConfigFinder();
     $this->environment = $environment ?: 'localhost';
     $this->messages[] = 'Environment Name: ' . $this->environment;
     if (isset($items['@class'])) {
         if ($items['@class'] != get_class($this)) {
             throw new \InvalidArgumentException('Unrecognized config cache file!');
         }
         // Loading pre-compiled configuration.
         $this->timestamp = (int) $items['timestamp'];
         $this->checksum = $items['checksum'];
         $this->items = (array) $items['data'];
     } else {
         // Make sure that
         if (!isset($items['streams']['schemes'])) {
             $items['streams']['schemes'] = [];
         }
         $items['streams']['schemes'] += $this->streams;
         $items = $this->autoDetectEnvironmentConfig($items);
         $this->messages[] = $items['streams']['schemes']['config']['prefixes'][''];
         parent::__construct($items);
     }
     $this->check();
 }
Ejemplo n.º 5
0
 /**
  * Construct.
  *
  * @param array $items
  * @param Blueprint $blueprint
  */
 public function __construct($items = [], Blueprint $blueprint = null)
 {
     parent::__construct($items, $blueprint);
     if (self::getGrav()['config']->get('system.media.enable_media_timestamp', true)) {
         $this->querystring('&' . self::getGrav()['cache']->getKey());
     }
     $this->def('mime', 'application/octet-stream');
     $this->reset();
 }
 protected function prepareStandardEmbed($embedUrl, $urlQuery, array $ignore = [])
 {
     $userOpts = [];
     if (!empty($urlQuery)) {
         parse_str(trim($urlQuery, '?&'), $userOpts);
     }
     $userOpts = array_merge((array) $this->config->get('embed_options', []), $userOpts);
     $userOpts = array_diff_key($userOpts, array_flip($ignore));
     if (!empty($userOpts)) {
         $embedUrl .= '?' . http_build_query($userOpts);
     }
     $this->embed->setAttribute('src', $embedUrl);
     return $this->embed;
 }
Ejemplo n.º 7
0
 public function __construct($items = array(), Blueprint $blueprint = null)
 {
     parent::__construct($items, $blueprint);
     if ($this->get('type') == 'image') {
         $filePath = $this->get('path') . '/' . $this->get('filename');
         $image_info = getimagesize($filePath);
         $this->set('thumb', $filePath);
         $this->def('width', $image_info[0]);
         $this->def('height', $image_info[1]);
         $this->def('mime', $image_info['mime']);
         $this->reset();
     } else {
         $this->def('mime', 'application/octet-stream');
     }
 }
Ejemplo n.º 8
0
 public function __construct(array $setup = array(), Grav $grav = null, $environment = null)
 {
     $this->grav = $grav ?: Grav::instance();
     $this->finder = new ConfigFinder();
     $this->environment = $environment ?: 'localhost';
     $this->messages[] = 'Environment Name: ' . $this->environment;
     // Make sure that
     if (!isset($setup['streams']['schemes'])) {
         $setup['streams']['schemes'] = [];
     }
     $setup['streams']['schemes'] += $this->streams;
     $setup = $this->autoDetectEnvironmentConfig($setup);
     $this->setup = $setup;
     parent::__construct($setup);
     $this->check();
 }
Ejemplo n.º 9
0
 public function __construct($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.
     $file = 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);
     $this->def('streams.schemes.environment.prefixes', ['' => ["user://{$this->environment}"]]);
 }
 /**
  * Load shortcodes already provided by this plugin.
  */
 protected function loadShortcodes()
 {
     $iterator = new \FilesystemIterator(__DIR__ . '/Shortcodes');
     foreach ($iterator as $fileinfo) {
         $name = $fileinfo->getBasename('.php');
         // Load shortcodes in directory "Shortcodes"
         $class = __NAMESPACE__ . "\\Shortcodes\\{$name}";
         $defaults = $this->config->get('plugins.shortcodes.shortcodes.' . strtolower($name), []);
         if (empty($defaults) || $defaults['enabled']) {
             $options = isset($defaults['options']) ? $defaults['options'] : [];
             $shortcode = new $class($options);
             $this->register($shortcode);
         }
     }
     // Fire event
     self::getGrav()->fireEvent('onShortcodesInitialized', new Event(['shortcodes' => $this]));
     $this->shortcodes = $this->twig->getShortcodes();
     return array_keys($this->shortcodes);
 }
Ejemplo n.º 11
0
 /** -------------------------------
  * Private/protected helper methods
  * --------------------------------
  */
 protected function format($string, $params = [])
 {
     $keys = ['id', 'name', 'url'];
     foreach ($keys as $key) {
         if (!isset($params["{:{$key}}"])) {
             $params["{:{$key}}"] = $this->{$key}();
         }
     }
     $params += ['{:canonical}' => $this->config->get('canonical', '')];
     // Format URL placeholder with params
     $keys = ['{:url}', '{:canonical}'];
     foreach ($keys as $key) {
         $params[$key] = urlencode(str_ireplace(array_keys($params), $params, $params[$key]));
     }
     // Replace OEmbed calls with response
     $string = preg_replace_callback('~\\{\\:oembed(?:\\.(?=\\w))([\\.\\w_]+)?\\}~i', function ($match) {
         $ombed = $this->getOEmbed();
         return $oembed ? $oembed->get($match[1], '') : $match[0];
     }, $string);
     return str_ireplace(array_keys($params), $params, $string);
 }
Ejemplo n.º 12
0
 /**
  * Gets configuration data.
  *
  * @param string $type
  * @param array  $post
  *
  * @return mixed
  * @throws \RuntimeException
  */
 public function data($type, array $post = [])
 {
     static $data = [];
     if (isset($data[$type])) {
         return $data[$type];
     }
     if (!$post) {
         $post = isset($_POST['data']) ? $_POST['data'] : [];
     }
     // Check to see if a data type is plugin-provided, before looking into core ones
     $event = $this->grav->fireEvent('onAdminData', new Event(['type' => &$type]));
     if ($event && isset($event['data_type'])) {
         return $event['data_type'];
     }
     /** @var UniformResourceLocator $locator */
     $locator = $this->grav['locator'];
     $filename = $locator->findResource("config://{$type}.yaml", true, true);
     $file = CompiledYamlFile::instance($filename);
     if (preg_match('|plugins/|', $type)) {
         /** @var Plugins $plugins */
         $plugins = $this->grav['plugins'];
         $obj = $plugins->get(preg_replace('|plugins/|', '', $type));
         if (!$obj) {
             return [];
         }
         $obj->merge($post);
         $obj->file($file);
         $data[$type] = $obj;
     } elseif (preg_match('|themes/|', $type)) {
         /** @var Themes $themes */
         $themes = $this->grav['themes'];
         $obj = $themes->get(preg_replace('|themes/|', '', $type));
         if (!$obj) {
             return [];
         }
         $obj->merge($post);
         $obj->file($file);
         $data[$type] = $obj;
     } elseif (preg_match('|users/|', $type)) {
         $obj = User::load(preg_replace('|users/|', '', $type));
         $obj->merge($post);
         $data[$type] = $obj;
     } elseif (preg_match('|user/|', $type)) {
         $obj = User::load(preg_replace('|user/|', '', $type));
         $obj->merge($post);
         $data[$type] = $obj;
     } elseif (preg_match('|config/|', $type)) {
         $type = preg_replace('|config/|', '', $type);
         $blueprints = $this->blueprints("config/{$type}");
         $config = $this->grav['config'];
         $obj = new Data\Data($config->get($type, []), $blueprints);
         $obj->merge($post);
         // FIXME: We shouldn't allow user to change configuration files in system folder!
         $filename = $this->grav['locator']->findResource("config://{$type}.yaml") ?: $this->grav['locator']->findResource("config://{$type}.yaml", true, true);
         $file = CompiledYamlFile::instance($filename);
         $obj->file($file);
         $data[$type] = $obj;
     } else {
         throw new \RuntimeException("Data type '{$type}' doesn't exist!");
     }
     return $data[$type];
 }
Ejemplo n.º 13
0
 /**
  * Remove a group
  *
  * @param string $groupname
  *
  * @return bool True if the action was performed
  */
 public static function remove($groupname)
 {
     $blueprints = new Blueprints('blueprints://');
     $blueprint = $blueprints->get('user/group');
     $groups = self::getGrav()['config']->get("groups");
     unset($groups[$groupname]);
     self::getGrav()['config']->set("groups", $groups);
     $type = 'groups';
     $obj = new Data(self::getGrav()['config']->get($type), $blueprint);
     $file = CompiledYamlFile::instance(self::getGrav()['locator']->findResource("config://{$type}.yaml"));
     $obj->file($file);
     $obj->save();
     return true;
 }
Ejemplo n.º 14
0
 /**
  * Get theme configuration or throw exception if it cannot be found.
  *
  * @param  string            $name
  * @return Data
  * @throws \RuntimeException
  */
 public function get($name)
 {
     if (!$name) {
         throw new \RuntimeException('Theme name not provided.');
     }
     $blueprints = new Blueprints("themes://{$name}");
     $blueprint = $blueprints->get('blueprints');
     $blueprint->name = $name;
     // Find thumbnail.
     $thumb = "themes://{$name}/thumbnail.jpg";
     if (file_exists($thumb)) {
         $blueprint->set('thumbnail', $this->grav['base_url'] . "/user/themes/{$name}/thumbnail.jpg");
     }
     // Load default configuration.
     $file = CompiledYamlFile::instance("themes://{$name}/{$name}" . YAML_EXT);
     $obj = new Data($file->content(), $blueprint);
     // Override with user configuration.
     $file = CompiledYamlFile::instance("user://config/themes/{$name}" . YAML_EXT);
     $obj->merge($file->content());
     // Save configuration always to user/config.
     $obj->file($file);
     return $obj;
 }
Ejemplo n.º 15
0
 /**
  * Gets configuration data.
  *
  * @param string $type
  * @param array $post
  * @return Data\Data|null
  * @throws \RuntimeException
  */
 public function data($type, $post = array())
 {
     static $data = [];
     if (isset($data[$type])) {
         return $data[$type];
     }
     if (!$post) {
         $post = isset($_POST) ? $_POST : [];
     }
     switch ($type) {
         case 'configuration':
         case 'system':
             $type = 'system';
             $blueprints = $this->blueprints("config/{$type}");
             $config = $this->grav['config'];
             $obj = new Data\Data($config->get('system'), $blueprints);
             $obj->merge($post);
             $file = CompiledYamlFile::instance($this->grav['locator']->findResource("config://{$type}.yaml"));
             $obj->file($file);
             $data[$type] = $obj;
             break;
         case 'settings':
         case 'site':
             $type = 'site';
             $blueprints = $this->blueprints("config/{$type}");
             $config = $this->grav['config'];
             $obj = new Data\Data($config->get('site'), $blueprints);
             $obj->merge($post);
             $file = CompiledYamlFile::instance($this->grav['locator']->findResource("config://{$type}.yaml"));
             $obj->file($file);
             $data[$type] = $obj;
             break;
         case 'login':
             $data[$type] = null;
             break;
         default:
             /** @var UniformResourceLocator $locator */
             $locator = $this->grav['locator'];
             $filename = $locator->findResource("config://{$type}.yaml", true, true);
             $file = CompiledYamlFile::instance($filename);
             if (preg_match('|plugins/|', $type)) {
                 /** @var Plugins $plugins */
                 $plugins = $this->grav['plugins'];
                 $obj = $plugins->get(preg_replace('|plugins/|', '', $type));
                 $obj->merge($post);
                 $obj->file($file);
                 $data[$type] = $obj;
             } elseif (preg_match('|themes/|', $type)) {
                 /** @var Themes $themes */
                 $themes = $this->grav['themes'];
                 $obj = $themes->get(preg_replace('|themes/|', '', $type));
                 $obj->merge($post);
                 $obj->file($file);
                 $data[$type] = $obj;
             } elseif (preg_match('|users/|', $type)) {
                 $obj = User::load(preg_replace('|users/|', '', $type));
                 $obj->merge($post);
                 $data[$type] = $obj;
             } else {
                 throw new \RuntimeException("Data type '{$type}' doesn't exist!");
             }
     }
     return $data[$type];
 }
Ejemplo n.º 16
0
 /**
  * Toggle the gpm.releases setting
  */
 protected function taskGpmRelease()
 {
     if (!$this->authorizeTask('configuration', ['admin.configuration', 'admin.super'])) {
         return false;
     }
     // Default release state
     $release = 'stable';
     $reload = false;
     // Get the testing release value if set
     if ($this->post['release'] == 'testing') {
         $release = 'testing';
     }
     $config = $this->grav['config'];
     $current_release = $config->get('system.gpm.releases');
     // If the releases setting is different, save it in the system config
     if ($current_release != $release) {
         $data = new Data\Data($config->get('system'));
         $data->set('gpm.releases', $release);
         // Get the file location
         $file = CompiledYamlFile::instance($this->grav['locator']->findResource("config://system.yaml"));
         $data->file($file);
         // Save the configuration
         $data->save();
         $config->reload();
         $reload = true;
     }
     $this->admin->json_response = ['status' => 'success', 'reload' => $reload];
     return true;
 }
Ejemplo n.º 17
0
 public static function get($name)
 {
     $blueprints = new Blueprints('plugins://');
     $blueprint = $blueprints->get("{$name}/blueprints");
     $blueprint->name = $name;
     // Load default configuration.
     $file = CompiledYamlFile::instance("plugins://{$name}/{$name}.yaml");
     // ensure the plugin exists physically
     if (!$file->exists()) {
         return null;
     }
     $obj = new Data($file->content(), $blueprint);
     // Override with user configuration.
     $obj->merge(self::getGrav()['config']->get('plugins.' . $name) ?: []);
     // Save configuration always to user/config.
     $file = CompiledYamlFile::instance("config://plugins/{$name}.yaml");
     $obj->file($file);
     return $obj;
 }
Ejemplo n.º 18
0
 public static function get($type)
 {
     $blueprints = new Data\Blueprints('plugin://' . $type);
     $blueprint = $blueprints->get('blueprints');
     $blueprint->name = $type;
     // Load default configuration.
     $file = File\Yaml::instance('plugin://' . "{$type}/{$type}" . YAML_EXT);
     $obj = new Data\Data($file->content(), $blueprint);
     // Override with user configuration.
     $file = File\Yaml::instance('plugin://' . "config/plugins/{$type}" . YAML_EXT);
     $obj->merge($file->content());
     // Save configuration always to user/config.
     $obj->file($file);
     return $obj;
 }
Ejemplo n.º 19
0
 /** -------------------------------
  * Private/protected helper methods
  * --------------------------------
  */
 protected function format($string, $params = [])
 {
     $params += ['{:id}' => $this->id(), '{:name}' => $this->name(), '{:url}' => urlencode($this->config->get('website', ''))];
     // Format URL placeholder with params
     $params['{:url}'] = urlencode(str_ireplace(array_keys($params), $params, $params['{:url}']));
     $string = preg_replace_callback('~\\{\\:oembed(?:\\.(?=\\w))([\\.\\w_]+)?\\}~i', function ($match) {
         static $oembed;
         if (is_null($oembed)) {
             $oembed = new Data($this->getOEmbed());
         }
         return $oembed->get($match[1], '');
     }, $string);
     return str_ireplace(array_keys($params), $params, $string);
 }
Ejemplo n.º 20
0
 /**
  * Handle form processing on POST action.
  */
 public function post()
 {
     $grav = Grav::instance();
     $uri = $grav['uri']->url;
     $session = $grav['session'];
     if (isset($_POST)) {
         $this->values = new Data(isset($_POST) ? (array) $_POST : []);
         $data = $this->values->get('data');
         // Add post data to form dataset
         if (!$data) {
             $data = $this->values->toArray();
         }
         if (method_exists('Grav\\Common\\Utils', 'getNonce')) {
             if (!$this->values->get('form-nonce') || !Utils::verifyNonce($this->values->get('form-nonce'), 'form')) {
                 $event = new Event(['form' => $this, 'message' => $grav['language']->translate('PLUGIN_FORM.NONCE_NOT_VALIDATED')]);
                 $grav->fireEvent('onFormValidationError', $event);
                 return;
             }
         }
         $i = 0;
         foreach ($this->items['fields'] as $key => $field) {
             $name = isset($field['name']) ? $field['name'] : $key;
             if (!isset($field['name'])) {
                 if (isset($data[$i])) {
                     //Handle input@ false fields
                     $data[$name] = $data[$i];
                     unset($data[$i]);
                 }
             }
             if ($field['type'] == 'checkbox') {
                 $data[$name] = isset($data[$name]) ? true : false;
             }
             $i++;
         }
         $this->data->merge($data);
     }
     // Validate and filter data
     try {
         $this->data->validate();
         $this->data->filter();
         $grav->fireEvent('onFormValidationProcessed', new Event(['form' => $this]));
     } catch (\RuntimeException $e) {
         $event = new Event(['form' => $this, 'message' => $e->getMessage(), 'messages' => $e->getMessages()]);
         $grav->fireEvent('onFormValidationError', $event);
         if ($event->isPropagationStopped()) {
             return;
         }
     }
     // Process previously uploaded files for the current URI
     // and finally store them. Everything else will get discarded
     $queue = $session->getFlashObject('files-upload');
     $queue = $queue[base64_encode($uri)];
     if (is_array($queue)) {
         foreach ($queue as $key => $files) {
             foreach ($files as $destination => $file) {
                 if (!rename($file['tmp_name'], $destination)) {
                     throw new \RuntimeException(sprintf($grav['language']->translate('PLUGIN_FORM.FILEUPLOAD_UNABLE_TO_MOVE', null, true), '"' . $file['tmp_name'] . '"', $destination));
                 }
                 unset($files[$destination]['tmp_name']);
             }
             $this->data->merge([$key => $files]);
         }
     }
     $process = isset($this->items['process']) ? $this->items['process'] : [];
     if (is_array($process)) {
         $event = null;
         foreach ($process as $action => $data) {
             if (is_numeric($action)) {
                 $action = \key($data);
                 $data = $data[$action];
             }
             $previousEvent = $event;
             $event = new Event(['form' => $this, 'action' => $action, 'params' => $data]);
             if ($previousEvent) {
                 if (!$previousEvent->isPropagationStopped()) {
                     $grav->fireEvent('onFormProcessed', $event);
                 } else {
                     break;
                 }
             } else {
                 $grav->fireEvent('onFormProcessed', $event);
             }
         }
     } else {
         // Default action.
     }
 }
 /**
  * process the content by running over all the known shortcodes with the
  * chosen parser
  * 
  * @param  Page   $page   the page to work on
  * @param  Data   $config configuration merged with the page config
  */
 public function processContent(Page $page, Data $config)
 {
     switch ($config->get('parser')) {
         case 'regular':
             $parser = 'Thunder\\Shortcode\\Parser\\RegularParser';
             break;
         case 'wordpress':
             $parser = 'Thunder\\Shortcode\\Parser\\WordpressParser';
             break;
         default:
             $parser = 'Thunder\\Shortcode\\Parser\\RegexParser';
             break;
     }
     if ($page && $config->get('enabled')) {
         $content = $page->getRawContent();
         $processor = new Processor(new $parser(new CommonSyntax()), $this->handlers);
         $processor = $processor->withEventContainer($this->events);
         $processed_content = $processor->process($content);
         return $processed_content;
     }
 }
Ejemplo n.º 22
0
 /**
  * Get theme configuration or throw exception if it cannot be found.
  *
  * @param  string $name
  *
  * @return Data
  * @throws \RuntimeException
  */
 public function get($name)
 {
     if (!$name) {
         throw new \RuntimeException('Theme name not provided.');
     }
     $blueprints = new Blueprints('themes://');
     $blueprint = $blueprints->get("{$name}/blueprints");
     $blueprint->name = $name;
     // Load default configuration.
     $file = CompiledYamlFile::instance("themes://{$name}/{$name}" . YAML_EXT);
     // ensure this is a valid theme
     if (!$file->exists()) {
         return null;
     }
     // Find thumbnail.
     $thumb = "themes://{$name}/thumbnail.jpg";
     $path = $this->grav['locator']->findResource($thumb, false);
     if ($path) {
         $blueprint->set('thumbnail', $this->grav['base_url'] . '/' . $path);
     }
     $obj = new Data($file->content(), $blueprint);
     // Override with user configuration.
     $obj->merge($this->grav['config']->get('themes.' . $name) ?: []);
     // Save configuration always to user/config.
     $file = CompiledYamlFile::instance("config://themes/{$name}" . YAML_EXT);
     $obj->file($file);
     return $obj;
 }
Ejemplo n.º 23
0
 public static function get($name)
 {
     $blueprints = new Blueprints("plugins://{$name}");
     $blueprint = $blueprints->get('blueprints');
     $blueprint->name = $name;
     // Load default configuration.
     $file = CompiledYamlFile::instance("plugins://{$name}/{$name}.yaml");
     $obj = new Data($file->content(), $blueprint);
     // Override with user configuration.
     $file = CompiledYamlFile::instance("user://config/plugins/{$name}.yaml");
     $obj->merge($file->content());
     // Save configuration always to user/config.
     $obj->file($file);
     return $obj;
 }
Ejemplo n.º 24
0
 /**
  * @param Data $config
  * @return \DOMElement|null
  */
 protected function getEmbedContainer(Data $config)
 {
     $container = null;
     if ($cElem = $config->get('container.element')) {
         $document = new \DOMDocument();
         $container = $document->createElement($cElem);
         $containerAttr = (array) $config->get('container.html_attr', []);
         foreach ($containerAttr as $htmlAttr => $attrValue) {
             $container->setAttribute($htmlAttr, $attrValue);
         }
     }
     return $container;
 }
Ejemplo n.º 25
0
 /**
  * Initialize object by loading all the configuration files.
  *
  * @param array $files
  */
 protected function init(array $files)
 {
     $this->updated = true;
     // Combine all configuration files into one larger lookup table (only keys matter).
     $allFiles = $files['user'] + $files['plugins'] + $files['system'];
     // Then sort the files to have all parent nodes first.
     // This is to make sure that child nodes override parents content.
     uksort($allFiles, function ($a, $b) {
         $diff = substr_count($a, '/') - substr_count($b, '/');
         return $diff ? $diff : strcmp($a, $b);
     });
     $systemBlueprints = new Blueprints(SYSTEM_DIR . 'blueprints');
     $pluginBlueprints = new Blueprints(USER_DIR);
     $items = array();
     foreach ($allFiles as $name => $dummy) {
         $lookup = array('system' => SYSTEM_DIR . 'config/' . $name . YAML_EXT, 'plugins' => USER_DIR . $name . '/' . basename($name) . YAML_EXT, 'user' => USER_DIR . 'config/' . $name . YAML_EXT);
         if (strpos($name, 'plugins/') === 0) {
             $blueprint = $pluginBlueprints->get("{$name}/blueprints");
         } else {
             $blueprint = $systemBlueprints->get($name);
         }
         $data = new Data(array(), $blueprint);
         foreach ($lookup as $key => $path) {
             if (is_file($path)) {
                 $data->merge(File\Yaml::instance($path)->content());
             }
         }
         //            $data->validate();
         //            $data->filter();
         // Find the current sub-tree location.
         $current =& $items;
         $parts = explode('/', $name);
         foreach ($parts as $part) {
             if (!isset($current[$part])) {
                 $current[$part] = array();
             }
             $current =& $current[$part];
         }
         // Handle both updated and deleted configuration files.
         $current = $data->toArray();
     }
     $this->items = $items;
     $this->files = $files;
 }
 /**
  * @param \Grav\Common\Page\Page|\Grav\Common\Data\Data $obj
  *
  * @return \Grav\Common\Page\Page|\Grav\Common\Data\Data
  */
 protected function storeFiles($obj)
 {
     // Process previously uploaded files for the current URI
     // and finally store them. Everything else will get discarded
     $queue = $this->admin->session()->getFlashObject('files-upload');
     $queue = $queue[base64_encode($this->grav['uri']->url())];
     if (is_array($queue)) {
         foreach ($queue as $key => $files) {
             foreach ($files as $destination => $file) {
                 if (!rename($file['tmp_name'], $destination)) {
                     throw new \RuntimeException(sprintf($this->admin->translate('PLUGIN_ADMIN.FILEUPLOAD_UNABLE_TO_MOVE', null), '"' . $file['tmp_name'] . '"', $destination));
                 }
                 unset($files[$destination]['tmp_name']);
             }
             if ($this->view == 'pages') {
                 $keys = explode('.', preg_replace('/^header./', '', $key));
                 $init_key = array_shift($keys);
                 if (count($keys) > 0) {
                     $new_data = isset($obj->header()->{$init_key}) ? $obj->header()->{$init_key} : [];
                     Utils::setDotNotation($new_data, implode('.', $keys), $files, true);
                 } else {
                     $new_data = $files;
                 }
                 if (isset($data['header'][$init_key])) {
                     $obj->modifyHeader($init_key, array_replace_recursive([], $data['header'][$init_key], $new_data));
                 } else {
                     $obj->modifyHeader($init_key, $new_data);
                 }
             } else {
                 // TODO: [this is JS handled] if it's single file, remove existing and use set, if it's multiple, use join
                 $obj->join($key, $files);
                 // stores
             }
         }
     }
     return $obj;
 }