From 9d983e74867092663a2ec7d1a420967739bf30cf Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 11 Jan 2016 19:56:18 +0200 Subject: [PATCH 01/59] Feature: Load plugins early --- system/src/Grav/Common/Config/Setup.php | 5 +- system/src/Grav/Common/Grav.php | 3 +- system/src/Grav/Common/Plugin.php | 28 ++++-- system/src/Grav/Common/Plugins.php | 117 ++++++++++++------------ 4 files changed, 84 insertions(+), 69 deletions(-) diff --git a/system/src/Grav/Common/Config/Setup.php b/system/src/Grav/Common/Config/Setup.php index b345426c1..e904ecff9 100644 --- a/system/src/Grav/Common/Config/Setup.php +++ b/system/src/Grav/Common/Config/Setup.php @@ -115,10 +115,7 @@ class Setup extends Data public function __construct($container) { - $environment = $container['uri']->environment(); - if (!$environment) { - $environment = 'localhost'; - } + $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. diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 1642211d2..d4cd2a162 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -191,6 +191,7 @@ class Grav extends Container // Initialize configuration. $debugger->startTimer('_config', 'Configuration'); + $plugins = $this['plugins']; $this['config']->init(); $debugger->stopTimer('_config'); @@ -230,7 +231,7 @@ class Grav extends Container $debugger->stopTimer('init'); $debugger->startTimer('plugins', 'Plugins'); - $this['plugins']->init(); + $plugins->init(); $this->fireEvent('onPluginsInitialized'); $debugger->stopTimer('plugins'); diff --git a/system/src/Grav/Common/Plugin.php b/system/src/Grav/Common/Plugin.php index 96084b0ed..bee2c69f6 100644 --- a/system/src/Grav/Common/Plugin.php +++ b/system/src/Grav/Common/Plugin.php @@ -16,6 +16,11 @@ use RocketTheme\Toolbox\File\YamlFile; */ class Plugin implements EventSubscriberInterface { + /** + * @var string + */ + public $name; + /** * @var Grav */ @@ -27,10 +32,6 @@ class Plugin implements EventSubscriberInterface protected $config; protected $active = true; - /** - * @var \Grav\Common\string - */ - protected $name; /** * By default assign all methods as listeners using the default priority. @@ -58,13 +59,26 @@ class Plugin implements EventSubscriberInterface * @param Grav $grav * @param Config $config */ - public function __construct($name, Grav $grav, Config $config) + public function __construct($name, Grav $grav) { - $this->grav = $grav; - $this->config = $config; $this->name = $name; + $this->grav = $grav; } + /** + * @param Config $config + * @return $this + */ + public function setConfig(Config $config) + { + $this->config = $config; + + return $this; + } + + /** + * @return bool + */ public function isAdmin() { if (isset($this->grav['admin'])) { diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index de479e138..dc6e85497 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -6,7 +6,7 @@ use Grav\Common\Data\Blueprints; use Grav\Common\Data\Data; use Grav\Common\File\CompiledYamlFile; use RocketTheme\Toolbox\Event\EventDispatcher; -use RocketTheme\Toolbox\Event\EventSubscriberInterface; +use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; /** * The Plugins object holds an array of all the plugin objects that @@ -19,8 +19,27 @@ class Plugins extends Iterator { use GravTrait; + public function __construct() + { + parent::__construct(); + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + $iterator = $locator->getIterator('plugins://'); + foreach ($iterator as $directory) { + if (!$directory->isDir()) { + continue; + } + + $plugin = $directory->getBasename(); + + $this->add($this->loadPlugin($plugin)); + } + } + /** - * Recurses through the plugins directory creating Plugin objects for each plugin it finds. + * Registers all plugins. * * @return array|Plugin[] array of Plugin objects * @throws \RuntimeException @@ -29,47 +48,14 @@ class Plugins extends Iterator { /** @var Config $config */ $config = self::getGrav()['config']; - $plugins = (array) $config->get('plugins'); - - $inflector = self::getGrav()['inflector']; /** @var EventDispatcher $events */ $events = self::getGrav()['events']; - foreach ($plugins as $plugin => $data) { - if (empty($data['enabled'])) { - // Only load enabled plugins. - continue; - } - - $locator = self::getGrav()['locator']; - $filePath = $locator->findResource('plugins://' . $plugin . DS . $plugin . PLUGIN_EXT); - if (!is_file($filePath)) { - self::getGrav()['log']->addWarning(sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clear-cache`", $plugin)); - continue; - } - - require_once $filePath; - - $pluginClassFormat = [ - 'Grav\\Plugin\\'.ucfirst($plugin).'Plugin', - 'Grav\\Plugin\\'.$inflector->camelize($plugin).'Plugin' - ]; - $pluginClassName = false; - - foreach ($pluginClassFormat as $pluginClass) { - if (class_exists($pluginClass)) { - $pluginClassName = $pluginClass; - break; - } - } - - if (false === $pluginClassName) { - throw new \RuntimeException(sprintf("Plugin '%s' class not found! Try reinstalling this plugin.", $plugin)); - } - - $instance = new $pluginClassName($plugin, self::getGrav(), $config); - if ($instance instanceof EventSubscriberInterface) { + foreach ($this->items as $instance) { + // Register only enabled plugins. + if ($config["plugins.{$instance->name}.enabled"] && $instance instanceof Plugin) { + $instance->setConfig($config); $events->addSubscriber($instance); } } @@ -77,6 +63,9 @@ class Plugins extends Iterator return $this->items; } + /** + * @param $plugin + */ public function add($plugin) { if (is_object($plugin)) { @@ -91,28 +80,17 @@ class Plugins extends Iterator */ public static function all() { - $list = array(); - $locator = Grav::instance()['locator']; + $plugins = self::getGrav()['plugins']; + $list = []; - $plugins = (array) $locator->findResources('plugins://', false); - foreach ($plugins as $path) { - $iterator = new \DirectoryIterator($path); + foreach ($plugins as $instance) { + $name = $instance->name; + $result = self::get($name); - /** @var \DirectoryIterator $directory */ - foreach ($iterator as $directory) { - if (!$directory->isDir() || $directory->isDot()) { - continue; - } - - $plugin = $directory->getBasename(); - $result = self::get($plugin); - - if ($result) { - $list[$plugin] = $result; - } + if ($result) { + $list[$name] = $result; } } - ksort($list); return $list; } @@ -143,4 +121,29 @@ class Plugins extends Iterator return $obj; } + protected function loadPlugin($name) + { + $grav = self::getGrav(); + $locator = $grav['locator']; + + $filePath = $locator->findResource('plugins://' . $name . DS . $name . PLUGIN_EXT); + if (!is_file($filePath)) { + self::getGrav()['log']->addWarning( + sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clear-cache`", $name) + ); + return null; + } + + require_once $filePath; + + $pluginClassName = 'Grav\\Plugin\\' . ucfirst($name) . 'Plugin'; + if (!class_exists($pluginClassName)) { + $pluginClassName = 'Grav\\Plugin\\' . $grav['inflector']->camelize($name) . 'Plugin'; + if (!class_exists($pluginClassName)) { + throw new \RuntimeException(sprintf("Plugin '%s' class not found! Try reinstalling this plugin.", $name)); + } + } + return new $pluginClassName($name, self::getGrav()); + } + } From 5786530cda1b97df0fece1cb9bfd057b68f4174d Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 12 Jan 2016 12:53:54 +0200 Subject: [PATCH 02/59] Fix stream override ordering --- system/src/Grav/Common/Config/Setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Config/Setup.php b/system/src/Grav/Common/Config/Setup.php index e904ecff9..bd4cf469e 100644 --- a/system/src/Grav/Common/Config/Setup.php +++ b/system/src/Grav/Common/Config/Setup.php @@ -155,7 +155,7 @@ class Setup extends Data } // Update streams. - foreach ($files as $path) { + foreach (array_reverse($files) as $path) { $file = CompiledYamlFile::instance($path); $content = $file->content(); if (!empty($content['schemes'])) { From a118824cf5a31dbda3f00ff20e83b3cbaadd2919 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 13 Jan 2016 11:00:53 +0200 Subject: [PATCH 03/59] Allow plugins to have their own blueprints --- system/src/Grav/Common/Grav.php | 2 +- system/src/Grav/Common/Plugins.php | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index d4cd2a162..4f01f62fb 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -191,7 +191,7 @@ class Grav extends Container // Initialize configuration. $debugger->startTimer('_config', 'Configuration'); - $plugins = $this['plugins']; + $plugins = $this['plugins']->setup(); $this['config']->init(); $debugger->stopTimer('_config'); diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index dc6e85497..1b0bd510b 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -38,6 +38,30 @@ class Plugins extends Iterator } } + /** + * @return $this + */ + public function setup() + { + $blueprints = []; + foreach ($this->items as $plugin) { + if (isset($plugin->features['blueprints'])) { + $blueprints["plugin://{$plugin->name}/blueprints"] = $plugin->features['blueprints']; + } + } + + if ($blueprints) { + arsort($blueprints); + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + $locator->addPath('blueprints', '', array_keys($blueprints), 'system/blueprints'); + } + + return $this; + } + /** * Registers all plugins. * From 431f53853652c8339b666a060bbd99be5ea5ecc4 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 14 Jan 2016 12:59:48 +0200 Subject: [PATCH 04/59] Fix bug in Data:extra() --- system/src/Grav/Common/Data/Data.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Data/Data.php b/system/src/Grav/Common/Data/Data.php index 0a0850765..fe70efb1b 100644 --- a/system/src/Grav/Common/Data/Data.php +++ b/system/src/Grav/Common/Data/Data.php @@ -211,7 +211,7 @@ class Data implements DataInterface, \ArrayAccess, \Countable, ExportInterface */ public function extra() { - return $this->blueprints ? $this->blueprints->extra($this->items) : array(); + return $this->blueprints()->extra($this->items); } /** From 9a4830808df66228643059d098c5be5b25fd805d Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 21 Jan 2016 10:11:57 +0200 Subject: [PATCH 05/59] Refactor Blueprints class --- system/src/Grav/Common/Data/Blueprint.php | 396 ++++++---------------- 1 file changed, 100 insertions(+), 296 deletions(-) diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 68de5de81..8b110201b 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -4,7 +4,7 @@ namespace Grav\Common\Data; use Grav\Common\GravTrait; use RocketTheme\Toolbox\ArrayTraits\Export; use RocketTheme\Toolbox\ArrayTraits\ExportInterface; -use RocketTheme\Toolbox\ArrayTraits\NestedArrayAccessWithGetters; +use RocketTheme\Toolbox\Blueprints\Blueprints as BaseBlueprints; /** * Blueprint handles the inside logic of blueprints. @@ -12,56 +12,85 @@ use RocketTheme\Toolbox\ArrayTraits\NestedArrayAccessWithGetters; * @author RocketTheme * @license MIT */ -class Blueprint implements \ArrayAccess, ExportInterface +class Blueprint extends BaseBlueprints implements ExportInterface { - use Export, NestedArrayAccessWithGetters, GravTrait; - - public $name; + use Export, GravTrait; public $initialized = false; - protected $items; protected $context; - protected $fields; - protected $rules = array(); - protected $nested = array(); - protected $filter = ['validation' => 1]; /** - * @param string $name - * @param array $data + * @param string|array $name + * @param array $data * @param Blueprints $context */ - public function __construct($name, array $data = array(), Blueprints $context = null) + public function __construct($name = null, array $data = [], Blueprints $context = null) { - $this->name = $name; - $this->items = $data; - $this->context = $context; + parent::__construct(is_array($name) ? $name : null); + + if ($data) { + $this->embed('', $data); + } + + if ($context) { + $this->setContext($context); + } } /** - * Set filter for inherited properties. + * Set context to find external blueprints. * - * @param array $filter List of field names to be inherited. + * @param Blueprints $context + * @return $this */ - public function setFilter(array $filter) + public function setContext(Blueprints $context) { - $this->filter = array_flip($filter); + $this->context = $context; + + return $this; } /** - * Return all form fields. + * Return all form fields in a nested list. * * @return array */ - public function fields() + public function fields($name = '', $separator = '.') { - if (!isset($this->fields)) { - $this->fields = []; - $this->embed('', $this->items); + $name = $separator != '.' ? strtr($name, $separator, '.') : $name; + if (isset($this->form[$name])) { + $form = &$this->form[$name]; + } else { + return []; } - return $this->fields; + $fields = $this->buildFields($form); + + return $fields; + } + + public function toArray($name = '', $separator = '.') + { + $meta = isset($this->items[$name]['meta']) ? $this->items[$name]['meta'] : []; + $formMeta = isset($this->items[$name]['form']) ? $this->items[$name]['form'] : []; + $fields = $this->fields($name, $separator); + + return $meta + ['form' => $formMeta + ['fields' => $fields]]; + } + + protected function buildFields(array &$fields) + { + $result = []; + + foreach ($fields as $key => $value) { + $result[$key] = isset($this->items[$key]) ? $this->items[$key] : []; + if (is_array($value)) { + $result[$key]['fields'] = $this->buildFields($value); + } + } + + return $result; } /** @@ -72,9 +101,6 @@ class Blueprint implements \ArrayAccess, ExportInterface */ public function validate(array $data) { - // Initialize data - $this->fields(); - try { $this->validateArray($data, $this->nested); } catch (\RuntimeException $e) { @@ -84,20 +110,6 @@ class Blueprint implements \ArrayAccess, ExportInterface } } - /** - * Merge two arrays by using blueprints. - * - * @param array $data1 - * @param array $data2 - * @return array - */ - public function mergeData(array $data1, array $data2) - { - // Initialize data - $this->fields(); - return $this->mergeArrays($data1, $data2, $this->nested); - } - /** * Filter data by using blueprints. * @@ -106,35 +118,9 @@ class Blueprint implements \ArrayAccess, ExportInterface */ public function filter(array $data) { - // Initialize data - $this->fields(); return $this->filterArray($data, $this->nested); } - /** - * Return data fields that do not exist in blueprints. - * - * @param array $data - * @param string $prefix - * @return array - */ - public function extra(array $data, $prefix = '') - { - // Initialize data - $this->fields(); - $rules = $this->nested; - - // Drill down to prefix level - if (!empty($prefix)) { - $parts = explode('.', trim($prefix, '.')); - foreach ($parts as $part) { - $rules = isset($rules[$part]) ? $rules[$part] : []; - } - } - - return $this->extraArray($data, $rules, $prefix); - } - /** * Extend blueprint with another blueprint. * @@ -143,8 +129,9 @@ class Blueprint implements \ArrayAccess, ExportInterface */ public function extend(Blueprint $extends, $append = false) { - $blueprints = $append ? $this->items : $extends->toArray(); - $appended = $append ? $extends->toArray() : $this->items; + // FIXME: Currently not working... + $blueprints = $append ? $this->form : $extends->fields(); + $appended = $append ? $extends->fields() : $this->form; $bref_stack = array(&$blueprints); $head_stack = array($appended); @@ -167,37 +154,7 @@ class Blueprint implements \ArrayAccess, ExportInterface } } while (count($head_stack)); - $this->items = $blueprints; - } - - /** - * Convert object into an array. - * - * @return array - */ - public function getState() - { - return ['name' => $this->name, 'items' => $this->items, 'rules' => $this->rules, 'nested' => $this->nested]; - } - - /** - * Embed an array to the blueprint. - * - * @param $name - * @param array $value - * @param string $separator - */ - public function embed($name, array $value, $separator = '.') - { - - if (!isset($value['form']['fields']) || !is_array($value['form']['fields'])) { - return; - } - // Initialize data - $this->fields(); - $prefix = $name ? strtr($name, $separator, '.') . '.' : ''; - $params = array_intersect_key($this->filter, $value); - $this->parseFormFields($value['form']['fields'], $params, $prefix, $this->fields); + $this->form = $blueprints; } /** @@ -221,8 +178,8 @@ class Blueprint implements \ArrayAccess, ExportInterface // Array has been defined in blueprints. $this->validateArray($field, $val); } elseif (isset($this->items['form']['validation']) && $this->items['form']['validation'] == 'strict') { - // Undefined/extra item. - throw new \RuntimeException(sprintf('%s is not defined in blueprints', $key)); + // Undefined/extra item. + throw new \RuntimeException(sprintf('%s is not defined in blueprints', $key)); } } } @@ -258,198 +215,6 @@ class Blueprint implements \ArrayAccess, ExportInterface return $results; } - /** - * @param array $data1 - * @param array $data2 - * @param array $rules - * @return array - * @internal - */ - protected function mergeArrays(array $data1, array $data2, array $rules) - { - foreach ($data2 as $key => $field) { - $val = isset($rules[$key]) ? $rules[$key] : null; - $rule = is_string($val) ? $this->rules[$val] : null; - - if (!$rule && array_key_exists($key, $data1) && is_array($field) && is_array($val)) { - // Array has been defined in blueprints. - $data1[$key] = $this->mergeArrays($data1[$key], $field, $val); - } else { - // Otherwise just take value from the data2. - $data1[$key] = $field; - } - } - - return $data1; - } - - /** - * @param array $data - * @param array $rules - * @param string $prefix - * @return array - * @internal - */ - protected function extraArray(array $data, array $rules, $prefix) - { - $array = array(); - foreach ($data as $key => $field) { - $val = isset($rules[$key]) ? $rules[$key] : null; - $rule = is_string($val) ? $this->rules[$val] : null; - - if ($rule) { - // Item has been defined in blueprints. - } elseif (is_array($field) && is_array($val)) { - // Array has been defined in blueprints. - $array += $this->ExtraArray($field, $val, $prefix . $key . '.'); - } else { - // Undefined/extra item. - $array[$prefix.$key] = $field; - } - } - return $array; - } - - /** - * Gets all field definitions from the blueprints. - * - * @param array $fields - * @param array $params - * @param string $prefix - * @param array $current - * @internal - */ - protected function parseFormFields(array &$fields, $params, $prefix, array &$current) - { - // Go though all the fields in current level. - foreach ($fields as $key => &$field) { - $current[$key] = &$field; - // Set name from the array key. - $field['name'] = $prefix . $key; - $field += $params; - - if (isset($field['fields']) && (!isset($field['type']) || $field['type'] !== 'list')) { - // Recursively get all the nested fields. - $newParams = array_intersect_key($this->filter, $field); - $this->parseFormFields($field['fields'], $newParams, $prefix, $current[$key]['fields']); - } else if ($field['type'] !== 'ignore') { - $this->rules[$prefix . $key] = &$field; - $this->addProperty($prefix . $key); - - if ($field['type'] === 'list') { - // we loop through list to get the actual field - if (isset($field['fields']) && $field['fields']) { - foreach($field['fields'] as $subName => &$subField) { - $this->parseFormField($subField); - } - } - } else { - $this->parseFormField($field); - } - - if (isset($field['validate']['rule']) && $field['type'] !== 'ignore') { - $field['validate'] += $this->getRule($field['validate']['rule']); - } - } - } - } - /** - * Parses individual field definition - * - * @param array $field - * @internal - */ - protected function parseFormField(&$field) { - foreach ($field as $name => $value) { - // Support nested blueprints. - if ($this->context && $name == '@import') { - $values = (array) $value; - if (!isset($field['fields'])) { - $field['fields'] = array(); - } - foreach ($values as $bname) { - $b = $this->context->get($bname); - $field['fields'] = array_merge($field['fields'], $b->fields()); - } - } - - // Support for callable data values. - elseif (substr($name, 0, 6) == '@data-') { - $property = substr($name, 6); - if (is_array($value)) { - $func = array_shift($value); - } else { - $func = $value; - $value = array(); - } - list($o, $f) = preg_split('/::/', $func); - if (!$f && function_exists($o)) { - $data = call_user_func_array($o, $value); - } elseif ($f && method_exists($o, $f)) { - $data = call_user_func_array(array($o, $f), $value); - } - - // If function returns a value, - if (isset($data)) { - if (isset($field[$property]) && is_array($field[$property]) && is_array($data)) { - // Combine field and @data-field together. - $field[$property] += $data; - } else { - // Or create/replace field with @data-field. - $field[$property] = $data; - } - } - } - - elseif (substr($name, 0, 8) == '@config-') { - $property = substr($name, 8); - $default = isset($field[$property]) ? $field[$property] : null; - $config = self::getGrav()['config']->get($value, $default); - - if (!is_null($config)) { - $field[$property] = $config; - } - } - } - } - - /** - * Add property to the definition. - * - * @param string $path Comma separated path to the property. - * @internal - */ - protected function addProperty($path) - { - $parts = explode('.', $path); - $item = array_pop($parts); - - $nested = &$this->nested; - foreach ($parts as $part) { - if (!isset($nested[$part])) { - $nested[$part] = array(); - } - $nested = &$nested[$part]; - } - - if (!isset($nested[$item])) { - $nested[$item] = $path; - } - } - - /** - * @param $rule - * @return array - * @internal - */ - protected function getRule($rule) - { - if (isset($this->items['rules'][$rule]) && is_array($this->items['rules'][$rule])) { - return $this->items['rules'][$rule]; - } - return array(); - } - /** * @param array $data * @param array $fields @@ -473,4 +238,43 @@ class Blueprint implements \ArrayAccess, ExportInterface } } } + + /** + * @param array $field + * @param string $property + * @param array $call + */ + protected function dynamicImport(array &$field, $property, array &$call) + { + $params = $call['params']; + + // Support nested blueprints. + if ($this->context) { + $values = (array) $params; + if (!isset($field['fields'])) { + $field['fields'] = array(); + } + foreach ($values as $bname) { + $b = $this->context->get($bname); + $field['fields'] = array_merge($field['fields'], $b->fields()); + } + } + } + + /** + * @param array $field + * @param string $property + * @param array $call + */ + protected function dynamicConfig(array &$field, $property, array &$call) + { + $value = $call['params']; + + $default = isset($field[$property]) ? $field[$property] : null; + $config = self::getGrav()['config']->get($value, $default); + + if (!is_null($config)) { + $field[$property] = $config; + } + } } From 5c08439633c87040711630fffc8000956b1c9353 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 21 Jan 2016 11:17:31 +0200 Subject: [PATCH 06/59] Update composer requirement for toolbox --- composer.json | 2 +- composer.lock | 123 ++++++++++++++++---------------------------------- 2 files changed, 40 insertions(+), 85 deletions(-) diff --git a/composer.json b/composer.json index a0b000e04..6c58ebb1f 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "mrclay/minify": "~2.2", "donatj/phpuseragentparser": "~0.3", "pimple/pimple": "~3.0", - "rockettheme/toolbox": "~1.2", + "rockettheme/toolbox": "dev-develop", "maximebf/debugbar": "~1.10", "ext-mbstring": "*", "ext-openssl": "*", diff --git a/composer.lock b/composer.lock index 006287240..5ee6bc999 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "85173a1bfa9ece106f687d69402d99d8", - "content-hash": "410b016e6cd8af6cd8ee9cdb6d5fd7a4", + "hash": "830fd45c43ba3b23a91a091237f64521", + "content-hash": "3ff379f8b303e28443453058c6e909cb", "packages": [ { "name": "doctrine/cache", @@ -148,6 +148,7 @@ "Parsedown": "" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -164,9 +165,6 @@ "markdown", "parser" ], - "support": { - "source": "https://github.com/getgrav/parsedown/tree/1.6.0" - }, "time": "2015-10-04 16:44:32" }, { @@ -215,16 +213,16 @@ }, { "name": "filp/whoops", - "version": "2.0.0-alpha2", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "eb1ce6439db161a9f00cd57f33a9cfa1355229ec" + "reference": "a327942c50cbd62b25c6fbe08f173031ce25fbff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/eb1ce6439db161a9f00cd57f33a9cfa1355229ec", - "reference": "eb1ce6439db161a9f00cd57f33a9cfa1355229ec", + "url": "https://api.github.com/repos/filp/whoops/zipball/a327942c50cbd62b25c6fbe08f173031ce25fbff", + "reference": "a327942c50cbd62b25c6fbe08f173031ce25fbff", "shasum": "" }, "require": { @@ -247,10 +245,7 @@ "autoload": { "psr-4": { "Whoops\\": "src/Whoops/" - }, - "files": [ - "src/Whoops/functions.php" - ] + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -273,7 +268,7 @@ "whoops", "zf2" ], - "time": "2015-12-15 12:27:17" + "time": "2016-01-06 17:51:21" }, { "name": "gregwar/cache", @@ -366,48 +361,6 @@ ], "time": "2015-05-30 19:24:37" }, - { - "name": "ircmaxell/password-compat", - "version": "v1.0.4", - "source": { - "type": "git", - "url": "https://github.com/ircmaxell/password_compat.git", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", - "shasum": "" - }, - "require-dev": { - "phpunit/phpunit": "4.*" - }, - "type": "library", - "autoload": { - "files": [ - "lib/password.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Anthony Ferrara", - "email": "ircmaxell@php.net", - "homepage": "http://blog.ircmaxell.com" - } - ], - "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", - "homepage": "https://github.com/ircmaxell/password_compat", - "keywords": [ - "hashing", - "password" - ], - "time": "2014-11-20 16:49:30" - }, { "name": "maximebf/debugbar", "version": "v1.11.0", @@ -677,20 +630,19 @@ }, { "name": "rockettheme/toolbox", - "version": "1.2.0", + "version": "dev-develop", "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "0c7a3b4b6e4d73be8512e89f7acde6899334b7f2" + "reference": "a29f5d0a7fab86f6d20286c9f59f234187e46d5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/0c7a3b4b6e4d73be8512e89f7acde6899334b7f2", - "reference": "0c7a3b4b6e4d73be8512e89f7acde6899334b7f2", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/a29f5d0a7fab86f6d20286c9f59f234187e46d5b", + "reference": "a29f5d0a7fab86f6d20286c9f59f234187e46d5b", "shasum": "" }, "require": { - "ircmaxell/password-compat": "1.0.*", "php": ">=5.4.0", "pimple/pimple": "~3.0", "symfony/event-dispatcher": "~2.5", @@ -722,20 +674,20 @@ "php", "rockettheme" ], - "time": "2015-11-24 17:04:24" + "time": "2016-01-21 08:19:59" }, { "name": "symfony/console", - "version": "v2.8.1", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "2e06a5ccb19dcf9b89f1c6a677a39a8df773635a" + "reference": "d0239fb42f98dd02e7d342f793c5d2cdee0c478d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/2e06a5ccb19dcf9b89f1c6a677a39a8df773635a", - "reference": "2e06a5ccb19dcf9b89f1c6a677a39a8df773635a", + "url": "https://api.github.com/repos/symfony/console/zipball/d0239fb42f98dd02e7d342f793c5d2cdee0c478d", + "reference": "d0239fb42f98dd02e7d342f793c5d2cdee0c478d", "shasum": "" }, "require": { @@ -782,20 +734,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2015-12-22 10:25:57" + "time": "2016-01-14 08:33:16" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.1", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc" + "reference": "ee278f7c851533e58ca307f66305ccb9188aceda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5eb815363c0388e83247e7e9853e5dbc14999cc", - "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ee278f7c851533e58ca307f66305ccb9188aceda", + "reference": "ee278f7c851533e58ca307f66305ccb9188aceda", "shasum": "" }, "require": { @@ -842,7 +794,7 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2015-10-30 20:15:42" + "time": "2016-01-13 10:28:07" }, { "name": "symfony/polyfill-iconv", @@ -964,16 +916,16 @@ }, { "name": "symfony/var-dumper", - "version": "v2.8.1", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "f943f29ae69c42511a2d85adee9d13d835b5c803" + "reference": "ab94426d127ad9e95433778a3a451fe9d18f3d6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/f943f29ae69c42511a2d85adee9d13d835b5c803", - "reference": "f943f29ae69c42511a2d85adee9d13d835b5c803", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/ab94426d127ad9e95433778a3a451fe9d18f3d6b", + "reference": "ab94426d127ad9e95433778a3a451fe9d18f3d6b", "shasum": "" }, "require": { @@ -1023,20 +975,20 @@ "debug", "dump" ], - "time": "2015-12-05 11:09:21" + "time": "2016-01-07 13:38:40" }, { "name": "symfony/yaml", - "version": "v2.8.1", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966" + "reference": "34c8a4b51e751e7ea869b8262f883d008a2b81b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966", - "reference": "ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966", + "url": "https://api.github.com/repos/symfony/yaml/zipball/34c8a4b51e751e7ea869b8262f883d008a2b81b8", + "reference": "34c8a4b51e751e7ea869b8262f883d008a2b81b8", "shasum": "" }, "require": { @@ -1072,7 +1024,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2015-12-26 13:37:56" + "time": "2016-01-13 10:28:07" }, { "name": "twig/twig", @@ -1140,12 +1092,15 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "filp/whoops": 15 + "rockettheme/toolbox": 20 }, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.5.9" + "php": ">=5.5.9", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-curl": "*" }, "platform-dev": [] } From ebee88dd3995d04637a7d5cc58abb96c769d15b1 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 21 Jan 2016 14:00:54 +0200 Subject: [PATCH 07/59] Update blueprints object version --- system/src/Grav/Common/Config/CompiledBlueprints.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php index d78a0e04e..4c96baf38 100644 --- a/system/src/Grav/Common/Config/CompiledBlueprints.php +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -12,7 +12,7 @@ class CompiledBlueprints extends CompiledBase /** * @var int Version number for the compiled file. */ - public $version = 1; + public $version = 2; /** * @var Blueprints Blueprints object. From b791e8efdad8b6071fcdbf02adf3b020d8cee8aa Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 21 Jan 2016 15:38:12 +0200 Subject: [PATCH 08/59] Blueprint refactor: fix site blueprint --- system/blueprints/config/site.yaml | 8 ++++---- system/src/Grav/Common/Data/Blueprint.php | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/system/blueprints/config/site.yaml b/system/blueprints/config/site.yaml index 485f2c375..149dcdf4b 100644 --- a/system/blueprints/config/site.yaml +++ b/system/blueprints/config/site.yaml @@ -3,7 +3,7 @@ form: validation: loose fields: - content: + section_content: type: section title: PLUGIN_ADMIN.DEFAULTS underline: true @@ -39,7 +39,7 @@ form: validate: type: commalist - summary: + section_summary: type: section title: PLUGIN_ADMIN.PAGE_SUMMARY underline: true @@ -82,7 +82,7 @@ form: label: PLUGIN_ADMIN.DELIMITER help: PLUGIN_ADMIN.DELIMITER_HELP - metadata: + section_metadata: type: section title: PLUGIN_ADMIN.METADATA underline: true @@ -95,7 +95,7 @@ form: placeholder_key: PLUGIN_ADMIN.METADATA_KEY placeholder_value: PLUGIN_ADMIN.METADATA_VALUE - routes: + section_routes: type: section title: PLUGIN_ADMIN.REDIRECTS_AND_ROUTES underline: true diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 8b110201b..5bbf3b70a 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -129,6 +129,7 @@ class Blueprint extends BaseBlueprints implements ExportInterface */ public function extend(Blueprint $extends, $append = false) { + throw new \Exception('Extend is not implemented yet'); // FIXME: Currently not working... $blueprints = $append ? $this->form : $extends->fields(); $appended = $append ? $extends->fields() : $this->form; From 80d0c2a40589b7e354e64f3f9744e7c3477d1bfa Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 22 Jan 2016 10:07:40 +0200 Subject: [PATCH 09/59] Blueprint refactor: fix theme thumbnails --- system/src/Grav/Common/Data/Blueprint.php | 46 +++++++++++++++++++++++ system/src/Grav/Common/Themes.php | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 5bbf3b70a..cb5ec43f7 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -51,6 +51,52 @@ class Blueprint extends BaseBlueprints implements ExportInterface return $this; } + + /** + * Get meta value by using dot notation for nested arrays/objects. + * + * @param string $name Dot separated path to the requested value. + * @param string $field Meta field to fetch. + * @param mixed $default Default value (or null). + * @param string $separator Separator, defaults to '.' + * + * @return mixed Value. + */ + public function getMeta($name, $field, $default = null, $separator = '.') + { + $name = $separator != '.' ? strtr($name, $separator, '.') : $name; + + return isset($this->items[$name]['meta'][$field]) ? $this->items[$name]['meta'][$field] : $default; + } + + /** + * Set meta value by using dot notation for nested arrays/objects. + * + * @param string $name Dot separated path to the requested value. + * @param string $field Meta field to fetch. + * @param mixed $value New value. + * @param string $separator Separator, defaults to '.' + */ + public function setMeta($name, $field, $value, $separator = '.') + { + $name = $separator != '.' ? strtr($name, $separator, '.') : $name; + + $this->items[$name]['meta'][$field] = $value; + } + + /** + * Define meta value by using dot notation for nested arrays/objects. + * + * @param string $name Dot separated path to the requested value. + * @param string $field Meta field to fetch. + * @param mixed $value New value. + * @param string $separator Separator, defaults to '.' + */ + public function defMeta($name, $field, $value, $separator = '.') + { + $this->setMeta($name, $field, $this->getMeta($name, $field, $value, $separator), $separator); + } + /** * Return all form fields in a nested list. * diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php index 2f020f7a4..358275fab 100644 --- a/system/src/Grav/Common/Themes.php +++ b/system/src/Grav/Common/Themes.php @@ -127,7 +127,7 @@ class Themes extends Iterator // Find thumbnail. $thumb = "themes://{$name}/thumbnail.jpg"; if ($path = $this->grav['locator']->findResource($thumb, false)) { - $blueprint->set('thumbnail', $this->grav['base_url'] . '/' . $path); + $blueprint->setMeta('', 'thumbnail', $this->grav['base_url'] . '/' . $path); } $obj = new Data($file->content(), $blueprint); From 4f73fd62c9f3d485503d2c563b5b7302340dd35c Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 22 Jan 2016 12:49:19 +0200 Subject: [PATCH 10/59] Blueprint refactor: Fix missing dynamic properties --- system/src/Grav/Common/Data/Blueprints.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index 4c144a37a..d7891c940 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -103,7 +103,7 @@ class Blueprints } } - $this->instances[$type] = $blueprint; + $this->instances[$type] = $blueprint->init(); } return $this->instances[$type]; From 7760f541fb2091d8f299ad1925d609d6cb4d2f9b Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 22 Jan 2016 13:04:32 +0200 Subject: [PATCH 11/59] Blueprint refactor: Fix page blueprints --- system/blueprints/pages/default.yaml | 6 +++--- system/blueprints/pages/modular.yaml | 2 +- system/blueprints/pages/modular_raw.yaml | 4 ++-- system/blueprints/pages/raw.yaml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/system/blueprints/pages/default.yaml b/system/blueprints/pages/default.yaml index 6eab5d464..3c044074c 100644 --- a/system/blueprints/pages/default.yaml +++ b/system/blueprints/pages/default.yaml @@ -16,7 +16,7 @@ form: active: 1 fields: - content: + tab_content: type: tab title: PLUGIN_ADMIN.CONTENT @@ -37,7 +37,7 @@ form: type: pagemedia label: PLUGIN_ADMIN.PAGE_MEDIA - options: + tab_options: type: tab title: PLUGIN_ADMIN.OPTIONS @@ -101,7 +101,7 @@ form: validate: type: array - advanced: + tab_advanced: type: tab title: PLUGIN_ADMIN.ADVANCED diff --git a/system/blueprints/pages/modular.yaml b/system/blueprints/pages/modular.yaml index ce62ecd1c..32492e056 100644 --- a/system/blueprints/pages/modular.yaml +++ b/system/blueprints/pages/modular.yaml @@ -10,7 +10,7 @@ form: active: 1 fields: - content: + tab_content: fields: header.content.items: diff --git a/system/blueprints/pages/modular_raw.yaml b/system/blueprints/pages/modular_raw.yaml index 393cde5fd..f6fd2d8ea 100644 --- a/system/blueprints/pages/modular_raw.yaml +++ b/system/blueprints/pages/modular_raw.yaml @@ -13,7 +13,7 @@ form: active: 1 fields: - content: + tab_content: type: tab title: PLUGIN_ADMIN.CONTENT @@ -32,7 +32,7 @@ form: label: PLUGIN_ADMIN.PAGE_MEDIA - options: + tab_options: type: tab title: PLUGIN_ADMIN.OPTIONS diff --git a/system/blueprints/pages/raw.yaml b/system/blueprints/pages/raw.yaml index bed82d593..a0a5a710f 100644 --- a/system/blueprints/pages/raw.yaml +++ b/system/blueprints/pages/raw.yaml @@ -13,7 +13,7 @@ form: active: 1 fields: - content: + tab_content: type: tab title: PLUGIN_ADMIN.CONTENT @@ -31,7 +31,7 @@ form: type: pagemedia label: PLUGIN_ADMIN.PAGE_MEDIA - options: + tab_options: type: tab title: PLUGIN_ADMIN.OPTIONS From f87887920a9574e7e233575f471c541298babcbc Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 22 Jan 2016 14:39:32 +0200 Subject: [PATCH 12/59] Blueprint refactor: Fix Blueprint::checkRequired() --- system/src/Grav/Common/Data/Blueprint.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index cb5ec43f7..9d4f9feb0 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -274,7 +274,7 @@ class Blueprint extends BaseBlueprints implements ExportInterface if (!is_string($field)) { continue; } - $field = $this->rules[$field]; + $field = $this->items[$field]; if (isset($field['validate']['required']) && $field['validate']['required'] === true && empty($data[$name])) { From a69116738ff5a93e7f323257874708a603c7fd4a Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 22 Jan 2016 14:47:05 +0200 Subject: [PATCH 13/59] Blueprint refactor: Fix Blueprint validation --- system/src/Grav/Common/Data/Blueprint.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 9d4f9feb0..03ed41f50 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -216,7 +216,7 @@ class Blueprint extends BaseBlueprints implements ExportInterface foreach ($data as $key => $field) { $val = isset($rules[$key]) ? $rules[$key] : null; - $rule = is_string($val) ? $this->rules[$val] : null; + $rule = is_string($val) ? $this->items[$val] : null; if ($rule) { // Item has been defined in blueprints. @@ -242,7 +242,7 @@ class Blueprint extends BaseBlueprints implements ExportInterface $results = array(); foreach ($data as $key => $field) { $val = isset($rules[$key]) ? $rules[$key] : null; - $rule = is_string($val) ? $this->rules[$val] : null; + $rule = is_string($val) ? $this->items[$val] : null; if ($rule) { // Item has been defined in blueprints. From e3e47717c68fccb7e99c35123fc47ecf04a5ce7c Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 22 Jan 2016 21:44:23 +0200 Subject: [PATCH 14/59] Blueprint refactor: Composer update --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 5ee6bc999..4d2aaebed 100644 --- a/composer.lock +++ b/composer.lock @@ -634,12 +634,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "a29f5d0a7fab86f6d20286c9f59f234187e46d5b" + "reference": "09be2b8208ea9ceea9d0b30ed2dcdb8b97b4ac79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/a29f5d0a7fab86f6d20286c9f59f234187e46d5b", - "reference": "a29f5d0a7fab86f6d20286c9f59f234187e46d5b", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/09be2b8208ea9ceea9d0b30ed2dcdb8b97b4ac79", + "reference": "09be2b8208ea9ceea9d0b30ed2dcdb8b97b4ac79", "shasum": "" }, "require": { @@ -674,7 +674,7 @@ "php", "rockettheme" ], - "time": "2016-01-21 08:19:59" + "time": "2016-01-22 19:38:57" }, { "name": "symfony/console", From b6329b196442a722d04ebf33472f8a79994c361b Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 26 Jan 2016 20:38:13 +0200 Subject: [PATCH 15/59] Blueprint refactor: Code style --- system/src/Grav/Common/Data/Blueprint.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 03ed41f50..fd206ac44 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -299,7 +299,7 @@ class Blueprint extends BaseBlueprints implements ExportInterface if ($this->context) { $values = (array) $params; if (!isset($field['fields'])) { - $field['fields'] = array(); + $field['fields'] = []; } foreach ($values as $bname) { $b = $this->context->get($bname); From 233af34bdc952c851adbb38c4c911058feb4c417 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 29 Jan 2016 14:24:48 +0200 Subject: [PATCH 16/59] Add missing parameter after merge --- system/src/Grav/Common/Themes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php index 7490cef8e..b91ae8db4 100644 --- a/system/src/Grav/Common/Themes.php +++ b/system/src/Grav/Common/Themes.php @@ -135,7 +135,7 @@ class Themes extends Iterator $path = $this->grav['locator']->findResource($thumb, false); if ($path) { - $blueprint->setMeta('thumbnail', $this->grav['base_url'] . '/' . $path); + $blueprint->setMeta('', 'thumbnail', $this->grav['base_url'] . '/' . $path); } $obj = new Data($file->content(), $blueprint); From 8bc4d1e460a74e35353443d86f70e9a53f8279e4 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 1 Feb 2016 10:03:25 +0200 Subject: [PATCH 17/59] Implement Blueprints::extend() --- system/src/Grav/Common/Data/Blueprint.php | 28 +---------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index fd206ac44..3fe78cc24 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -175,33 +175,7 @@ class Blueprint extends BaseBlueprints implements ExportInterface */ public function extend(Blueprint $extends, $append = false) { - throw new \Exception('Extend is not implemented yet'); - // FIXME: Currently not working... - $blueprints = $append ? $this->form : $extends->fields(); - $appended = $append ? $extends->fields() : $this->form; - - $bref_stack = array(&$blueprints); - $head_stack = array($appended); - - do { - end($bref_stack); - - $bref = &$bref_stack[key($bref_stack)]; - $head = array_pop($head_stack); - - unset($bref_stack[key($bref_stack)]); - - foreach (array_keys($head) as $key) { - if (isset($key, $bref[$key]) && is_array($bref[$key]) && is_array($head[$key])) { - $bref_stack[] = &$bref[$key]; - $head_stack[] = $head[$key]; - } else { - $bref = array_merge($bref, array($key => $head[$key])); - } - } - } while (count($head_stack)); - - $this->form = $blueprints; + $this->embed('', $extends->toArray(), '.', ($append ? 1 : -1)); } /** From e223b506cb73cf6135f723d67ac395ea26c5dc8a Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 1 Feb 2016 10:30:53 +0200 Subject: [PATCH 18/59] Blueprints: Add alternative syntax for extends@: parent@ --- system/src/Grav/Common/Data/Blueprints.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index d7891c940..ce40edd8c 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -62,10 +62,11 @@ class Blueprints $blueprint = new Blueprint($type, $blueprints, $this); - if (isset($blueprints['@extends'])) { - // Extend blueprint by other blueprints. - $extends = (array) $blueprints['@extends']; + $extends = isset($blueprints['@extends']) ? (array) $blueprints['@extends'] + : (isset($blueprints['extends@']) ? (array) $blueprints['extends@'] : null); + if (isset($extends)) { + // Extend blueprint by other blueprints. if (is_string(key($extends))) { $extends = [ $extends ]; } @@ -75,7 +76,7 @@ class Blueprints if (!$extendType) { continue; - } elseif ($extendType === '@parent') { + } elseif ($extendType === '@parent' || $extendType === 'parent@') { $parentFile = array_shift($parents); if (!$parentFile || !is_file($parentFile)) { continue; From 9024d0f3e302fc07191120f1b7beb77221a00072 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 1 Feb 2016 20:16:50 +0200 Subject: [PATCH 19/59] Composer update --- composer.lock | 75 +++++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/composer.lock b/composer.lock index 4d2aaebed..14ceda2fe 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "830fd45c43ba3b23a91a091237f64521", - "content-hash": "3ff379f8b303e28443453058c6e909cb", + "hash": "331f0e738802421f81e7e0d0b8222897", + "content-hash": "93e9fc9ecc82e91296f8a21aa9756123", "packages": [ { "name": "doctrine/cache", @@ -130,18 +130,21 @@ }, { "name": "erusev/parsedown", - "version": "1.6.0", + "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/getgrav/parsedown.git", - "reference": "3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7" + "url": "https://github.com/erusev/parsedown.git", + "reference": "94688f21cc5d8bc85f1783b4c8b98b3288d712cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getgrav/parsedown/zipball/3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7", - "reference": "3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7", + "url": "https://api.github.com/repos/erusev/parsedown/zipball/94688f21cc5d8bc85f1783b4c8b98b3288d712cb", + "reference": "94688f21cc5d8bc85f1783b4c8b98b3288d712cb", "shasum": "" }, + "require": { + "php": ">=5.3.0" + }, "type": "library", "autoload": { "psr-0": { @@ -165,7 +168,7 @@ "markdown", "parser" ], - "time": "2015-10-04 16:44:32" + "time": "2016-01-07 17:36:51" }, { "name": "erusev/parsedown-extra", @@ -634,12 +637,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "09be2b8208ea9ceea9d0b30ed2dcdb8b97b4ac79" + "reference": "cb0ddd98b1e54f78be9927a217c0d53d122d5049" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/09be2b8208ea9ceea9d0b30ed2dcdb8b97b4ac79", - "reference": "09be2b8208ea9ceea9d0b30ed2dcdb8b97b4ac79", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/cb0ddd98b1e54f78be9927a217c0d53d122d5049", + "reference": "cb0ddd98b1e54f78be9927a217c0d53d122d5049", "shasum": "" }, "require": { @@ -674,7 +677,7 @@ "php", "rockettheme" ], - "time": "2016-01-22 19:38:57" + "time": "2016-02-01 08:32:50" }, { "name": "symfony/console", @@ -798,16 +801,16 @@ }, { "name": "symfony/polyfill-iconv", - "version": "v1.0.1", + "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "541cce29a46d6ee18bb9271c6ac3ca783b0faab0" + "reference": "be8627f0936f86fed0bec16fe79ebb4337299764" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/541cce29a46d6ee18bb9271c6ac3ca783b0faab0", - "reference": "541cce29a46d6ee18bb9271c6ac3ca783b0faab0", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/be8627f0936f86fed0bec16fe79ebb4337299764", + "reference": "be8627f0936f86fed0bec16fe79ebb4337299764", "shasum": "" }, "require": { @@ -819,7 +822,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.1-dev" } }, "autoload": { @@ -853,20 +856,20 @@ "portable", "shim" ], - "time": "2015-11-20 09:19:13" + "time": "2016-01-20 09:13:37" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.0.1", + "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25" + "reference": "1289d16209491b584839022f29257ad859b8532d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/49ff736bd5d41f45240cec77b44967d76e0c3d25", - "reference": "49ff736bd5d41f45240cec77b44967d76e0c3d25", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d", + "reference": "1289d16209491b584839022f29257ad859b8532d", "shasum": "" }, "require": { @@ -878,7 +881,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.1-dev" } }, "autoload": { @@ -912,7 +915,7 @@ "portable", "shim" ], - "time": "2015-11-20 09:19:13" + "time": "2016-01-20 09:13:37" }, { "name": "symfony/var-dumper", @@ -1028,16 +1031,16 @@ }, { "name": "twig/twig", - "version": "v1.23.3", + "version": "v1.24.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "ae53fc2c312fdee63773b75cb570304f85388b08" + "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/ae53fc2c312fdee63773b75cb570304f85388b08", - "reference": "ae53fc2c312fdee63773b75cb570304f85388b08", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", + "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", "shasum": "" }, "require": { @@ -1050,7 +1053,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.23-dev" + "dev-master": "1.24-dev" } }, "autoload": { @@ -1085,13 +1088,21 @@ "keywords": [ "templating" ], - "time": "2016-01-11 14:02:19" + "time": "2016-01-25 21:22:18" + } + ], + "packages-dev": null, + "aliases": [ + { + "alias": "1.6.0", + "alias_normalized": "1.6.0.0", + "version": "9999999-dev", + "package": "erusev/parsedown" } ], - "packages-dev": [], - "aliases": [], "minimum-stability": "stable", "stability-flags": { + "erusev/parsedown": 20, "rockettheme/toolbox": 20 }, "prefer-stable": false, From 327826542dcf17fce802d0cac502e7d063f3afdc Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 2 Feb 2016 11:56:12 +0200 Subject: [PATCH 20/59] Blueprints: Add support for importing fields (#637) --- system/src/Grav/Common/Data/Blueprint.php | 40 ++++++++++++++--------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 3fe78cc24..869e06391 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -1,6 +1,7 @@ embed('', $data); - } - if ($context) { $this->setContext($context); } + + if ($data) { + $this->embed('', $data); + $this->init('static'); + } } /** @@ -265,21 +267,27 @@ class Blueprint extends BaseBlueprints implements ExportInterface * @param string $property * @param array $call */ - protected function dynamicImport(array &$field, $property, array &$call) + protected function staticImport(array &$field, $property, array &$call) { - $params = $call['params']; - // Support nested blueprints. - if ($this->context) { - $values = (array) $params; - if (!isset($field['fields'])) { - $field['fields'] = []; - } - foreach ($values as $bname) { - $b = $this->context->get($bname); - $field['fields'] = array_merge($field['fields'], $b->fields()); - } + $value = $call['params']; + if (is_array($value)) { + $filename = $value['context'] . '/' . $value['type'] . YAML_EXT; + $type = $value['type']; + } else { + $filename = 'blueprints://' . $value . YAML_EXT; + $type = $value; } + + if (!is_file($filename)) { + return; + } + + $file = CompiledYamlFile::instance($filename); + $blueprint = (new Blueprint($type, $file->content(), $this->context))->init('static'); + + //$this->embed($field['name'], $blueprint->toArray(), '.', -1); + $this->parseFormFields($blueprint->toArray()['form']['fields'], $this->filter, '', $field['name'].'.', -1, $call['form']); } /** From 1d7fbe42d3cedaac68194f33401ec8e2d70269ac Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 2 Feb 2016 14:31:10 +0200 Subject: [PATCH 21/59] Blueprints: Fix form ordering in @import --- system/src/Grav/Common/Data/Blueprint.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 869e06391..d778a9581 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -286,8 +286,9 @@ class Blueprint extends BaseBlueprints implements ExportInterface $file = CompiledYamlFile::instance($filename); $blueprint = (new Blueprint($type, $file->content(), $this->context))->init('static'); - //$this->embed($field['name'], $blueprint->toArray(), '.', -1); - $this->parseFormFields($blueprint->toArray()['form']['fields'], $this->filter, '', $field['name'].'.', -1, $call['form']); + $fields = $this->parseFormFields($blueprint->toArray()['form']['fields'], $this->filter, '', $field['name'].'.', -1, $call['form']); + + $this->setFormFields($call['form'], $fields); } /** From 6e3d08d9d08b9c853552abf2e98430d258082987 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 4 Feb 2016 13:49:21 +0200 Subject: [PATCH 22/59] Form validation: Display multiple validation errors --- system/src/Grav/Common/Data/Blueprint.php | 31 ++++--- system/src/Grav/Common/Data/Validation.php | 80 +++++++++++-------- .../Grav/Common/Data/ValidationException.php | 30 +++++++ 3 files changed, 96 insertions(+), 45 deletions(-) create mode 100644 system/src/Grav/Common/Data/ValidationException.php diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index d778a9581..dddeb5399 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -150,11 +150,14 @@ class Blueprint extends BaseBlueprints implements ExportInterface public function validate(array $data) { try { - $this->validateArray($data, $this->nested); + $messages = $this->validateArray($data, $this->nested); + } catch (\RuntimeException $e) { - $language = self::getGrav()['language']; - $message = sprintf($language->translate('FORM.VALIDATION_FAIL', null, true) . ' %s', $e->getMessage()); - throw new \RuntimeException($message); + throw (new ValidationException($e->getMessage(), $e->getCode(), $e))->setMessages(); + } + + if (!empty($messages)) { + throw (new ValidationException())->setMessages($messages); } } @@ -183,12 +186,13 @@ class Blueprint extends BaseBlueprints implements ExportInterface /** * @param array $data * @param array $rules + * @returns array * @throws \RuntimeException * @internal */ protected function validateArray(array $data, array $rules) { - $this->checkRequired($data, $rules); + $messages = $this->checkRequired($data, $rules); foreach ($data as $key => $field) { $val = isset($rules[$key]) ? $rules[$key] : null; @@ -196,15 +200,17 @@ class Blueprint extends BaseBlueprints implements ExportInterface if ($rule) { // Item has been defined in blueprints. - Validation::validate($field, $rule); + $messages += Validation::validate($field, $rule); } elseif (is_array($field) && is_array($val)) { // Array has been defined in blueprints. - $this->validateArray($field, $val); + $messages += $this->validateArray($field, $val); } elseif (isset($this->items['form']['validation']) && $this->items['form']['validation'] == 'strict') { // Undefined/extra item. throw new \RuntimeException(sprintf('%s is not defined in blueprints', $key)); } } + + return $messages; } /** @@ -241,11 +247,12 @@ class Blueprint extends BaseBlueprints implements ExportInterface /** * @param array $data * @param array $fields - * @throws \RuntimeException - * @internal + * @return array */ protected function checkRequired(array $data, array $fields) { + $messages = []; + foreach ($fields as $name => $field) { if (!is_string($field)) { continue; @@ -253,13 +260,15 @@ class Blueprint extends BaseBlueprints implements ExportInterface $field = $this->items[$field]; if (isset($field['validate']['required']) && $field['validate']['required'] === true - && empty($data[$name])) { + && !isset($data[$name])) { $value = isset($field['label']) ? $field['label'] : $field['name']; $language = self::getGrav()['language']; $message = sprintf($language->translate('FORM.MISSING_REQUIRED_FIELD', null, true) . ' %s', $value); - throw new \RuntimeException($message); + $messages[$field['name']][] = $message; } } + + return $messages; } /** diff --git a/system/src/Grav/Common/Data/Validation.php b/system/src/Grav/Common/Data/Validation.php index f8e0c3119..df442f87e 100644 --- a/system/src/Grav/Common/Data/Validation.php +++ b/system/src/Grav/Common/Data/Validation.php @@ -18,53 +18,63 @@ class Validation /** * Validate value against a blueprint field definition. * - * @param mixed $value + * @param $value * @param array $field - * @throws \RuntimeException + * @return array */ public static function validate($value, array $field) { - $validate = isset($field['validate']) ? (array) $field['validate'] : array(); + $messages = []; + + $validate = isset($field['validate']) ? (array) $field['validate'] : []; // If value isn't required, we will stop validation if empty value is given. if (empty($validate['required']) && ($value === null || $value === '')) { - return; + return $messages; } - // special case for files, value is never empty and errors with code 4 instead - if (empty($validate['required']) && $field['type'] == 'file' && (isset($value['error']) && ($value['error'] == UPLOAD_ERR_NO_FILE || in_array(UPLOAD_ERR_NO_FILE, $value['error'])))) { - return; + // Special case for files, value is never empty and errors with code 4 instead. + if (empty($validate['required']) && $field['type'] == 'file' && isset($value['error']) + && ($value['error'] == UPLOAD_ERR_NO_FILE || in_array(UPLOAD_ERR_NO_FILE, $value['error']))) { + return $messages; } - // Get language class + // Get language class. $language = self::getGrav()['language']; // Validate type with fallback type text. $type = (string) isset($field['validate']['type']) ? $field['validate']['type'] : $field['type']; $method = 'type'.strtr($type, '-', '_'); + + if (!method_exists(__CLASS__, $method)) { + $method = 'typeText'; + } + $name = ucfirst(isset($field['label']) ? $field['label'] : $field['name']); - $message = (string) isset($field['validate']['message']) ? $language->translate($field['validate']['message']) : $language->translate('FORM.INVALID_INPUT', null, true) . ' "' . $language->translate($name) . '"'; + $message = (string) isset($field['validate']['message']) + ? $language->translate($field['validate']['message']) + : $language->translate('FORM.INVALID_INPUT', null, true) . ' "' . $language->translate($name) . '"'; + + $success = self::$method($value, $validate, $field); - if (method_exists(__CLASS__, $method)) { - $success = self::$method($value, $validate, $field); - } else { - $success = self::typeText($value, $validate, $field); - } if (!$success) { - throw new \RuntimeException($message); + $messages[$field['name']][] = $message; } - // Check individual rules + // Check individual rules. foreach ($validate as $rule => $params) { - $method = 'validate'.strtr($rule, '-', '_'); + $method = 'validate' . ucfirst(strtr($rule, '-', '_')); + if (method_exists(__CLASS__, $method)) { $success = self::$method($value, $params); if (!$success) { - throw new \RuntimeException($message); + $messages[$field['name']][] = $message; } } } + + return $messages; } /** @@ -76,22 +86,24 @@ class Validation */ public static function filter($value, array $field) { - $validate = isset($field['validate']) ? (array) $field['validate'] : array(); + $validate = isset($field['validate']) ? (array) $field['validate'] : []; // If value isn't required, we will return null if empty value is given. if (empty($validate['required']) && ($value === null || $value === '')) { return null; } - // special case for files, value is never empty and errors with code 4 instead - if (empty($validate['required']) && $field['type'] == 'file' && (isset($value['error']) && ($value['error'] == UPLOAD_ERR_NO_FILE || in_array(UPLOAD_ERR_NO_FILE, $value['error'])))) { + // Special case for files, value is never empty and errors with code 4 instead. + if (empty($validate['required']) && $field['type'] == 'file' && isset($value['error']) + && ($value['error'] == UPLOAD_ERR_NO_FILE || in_array(UPLOAD_ERR_NO_FILE, $value['error']))) { return null; } - // if this is a YAML field, simply parse it and return the value + // If this is a YAML field, simply parse it and return the value. if (isset($field['yaml']) && $field['yaml'] === true) { try { $yaml = new Parser(); + return $yaml->parse($value); } catch (ParseException $e) { throw new \RuntimeException($e->getMessage()); @@ -100,14 +112,13 @@ class Validation // Validate type with fallback type text. $type = (string) isset($field['validate']['type']) ? $field['validate']['type'] : $field['type']; - $method = 'filter'.strtr($type, '-', '_'); - if (method_exists(__CLASS__, $method)) { - $value = self::$method($value, $validate, $field); - } else { - $value = self::filterText($value, $validate, $field); + $method = 'filter' . ucfirst(strtr($type, '-', '_')); + + if (!method_exists(__CLASS__, $method)) { + $method = 'filterText'; } - return $value; + return self::$method($value, $validate, $field); } /** @@ -629,11 +640,11 @@ class Validation public static function validateRequired($value, $params) { - if (is_string($value)) { - $value = trim($value); + if (is_scalar($value)) { + return (bool) $params !== true || $value !== ''; + } else { + return (bool) $params !== true || !empty($value); } - - return (bool) $params !== true || !empty($value); } public static function validatePattern($value, $params) @@ -701,13 +712,14 @@ class Validation public static function validateArray($value, $params) { - return is_array($value) || ($value instanceof \ArrayAccess + return is_array($value) + || ($value instanceof \ArrayAccess && $value instanceof \Traversable && $value instanceof \Countable); } public static function validateJson($value, $params) { - return (bool) (json_decode($value)); + return (bool) (@json_decode($value)); } } diff --git a/system/src/Grav/Common/Data/ValidationException.php b/system/src/Grav/Common/Data/ValidationException.php new file mode 100644 index 000000000..20011cb8e --- /dev/null +++ b/system/src/Grav/Common/Data/ValidationException.php @@ -0,0 +1,30 @@ +messages = $messages; + + $language = Grav::instance()['language']; + $this->message = $language->translate('FORM.VALIDATION_FAIL', null, true) . ' ' . $this->message; + + foreach ($messages as $variable => &$list) { + $list = array_unique($list); + foreach ($list as $message) { + $this->message .= "
$message"; + } + } + + return $this; + } + + public function getMessages() + { + return $this->messages; + } +} \ No newline at end of file From 927ef9b8ba3bc3addf91e2654e74f120c66f72db Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 4 Feb 2016 14:31:24 +0200 Subject: [PATCH 23/59] Form validation: Fix strict mode --- system/src/Grav/Common/Data/Blueprint.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index dddeb5399..4cab1808e 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -204,7 +204,7 @@ class Blueprint extends BaseBlueprints implements ExportInterface } elseif (is_array($field) && is_array($val)) { // Array has been defined in blueprints. $messages += $this->validateArray($field, $val); - } elseif (isset($this->items['form']['validation']) && $this->items['form']['validation'] == 'strict') { + } elseif (isset($rules['validation']) && $rules['validation'] == 'strict') { // Undefined/extra item. throw new \RuntimeException(sprintf('%s is not defined in blueprints', $key)); } @@ -232,7 +232,7 @@ class Blueprint extends BaseBlueprints implements ExportInterface } elseif (is_array($field) && is_array($val)) { // Array has been defined in blueprints. $field = $this->filterArray($field, $val); - } elseif (isset($this->items['form']['validation']) && $this->items['form']['validation'] == 'strict') { + } elseif (isset($rules['validation']) && $rules['validation'] == 'strict') { $field = null; } From 1cfc7784676fc49ac22f9b2d146a243198610079 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 12 Feb 2016 09:32:38 +0200 Subject: [PATCH 24/59] Composer update --- composer.lock | 1523 +------------------------------------------------ 1 file changed, 5 insertions(+), 1518 deletions(-) diff --git a/composer.lock b/composer.lock index ab8df3b4c..f5ead9a20 100644 --- a/composer.lock +++ b/composer.lock @@ -637,12 +637,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "dd0c67ed725f4db12ae891dc5bd6a361117990ac" + "reference": "ede7afafb4ab4e808324ea2b6e6f58aee3efaf26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/dd0c67ed725f4db12ae891dc5bd6a361117990ac", - "reference": "dd0c67ed725f4db12ae891dc5bd6a361117990ac", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/ede7afafb4ab4e808324ea2b6e6f58aee3efaf26", + "reference": "ede7afafb4ab4e808324ea2b6e6f58aee3efaf26", "shasum": "" }, "require": { @@ -677,7 +677,7 @@ "php", "rockettheme" ], - "time": "2016-02-08 11:59:54" + "time": "2016-02-11 19:08:48" }, { "name": "symfony/console", @@ -1091,1520 +1091,7 @@ "time": "2016-01-25 21:22:18" } ], - "packages-dev": [ - { - "name": "codeception/codeception", - "version": "2.1.6", - "source": { - "type": "git", - "url": "https://github.com/Codeception/Codeception.git", - "reference": "b199941f5e59d1e7fd32d78296c8ab98db873d89" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/b199941f5e59d1e7fd32d78296c8ab98db873d89", - "reference": "b199941f5e59d1e7fd32d78296c8ab98db873d89", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "facebook/webdriver": ">=1.0.1", - "guzzlehttp/guzzle": ">=4.1.4 <7.0", - "guzzlehttp/psr7": "~1.0", - "php": ">=5.4.0", - "phpunit/phpunit": "~4.8.0", - "symfony/browser-kit": ">=2.4|<3.1", - "symfony/console": ">=2.4|<3.1", - "symfony/css-selector": ">=2.4|<3.1", - "symfony/dom-crawler": ">=2.4|<3.1", - "symfony/event-dispatcher": ">=2.4|<3.1", - "symfony/finder": ">=2.4|<3.1", - "symfony/yaml": ">=2.4|<3.1" - }, - "require-dev": { - "codeception/specify": "~0.3", - "facebook/php-sdk-v4": "~4.0", - "flow/jsonpath": "~0.2", - "monolog/monolog": "~1.8", - "pda/pheanstalk": "~2.0", - "videlalvaro/php-amqplib": "~2.4" - }, - "suggest": { - "codeception/phpbuiltinserver": "Extension to start and stop PHP built-in web server for your tests", - "codeception/specify": "BDD-style code blocks", - "codeception/verify": "BDD-style assertions", - "monolog/monolog": "Log test steps", - "phpseclib/phpseclib": "Extension required to use the SFTP option in the FTP Module." - }, - "bin": [ - "codecept" - ], - "type": "library", - "extra": { - "branch-alias": [] - }, - "autoload": { - "psr-4": { - "Codeception\\": "src\\Codeception", - "Codeception\\Extension\\": "ext" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Bodnarchuk", - "email": "davert@mail.ua", - "homepage": "http://codegyre.com" - } - ], - "description": "BDD-style testing framework", - "homepage": "http://codeception.com/", - "keywords": [ - "BDD", - "TDD", - "acceptance testing", - "functional testing", - "unit testing" - ], - "time": "2016-02-09 22:27:48" - }, - { - "name": "doctrine/instantiator", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", - "shasum": "" - }, - "require": { - "php": ">=5.3,<8.0-DEV" - }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2015-06-14 21:17:01" - }, - { - "name": "facebook/webdriver", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/facebook/php-webdriver.git", - "reference": "1c98108ba3eb435b681655764de11502a0653705" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/1c98108ba3eb435b681655764de11502a0653705", - "reference": "1c98108ba3eb435b681655764de11502a0653705", - "shasum": "" - }, - "require": { - "php": ">=5.3.19" - }, - "require-dev": { - "phpunit/phpunit": "4.6.*" - }, - "suggest": { - "phpdocumentor/phpdocumentor": "2.*" - }, - "type": "library", - "autoload": { - "psr-4": { - "Facebook\\WebDriver\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "description": "A PHP client for WebDriver", - "homepage": "https://github.com/facebook/php-webdriver", - "keywords": [ - "facebook", - "php", - "selenium", - "webdriver" - ], - "time": "2015-12-31 15:58:49" - }, - { - "name": "fzaninotto/faker", - "version": "v1.5.0", - "source": { - "type": "git", - "url": "https://github.com/fzaninotto/Faker.git", - "reference": "d0190b156bcca848d401fb80f31f504f37141c8d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/d0190b156bcca848d401fb80f31f504f37141c8d", - "reference": "d0190b156bcca848d401fb80f31f504f37141c8d", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~1.5" - }, - "suggest": { - "ext-intl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5.x-dev" - } - }, - "autoload": { - "psr-4": { - "Faker\\": "src/Faker/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "François Zaninotto" - } - ], - "description": "Faker is a PHP library that generates fake data for you.", - "keywords": [ - "data", - "faker", - "fixtures" - ], - "time": "2015-05-29 06:29:14" - }, - { - "name": "guzzlehttp/guzzle", - "version": "6.1.1", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/c6851d6e48f63b69357cbfa55bca116448140e0c", - "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c", - "shasum": "" - }, - "require": { - "guzzlehttp/promises": "~1.0", - "guzzlehttp/psr7": "~1.1", - "php": ">=5.5.0" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "~4.0", - "psr/log": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.1-dev" - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "time": "2015-11-23 00:47:50" - }, - { - "name": "guzzlehttp/promises", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b1e1c0d55f8083c71eda2c28c12a228d708294ea", - "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea", - "shasum": "" - }, - "require": { - "php": ">=5.5.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ], - "time": "2015-10-15 22:28:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "1.2.2", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5d04bdd2881ac89abde1fb78cc234bce24327bb", - "reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "PSR-7 message implementation", - "keywords": [ - "http", - "message", - "stream", - "uri" - ], - "time": "2016-01-23 01:23:02" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "dflydev/markdown": "~1.0", - "erusev/parsedown": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" - } - ], - "time": "2015-02-03 12:10:50" - }, - { - "name": "phpspec/prophecy", - "version": "v1.5.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7", - "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "phpdocumentor/reflection-docblock": "~2.0", - "sebastian/comparator": "~1.1" - }, - "require-dev": { - "phpspec/phpspec": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "psr-0": { - "Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2015-08-13 10:07:40" - }, - { - "name": "phpunit/php-code-coverage", - "version": "2.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.2", - "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "^1.3.2", - "sebastian/version": "~1.0" - }, - "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2015-10-06 15:47:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2015-06-21 13:08:43" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21 13:50:34" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.7", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2015-06-21 08:01:12" - }, - { - "name": "phpunit/php-token-stream", - "version": "1.4.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2015-09-15 10:49:45" - }, - { - "name": "phpunit/phpunit", - "version": "4.8.23", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6e351261f9cd33daf205a131a1ba61c6d33bd483", - "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "~2.1", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": ">=1.0.6", - "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.1", - "sebastian/diff": "~1.2", - "sebastian/environment": "~1.3", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.1|~3.0" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.8.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2016-02-11 14:56:33" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "2.3.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2", - "sebastian/exporter": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2015-10-02 06:51:40" - }, - { - "name": "psr/http-message", - "version": "1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "time": "2015-05-04 20:22:00" - }, - { - "name": "sebastian/comparator", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2015-07-26 15:48:44" - }, - { - "name": "sebastian/diff", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "time": "2015-12-08 07:14:41" - }, - { - "name": "sebastian/environment", - "version": "1.3.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "6e7133793a8e5a5714a551a8324337374be209df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e7133793a8e5a5714a551a8324337374be209df", - "reference": "6e7133793a8e5a5714a551a8324337374be209df", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2015-12-02 08:37:27" - }, - { - "name": "sebastian/exporter", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "7ae5513327cb536431847bcc0c10edba2701064e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", - "reference": "7ae5513327cb536431847bcc0c10edba2701064e", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2015-06-21 07:55:53" - }, - { - "name": "sebastian/global-state", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "time": "2015-10-12 03:26:01" - }, - { - "name": "sebastian/recursion-context", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-11-11 19:50:13" - }, - { - "name": "sebastian/version", - "version": "1.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2015-06-21 13:59:46" - }, - { - "name": "symfony/browser-kit", - "version": "v3.0.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/browser-kit.git", - "reference": "dde849a0485b70a24b36f826ed3fb95b904d80c3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/dde849a0485b70a24b36f826ed3fb95b904d80c3", - "reference": "dde849a0485b70a24b36f826ed3fb95b904d80c3", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "symfony/dom-crawler": "~2.8|~3.0" - }, - "require-dev": { - "symfony/css-selector": "~2.8|~3.0", - "symfony/process": "~2.8|~3.0" - }, - "suggest": { - "symfony/process": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\BrowserKit\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony BrowserKit Component", - "homepage": "https://symfony.com", - "time": "2016-01-27 11:34:55" - }, - { - "name": "symfony/css-selector", - "version": "v3.0.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "6605602690578496091ac20ec7a5cbd160d4dff4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/6605602690578496091ac20ec7a5cbd160d4dff4", - "reference": "6605602690578496091ac20ec7a5cbd160d4dff4", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\CssSelector\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony CssSelector Component", - "homepage": "https://symfony.com", - "time": "2016-01-27 05:14:46" - }, - { - "name": "symfony/dom-crawler", - "version": "v3.0.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/dom-crawler.git", - "reference": "b693a9650aa004576b593ff2e91ae749dc90123d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b693a9650aa004576b593ff2e91ae749dc90123d", - "reference": "b693a9650aa004576b593ff2e91ae749dc90123d", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "symfony/polyfill-mbstring": "~1.0" - }, - "require-dev": { - "symfony/css-selector": "~2.8|~3.0" - }, - "suggest": { - "symfony/css-selector": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\DomCrawler\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony DomCrawler Component", - "homepage": "https://symfony.com", - "time": "2016-01-25 09:56:57" - }, - { - "name": "symfony/finder", - "version": "v3.0.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/623bda0abd9aa29e529c8e9c08b3b84171914723", - "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Finder Component", - "homepage": "https://symfony.com", - "time": "2016-01-27 05:14:46" - } - ], + "packages-dev": null, "aliases": [ { "alias": "1.6.0", From ed3c1c7b3ac9fd4e51584b2f9f35b0cc3b6198de Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 15 Feb 2016 11:19:46 +0200 Subject: [PATCH 25/59] Blueprint extend: reverse order of the multi-extend --- system/src/Grav/Common/Data/Blueprints.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index ce40edd8c..89fec0ccc 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -71,7 +71,7 @@ class Blueprints $extends = [ $extends ]; } - foreach ($extends as $extendConfig) { + foreach (array_reverse($extends) as $extendConfig) { $extendType = !is_string($extendConfig) ? empty($extendConfig['type']) ? false : $extendConfig['type'] : $extendConfig; if (!$extendType) { From 3a0a20ab9705ac3bec38734829a212f3b5282cd1 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 16 Feb 2016 13:58:13 +0200 Subject: [PATCH 26/59] Blueprint extend: Add blueprint special types support --- composer.lock | 14 ++++----- .../Grav/Common/Config/CompiledBlueprints.php | 29 +++++++++++++++++-- system/src/Grav/Common/Data/Blueprint.php | 12 +++++--- system/src/Grav/Common/Plugin.php | 5 ++++ system/src/Grav/Common/Plugins.php | 23 ++++++++++++++- 5 files changed, 69 insertions(+), 14 deletions(-) diff --git a/composer.lock b/composer.lock index f5ead9a20..527905e1b 100644 --- a/composer.lock +++ b/composer.lock @@ -637,22 +637,22 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "ede7afafb4ab4e808324ea2b6e6f58aee3efaf26" + "reference": "a88015f9e6e473e5ddf4294f747d8fe434de3857" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/ede7afafb4ab4e808324ea2b6e6f58aee3efaf26", - "reference": "ede7afafb4ab4e808324ea2b6e6f58aee3efaf26", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/a88015f9e6e473e5ddf4294f747d8fe434de3857", + "reference": "a88015f9e6e473e5ddf4294f747d8fe434de3857", "shasum": "" }, "require": { "php": ">=5.4.0", "pimple/pimple": "~3.0", - "symfony/event-dispatcher": "~2.5", - "symfony/yaml": "~2.5" + "symfony/event-dispatcher": ">2.5", + "symfony/yaml": ">2.5" }, "require-dev": { - "phpunit/phpunit": "4.0.*" + "phpunit/phpunit": "~5.1" }, "type": "library", "autoload": { @@ -677,7 +677,7 @@ "php", "rockettheme" ], - "time": "2016-02-11 19:08:48" + "time": "2016-02-16 10:01:59" }, { "name": "symfony/console", diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php index 4c96baf38..d35bbbd45 100644 --- a/system/src/Grav/Common/Config/CompiledBlueprints.php +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -2,6 +2,7 @@ namespace Grav\Common\Config; use Grav\Common\File\CompiledYamlFile; +use Grav\Common\Grav; use RocketTheme\Toolbox\Blueprints\Blueprints; /** @@ -19,6 +20,22 @@ class CompiledBlueprints extends CompiledBase */ protected $object; + /** + * Returns checksum from the configuration files. + * + * You can set $this->checksum = false to disable this check. + * + * @return bool|string + */ + public function checksum() + { + if (!isset($this->checksum)) { + $this->checksum = md5(json_encode($this->files) . json_encode($this->getTypes()) . $this->version); + } + + return $this->checksum; + } + /** * Create configuration object. * @@ -26,13 +43,21 @@ class CompiledBlueprints extends CompiledBase */ protected function createObject(array $data = []) { - $this->object = new Blueprints($data); + $this->object = (new Blueprints($data))->setTypes($this->getTypes()); + } + + protected function getTypes() + { + return Grav::instance()['plugins']->formFieldTypes; } /** * Finalize configuration object. */ - protected function finalizeObject() {} + protected function finalizeObject() + { + $this->object->init('static'); + } /** * Load single configuration file and append it to the correct position. diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 4cab1808e..e4f805bff 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -2,7 +2,7 @@ namespace Grav\Common\Data; use Grav\Common\File\CompiledYamlFile; -use Grav\Common\GravTrait; +use Grav\Common\Grav; use RocketTheme\Toolbox\ArrayTraits\Export; use RocketTheme\Toolbox\ArrayTraits\ExportInterface; use RocketTheme\Toolbox\Blueprints\Blueprints as BaseBlueprints; @@ -15,7 +15,7 @@ use RocketTheme\Toolbox\Blueprints\Blueprints as BaseBlueprints; */ class Blueprint extends BaseBlueprints implements ExportInterface { - use Export, GravTrait; + use Export; public $initialized = false; @@ -34,6 +34,10 @@ class Blueprint extends BaseBlueprints implements ExportInterface $this->setContext($context); } + $types = Grav::instance()['plugins']->formFieldTypes; + + $this->setTypes($types); + if ($data) { $this->embed('', $data); $this->init('static'); @@ -262,7 +266,7 @@ class Blueprint extends BaseBlueprints implements ExportInterface && $field['validate']['required'] === true && !isset($data[$name])) { $value = isset($field['label']) ? $field['label'] : $field['name']; - $language = self::getGrav()['language']; + $language = Grav::instance()['language']; $message = sprintf($language->translate('FORM.MISSING_REQUIRED_FIELD', null, true) . ' %s', $value); $messages[$field['name']][] = $message; } @@ -310,7 +314,7 @@ class Blueprint extends BaseBlueprints implements ExportInterface $value = $call['params']; $default = isset($field[$property]) ? $field[$property] : null; - $config = self::getGrav()['config']->get($value, $default); + $config = Grav::instance()['config']->get($value, $default); if (!is_null($config)) { $field[$property] = $config; diff --git a/system/src/Grav/Common/Plugin.php b/system/src/Grav/Common/Plugin.php index f066bff20..3a30acf39 100644 --- a/system/src/Grav/Common/Plugin.php +++ b/system/src/Grav/Common/Plugin.php @@ -21,6 +21,11 @@ class Plugin implements EventSubscriberInterface */ public $name; + /** + * @var array + */ + public $features = []; + /** * @var Grav */ diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index eebd3e7ee..97187b2f5 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -19,6 +19,8 @@ class Plugins extends Iterator { use GravTrait; + public $formFieldTypes; + public function __construct() { parent::__construct(); @@ -44,21 +46,40 @@ class Plugins extends Iterator public function setup() { $blueprints = []; + $formFields = []; + + /** @var Plugin $plugin */ foreach ($this->items as $plugin) { if (isset($plugin->features['blueprints'])) { $blueprints["plugin://{$plugin->name}/blueprints"] = $plugin->features['blueprints']; } + if (method_exists($plugin, 'getFormFieldTypes')) { + $formFields[get_class($plugin)] = isset($plugin->features['formfields']) ? $plugin->features['formfields'] : 0; + } } if ($blueprints) { + // Order by priority. arsort($blueprints); /** @var UniformResourceLocator $locator */ $locator = Grav::instance()['locator']; - $locator->addPath('blueprints', '', array_keys($blueprints), 'system/blueprints'); } + if ($formFields) { + // Order by priority. + arsort($formFields); + + $list = []; + foreach ($formFields as $className => $priority) { + $plugin = $this->items[$className]; + $list += $plugin->getFormFieldTypes(); + } + + $this->formFieldTypes = $list; + } + return $this; } From be297677e8940b27aaa32a12dbdc212ab88162de Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 18 Feb 2016 14:16:37 +0200 Subject: [PATCH 27/59] 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; } } From fb32805f69ab002f6bc8f900e192a84215301fb1 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 18 Feb 2016 15:06:57 +0200 Subject: [PATCH 28/59] Blueprint extend: Implement better way to extend blueprint --- .../Grav/Common/Config/CompiledBlueprints.php | 13 ++ system/src/Grav/Common/Data/Blueprints.php | 175 +++++++++++------- 2 files changed, 124 insertions(+), 64 deletions(-) diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php index bd028c0c3..aff9df283 100644 --- a/system/src/Grav/Common/Config/CompiledBlueprints.php +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -81,6 +81,12 @@ class CompiledBlueprints extends CompiledBase } } + /** + * Internal function that handles loading extended blueprints. + * + * @param array $files + * @return array + */ protected function loadBlueprints(array $files) { $filename = array_shift($files); @@ -97,6 +103,13 @@ class CompiledBlueprints extends CompiledBase 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))) { diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index 89fec0ccc..5ad081948 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -2,6 +2,7 @@ namespace Grav\Common\Data; use Grav\Common\File\CompiledYamlFile; +use Grav\Common\Grav; use Grav\Common\GravTrait; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; @@ -13,8 +14,6 @@ use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; */ class Blueprints { - use GravTrait; - protected $search; protected $types; protected $instances = array(); @@ -37,72 +36,23 @@ class Blueprints public function get($type) { if (!isset($this->instances[$type])) { - $parents = []; - if (is_string($this->search)) { + 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 (strpos($filename, '://')) { - $grav = static::getGrav(); - /** @var UniformResourceLocator $locator */ - $locator = $grav['locator']; - $parents = $locator->findResources($filename); - $filename = array_shift($parents); - } + // 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 { - $filename = isset($this->search[$type]) ? $this->search[$type] : ''; + $files = (array) $filename; } - if ($filename && is_file($filename)) { - $file = CompiledYamlFile::instance($filename); - $blueprints = $file->content(); - } else { - $blueprints = []; - } - - $blueprint = new Blueprint($type, $blueprints, $this); - - $extends = isset($blueprints['@extends']) ? (array) $blueprints['@extends'] - : (isset($blueprints['extends@']) ? (array) $blueprints['extends@'] : null); - - if (isset($extends)) { - // Extend blueprint by other blueprints. - if (is_string(key($extends))) { - $extends = [ $extends ]; - } - - foreach (array_reverse($extends) as $extendConfig) { - $extendType = !is_string($extendConfig) ? empty($extendConfig['type']) ? false : $extendConfig['type'] : $extendConfig; - - if (!$extendType) { - continue; - } elseif ($extendType === '@parent' || $extendType === 'parent@') { - $parentFile = array_shift($parents); - if (!$parentFile || !is_file($parentFile)) { - continue; - } - $blueprints = CompiledYamlFile::instance($parentFile)->content(); - $parent = new Blueprint($type.'-parent', $blueprints, $this); - $blueprint->extend($parent); - continue; - } - - if (is_string($extendConfig) || empty($extendConfig['context'])) { - $context = $this; - } else { - // Load blueprints from external context. - $array = explode('://', $extendConfig['context'], 2); - $scheme = array_shift($array); - $path = array_shift($array); - if ($path) { - $scheme .= '://'; - $extendType = $path ? "{$path}/{$extendType}" : $extendType; - } - $context = new self($scheme); - } - $blueprint->extend($context->get($extendType)); - } - } + $blueprint = $this->loadFile($type, $files); $this->instances[$type] = $blueprint->init(); } @@ -123,7 +73,7 @@ class Blueprints // Check if search is a stream. if (strpos($this->search, '://')) { // Stream: use UniformResourceIterator. - $grav = static::getGrav(); + $grav = Grav::instance(); /** @var UniformResourceLocator $locator */ $locator = $grav['locator']; $iterator = $locator->getIterator($this->search, null); @@ -143,4 +93,101 @@ class Blueprints } return $this->types; } + + + /** + * Load single configuration file and make a blueprint. + * + * @param string $name Name of the position. + * @param array $files Files to be loaded. + * @return Blueprint + */ + protected function loadFile($name, $files) + { + $blueprint = new Blueprint($name, [], $this); + + $data = $this->loadBlueprints($files); + + // Merge all extends into a single blueprint. + foreach ($data as $content) { + $blueprint->embed('', $content, '/', 1); + } + + 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 = "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; + } } From 931d08b46d18f5c471c55555bdb5f539f9d5531f Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 18 Feb 2016 15:40:09 +0200 Subject: [PATCH 29/59] Composer update --- composer.lock | 8 ++++---- system/src/Grav/Common/Config/CompiledBlueprints.php | 2 +- system/src/Grav/Common/Data/Blueprint.php | 11 ----------- system/src/Grav/Common/Data/Blueprints.php | 2 +- 4 files changed, 6 insertions(+), 17 deletions(-) diff --git a/composer.lock b/composer.lock index 093ff4a34..c8f8c38de 100644 --- a/composer.lock +++ b/composer.lock @@ -637,12 +637,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "2c6f703d6da8570ec2ab51d5111189e284d5a12e" + "reference": "ceb00d34e24bf137e1fc368411d1a94497d991c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/2c6f703d6da8570ec2ab51d5111189e284d5a12e", - "reference": "2c6f703d6da8570ec2ab51d5111189e284d5a12e", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/ceb00d34e24bf137e1fc368411d1a94497d991c8", + "reference": "ceb00d34e24bf137e1fc368411d1a94497d991c8", "shasum": "" }, "require": { @@ -677,7 +677,7 @@ "php", "rockettheme" ], - "time": "2016-02-18 12:10:06" + "time": "2016-02-18 13:35:02" }, { "name": "symfony/console", diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php index aff9df283..9eac0fb68 100644 --- a/system/src/Grav/Common/Config/CompiledBlueprints.php +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -77,7 +77,7 @@ class CompiledBlueprints extends CompiledBase // Merge all extends into a single blueprint. foreach ($data as $content) { - $this->object->embed($name, $content, '/', 1); + $this->object->embed($name, $content, '/', true); } } diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index e4f805bff..74075743c 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -176,17 +176,6 @@ class Blueprint extends BaseBlueprints implements ExportInterface return $this->filterArray($data, $this->nested); } - /** - * Extend blueprint with another blueprint. - * - * @param Blueprint $extends - * @param bool $append - */ - public function extend(Blueprint $extends, $append = false) - { - $this->embed('', $extends->toArray(), '.', ($append ? 1 : -1)); - } - /** * @param array $data * @param array $rules diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index 5ad081948..f954ab85e 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -110,7 +110,7 @@ class Blueprints // Merge all extends into a single blueprint. foreach ($data as $content) { - $blueprint->embed('', $content, '/', 1); + $blueprint->embed('', $content, '/', true); } return $blueprint; From 1263a0bcabd285283f2fb6275fade90b733db79b Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 18 Feb 2016 17:09:27 +0200 Subject: [PATCH 30/59] Always use the same Blueprint class --- system/src/Grav/Common/Config/CompiledBase.php | 7 ++++++- system/src/Grav/Common/Config/CompiledBlueprints.php | 9 +++++++-- system/src/Grav/Common/Data/Blueprint.php | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/system/src/Grav/Common/Config/CompiledBase.php b/system/src/Grav/Common/Config/CompiledBase.php index 9f51d7d26..833b4da7a 100644 --- a/system/src/Grav/Common/Config/CompiledBase.php +++ b/system/src/Grav/Common/Config/CompiledBase.php @@ -226,7 +226,7 @@ abstract class CompiledBase 'timestamp' => time(), 'checksum' => $this->checksum(), 'files' => $this->files, - 'data' => $this->object->toArray() + 'data' => $this->getState() ]; $file->save($cache); @@ -235,4 +235,9 @@ abstract class CompiledBase $this->modified(); } + + protected function getState() + { + return $this->object->toArray(); + } } diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php index 9eac0fb68..ab176ac56 100644 --- a/system/src/Grav/Common/Config/CompiledBlueprints.php +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -1,9 +1,9 @@ object = (new Blueprints($data))->setTypes($this->getTypes()); + $this->object = (new Blueprint($data))->setTypes($this->getTypes()); } /** @@ -183,4 +183,9 @@ class CompiledBlueprints extends CompiledBase return true; } + + protected function getState() + { + return $this->object->getState(); + } } diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 74075743c..3766644e2 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -26,7 +26,7 @@ class Blueprint extends BaseBlueprints implements ExportInterface * @param array $data * @param Blueprints $context */ - public function __construct($name = null, array $data = [], Blueprints $context = null) + public function __construct($name = null, array $data = null, Blueprints $context = null) { parent::__construct(is_array($name) ? $name : null); From 989f5bb1295a83d2f7506fd8046580fc9a036f2a Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 18 Feb 2016 20:45:17 +0200 Subject: [PATCH 31/59] Fix import@ in Blueprint --- system/src/Grav/Common/Data/Blueprint.php | 17 ++++++++++++----- system/src/Grav/Common/Data/Blueprints.php | 2 ++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 3766644e2..0be3d5fea 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -273,12 +273,19 @@ class Blueprint extends BaseBlueprints implements ExportInterface { // Support nested blueprints. $value = $call['params']; - if (is_array($value)) { - $filename = $value['context'] . '/' . $value['type'] . YAML_EXT; - $type = $value['type']; + + $type = !is_string($value) ? !isset($value['type']) ? null : $value['type'] : $value; + + if (strpos($type, '://')) { + $filename = $type; + } elseif (empty($value['context'])) { + $filename = "blueprints://{$type}"; } else { - $filename = 'blueprints://' . $value . YAML_EXT; - $type = $value; + $separator = $value['context'][strlen($value['context'])-1] === '/' ? '' : '/'; + $filename = $value['context'] . $separator . $type; + } + if (!preg_match('/\.yaml$/', $filename)) { + $filename .= YAML_EXT; } if (!is_file($filename)) { diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index f954ab85e..0a6fe979a 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -113,6 +113,8 @@ class Blueprints $blueprint->embed('', $content, '/', true); } + $blueprint->init('static'); + return $blueprint; } From 0b53d39cdb7ef9de6b63fe44c8e416ac8b8a32e1 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 19 Feb 2016 11:56:09 +0200 Subject: [PATCH 32/59] Refactor Blueprints object creation --- system/src/Grav/Common/Data/Blueprint.php | 2 -- system/src/Grav/Common/Data/Blueprints.php | 2 +- system/src/Grav/Common/User/Group.php | 6 +++--- system/src/Grav/Common/User/User.php | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 0be3d5fea..60ac28308 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -40,7 +40,6 @@ class Blueprint extends BaseBlueprints implements ExportInterface if ($data) { $this->embed('', $data); - $this->init('static'); } } @@ -57,7 +56,6 @@ class Blueprint extends BaseBlueprints implements ExportInterface return $this; } - /** * Get meta value by using dot notation for nested arrays/objects. * diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index 0a6fe979a..e1d76581e 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -21,7 +21,7 @@ class Blueprints /** * @param string|array $search Search path. */ - public function __construct($search) + public function __construct($search = 'blueprints://') { $this->search = $search; } diff --git a/system/src/Grav/Common/User/Group.php b/system/src/Grav/Common/User/Group.php index f32402b5a..475090bd7 100644 --- a/system/src/Grav/Common/User/Group.php +++ b/system/src/Grav/Common/User/Group.php @@ -56,7 +56,7 @@ class Group extends Data $content = []; } - $blueprints = new Blueprints('blueprints://'); + $blueprints = new Blueprints; $blueprint = $blueprints->get('user/group'); if (!isset($content['groupname'])) { $content['groupname'] = $groupname; @@ -71,7 +71,7 @@ class Group extends Data */ public function save() { - $blueprints = new Blueprints('blueprints://'); + $blueprints = new Blueprints; $blueprint = $blueprints->get('user/group'); $fields = $blueprint->fields(); @@ -114,7 +114,7 @@ class Group extends Data */ public static function remove($groupname) { - $blueprints = new Blueprints('blueprints://'); + $blueprints = new Blueprints; $blueprint = $blueprints->get('user/group'); $groups = self::getGrav()['config']->get("groups"); diff --git a/system/src/Grav/Common/User/User.php b/system/src/Grav/Common/User/User.php index da51c1235..394f52d19 100644 --- a/system/src/Grav/Common/User/User.php +++ b/system/src/Grav/Common/User/User.php @@ -36,7 +36,7 @@ class User extends Data // force lowercase of username $username = strtolower($username); - $blueprints = new Blueprints('blueprints://'); + $blueprints = new Blueprints; $blueprint = $blueprints->get('user/account'); $file_path = $locator->findResource('account://' . $username . YAML_EXT); $file = CompiledYamlFile::instance($file_path); From 17f6a9b87745a1a4d09715ae31c17f8d755dd012 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 19 Feb 2016 13:43:32 +0200 Subject: [PATCH 33/59] Fix context on page blueprints --- system/src/Grav/Common/Data/BlueprintForm.php | 112 ++++++++++++++++++ system/src/Grav/Common/Data/Blueprints.php | 12 +- 2 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 system/src/Grav/Common/Data/BlueprintForm.php diff --git a/system/src/Grav/Common/Data/BlueprintForm.php b/system/src/Grav/Common/Data/BlueprintForm.php new file mode 100644 index 000000000..0f96d4e01 --- /dev/null +++ b/system/src/Grav/Common/Data/BlueprintForm.php @@ -0,0 +1,112 @@ +items : $extends->toArray(); + $appended = $append ? $extends->toArray() : $this->items; + $bref_stack = array(&$blueprints); + $head_stack = array($appended); + + do { + end($bref_stack); + $bref = &$bref_stack[key($bref_stack)]; + $head = array_pop($head_stack); + unset($bref_stack[key($bref_stack)]); + + foreach (array_keys($head) as $key) { + if (isset($key, $bref[$key]) && is_array($bref[$key]) && is_array($head[$key])) { + $bref_stack[] = &$bref[$key]; + $head_stack[] = $head[$key]; + } else { + $bref = array_merge($bref, array($key => $head[$key])); + } + } + } while (count($head_stack)); + + $this->items = $blueprints; + } + + /** + * Get blueprints by using dot notation for nested arrays/objects. + * + * @example $value = $this->resolve('this.is.my.nested.variable'); + * returns ['this.is.my', 'nested.variable'] + * + * @param array $path + * @param string $separator + * @return array + */ + public function resolve(array $path, $separator = '.') + { + $fields = false; + $parts = []; + $current = $this['form.fields']; + $result = [null, null, null]; + + while (($field = current($path)) !== null) { + if (!$fields && isset($current['fields'])) { + if (!empty($current['array'])) { + $result = [$current, $parts, $path ? implode($separator, $path) : null]; + // Skip item offset. + $parts[] = array_shift($path); + } + + $current = $current['fields']; + $fields = true; + + } elseif (isset($current[$field])) { + $parts[] = array_shift($path); + $current = $current[$field]; + $fields = false; + + } elseif (isset($current['.' . $field])) { + $parts[] = array_shift($path); + $current = $current['.' . $field]; + $fields = false; + + } else { + break; + } + } + + return $result; + } +} diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index e1d76581e..3a49eaeaf 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -170,7 +170,7 @@ class Blueprints if (strpos($extendType, '://')) { $path = $extendType; } elseif (empty($extendConfig['context'])) { - $path = "blueprints://{$extendType}"; + $path = isset($this->search[$extendType]) ? $this->search[$extendType] : "blueprints://{$extendType}"; } else { $separator = $extendConfig['context'][strlen($extendConfig['context'])-1] === '/' ? '' : '/'; $path = $extendConfig['context'] . $separator . $extendType; @@ -179,10 +179,14 @@ class Blueprints $path .= '.yaml'; } - /** @var UniformResourceLocator $locator */ - $locator = Grav::instance()['locator']; + if (strpos($path, '://')) { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; - $files = $locator->findResources($path); + $files = $locator->findResources($path); + } else { + $files = [$path]; + } } if ($files) { From 37799fd1736f0b039f37e5c3b66f748a89762f22 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 19 Feb 2016 14:49:48 +0200 Subject: [PATCH 34/59] Extend blueprints by using new BlueprintForm class --- .../Grav/Common/Config/CompiledBlueprints.php | 8 ++++-- system/src/Grav/Common/Data/BlueprintForm.php | 26 +++++++------------ system/src/Grav/Common/Data/Blueprints.php | 10 +++---- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php index ab176ac56..ac250c98f 100644 --- a/system/src/Grav/Common/Config/CompiledBlueprints.php +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -2,6 +2,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; @@ -17,7 +18,7 @@ class CompiledBlueprints extends CompiledBase public $version = 2; /** - * @var Blueprints Blueprints object. + * @var Blueprint Blueprints object. */ protected $object; @@ -76,9 +77,12 @@ class CompiledBlueprints extends CompiledBase $data = $this->loadBlueprints($files); // Merge all extends into a single blueprint. + $blueprintForm = new BlueprintForm(array_shift($data)); foreach ($data as $content) { - $this->object->embed($name, $content, '/', true); + $blueprintForm->extend($content, true); } + + $this->object->embed($name, $blueprintForm->toArray(), '/', true); } /** diff --git a/system/src/Grav/Common/Data/BlueprintForm.php b/system/src/Grav/Common/Data/BlueprintForm.php index 0f96d4e01..c1741fdb4 100644 --- a/system/src/Grav/Common/Data/BlueprintForm.php +++ b/system/src/Grav/Common/Data/BlueprintForm.php @@ -1,17 +1,5 @@ items : $extends->toArray(); - $appended = $append ? $extends->toArray() : $this->items; + if ($extends instanceof BlueprintForm) { + $extends = $extends->toArray(); + } + + $blueprints = $append ? $this->items : $extends; + $appended = $append ? $extends : $this->items; $bref_stack = array(&$blueprints); $head_stack = array($appended); diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index 3a49eaeaf..64bdd6fba 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -3,7 +3,6 @@ namespace Grav\Common\Data; use Grav\Common\File\CompiledYamlFile; use Grav\Common\Grav; -use Grav\Common\GravTrait; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; /** @@ -104,15 +103,16 @@ class Blueprints */ protected function loadFile($name, $files) { - $blueprint = new Blueprint($name, [], $this); - $data = $this->loadBlueprints($files); // Merge all extends into a single blueprint. + $blueprintForm = new BlueprintForm(array_shift($data)); foreach ($data as $content) { - $blueprint->embed('', $content, '/', true); + $blueprintForm->extend($content, true); } + $blueprint = new Blueprint($name, $blueprintForm->toArray(), $this); + $blueprint->init('static'); return $blueprint; @@ -185,7 +185,7 @@ class Blueprints $files = $locator->findResources($path); } else { - $files = [$path]; + $files = (array) $path; } } From ebe46f14824f6eadea9b9fcf8e5685481596d562 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 19 Feb 2016 20:06:41 +0200 Subject: [PATCH 35/59] Implement import@ in BlueprintForm class --- system/src/Grav/Common/Data/BlueprintForm.php | 166 ++++++++++++++++-- system/src/Grav/Common/Data/Blueprints.php | 1 + 2 files changed, 148 insertions(+), 19 deletions(-) diff --git a/system/src/Grav/Common/Data/BlueprintForm.php b/system/src/Grav/Common/Data/BlueprintForm.php index c1741fdb4..b805e2401 100644 --- a/system/src/Grav/Common/Data/BlueprintForm.php +++ b/system/src/Grav/Common/Data/BlueprintForm.php @@ -1,6 +1,7 @@ deepInit($this->items); + + return $this; + } + + /** + * Get form fields. + * + * @return array + */ + public function fields() + { + return (array) $this->get('form.fields'); + } + + /** + * Get form. + * + * @return array + */ + public function form() + { + return (array) $this->get('form'); + } + /** * Extend blueprint with another blueprint. * * @param BlueprintForm|array $extends * @param bool $append + * @return $this */ public function extend($extends, $append = false) { @@ -32,28 +61,45 @@ class BlueprintForm implements \ArrayAccess, ExportInterface $extends = $extends->toArray(); } - $blueprints = $append ? $this->items : $extends; - $appended = $append ? $extends : $this->items; - $bref_stack = array(&$blueprints); - $head_stack = array($appended); + if ($append) { + $a = $this->items; + $b = $extends; + } else { + $a = $extends; + $b = $this->items; + } - do { - end($bref_stack); - $bref = &$bref_stack[key($bref_stack)]; - $head = array_pop($head_stack); - unset($bref_stack[key($bref_stack)]); + $this->items = $this->deepMerge($a, $b); - foreach (array_keys($head) as $key) { - if (isset($key, $bref[$key]) && is_array($bref[$key]) && is_array($head[$key])) { - $bref_stack[] = &$bref[$key]; - $head_stack[] = $head[$key]; - } else { - $bref = array_merge($bref, array($key => $head[$key])); - } + return $this; + } + + /** + * @param string $name + * @param mixed $value + * @param string $separator + * @param bool $append + * @return $this + */ + public function embed($name, $value, $separator = '/', $append = false) + { + $oldValue = $this->get($name, null, $separator); + + if (is_array($oldValue) && is_array($value)) { + if ($append) { + $a = $oldValue; + $b = $value; + } else { + $a = $value; + $b = $oldValue; } - } while (count($head_stack)); - $this->items = $blueprints; + $value = $this->deepMerge($a, $b); + } + + $this->set($name, $value, $separator); + + return $this; } /** @@ -66,7 +112,7 @@ class BlueprintForm implements \ArrayAccess, ExportInterface * @param string $separator * @return array */ - public function resolve(array $path, $separator = '.') + public function resolve(array $path, $separator = '/') { $fields = false; $parts = []; @@ -101,4 +147,86 @@ class BlueprintForm implements \ArrayAccess, ExportInterface return $result; } + + /** + * Deep merge two arrays together. + * + * @param array $a + * @param array $b + * @return array + */ + protected function deepMerge(array $a, array $b) + { + $bref_stack = array(&$a); + $head_stack = array($b); + + do { + end($bref_stack); + $bref = &$bref_stack[key($bref_stack)]; + $head = array_pop($head_stack); + unset($bref_stack[key($bref_stack)]); + + foreach (array_keys($head) as $key) { + if (isset($key, $bref[$key]) && is_array($bref[$key]) && is_array($head[$key])) { + $bref_stack[] = &$bref[$key]; + $head_stack[] = $head[$key]; + } else { + $bref = array_merge($bref, [$key => $head[$key]]); + } + } + } while (count($head_stack)); + + return $a; + } + + protected function deepInit(array &$items, $path = []) + { + foreach ($items as $key => &$item) { + if (!empty($key) && ($key[0] === '@' || $key[strlen($key) - 1] === '@')) { + $name = trim($key, '@'); + + if ($name === 'import') { + $this->import($item, $path); + unset($items[$key]); + } + + } elseif (is_array($item)) { + $newPath = array_merge($path, [$key]); + + $this->deepInit($item, $newPath); + } + } + } + + /** + * @param array $value + * @param array $path + */ + protected function import(array &$value, array &$path) + { + $type = !is_string($value) ? !isset($value['type']) ? null : $value['type'] : $value; + + if (strpos($type, '://')) { + $filename = $type; + } elseif (empty($value['context'])) { + $filename = "blueprints://{$type}"; + } else { + $separator = $value['context'][strlen($value['context'])-1] === '/' ? '' : '/'; + $filename = $value['context'] . $separator . $type; + } + if (!preg_match('/\.yaml$/', $filename)) { + $filename .= YAML_EXT; + } + + if (!is_file($filename)) { + return; + } + + $file = CompiledYamlFile::instance($filename); + $blueprint = (new BlueprintForm($file->content()))->init(); + + $name = implode('/', $path); + + $this->embed($name, $blueprint->form(), '/', false); + } } diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index 64bdd6fba..249c2bf0d 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -110,6 +110,7 @@ class Blueprints foreach ($data as $content) { $blueprintForm->extend($content, true); } + $blueprintForm->init(); $blueprint = new Blueprint($name, $blueprintForm->toArray(), $this); From 86be0b3f3489fbd900648d02f21416976504a2c0 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 22 Feb 2016 11:33:28 +0200 Subject: [PATCH 36/59] Remove deprecated import@ from Blueprint class --- .../Grav/Common/Config/CompiledBlueprints.php | 2 +- system/src/Grav/Common/Data/Blueprint.php | 36 ------------------- system/src/Grav/Common/Data/BlueprintForm.php | 24 ++++++------- system/src/Grav/Common/Data/Blueprints.php | 2 -- 4 files changed, 13 insertions(+), 51 deletions(-) diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php index ac250c98f..36fe1b826 100644 --- a/system/src/Grav/Common/Config/CompiledBlueprints.php +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -63,7 +63,6 @@ class CompiledBlueprints extends CompiledBase */ protected function finalizeObject() { - $this->object->init('static'); } /** @@ -81,6 +80,7 @@ class CompiledBlueprints extends CompiledBase foreach ($data as $content) { $blueprintForm->extend($content, true); } + $blueprintForm->init(); $this->object->embed($name, $blueprintForm->toArray(), '/', true); } diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 60ac28308..5f9f0f8a1 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -262,42 +262,6 @@ class Blueprint extends BaseBlueprints implements ExportInterface return $messages; } - /** - * @param array $field - * @param string $property - * @param array $call - */ - protected function staticImport(array &$field, $property, array &$call) - { - // Support nested blueprints. - $value = $call['params']; - - $type = !is_string($value) ? !isset($value['type']) ? null : $value['type'] : $value; - - if (strpos($type, '://')) { - $filename = $type; - } elseif (empty($value['context'])) { - $filename = "blueprints://{$type}"; - } else { - $separator = $value['context'][strlen($value['context'])-1] === '/' ? '' : '/'; - $filename = $value['context'] . $separator . $type; - } - if (!preg_match('/\.yaml$/', $filename)) { - $filename .= YAML_EXT; - } - - if (!is_file($filename)) { - return; - } - - $file = CompiledYamlFile::instance($filename); - $blueprint = (new Blueprint($type, $file->content(), $this->context))->init('static'); - - $fields = $this->parseFormFields($blueprint->toArray()['form']['fields'], $this->filter, '', $field['name'].'.', -1, $call['form']); - - $this->setFormFields($call['form'], $fields); - } - /** * @param array $field * @param string $property diff --git a/system/src/Grav/Common/Data/BlueprintForm.php b/system/src/Grav/Common/Data/BlueprintForm.php index b805e2401..164d12c3b 100644 --- a/system/src/Grav/Common/Data/BlueprintForm.php +++ b/system/src/Grav/Common/Data/BlueprintForm.php @@ -28,16 +28,6 @@ class BlueprintForm implements \ArrayAccess, ExportInterface return $this; } - /** - * Get form fields. - * - * @return array - */ - public function fields() - { - return (array) $this->get('form.fields'); - } - /** * Get form. * @@ -48,6 +38,16 @@ class BlueprintForm implements \ArrayAccess, ExportInterface return (array) $this->get('form'); } + /** + * Get form fields. + * + * @return array + */ + public function fields() + { + return (array) $this->get('form.fields'); + } + /** * Extend blueprint with another blueprint. * @@ -186,7 +186,7 @@ class BlueprintForm implements \ArrayAccess, ExportInterface $name = trim($key, '@'); if ($name === 'import') { - $this->import($item, $path); + $this->doImport($item, $path); unset($items[$key]); } @@ -202,7 +202,7 @@ class BlueprintForm implements \ArrayAccess, ExportInterface * @param array $value * @param array $path */ - protected function import(array &$value, array &$path) + protected function doImport(array &$value, array &$path) { $type = !is_string($value) ? !isset($value['type']) ? null : $value['type'] : $value; diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index 249c2bf0d..a880cb313 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -114,8 +114,6 @@ class Blueprints $blueprint = new Blueprint($name, $blueprintForm->toArray(), $this); - $blueprint->init('static'); - return $blueprint; } From 024ae687825009532c38b419d288244ca3f70f41 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 22 Feb 2016 19:57:42 +0200 Subject: [PATCH 37/59] Blueprints: Move duplicated extends@ logic into BlueprintForm class --- .../Grav/Common/Config/CompiledBlueprints.php | 89 +------- system/src/Grav/Common/Data/BlueprintForm.php | 191 +++++++++++++++++- system/src/Grav/Common/Data/Blueprints.php | 127 ++---------- 3 files changed, 203 insertions(+), 204 deletions(-) diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php index 36fe1b826..daa0bd25d 100644 --- a/system/src/Grav/Common/Config/CompiledBlueprints.php +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -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); } /** diff --git a/system/src/Grav/Common/Data/BlueprintForm.php b/system/src/Grav/Common/Data/BlueprintForm.php index 164d12c3b..27bcda8e1 100644 --- a/system/src/Grav/Common/Data/BlueprintForm.php +++ b/system/src/Grav/Common/Data/BlueprintForm.php @@ -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; + } } diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index a880cb313..5afa4f93d 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -1,7 +1,6 @@ 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(); } } From 02d2b05a470c92872e68dc979e0de98e959b53ad Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 22 Feb 2016 19:58:43 +0200 Subject: [PATCH 38/59] Context is no more needed in Blueprint class --- system/src/Grav/Common/Data/Blueprint.php | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 5f9f0f8a1..6a5259c20 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -1,7 +1,6 @@ setContext($context); - } - $types = Grav::instance()['plugins']->formFieldTypes; $this->setTypes($types); @@ -43,19 +36,6 @@ class Blueprint extends BaseBlueprints implements ExportInterface } } - /** - * Set context to find external blueprints. - * - * @param Blueprints $context - * @return $this - */ - public function setContext(Blueprints $context) - { - $this->context = $context; - - return $this; - } - /** * Get meta value by using dot notation for nested arrays/objects. * From 5c4c7402faa824ef7686102107af057f268c45ab Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 24 Feb 2016 21:36:40 +0200 Subject: [PATCH 39/59] Restructure blueprint classes (incomplete) --- .../Grav/Common/Config/CompiledBlueprints.php | 10 +- system/src/Grav/Common/Data/Blueprint.php | 262 ++++++------------ system/src/Grav/Common/Data/BlueprintForm.php | 96 +++---- .../src/Grav/Common/Data/BlueprintSchema.php | 154 ++++++++++ system/src/Grav/Common/Data/Blueprints.php | 12 +- system/src/Grav/Common/Themes.php | 2 +- 6 files changed, 281 insertions(+), 255 deletions(-) create mode 100644 system/src/Grav/Common/Data/BlueprintSchema.php diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php index daa0bd25d..616355f10 100644 --- a/system/src/Grav/Common/Config/CompiledBlueprints.php +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -2,7 +2,7 @@ namespace Grav\Common\Config; use Grav\Common\Data\Blueprint; -use Grav\Common\Data\BlueprintForm; +use Grav\Common\Data\BlueprintSchema; use Grav\Common\Grav; /** @@ -16,7 +16,7 @@ class CompiledBlueprints extends CompiledBase public $version = 2; /** - * @var Blueprint Blueprints object. + * @var BlueprintSchema Blueprints object. */ protected $object; @@ -43,7 +43,7 @@ class CompiledBlueprints extends CompiledBase */ protected function createObject(array $data = []) { - $this->object = (new Blueprint($data))->setTypes($this->getTypes()); + $this->object = (new BlueprintSchema($data))->setTypes($this->getTypes()); } /** @@ -72,9 +72,9 @@ class CompiledBlueprints extends CompiledBase protected function loadFile($name, $files) { // Load blueprint file. - $blueprintForm = new BlueprintForm($files); + $blueprint = new Blueprint($files); - $this->object->embed($name, $blueprintForm->load()->toArray(), '/', true); + $this->object->embed($name, $blueprint->load()->toArray(), '/', true); } /** diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 6a5259c20..1fb19f1ad 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -1,126 +1,72 @@ formFieldTypes; - - $this->setTypes($types); - - if ($data) { - $this->embed('', $data); - } - } + protected $context = 'blueprints://'; /** - * Get meta value by using dot notation for nested arrays/objects. - * - * @param string $name Dot separated path to the requested value. - * @param string $field Meta field to fetch. - * @param mixed $default Default value (or null). - * @param string $separator Separator, defaults to '.' - * - * @return mixed Value. + * @var BlueprintSchema */ - public function getMeta($name, $field, $default = null, $separator = '.') - { - $name = $separator != '.' ? strtr($name, $separator, '.') : $name; - - return isset($this->items[$name]['meta'][$field]) ? $this->items[$name]['meta'][$field] : $default; - } + protected $blueprintSchema; /** - * Set meta value by using dot notation for nested arrays/objects. + * Get nested structure containing default values defined in the blueprints. * - * @param string $name Dot separated path to the requested value. - * @param string $field Meta field to fetch. - * @param mixed $value New value. - * @param string $separator Separator, defaults to '.' - */ - public function setMeta($name, $field, $value, $separator = '.') - { - $name = $separator != '.' ? strtr($name, $separator, '.') : $name; - - $this->items[$name]['meta'][$field] = $value; - } - - /** - * Define meta value by using dot notation for nested arrays/objects. - * - * @param string $name Dot separated path to the requested value. - * @param string $field Meta field to fetch. - * @param mixed $value New value. - * @param string $separator Separator, defaults to '.' - */ - public function defMeta($name, $field, $value, $separator = '.') - { - $this->setMeta($name, $field, $this->getMeta($name, $field, $value, $separator), $separator); - } - - /** - * Return all form fields in a nested list. + * Fields without default value are ignored in the list. * * @return array */ - public function fields($name = '', $separator = '.') + public function getDefaults() { - $name = $separator != '.' ? strtr($name, $separator, '.') : $name; - if (isset($this->form[$name])) { - $form = &$this->form[$name]; - } else { - return []; - } + $this->initInternals(); - $fields = $this->buildFields($form); - - return $fields; + return $this->blueprintSchema->getDefaults(); } - public function toArray($name = '', $separator = '.') + /** + * Merge two arrays by using blueprints. + * + * @param array $data1 + * @param array $data2 + * @param string $name Optional + * @param string $separator Optional + * @return array + */ + public function mergeData(array $data1, array $data2, $name = null, $separator = '.') { - $meta = isset($this->items[$name]['meta']) ? $this->items[$name]['meta'] : []; - $formMeta = isset($this->items[$name]['form']) ? $this->items[$name]['form'] : []; - $fields = $this->fields($name, $separator); + $this->initInternals(); - return $meta + ['form' => $formMeta + ['fields' => $fields]]; + return $this->blueprintSchema->mergeData($data1, $data2, $name, $separator); } - protected function buildFields(array &$fields) + /** + * Return data fields that do not exist in blueprints. + * + * @param array $data + * @param string $prefix + * @return array + */ + public function extra(array $data, $prefix = '') { - $result = []; + $this->initInternals(); - foreach ($fields as $key => $value) { - $result[$key] = isset($this->items[$key]) ? $this->items[$key] : []; - if (is_array($value)) { - $result[$key]['fields'] = $this->buildFields($value); - } - } - - return $result; + return $this->blueprintSchema->extra($data, $prefix); } /** @@ -131,16 +77,9 @@ class Blueprint extends BaseBlueprints implements ExportInterface */ public function validate(array $data) { - try { - $messages = $this->validateArray($data, $this->nested); + $this->initInternals(); - } catch (\RuntimeException $e) { - throw (new ValidationException($e->getMessage(), $e->getCode(), $e))->setMessages(); - } - - if (!empty($messages)) { - throw (new ValidationException())->setMessages($messages); - } + $this->blueprintSchema->validate($data); } /** @@ -151,111 +90,74 @@ class Blueprint extends BaseBlueprints implements ExportInterface */ public function filter(array $data) { - return $this->filterArray($data, $this->nested); + $this->initInternals(); + + return $this->blueprintSchema->filter($data); } /** - * @param array $data - * @param array $rules - * @returns array - * @throws \RuntimeException - * @internal + * Initialize validator. */ - protected function validateArray(array $data, array $rules) + protected function initInternals() { - $messages = $this->checkRequired($data, $rules); + if (!isset($this->blueprintSchema)) { + $types = Grav::instance()['plugins']->formFieldTypes; - foreach ($data as $key => $field) { - $val = isset($rules[$key]) ? $rules[$key] : null; - $rule = is_string($val) ? $this->items[$val] : null; - - if ($rule) { - // Item has been defined in blueprints. - $messages += Validation::validate($field, $rule); - } elseif (is_array($field) && is_array($val)) { - // Array has been defined in blueprints. - $messages += $this->validateArray($field, $val); - } elseif (isset($rules['validation']) && $rules['validation'] == 'strict') { - // Undefined/extra item. - throw new \RuntimeException(sprintf('%s is not defined in blueprints', $key)); - } + $this->blueprintSchema = new BlueprintSchema; + $this->blueprintSchema->setTypes($types); + $this->blueprintSchema->embed('', $this->items); + $this->blueprintSchema->init(); } - - return $messages; } /** - * @param array $data - * @param array $rules - * @return array - * @internal + * @param string $filename + * @return string */ - protected function filterArray(array $data, array $rules) + protected function loadFile($filename) { - $results = array(); - foreach ($data as $key => $field) { - $val = isset($rules[$key]) ? $rules[$key] : null; - $rule = is_string($val) ? $this->items[$val] : null; + $file = CompiledYamlFile::instance($filename); + $content = $file->content(); + $file->free(); - if ($rule) { - // Item has been defined in blueprints. - $field = Validation::filter($field, $rule); - } elseif (is_array($field) && is_array($val)) { - // Array has been defined in blueprints. - $field = $this->filterArray($field, $val); - } elseif (isset($rules['validation']) && $rules['validation'] == 'strict') { - $field = null; - } - - if (isset($field) && (!is_array($field) || !empty($field))) { - $results[$key] = $field; - } - } - - return $results; + return $content; } /** - * @param array $data - * @param array $fields + * @param string|array $path + * @param string $context * @return array */ - protected function checkRequired(array $data, array $fields) + protected function getFiles($path, $context = null) { - $messages = []; + if (is_string($path) && !strpos($path, '://')) { + // Resolve filename. + if (isset($this->overrides[$path])) { + $path = $this->overrides[$path]; + } else { + if ($context === null) { + $context = $this->context; + } + if ($context && $context[strlen($context)-1] !== '/') { + $context .= '/'; + } + $path = $context . $path; - foreach ($fields as $name => $field) { - if (!is_string($field)) { - continue; - } - $field = $this->items[$field]; - if (isset($field['validate']['required']) - && $field['validate']['required'] === true - && !isset($data[$name])) { - $value = isset($field['label']) ? $field['label'] : $field['name']; - $language = Grav::instance()['language']; - $message = sprintf($language->translate('FORM.MISSING_REQUIRED_FIELD', null, true) . ' %s', $value); - $messages[$field['name']][] = $message; + if (!preg_match('/\.yaml$/', $path)) { + $path .= '.yaml'; + } } } - return $messages; - } + if (is_string($path) && strpos($path, '://')) { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; - /** - * @param array $field - * @param string $property - * @param array $call - */ - protected function dynamicConfig(array &$field, $property, array &$call) - { - $value = $call['params']; - - $default = isset($field[$property]) ? $field[$property] : null; - $config = Grav::instance()['config']->get($value, $default); - - if (!is_null($config)) { - $field[$property] = $config; + $files = $locator->findResources($path); + } else { + $files = (array) $path; } + + return $files; } } diff --git a/system/src/Grav/Common/Data/BlueprintForm.php b/system/src/Grav/Common/Data/BlueprintForm.php index 27bcda8e1..e91008309 100644 --- a/system/src/Grav/Common/Data/BlueprintForm.php +++ b/system/src/Grav/Common/Data/BlueprintForm.php @@ -1,19 +1,16 @@ 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; - } + // Get list of files. + $files = $this->getFiles($this->filename); // Load and extend blueprints. $data = $this->doLoad($files); $this->items = array_shift($data); + foreach ($data as $content) { $this->extend($content, true); } @@ -281,6 +280,10 @@ class BlueprintForm implements \ArrayAccess, ExportInterface return $a; } + /** + * @param array $items + * @param array $path + */ protected function deepInit(array &$items, $path = []) { foreach ($items as $key => &$item) { @@ -308,24 +311,15 @@ class BlueprintForm implements \ArrayAccess, ExportInterface { $type = !is_string($value) ? !isset($value['type']) ? null : $value['type'] : $value; - if (strpos($type, '://')) { - $filename = $type; - } elseif (empty($value['context'])) { - $filename = isset($this->overrides[$type]) ? $this->overrides[$type] : "{$this->context}{$type}"; - } else { - $separator = $value['context'][strlen($value['context'])-1] === '/' ? '' : '/'; - $filename = $value['context'] . $separator . $type; - } - if (!preg_match('/\.yaml$/', $filename)) { - $filename .= YAML_EXT; - } + $files = $this->getFiles($type, isset($value['context']) ? $value['context'] : null); - - if (!is_file($filename)) { + if (!$files) { return; } - $blueprint = (new BlueprintForm($filename))->setContext($this->context)->setOverrides($this->overrides)->load(); + /** @var BlueprintForm $blueprint */ + $blueprint = new static($files); + $blueprint->setContext($this->context)->$blueprint->setOverrides($this->overrides)->load(); $name = implode('/', $path); @@ -341,9 +335,7 @@ class BlueprintForm implements \ArrayAccess, ExportInterface protected function doLoad(array $files) { $filename = array_shift($files); - $file = CompiledYamlFile::instance($filename); - $content = $file->content(); - $file->free(); + $content = $this->loadFile($filename); $extends = isset($content['@extends']) ? (array) $content['@extends'] : (isset($content['extends@']) ? (array) $content['extends@'] : null); @@ -379,28 +371,8 @@ class BlueprintForm implements \ArrayAccess, ExportInterface 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; - } + $files = $this->getFiles($type, isset($value['context']) ? $value['context'] : null); } if ($files) { diff --git a/system/src/Grav/Common/Data/BlueprintSchema.php b/system/src/Grav/Common/Data/BlueprintSchema.php new file mode 100644 index 000000000..6a93ea1ae --- /dev/null +++ b/system/src/Grav/Common/Data/BlueprintSchema.php @@ -0,0 +1,154 @@ +validateArray($data, $this->nested); + + } catch (\RuntimeException $e) { + throw (new ValidationException($e->getMessage(), $e->getCode(), $e))->setMessages(); + } + + if (!empty($messages)) { + throw (new ValidationException())->setMessages($messages); + } + } + + /** + * Filter data by using blueprints. + * + * @param array $data + * @return array + */ + public function filter(array $data) + { + return $this->filterArray($data, $this->nested); + } + + /** + * @param array $data + * @param array $rules + * @returns array + * @throws \RuntimeException + * @internal + */ + protected function validateArray(array $data, array $rules) + { + $messages = $this->checkRequired($data, $rules); + + foreach ($data as $key => $field) { + $val = isset($rules[$key]) ? $rules[$key] : null; + $rule = is_string($val) ? $this->items[$val] : null; + + if ($rule) { + // Item has been defined in blueprints. + $messages += Validation::validate($field, $rule); + } elseif (is_array($field) && is_array($val)) { + // Array has been defined in blueprints. + $messages += $this->validateArray($field, $val); + } elseif (isset($rules['validation']) && $rules['validation'] == 'strict') { + // Undefined/extra item. + throw new \RuntimeException(sprintf('%s is not defined in blueprints', $key)); + } + } + + return $messages; + } + + /** + * @param array $data + * @param array $rules + * @return array + * @internal + */ + protected function filterArray(array $data, array $rules) + { + $results = array(); + foreach ($data as $key => $field) { + $val = isset($rules[$key]) ? $rules[$key] : null; + $rule = is_string($val) ? $this->items[$val] : null; + + if ($rule) { + // Item has been defined in blueprints. + $field = Validation::filter($field, $rule); + } elseif (is_array($field) && is_array($val)) { + // Array has been defined in blueprints. + $field = $this->filterArray($field, $val); + } elseif (isset($rules['validation']) && $rules['validation'] == 'strict') { + $field = null; + } + + if (isset($field) && (!is_array($field) || !empty($field))) { + $results[$key] = $field; + } + } + + return $results; + } + + /** + * @param array $data + * @param array $fields + * @return array + */ + protected function checkRequired(array $data, array $fields) + { + $messages = []; + + foreach ($fields as $name => $field) { + if (!is_string($field)) { + continue; + } + $field = $this->items[$field]; + if (isset($field['validate']['required']) + && $field['validate']['required'] === true + && !isset($data[$name])) { + $value = isset($field['label']) ? $field['label'] : $field['name']; + $language = Grav::instance()['language']; + $message = sprintf($language->translate('FORM.MISSING_REQUIRED_FIELD', null, true) . ' %s', $value); + $messages[$field['name']][] = $message; + } + } + + return $messages; + } + + /** + * @param array $field + * @param string $property + * @param array $call + */ + protected function dynamicConfig(array &$field, $property, array &$call) + { + $value = $call['params']; + + $default = isset($field[$property]) ? $field[$property] : null; + $config = Grav::instance()['config']->get($value, $default); + + if (!is_null($config)) { + $field[$property] = $config; + } + } +} diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index 5afa4f93d..cc8f830b8 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -84,16 +84,14 @@ class Blueprints */ protected function loadFile($name) { - $blueprintForm = new BlueprintForm($name); + $blueprint = new Blueprint($name); + if (is_array($this->search)) { - $blueprintForm->setOverrides($this->search); + $blueprint->setOverrides($this->search); } else { - $blueprintForm->setContext($this->search); + $blueprint->setContext($this->search); } - $blueprintForm->load(); - $blueprint = new Blueprint($name, $blueprintForm->toArray()); - - return $blueprint->init(); + return $blueprint->load(); } } diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php index b91ae8db4..9f360cc35 100644 --- a/system/src/Grav/Common/Themes.php +++ b/system/src/Grav/Common/Themes.php @@ -135,7 +135,7 @@ class Themes extends Iterator $path = $this->grav['locator']->findResource($thumb, false); if ($path) { - $blueprint->setMeta('', 'thumbnail', $this->grav['base_url'] . '/' . $path); + $blueprint->set('thumbnail', $this->grav['base_url'] . '/' . $path); } $obj = new Data($file->content(), $blueprint); From 979cf2061c4c0dd11fead5b6df8d981b1fdc9922 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 25 Feb 2016 17:09:50 +0200 Subject: [PATCH 40/59] Redo form field reordering in BlueprintForm class --- system/src/Grav/Common/Data/BlueprintForm.php | 58 +++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/system/src/Grav/Common/Data/BlueprintForm.php b/system/src/Grav/Common/Data/BlueprintForm.php index e91008309..7dc23d534 100644 --- a/system/src/Grav/Common/Data/BlueprintForm.php +++ b/system/src/Grav/Common/Data/BlueprintForm.php @@ -283,24 +283,46 @@ abstract class BlueprintForm implements \ArrayAccess, ExportInterface /** * @param array $items * @param array $path + * @return string */ protected function deepInit(array &$items, $path = []) { + $ordering = ''; + $order = []; + foreach ($items as $key => &$item) { + // Handle special instructions in the form. if (!empty($key) && ($key[0] === '@' || $key[strlen($key) - 1] === '@')) { $name = trim($key, '@'); - if ($name === 'import') { - $this->doImport($item, $path); - unset($items[$key]); + switch ($name) { + case 'import': + $this->doImport($item, $path); + unset($items[$key]); + break; + case 'ordering': + $ordering = $item; + unset($items[$key]); + break; } } elseif (is_array($item)) { + // Recursively initialize form. $newPath = array_merge($path, [$key]); - $this->deepInit($item, $newPath); + $location = $this->deepInit($item, $newPath); + if ($location) { + $order[$key] = $location; + } } } + + if ($order) { + // Reorder fields if needed. + $items = $this->doReorder($items, $order); + } + + return $ordering; } /** @@ -382,4 +404,32 @@ abstract class BlueprintForm implements \ArrayAccess, ExportInterface return $data; } + + /** + * Internal function to reorder items. + * + * @param array $items + * @param array $keys + * @return array + */ + protected function doReorder(array $items, array $keys) + { + $reordered = array_keys($items); + + foreach ($keys as $item => $ordering) { + if ((string)(int) $ordering === (string) $ordering) { + $location = array_search($item, $reordered); + $rel = array_splice($reordered, $location, 1); + array_splice($reordered, $ordering, 0, $rel); + + } elseif (isset($items[$ordering])) { + $location = array_search($item, $reordered); + $rel = array_splice($reordered, $location, 1); + $location = array_search($ordering, $reordered); + array_splice($reordered, $location + 1, 0, $rel); + } + } + + return array_merge(array_flip($reordered), $items); + } } From 2be8de4283667c51a0d4793f64981d8500a7b4cf Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Fri, 26 Feb 2016 11:32:14 +0200 Subject: [PATCH 41/59] BlueprintForm: Add support for dynamic fields --- composer.lock | 18 +++--- system/src/Grav/Common/Data/Blueprint.php | 56 ++++++++++++++++ system/src/Grav/Common/Data/BlueprintForm.php | 64 +++++++++++++++---- .../src/Grav/Common/Data/BlueprintSchema.php | 10 +++ system/src/Grav/Common/Data/Blueprints.php | 2 +- 5 files changed, 129 insertions(+), 21 deletions(-) diff --git a/composer.lock b/composer.lock index c8f8c38de..fe3eadfbf 100644 --- a/composer.lock +++ b/composer.lock @@ -366,16 +366,16 @@ }, { "name": "maximebf/debugbar", - "version": "v1.11.0", + "version": "v1.11.1", "source": { "type": "git", "url": "https://github.com/maximebf/php-debugbar.git", - "reference": "07741d84d39d10f00551c94284cdefcc69703e77" + "reference": "d9302891c1f0a0ac5a4f66725163a00537c6359f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/07741d84d39d10f00551c94284cdefcc69703e77", - "reference": "07741d84d39d10f00551c94284cdefcc69703e77", + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/d9302891c1f0a0ac5a4f66725163a00537c6359f", + "reference": "d9302891c1f0a0ac5a4f66725163a00537c6359f", "shasum": "" }, "require": { @@ -423,7 +423,7 @@ "debug", "debugbar" ], - "time": "2015-12-10 09:50:24" + "time": "2016-01-22 12:22:23" }, { "name": "monolog/monolog", @@ -637,12 +637,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "ceb00d34e24bf137e1fc368411d1a94497d991c8" + "reference": "cfb20f0396f1dc8e556cdf0e785f311e10742eee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/ceb00d34e24bf137e1fc368411d1a94497d991c8", - "reference": "ceb00d34e24bf137e1fc368411d1a94497d991c8", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/cfb20f0396f1dc8e556cdf0e785f311e10742eee", + "reference": "cfb20f0396f1dc8e556cdf0e785f311e10742eee", "shasum": "" }, "require": { @@ -677,7 +677,7 @@ "php", "rockettheme" ], - "time": "2016-02-18 13:35:02" + "time": "2016-02-25 18:01:13" }, { "name": "symfony/console", diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 1fb19f1ad..876d0d2b6 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -160,4 +160,60 @@ class Blueprint extends BlueprintForm return $files; } + + /** + * @param array $field + * @param string $property + * @param array $call + */ + protected function dynamicData(array &$field, $property, array &$call) + { + $params = $call['params']; + + if (is_array($params)) { + $function = array_shift($params); + } else { + $function = $params; + $params = []; + } + + list($o, $f) = preg_split('/::/', $function, 2); + if (!$f) { + if (function_exists($o)) { + $data = call_user_func_array($o, $params); + } + } else { + if (method_exists($o, $f)) { + $data = call_user_func_array(array($o, $f), $params); + } + } + + // If function returns a value, + if (isset($data)) { + if (isset($field[$property]) && is_array($field[$property]) && is_array($data)) { + // Combine field and @data-field together. + $field[$property] += $data; + } else { + // Or create/replace field with @data-field. + $field[$property] = $data; + } + } + } + + /** + * @param array $field + * @param string $property + * @param array $call + */ + protected function dynamicConfig(array &$field, $property, array &$call) + { + $value = $call['params']; + + $default = isset($field[$property]) ? $field[$property] : null; + $config = Grav::instance()['config']->get($value, $default); + + if (!is_null($config)) { + $field[$property] = $config; + } + } } diff --git a/system/src/Grav/Common/Data/BlueprintForm.php b/system/src/Grav/Common/Data/BlueprintForm.php index 7dc23d534..9927ef782 100644 --- a/system/src/Grav/Common/Data/BlueprintForm.php +++ b/system/src/Grav/Common/Data/BlueprintForm.php @@ -34,6 +34,10 @@ abstract class BlueprintForm implements \ArrayAccess, ExportInterface */ protected $overrides = []; + /** + * @var array + */ + protected $dynamic = []; /** * Load file and return its contents. @@ -112,23 +116,55 @@ abstract class BlueprintForm implements \ArrayAccess, ExportInterface } } - // Finally initialize blueprint. - return $this->init(); - } - - /** - * Initialize blueprint. - * - * @return $this - */ - public function init() - { // Import blueprints. $this->deepInit($this->items); return $this; } + /** + * Initialize blueprints with its dynamic fields. + * + * @return $this + */ + public function init() + { + foreach ($this->dynamic as $key => $data) { + // Locate field. + $path = explode('/', $key); + $current = &$this->items; + foreach ($path as $field) { + if (is_object($current)) { + // Handle objects. + if (!isset($current->{$field})) { + $current->{$field} = array(); + } + $current = &$current->{$field}; + } else { + // Handle arrays and scalars. + if (!is_array($current)) { + $current = array($field => array()); + } elseif (!isset($current[$field])) { + $current[$field] = array(); + } + $current = &$current[$field]; + } + } + + // Set dynamic property. + foreach ($data as $property => $call) { + $action = 'dynamic' . ucfirst($call['action']); + + if (method_exists($this, $action)) { + $this->{$action}($current, $property, $call); + } + } + } + + return $this; + } + + /** * Get form. * @@ -304,6 +340,12 @@ abstract class BlueprintForm implements \ArrayAccess, ExportInterface $ordering = $item; unset($items[$key]); break; + default: + $list = explode('-', trim($name, '@'), 2); + $action = array_shift($list); + $property = array_shift($list); + + $this->dynamic[implode('/', $path)][$property] = ['action' => $action, 'params' => $item]; } } elseif (is_array($item)) { diff --git a/system/src/Grav/Common/Data/BlueprintSchema.php b/system/src/Grav/Common/Data/BlueprintSchema.php index 6a93ea1ae..0e3157447 100644 --- a/system/src/Grav/Common/Data/BlueprintSchema.php +++ b/system/src/Grav/Common/Data/BlueprintSchema.php @@ -16,6 +16,16 @@ class BlueprintSchema extends BaseBlueprints implements ExportInterface { use Export; + protected $ignoreFormKeys = [ + 'label' => true, + 'title' => true, + 'help' => true, + 'placeholder' => true, + 'placeholder_key' => true, + 'placeholder_value' => true, + 'fields' => true + ]; + /** * Validate data against blueprints. * diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index cc8f830b8..4f8c67ae5 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -92,6 +92,6 @@ class Blueprints $blueprint->setContext($this->search); } - return $blueprint->load(); + return $blueprint->load()->init(); } } From 8f5a30cc508a22da02b86ce68666effdd76abe0e Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 29 Feb 2016 13:14:16 +0200 Subject: [PATCH 42/59] Blueprints: Fix for page blueprints --- system/src/Grav/Common/Data/BlueprintForm.php | 2 +- system/src/Grav/Common/Data/Blueprints.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Data/BlueprintForm.php b/system/src/Grav/Common/Data/BlueprintForm.php index 9927ef782..236603519 100644 --- a/system/src/Grav/Common/Data/BlueprintForm.php +++ b/system/src/Grav/Common/Data/BlueprintForm.php @@ -87,7 +87,7 @@ abstract class BlueprintForm implements \ArrayAccess, ExportInterface * @param array $overrides * @return $this */ - public function setOverrides(array $overrides) + public function setOverrides($overrides) { $this->overrides = $overrides; diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index 4f8c67ae5..af9e76044 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -86,7 +86,7 @@ class Blueprints { $blueprint = new Blueprint($name); - if (is_array($this->search)) { + if (is_array($this->search) || is_object($this->search)) { $blueprint->setOverrides($this->search); } else { $blueprint->setContext($this->search); From 16d532bb2eade2d67d7c18a25e49e4dcf75ca04d Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 29 Feb 2016 14:17:00 +0200 Subject: [PATCH 43/59] Blueprints: Fix empty values in admin fields --- system/src/Grav/Common/Data/BlueprintForm.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/system/src/Grav/Common/Data/BlueprintForm.php b/system/src/Grav/Common/Data/BlueprintForm.php index 236603519..64aecdffc 100644 --- a/system/src/Grav/Common/Data/BlueprintForm.php +++ b/system/src/Grav/Common/Data/BlueprintForm.php @@ -325,8 +325,14 @@ abstract class BlueprintForm implements \ArrayAccess, ExportInterface { $ordering = ''; $order = []; + $field = end($path) === 'fields'; foreach ($items as $key => &$item) { + // Set name for nested field. + if ($field && isset($item['type'])) { + $item['name'] = $key; + } + // Handle special instructions in the form. if (!empty($key) && ($key[0] === '@' || $key[strlen($key) - 1] === '@')) { $name = trim($key, '@'); From f2008135bb0b441fe5bb053aadcfc1c3082c563b Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 29 Feb 2016 14:20:12 +0200 Subject: [PATCH 44/59] BlueprintForm: Fix typo --- system/src/Grav/Common/Data/BlueprintForm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Data/BlueprintForm.php b/system/src/Grav/Common/Data/BlueprintForm.php index 64aecdffc..d5b1fc985 100644 --- a/system/src/Grav/Common/Data/BlueprintForm.php +++ b/system/src/Grav/Common/Data/BlueprintForm.php @@ -389,7 +389,7 @@ abstract class BlueprintForm implements \ArrayAccess, ExportInterface /** @var BlueprintForm $blueprint */ $blueprint = new static($files); - $blueprint->setContext($this->context)->$blueprint->setOverrides($this->overrides)->load(); + $blueprint->setContext($this->context)->setOverrides($this->overrides)->load(); $name = implode('/', $path); From 048ecb099a5d722c0b1e5ffd6cfcb50e87e6cd31 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 29 Feb 2016 20:34:33 +0200 Subject: [PATCH 45/59] Move BlueprintForm class into toolbox --- composer.lock | 50 +- system/src/Grav/Common/Data/Blueprint.php | 4 +- system/src/Grav/Common/Data/BlueprintForm.php | 483 ------------------ .../src/Grav/Common/Data/BlueprintSchema.php | 4 +- 4 files changed, 28 insertions(+), 513 deletions(-) delete mode 100644 system/src/Grav/Common/Data/BlueprintForm.php diff --git a/composer.lock b/composer.lock index fe3eadfbf..2430230b0 100644 --- a/composer.lock +++ b/composer.lock @@ -637,12 +637,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "cfb20f0396f1dc8e556cdf0e785f311e10742eee" + "reference": "687ca3b95950a07eb0d11f04f0ff0a1a0fab0b49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/cfb20f0396f1dc8e556cdf0e785f311e10742eee", - "reference": "cfb20f0396f1dc8e556cdf0e785f311e10742eee", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/687ca3b95950a07eb0d11f04f0ff0a1a0fab0b49", + "reference": "687ca3b95950a07eb0d11f04f0ff0a1a0fab0b49", "shasum": "" }, "require": { @@ -652,7 +652,7 @@ "symfony/yaml": ">2.5" }, "require-dev": { - "phpunit/phpunit": "~5.1" + "phpunit/phpunit": "~5.1.5" }, "type": "library", "autoload": { @@ -677,20 +677,20 @@ "php", "rockettheme" ], - "time": "2016-02-25 18:01:13" + "time": "2016-02-29 18:27:06" }, { "name": "symfony/console", - "version": "v2.8.2", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d0239fb42f98dd02e7d342f793c5d2cdee0c478d" + "reference": "56cc5caf051189720b8de974e4746090aaa10d44" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d0239fb42f98dd02e7d342f793c5d2cdee0c478d", - "reference": "d0239fb42f98dd02e7d342f793c5d2cdee0c478d", + "url": "https://api.github.com/repos/symfony/console/zipball/56cc5caf051189720b8de974e4746090aaa10d44", + "reference": "56cc5caf051189720b8de974e4746090aaa10d44", "shasum": "" }, "require": { @@ -737,20 +737,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-01-14 08:33:16" + "time": "2016-02-28 16:20:50" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.2", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "ee278f7c851533e58ca307f66305ccb9188aceda" + "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ee278f7c851533e58ca307f66305ccb9188aceda", - "reference": "ee278f7c851533e58ca307f66305ccb9188aceda", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/78c468665c9568c3faaa9c416a7134308f2d85c3", + "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3", "shasum": "" }, "require": { @@ -797,7 +797,7 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-01-13 10:28:07" + "time": "2016-01-27 05:14:19" }, { "name": "symfony/polyfill-iconv", @@ -919,16 +919,16 @@ }, { "name": "symfony/var-dumper", - "version": "v2.8.2", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "ab94426d127ad9e95433778a3a451fe9d18f3d6b" + "reference": "19b697abe08833ddf38c3ab0cb1bfad236b13bde" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/ab94426d127ad9e95433778a3a451fe9d18f3d6b", - "reference": "ab94426d127ad9e95433778a3a451fe9d18f3d6b", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/19b697abe08833ddf38c3ab0cb1bfad236b13bde", + "reference": "19b697abe08833ddf38c3ab0cb1bfad236b13bde", "shasum": "" }, "require": { @@ -978,20 +978,20 @@ "debug", "dump" ], - "time": "2016-01-07 13:38:40" + "time": "2016-02-13 09:21:29" }, { "name": "symfony/yaml", - "version": "v2.8.2", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "34c8a4b51e751e7ea869b8262f883d008a2b81b8" + "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/34c8a4b51e751e7ea869b8262f883d008a2b81b8", - "reference": "34c8a4b51e751e7ea869b8262f883d008a2b81b8", + "url": "https://api.github.com/repos/symfony/yaml/zipball/2a4ee40acb880c56f29fb1b8886e7ffe94f3b995", + "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995", "shasum": "" }, "require": { @@ -1027,7 +1027,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-01-13 10:28:07" + "time": "2016-02-23 07:41:20" }, { "name": "twig/twig", diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 876d0d2b6..c8917e537 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -3,9 +3,7 @@ namespace Grav\Common\Data; use Grav\Common\File\CompiledYamlFile; use Grav\Common\Grav; -use RocketTheme\Toolbox\ArrayTraits\Export; -use RocketTheme\Toolbox\ArrayTraits\ExportInterface; -use RocketTheme\Toolbox\ArrayTraits\NestedArrayAccessWithGetters; +use RocketTheme\Toolbox\Blueprints\BlueprintForm; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; /** diff --git a/system/src/Grav/Common/Data/BlueprintForm.php b/system/src/Grav/Common/Data/BlueprintForm.php deleted file mode 100644 index d5b1fc985..000000000 --- a/system/src/Grav/Common/Data/BlueprintForm.php +++ /dev/null @@ -1,483 +0,0 @@ -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($overrides) - { - $this->overrides = $overrides; - - return $this; - } - - /** - * Load blueprint. - * - * @return $this - */ - public function load() - { - // Only load and extend blueprint if it has not yet been loaded. - if (empty($this->items)) { - // Get list of files. - $files = $this->getFiles($this->filename); - - // Load and extend blueprints. - $data = $this->doLoad($files); - - $this->items = array_shift($data); - - foreach ($data as $content) { - $this->extend($content, true); - } - } - - // Import blueprints. - $this->deepInit($this->items); - - return $this; - } - - /** - * Initialize blueprints with its dynamic fields. - * - * @return $this - */ - public function init() - { - foreach ($this->dynamic as $key => $data) { - // Locate field. - $path = explode('/', $key); - $current = &$this->items; - foreach ($path as $field) { - if (is_object($current)) { - // Handle objects. - if (!isset($current->{$field})) { - $current->{$field} = array(); - } - $current = &$current->{$field}; - } else { - // Handle arrays and scalars. - if (!is_array($current)) { - $current = array($field => array()); - } elseif (!isset($current[$field])) { - $current[$field] = array(); - } - $current = &$current[$field]; - } - } - - // Set dynamic property. - foreach ($data as $property => $call) { - $action = 'dynamic' . ucfirst($call['action']); - - if (method_exists($this, $action)) { - $this->{$action}($current, $property, $call); - } - } - } - - return $this; - } - - - /** - * Get form. - * - * @return array - */ - public function form() - { - return (array) $this->get('form'); - } - - /** - * Get form fields. - * - * @return array - */ - public function fields() - { - return (array) $this->get('form.fields'); - } - - /** - * Extend blueprint with another blueprint. - * - * @param BlueprintForm|array $extends - * @param bool $append - * @return $this - */ - public function extend($extends, $append = false) - { - if ($extends instanceof BlueprintForm) { - $extends = $extends->toArray(); - } - - if ($append) { - $a = $this->items; - $b = $extends; - } else { - $a = $extends; - $b = $this->items; - } - - $this->items = $this->deepMerge($a, $b); - - return $this; - } - - /** - * @param string $name - * @param mixed $value - * @param string $separator - * @param bool $append - * @return $this - */ - public function embed($name, $value, $separator = '/', $append = false) - { - $oldValue = $this->get($name, null, $separator); - - if (is_array($oldValue) && is_array($value)) { - if ($append) { - $a = $oldValue; - $b = $value; - } else { - $a = $value; - $b = $oldValue; - } - - $value = $this->deepMerge($a, $b); - } - - $this->set($name, $value, $separator); - - return $this; - } - - /** - * Get blueprints by using dot notation for nested arrays/objects. - * - * @example $value = $this->resolve('this.is.my.nested.variable'); - * returns ['this.is.my', 'nested.variable'] - * - * @param array $path - * @param string $separator - * @return array - */ - public function resolve(array $path, $separator = '/') - { - $fields = false; - $parts = []; - $current = $this['form.fields']; - $result = [null, null, null]; - - while (($field = current($path)) !== null) { - if (!$fields && isset($current['fields'])) { - if (!empty($current['array'])) { - $result = [$current, $parts, $path ? implode($separator, $path) : null]; - // Skip item offset. - $parts[] = array_shift($path); - } - - $current = $current['fields']; - $fields = true; - - } elseif (isset($current[$field])) { - $parts[] = array_shift($path); - $current = $current[$field]; - $fields = false; - - } elseif (isset($current['.' . $field])) { - $parts[] = array_shift($path); - $current = $current['.' . $field]; - $fields = false; - - } else { - break; - } - } - - return $result; - } - - /** - * Deep merge two arrays together. - * - * @param array $a - * @param array $b - * @return array - */ - protected function deepMerge(array $a, array $b) - { - $bref_stack = array(&$a); - $head_stack = array($b); - - do { - end($bref_stack); - $bref = &$bref_stack[key($bref_stack)]; - $head = array_pop($head_stack); - unset($bref_stack[key($bref_stack)]); - - foreach (array_keys($head) as $key) { - if (isset($key, $bref[$key]) && is_array($bref[$key]) && is_array($head[$key])) { - $bref_stack[] = &$bref[$key]; - $head_stack[] = $head[$key]; - } else { - $bref = array_merge($bref, [$key => $head[$key]]); - } - } - } while (count($head_stack)); - - return $a; - } - - /** - * @param array $items - * @param array $path - * @return string - */ - protected function deepInit(array &$items, $path = []) - { - $ordering = ''; - $order = []; - $field = end($path) === 'fields'; - - foreach ($items as $key => &$item) { - // Set name for nested field. - if ($field && isset($item['type'])) { - $item['name'] = $key; - } - - // Handle special instructions in the form. - if (!empty($key) && ($key[0] === '@' || $key[strlen($key) - 1] === '@')) { - $name = trim($key, '@'); - - switch ($name) { - case 'import': - $this->doImport($item, $path); - unset($items[$key]); - break; - case 'ordering': - $ordering = $item; - unset($items[$key]); - break; - default: - $list = explode('-', trim($name, '@'), 2); - $action = array_shift($list); - $property = array_shift($list); - - $this->dynamic[implode('/', $path)][$property] = ['action' => $action, 'params' => $item]; - } - - } elseif (is_array($item)) { - // Recursively initialize form. - $newPath = array_merge($path, [$key]); - - $location = $this->deepInit($item, $newPath); - if ($location) { - $order[$key] = $location; - } - } - } - - if ($order) { - // Reorder fields if needed. - $items = $this->doReorder($items, $order); - } - - return $ordering; - } - - /** - * @param array $value - * @param array $path - */ - protected function doImport(array &$value, array &$path) - { - $type = !is_string($value) ? !isset($value['type']) ? null : $value['type'] : $value; - - $files = $this->getFiles($type, isset($value['context']) ? $value['context'] : null); - - if (!$files) { - return; - } - - /** @var BlueprintForm $blueprint */ - $blueprint = new static($files); - $blueprint->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); - $content = $this->loadFile($filename); - - $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 { - $files = $this->getFiles($type, isset($value['context']) ? $value['context'] : null); - } - - if ($files) { - $data = array_merge($data, $this->doLoad($files)); - } - } - - return $data; - } - - /** - * Internal function to reorder items. - * - * @param array $items - * @param array $keys - * @return array - */ - protected function doReorder(array $items, array $keys) - { - $reordered = array_keys($items); - - foreach ($keys as $item => $ordering) { - if ((string)(int) $ordering === (string) $ordering) { - $location = array_search($item, $reordered); - $rel = array_splice($reordered, $location, 1); - array_splice($reordered, $ordering, 0, $rel); - - } elseif (isset($items[$ordering])) { - $location = array_search($item, $reordered); - $rel = array_splice($reordered, $location, 1); - $location = array_search($ordering, $reordered); - array_splice($reordered, $location + 1, 0, $rel); - } - } - - return array_merge(array_flip($reordered), $items); - } -} diff --git a/system/src/Grav/Common/Data/BlueprintSchema.php b/system/src/Grav/Common/Data/BlueprintSchema.php index 0e3157447..5e8efeb1c 100644 --- a/system/src/Grav/Common/Data/BlueprintSchema.php +++ b/system/src/Grav/Common/Data/BlueprintSchema.php @@ -4,7 +4,7 @@ namespace Grav\Common\Data; use Grav\Common\Grav; use RocketTheme\Toolbox\ArrayTraits\Export; use RocketTheme\Toolbox\ArrayTraits\ExportInterface; -use RocketTheme\Toolbox\Blueprints\Blueprints as BaseBlueprints; +use RocketTheme\Toolbox\Blueprints\BlueprintSchema as BlueprintSchemaBase; /** * Blueprint schema handles the internal logic of blueprints. @@ -12,7 +12,7 @@ use RocketTheme\Toolbox\Blueprints\Blueprints as BaseBlueprints; * @author RocketTheme * @license MIT */ -class BlueprintSchema extends BaseBlueprints implements ExportInterface +class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface { use Export; From c5c16fc24dac850f74ad2ea6eb41a02654b3f0b4 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 1 Mar 2016 14:55:36 +0200 Subject: [PATCH 46/59] Composer update --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 2430230b0..dea6e1f62 100644 --- a/composer.lock +++ b/composer.lock @@ -637,12 +637,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "687ca3b95950a07eb0d11f04f0ff0a1a0fab0b49" + "reference": "65474f48cf8f556a6cffd4ef6f1d58c4f0b1d545" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/687ca3b95950a07eb0d11f04f0ff0a1a0fab0b49", - "reference": "687ca3b95950a07eb0d11f04f0ff0a1a0fab0b49", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/65474f48cf8f556a6cffd4ef6f1d58c4f0b1d545", + "reference": "65474f48cf8f556a6cffd4ef6f1d58c4f0b1d545", "shasum": "" }, "require": { @@ -677,7 +677,7 @@ "php", "rockettheme" ], - "time": "2016-02-29 18:27:06" + "time": "2016-03-01 11:54:12" }, { "name": "symfony/console", From 3196122f4e7cb33fd2cbdadfbbc19cc433a57f09 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 1 Mar 2016 19:14:11 +0200 Subject: [PATCH 47/59] Restore old blueprints from develop --- system/blueprints/config/site.yaml | 8 ++++---- system/blueprints/pages/default.yaml | 6 +++--- system/blueprints/pages/modular.yaml | 2 +- system/blueprints/pages/modular_raw.yaml | 4 ++-- system/blueprints/pages/raw.yaml | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/system/blueprints/config/site.yaml b/system/blueprints/config/site.yaml index 149dcdf4b..485f2c375 100644 --- a/system/blueprints/config/site.yaml +++ b/system/blueprints/config/site.yaml @@ -3,7 +3,7 @@ form: validation: loose fields: - section_content: + content: type: section title: PLUGIN_ADMIN.DEFAULTS underline: true @@ -39,7 +39,7 @@ form: validate: type: commalist - section_summary: + summary: type: section title: PLUGIN_ADMIN.PAGE_SUMMARY underline: true @@ -82,7 +82,7 @@ form: label: PLUGIN_ADMIN.DELIMITER help: PLUGIN_ADMIN.DELIMITER_HELP - section_metadata: + metadata: type: section title: PLUGIN_ADMIN.METADATA underline: true @@ -95,7 +95,7 @@ form: placeholder_key: PLUGIN_ADMIN.METADATA_KEY placeholder_value: PLUGIN_ADMIN.METADATA_VALUE - section_routes: + routes: type: section title: PLUGIN_ADMIN.REDIRECTS_AND_ROUTES underline: true diff --git a/system/blueprints/pages/default.yaml b/system/blueprints/pages/default.yaml index a4fcda7b6..1b9b166ee 100644 --- a/system/blueprints/pages/default.yaml +++ b/system/blueprints/pages/default.yaml @@ -16,7 +16,7 @@ form: active: 1 fields: - tab_content: + content: type: tab title: PLUGIN_ADMIN.CONTENT @@ -37,7 +37,7 @@ form: type: pagemedia label: PLUGIN_ADMIN.PAGE_MEDIA - tab_options: + options: type: tab title: PLUGIN_ADMIN.OPTIONS @@ -101,7 +101,7 @@ form: validate: type: array - tab_advanced: + advanced: type: tab title: PLUGIN_ADMIN.ADVANCED diff --git a/system/blueprints/pages/modular.yaml b/system/blueprints/pages/modular.yaml index 32492e056..ce62ecd1c 100644 --- a/system/blueprints/pages/modular.yaml +++ b/system/blueprints/pages/modular.yaml @@ -10,7 +10,7 @@ form: active: 1 fields: - tab_content: + content: fields: header.content.items: diff --git a/system/blueprints/pages/modular_raw.yaml b/system/blueprints/pages/modular_raw.yaml index f6fd2d8ea..393cde5fd 100644 --- a/system/blueprints/pages/modular_raw.yaml +++ b/system/blueprints/pages/modular_raw.yaml @@ -13,7 +13,7 @@ form: active: 1 fields: - tab_content: + content: type: tab title: PLUGIN_ADMIN.CONTENT @@ -32,7 +32,7 @@ form: label: PLUGIN_ADMIN.PAGE_MEDIA - tab_options: + options: type: tab title: PLUGIN_ADMIN.OPTIONS diff --git a/system/blueprints/pages/raw.yaml b/system/blueprints/pages/raw.yaml index a0a5a710f..bed82d593 100644 --- a/system/blueprints/pages/raw.yaml +++ b/system/blueprints/pages/raw.yaml @@ -13,7 +13,7 @@ form: active: 1 fields: - tab_content: + content: type: tab title: PLUGIN_ADMIN.CONTENT @@ -31,7 +31,7 @@ form: type: pagemedia label: PLUGIN_ADMIN.PAGE_MEDIA - tab_options: + options: type: tab title: PLUGIN_ADMIN.OPTIONS From 091a727fe156cbc1873626fe3dfbc70729b881ed Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 1 Mar 2016 20:14:03 +0200 Subject: [PATCH 48/59] Fix plugin installation from GPM --- composer.lock | 8 ++++---- system/src/Grav/Common/Data/Blueprint.php | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index dea6e1f62..9af35cddf 100644 --- a/composer.lock +++ b/composer.lock @@ -637,12 +637,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "65474f48cf8f556a6cffd4ef6f1d58c4f0b1d545" + "reference": "037289e773170e916783e551b20fdd9a7fe3255d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/65474f48cf8f556a6cffd4ef6f1d58c4f0b1d545", - "reference": "65474f48cf8f556a6cffd4ef6f1d58c4f0b1d545", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/037289e773170e916783e551b20fdd9a7fe3255d", + "reference": "037289e773170e916783e551b20fdd9a7fe3255d", "shasum": "" }, "require": { @@ -677,7 +677,7 @@ "php", "rockettheme" ], - "time": "2016-03-01 11:54:12" + "time": "2016-03-01 17:49:44" }, { "name": "symfony/console", diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index c8917e537..a48a92618 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -102,7 +102,9 @@ class Blueprint extends BlueprintForm $types = Grav::instance()['plugins']->formFieldTypes; $this->blueprintSchema = new BlueprintSchema; - $this->blueprintSchema->setTypes($types); + if ($types) { + $this->blueprintSchema->setTypes($types); + } $this->blueprintSchema->embed('', $this->items); $this->blueprintSchema->init(); } From 207e07876fbe59b1499a7e5221693845b7468334 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 1 Mar 2016 21:51:29 +0200 Subject: [PATCH 49/59] Fix blueprints bug in bin/grav --- system/src/Grav/Common/Config/CompiledBlueprints.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php index 616355f10..b7614b501 100644 --- a/system/src/Grav/Common/Config/CompiledBlueprints.php +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -53,7 +53,7 @@ class CompiledBlueprints extends CompiledBase */ protected function getTypes() { - return Grav::instance()['plugins']->formFieldTypes; + return Grav::instance()['plugins']->formFieldTypes ?: []; } /** From 48cabb19e7e11cfff734f17402e5b3b9a57b26ce Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 2 Mar 2016 12:50:50 +0200 Subject: [PATCH 50/59] Composer update, fixes saving pages --- composer.lock | 8 ++++---- system/src/Grav/Common/Data/Data.php | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index 633f54786..e37e6ddca 100644 --- a/composer.lock +++ b/composer.lock @@ -638,12 +638,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "037289e773170e916783e551b20fdd9a7fe3255d" + "reference": "f7484acade72c1106874d57cee06d6aa2401a748" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/037289e773170e916783e551b20fdd9a7fe3255d", - "reference": "037289e773170e916783e551b20fdd9a7fe3255d", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/f7484acade72c1106874d57cee06d6aa2401a748", + "reference": "f7484acade72c1106874d57cee06d6aa2401a748", "shasum": "" }, "require": { @@ -678,7 +678,7 @@ "php", "rockettheme" ], - "time": "2016-03-01 17:49:44" + "time": "2016-03-02 09:02:09" }, { "name": "symfony/console", diff --git a/system/src/Grav/Common/Data/Data.php b/system/src/Grav/Common/Data/Data.php index fe70efb1b..37590aa2f 100644 --- a/system/src/Grav/Common/Data/Data.php +++ b/system/src/Grav/Common/Data/Data.php @@ -5,7 +5,6 @@ use RocketTheme\Toolbox\ArrayTraits\Countable; use RocketTheme\Toolbox\ArrayTraits\Export; use RocketTheme\Toolbox\ArrayTraits\ExportInterface; use RocketTheme\Toolbox\ArrayTraits\NestedArrayAccessWithGetters; -use RocketTheme\Toolbox\Blueprints\Blueprints; use RocketTheme\Toolbox\File\File; use RocketTheme\Toolbox\File\FileInterface; @@ -217,12 +216,12 @@ class Data implements DataInterface, \ArrayAccess, \Countable, ExportInterface /** * Return blueprints. * - * @return Blueprints + * @return Blueprint */ public function blueprints() { if (!$this->blueprints){ - $this->blueprints = new Blueprints; + $this->blueprints = new Blueprint; } elseif (is_callable($this->blueprints)) { // Lazy load blueprints. $blueprints = $this->blueprints; From 99bd25f80545a433b7c23046cc0e797b5aa92e88 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 2 Mar 2016 20:58:34 +0200 Subject: [PATCH 51/59] Add streams support for Filesystem\Folder class --- composer.lock | 8 ++-- system/src/Grav/Common/Filesystem/Folder.php | 39 +++++++++++++++++--- system/src/Grav/Common/Page/Pages.php | 7 ++-- system/src/Grav/Common/Page/Types.php | 38 ++++++++++--------- 4 files changed, 60 insertions(+), 32 deletions(-) diff --git a/composer.lock b/composer.lock index e37e6ddca..2ae0bc50f 100644 --- a/composer.lock +++ b/composer.lock @@ -638,12 +638,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "f7484acade72c1106874d57cee06d6aa2401a748" + "reference": "f9005449d8430a96c28eda3d786ddd2aae7040d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/f7484acade72c1106874d57cee06d6aa2401a748", - "reference": "f7484acade72c1106874d57cee06d6aa2401a748", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/f9005449d8430a96c28eda3d786ddd2aae7040d3", + "reference": "f9005449d8430a96c28eda3d786ddd2aae7040d3", "shasum": "" }, "require": { @@ -678,7 +678,7 @@ "php", "rockettheme" ], - "time": "2016-03-02 09:02:09" + "time": "2016-03-02 18:28:47" }, { "name": "symfony/console", diff --git a/system/src/Grav/Common/Filesystem/Folder.php b/system/src/Grav/Common/Filesystem/Folder.php index 26e90fe31..a60d1ad14 100644 --- a/system/src/Grav/Common/Filesystem/Folder.php +++ b/system/src/Grav/Common/Filesystem/Folder.php @@ -1,6 +1,9 @@ isStream($path)) { + $directory = $locator->getRecursiveIterator($path, $flags); + } else { + $directory = new \RecursiveDirectoryIterator($path, $flags); + } $filter = new RecursiveFolderFilterIterator($directory); $iterator = new \RecursiveIteratorIterator($filter, \RecursiveIteratorIterator::SELF_FIRST); @@ -46,7 +56,14 @@ abstract class Folder { $last_modified = 0; - $directory = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS); + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $flags = \RecursiveDirectoryIterator::SKIP_DOTS; + if ($locator->isStream($path)) { + $directory = $locator->getRecursiveIterator($path, $flags); + } else { + $directory = new \RecursiveDirectoryIterator($path, $flags); + } $recursive = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST); $iterator = new \RegexIterator($recursive, '/^.+\.'.$extensions.'$/i'); @@ -145,7 +162,7 @@ abstract class Folder public static function all($path, array $params = []) { if ($path === false) { - throw new \RuntimeException("Path to {$path} doesn't exist."); + throw new \RuntimeException("Path doesn't exist."); } $compare = isset($params['compare']) ? 'get' . $params['compare'] : null; @@ -158,13 +175,23 @@ abstract class Folder $folders = isset($params['folders']) ? $params['folders'] : true; $files = isset($params['files']) ? $params['files'] : true; + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; if ($recursive) { - $directory = new \RecursiveDirectoryIterator($path, - \RecursiveDirectoryIterator::SKIP_DOTS + \FilesystemIterator::UNIX_PATHS + \FilesystemIterator::CURRENT_AS_SELF); + $flags = \RecursiveDirectoryIterator::SKIP_DOTS + \FilesystemIterator::UNIX_PATHS + \FilesystemIterator::CURRENT_AS_SELF; + if ($locator->isStream($path)) { + $directory = $locator->getRecursiveIterator($path, $flags); + } else { + $directory = new \RecursiveDirectoryIterator($path, $flags); + } $iterator = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST); $iterator->setMaxDepth(max($levels, -1)); } else { - $iterator = new \FilesystemIterator($path); + if ($locator->isStream($path)) { + $iterator = $locator->getIterator($path); + } else { + $iterator = new \FilesystemIterator($path); + } } $results = []; diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 407b964af..f9f1021a6 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -391,7 +391,7 @@ class Pages $blueprint = $this->blueprints->get('default'); } - if (!$blueprint->initialized) { + if (empty($blueprint->initialized)) { $this->grav->fireEvent('onBlueprintCreated', new Event(['blueprint' => $blueprint])); $blueprint->initialized = true; } @@ -470,11 +470,10 @@ class Pages */ public static function getTypes() { - $locator = Grav::instance()['locator']; if (!self::$types) { self::$types = new Types(); - file_exists('theme://blueprints/') && self::$types->scanBlueprints($locator->findResources('theme://blueprints/')); - file_exists('theme://templates/') && self::$types->scanTemplates($locator->findResources('theme://templates/')); + self::$types->scanBlueprints('theme://blueprints/'); + self::$types->scanTemplates('theme://templates/'); $event = new Event(); $event->types = self::$types; diff --git a/system/src/Grav/Common/Page/Types.php b/system/src/Grav/Common/Page/Types.php index 5fbeaea5e..46d64a542 100644 --- a/system/src/Grav/Common/Page/Types.php +++ b/system/src/Grav/Common/Page/Types.php @@ -28,13 +28,21 @@ class Types implements \ArrayAccess, \Iterator, \Countable } } - public function scanBlueprints($paths) + public function scanBlueprints($uri) { - $this->items = $this->findBlueprints($paths) + $this->items; + if (!is_string($uri)) { + throw new \InvalidArgumentException('First parameter must be URI'); + } + + $this->items = $this->findBlueprints($uri) + $this->items; } - public function scanTemplates($paths) + public function scanTemplates($uri) { + if (!is_string($uri)) { + throw new \InvalidArgumentException('First parameter must be URI'); + } + $options = [ 'compare' => 'Filename', 'pattern' => '|\.html\.twig$|', @@ -52,16 +60,13 @@ class Types implements \ArrayAccess, \Iterator, \Countable // register default by default $this->register('default'); - foreach ((array) $paths as $path) { - foreach (Folder::all($path, $options) as $type) { - $this->register($type); - } - $modular_path = rtrim($path, '/') . '/modular'; - if (file_exists($modular_path)) { - foreach (Folder::all($modular_path, $options) as $type) { - $this->register('modular/' . $type); - } - } + foreach (Folder::all($uri, $options) as $type) { + $this->register($type); + } + + $modular_uri = rtrim($uri, '/') . '/modular'; + foreach (Folder::all($modular_uri, $options) as $type) { + $this->register('modular/' . $type); } } @@ -91,7 +96,7 @@ class Types implements \ArrayAccess, \Iterator, \Countable return $list; } - private function findBlueprints($paths) + private function findBlueprints($uri) { $options = [ 'compare' => 'Filename', @@ -103,10 +108,7 @@ class Types implements \ArrayAccess, \Iterator, \Countable 'value' => 'PathName', ]; - $list = []; - foreach ((array) $paths as $path) { - $list += Folder::all($path, $options); - } + $list = Folder::all($uri, $options); return $list; } From d573ebbfe3185791df0f92fe2be663fdd871a93d Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 3 Mar 2016 14:15:29 +0200 Subject: [PATCH 52/59] Code review: Minor fixes and todos --- composer.lock | 8 ++--- system/src/Grav/Common/Assets.php | 7 +++-- system/src/Grav/Common/Backup/ZipBackup.php | 5 ++-- system/src/Grav/Common/Cache.php | 12 ++++---- system/src/Grav/Common/Config/Setup.php | 4 +++ system/src/Grav/Common/Data/Blueprints.php | 16 +++++----- system/src/Grav/Common/GPM/GPM.php | 4 ++- system/src/Grav/Common/Grav.php | 1 + system/src/Grav/Common/GravTrait.php | 1 + system/src/Grav/Common/Page/Media.php | 2 +- .../Grav/Common/Page/Medium/MediumFactory.php | 9 ++---- system/src/Grav/Common/Page/Page.php | 20 ++++++------- system/src/Grav/Common/Page/Pages.php | 11 ++++++- system/src/Grav/Common/Plugin.php | 11 +++++-- system/src/Grav/Common/Plugins.php | 6 ++-- .../Common/Service/LoggerServiceProvider.php | 1 + .../Common/Service/StreamsServiceProvider.php | 2 +- system/src/Grav/Common/Session.php | 6 +++- system/src/Grav/Common/Theme.php | 5 ++-- system/src/Grav/Common/Themes.php | 29 +++++++++---------- system/src/Grav/Common/Uri.php | 7 +++-- system/src/Grav/Common/User/Group.php | 23 +++++++++------ 22 files changed, 112 insertions(+), 78 deletions(-) diff --git a/composer.lock b/composer.lock index 2ae0bc50f..280ebd4f7 100644 --- a/composer.lock +++ b/composer.lock @@ -638,12 +638,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "f9005449d8430a96c28eda3d786ddd2aae7040d3" + "reference": "958e5ff3e184195327a4a59f1860f62b244e2268" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/f9005449d8430a96c28eda3d786ddd2aae7040d3", - "reference": "f9005449d8430a96c28eda3d786ddd2aae7040d3", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/958e5ff3e184195327a4a59f1860f62b244e2268", + "reference": "958e5ff3e184195327a4a59f1860f62b244e2268", "shasum": "" }, "require": { @@ -678,7 +678,7 @@ "php", "rockettheme" ], - "time": "2016-03-02 18:28:47" + "time": "2016-03-03 09:32:40" }, { "name": "symfony/console", diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index 102a49e6d..3a9a19d17 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -177,13 +177,14 @@ class Assets */ public function init() { + $grav = Grav::instance(); /** @var Config $config */ - $config = Grav::instance()['config']; - $base_url = Grav::instance()['base_url']; + $config = $grav['config']; + $base_url = $grav['base_url']; $asset_config = (array)$config->get('system.assets'); /** @var UniformResourceLocator $locator */ - $locator = Grav::instance()['locator']; + $locator = $grav['locator']; $this->assets_dir = $locator->findResource('asset://') . DS; $this->assets_url = $locator->findResource('asset://', false); diff --git a/system/src/Grav/Common/Backup/ZipBackup.php b/system/src/Grav/Common/Backup/ZipBackup.php index 94cfc4167..e69b4431f 100644 --- a/system/src/Grav/Common/Backup/ZipBackup.php +++ b/system/src/Grav/Common/Backup/ZipBackup.php @@ -40,10 +40,9 @@ class ZipBackup if (!$destination) { $destination = Grav::instance()['locator']->findResource('backup://', true); - if (!$destination) + if (!$destination) { throw new \RuntimeException('The backup folder is missing.'); - - Folder::mkdir($destination); + } } $name = Grav::instance()['config']->get('site.title', basename(GRAV_ROOT)); diff --git a/system/src/Grav/Common/Cache.php b/system/src/Grav/Common/Cache.php index 65dcfcf0e..81567d5cf 100644 --- a/system/src/Grav/Common/Cache.php +++ b/system/src/Grav/Common/Cache.php @@ -230,27 +230,29 @@ class Cache extends Getters /** * Deletes an item in the cache based on the id * - * @param $id the id of the cached data entry - * @return bool true if the item was deleted successfully + * @param string $id the id of the cached data entry + * @return bool true if the item was deleted successfully */ public function delete($id) { if ($this->enabled) { return $this->driver->delete($id); } + return false; } /** * Returns a boolean state of whether or not the item exists in the cache based on id key * - * @param $id the id of the cached data entry - * @return bool true if the cached items exists + * @param string $id the id of the cached data entry + * @return bool true if the cached items exists */ public function contains($id) { if ($this->enabled) { return $this->driver->contains(($id)); } + return false; } /** @@ -311,7 +313,7 @@ class Cache extends Getters $anything = true; } } elseif (is_dir($file)) { - if (@Folder::delete($file)) { + if (Folder::delete($file)) { $anything = true; } } diff --git a/system/src/Grav/Common/Config/Setup.php b/system/src/Grav/Common/Config/Setup.php index bd4cf469e..61f4dc9f2 100644 --- a/system/src/Grav/Common/Config/Setup.php +++ b/system/src/Grav/Common/Config/Setup.php @@ -4,6 +4,7 @@ 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; @@ -113,6 +114,9 @@ class Setup extends Data ], ]; + /** + * @param Container|array $container + */ public function __construct($container) { $environment = $container['uri']->environment() ?: 'localhost'; diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index af9e76044..f2f6a0224 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -50,15 +50,15 @@ class Blueprints if ($this->types === null) { $this->types = array(); - // Check if search is a stream. - if (strpos($this->search, '://')) { - // Stream: use UniformResourceIterator. - $grav = Grav::instance(); - /** @var UniformResourceLocator $locator */ - $locator = $grav['locator']; - $iterator = $locator->getIterator($this->search, null); + $grav = Grav::instance(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + // Get stream / directory iterator. + if ($locator->isStream($this->search)) { + $iterator = $locator->getIterator($this->search); } else { - // Not a stream: use DirectoryIterator. $iterator = new \DirectoryIterator($this->search); } diff --git a/system/src/Grav/Common/GPM/GPM.php b/system/src/Grav/Common/GPM/GPM.php index 246d40a28..bd1ff83a6 100644 --- a/system/src/Grav/Common/GPM/GPM.php +++ b/system/src/Grav/Common/GPM/GPM.php @@ -199,7 +199,7 @@ class GPM extends Iterator * * @param $package_name * - * @return string + * @return string|null */ public function getLatestVersionOfPackage($package_name) { @@ -214,6 +214,8 @@ class GPM extends Iterator if (isset($repository[$package_name])) { return $repository[$package_name]->version; } + + return null; } /** diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 7d5edeeab..829e7ab81 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -223,6 +223,7 @@ class Grav extends Container // Initialize configuration. $debugger->startTimer('_config', 'Configuration'); + /** @var Plugins $plugins */ $plugins = $this['plugins']->setup(); $this['config']->init(); $debugger->stopTimer('_config'); diff --git a/system/src/Grav/Common/GravTrait.php b/system/src/Grav/Common/GravTrait.php index 89883c595..8810291f6 100644 --- a/system/src/Grav/Common/GravTrait.php +++ b/system/src/Grav/Common/GravTrait.php @@ -5,6 +5,7 @@ namespace Grav\Common; * Class GravTrait * * @package Grav\Common + * @deprecated */ trait GravTrait { diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index 9013d8b62..3a7373444 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -87,7 +87,7 @@ class Media extends Getters $medium = MediumFactory::scaledFromMedium($altMedium, $ratio, 1)['file']; } - if (!$medium) { + if (empty($medium)) { continue; } diff --git a/system/src/Grav/Common/Page/Medium/MediumFactory.php b/system/src/Grav/Common/Page/Medium/MediumFactory.php index 0f4063cc0..60658135f 100644 --- a/system/src/Grav/Common/Page/Medium/MediumFactory.php +++ b/system/src/Grav/Common/Page/Medium/MediumFactory.php @@ -59,12 +59,9 @@ class MediumFactory $locator = Grav::instance()['locator']; - $lookup = $locator->findResources('image://'); - foreach ($lookup as $lookupPath) { - if (is_file($lookupPath . '/' . $params['thumb'])) { - $params['thumbnails']['default'] = $lookupPath . '/' . $params['thumb']; - break; - } + $file = $locator->findResource("image://{$params['thumb']}"); + if ($file) { + $params['thumbnails']['default'] = $file; } return static::fromArray($params); diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 149e1b302..7ec8c293e 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -100,8 +100,6 @@ class Page /** * Page Object Constructor - * - * @return $this */ public function __construct() { @@ -111,8 +109,6 @@ class Page $this->taxonomy = []; $this->process = $config->get('system.pages.process'); $this->published = true; - - return $this; } /** @@ -883,12 +879,14 @@ class Page */ public function blueprints() { + $grav = Grav::instance(); + /** @var Pages $pages */ - $pages = Grav::instance()['pages']; + $pages = $grav['pages']; $blueprint = $pages->blueprints($this->blueprintName()); $fields = $blueprint->fields(); - $edit_mode = isset(Grav::instance()['admin']) ? Grav::instance()['config']->get('plugins.admin.edit_mode') : null; + $edit_mode = isset($grav['admin']) ? $grav['config']->get('plugins.admin.edit_mode') : null; // override if you only want 'normal' mode if (empty($fields) && ($edit_mode == 'auto' || $edit_mode == 'normal')) { @@ -1419,17 +1417,19 @@ class Page */ public function url($include_host = false, $canonical = false, $include_lang = true) { + $grav = Grav::instance(); + /** @var Pages $pages */ - $pages = Grav::instance()['pages']; + $pages = $grav['pages']; /** @var Config $config */ - $config = Grav::instance()['config']; + $config = $grav['config']; /** @var Language $language */ - $language = Grav::instance()['language']; + $language = $grav['language']; /** @var Uri $uri */ - $uri = Grav::instance()['uri']; + $uri = $grav['uri']; // get pre-route if ($include_lang && $language->enabled()) { diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index f9f1021a6..569524151 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -682,6 +682,7 @@ class Pages /** @var UniformResourceLocator $locator */ $locator = $this->grav['locator']; + // TODO: Use streams to allow page overrides. Right now only one folder gets looked at. $pages_dir = $locator->findResource('page://'); if ($config->get('system.cache.enabled')) { @@ -718,6 +719,7 @@ class Pages $taxonomy->taxonomy($taxonomy_map); } } else { + // TODO: This function needs to be streams safe if we want to allow page overrides. $this->recurse($pages_dir); $this->buildRoutes(); } @@ -758,6 +760,7 @@ class Pages */ protected function recurse($directory, Page &$parent = null) { + // TODO: Cannot do this with streams. $directory = rtrim($directory, DS); $page = new Page; @@ -776,6 +779,7 @@ class Pages } } + // TODO: Do we want to use real folders or streams as page path? $page->path($directory); if ($parent) { $page->parent($parent); @@ -795,6 +799,7 @@ class Pages } $content_exists = false; + // TODO: Another solution needed for streams support. $pages_found = glob($directory . '/*' . CONTENT_EXT); $page_extension = ''; @@ -825,8 +830,11 @@ class Pages // set current modified of page $last_modified = $page->modified(); + // TODO: Add iterator from streams. + $iterator = new \FilesystemIterator($directory); + /** @var \DirectoryIterator $file */ - foreach (new \FilesystemIterator($directory) as $file) { + foreach ($iterator as $file) { $name = $file->getFilename(); // Ignore all hidden files if set. @@ -843,6 +851,7 @@ class Pages } } elseif ($file->isDir() && !in_array($file->getFilename(), $this->ignore_folders)) { if (!$page->path()) { + // TODO: Do we want to use real folders or streams as page path? $page->path($file->getPath()); } diff --git a/system/src/Grav/Common/Plugin.php b/system/src/Grav/Common/Plugin.php index 3a30acf39..d07c3f1b1 100644 --- a/system/src/Grav/Common/Plugin.php +++ b/system/src/Grav/Common/Plugin.php @@ -64,10 +64,13 @@ class Plugin implements EventSubscriberInterface * @param Grav $grav * @param Config $config */ - public function __construct($name, Grav $grav) + public function __construct($name, Grav $grav, Config $config = null) { $this->name = $name; $this->grav = $grav; + if ($config) { + $this->setConfig($config); + } } /** @@ -168,6 +171,7 @@ class Plugin implements EventSubscriberInterface */ protected function mergeConfig(Page $page, $deep = false, $params = []) { + // FIXME: This should be done with Config class; it has configuration merging with blueprints. $class_name = $this->name; $class_name_merged = $class_name . '.merged'; $defaults = $this->config->get('plugins.' . $class_name, []); @@ -219,10 +223,11 @@ class Plugin implements EventSubscriberInterface return false; } - $locator = Grav::instance()['locator']; + $grav = Grav::instance(); + $locator = $grav['locator']; $filename = 'config://plugins/' . $plugin_name . '.yaml'; $file = YamlFile::instance($locator->findResource($filename, true, true)); - $content = Grav::instance()['config']->get('plugins.' . $plugin_name); + $content = $grav['config']->get('plugins.' . $plugin_name); $file->save($content); $file->free(); diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index 3203e8c95..de7b72c97 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -89,11 +89,13 @@ class Plugins extends Iterator */ public function init() { + $grav = Grav::instance(); + /** @var Config $config */ - $config = Grav::instance()['config']; + $config = $grav['config']; /** @var EventDispatcher $events */ - $events = Grav::instance()['events']; + $events = $grav['events']; foreach ($this->items as $instance) { // Register only enabled plugins. diff --git a/system/src/Grav/Common/Service/LoggerServiceProvider.php b/system/src/Grav/Common/Service/LoggerServiceProvider.php index edaf92178..a85e3c6f0 100644 --- a/system/src/Grav/Common/Service/LoggerServiceProvider.php +++ b/system/src/Grav/Common/Service/LoggerServiceProvider.php @@ -11,6 +11,7 @@ class LoggerServiceProvider implements ServiceProviderInterface public function register(Container $container) { $log = new Logger('grav'); + // TODO: Use streams. $log_file = LOG_DIR.'grav.log'; $log->pushHandler(new StreamHandler($log_file, Logger::DEBUG)); diff --git a/system/src/Grav/Common/Service/StreamsServiceProvider.php b/system/src/Grav/Common/Service/StreamsServiceProvider.php index ec7f9cd85..98f396814 100644 --- a/system/src/Grav/Common/Service/StreamsServiceProvider.php +++ b/system/src/Grav/Common/Service/StreamsServiceProvider.php @@ -34,7 +34,7 @@ class StreamsServiceProvider implements ServiceProviderInterface Stream::setLocator($locator); ReadOnlyStream::setLocator($locator); - return new StreamBuilder($setup->getStreams($c)); + return new StreamBuilder($setup->getStreams()); }; } } diff --git a/system/src/Grav/Common/Session.php b/system/src/Grav/Common/Session.php index c73ddcfca..4f9faa17c 100644 --- a/system/src/Grav/Common/Session.php +++ b/system/src/Grav/Common/Session.php @@ -1,10 +1,12 @@ grav = $grav; } @@ -45,6 +48,7 @@ class Session extends \RocketTheme\Toolbox\Session\Session if ($config->get('system.session.enabled') || $is_admin) { // Define session service. + // FIXME: NOT LIKE THIS! parent::__construct($session_timeout, $session_path); $domain = $uri->host(); diff --git a/system/src/Grav/Common/Theme.php b/system/src/Grav/Common/Theme.php index f76e5f0b7..261c2ec4e 100644 --- a/system/src/Grav/Common/Theme.php +++ b/system/src/Grav/Common/Theme.php @@ -39,10 +39,11 @@ class Theme extends Plugin return false; } - $locator = Grav::instance()['locator']; + $grav = Grav::instance(); + $locator = $grav['locator']; $filename = 'config://themes/' . $theme_name . '.yaml'; $file = YamlFile::instance($locator->findResource($filename, true, true)); - $content = Grav::instance()['config']->get('themes.' . $theme_name); + $content = $grav['config']->get('themes.' . $theme_name); $file->save($content); $file->free(); diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php index 9f360cc35..505dd4465 100644 --- a/system/src/Grav/Common/Themes.php +++ b/system/src/Grav/Common/Themes.php @@ -79,24 +79,23 @@ class Themes extends Iterator public function all() { $list = []; - $locator = Grav::instance()['locator']; - $themes = (array)$locator->findResources('themes://', false); - foreach ($themes as $path) { - $iterator = new \DirectoryIterator($path); + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; - /** @var \DirectoryIterator $directory */ - foreach ($iterator as $directory) { - if (!$directory->isDir() || $directory->isDot()) { - continue; - } + $iterator = $locator->getIterator('themes://'); - $theme = $directory->getBasename(); - $result = self::get($theme); + /** @var \DirectoryIterator $directory */ + foreach ($iterator as $directory) { + if (!$directory->isDir() || $directory->isDot()) { + continue; + } - if ($result) { - $list[$theme] = $result; - } + $theme = $directory->getBasename(); + $result = self::get($theme); + + if ($result) { + $list[$theme] = $result; } } ksort($list); @@ -141,7 +140,7 @@ class Themes extends Iterator $obj = new Data($file->content(), $blueprint); // Override with user configuration. - $obj->merge($this->grav['config']->get('themes.' . $name) ?: []); + $obj->merge($this->config->get('themes.' . $name) ?: []); // Save configuration always to user/config. $file = CompiledYamlFile::instance("config://themes/{$name}" . YAML_EXT); diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index fca059a3f..d8fcf46d1 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -314,7 +314,7 @@ class Uri $valid_page_types = implode('|', $config->get('system.pages.types')); // Strip the file extension for valid page types - if (preg_match("/\.(" . $valid_page_types . ")$/", $parts['basename'])) { + if (preg_match('/\.(' . $valid_page_types . ')$/', $parts['basename'])) { $uri = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, $parts['dirname']), DS) . '/' . $parts['filename']; } @@ -722,7 +722,7 @@ class Uri * @param Page $page the current page to use as reference * @param string $url the URL as it was written in the markdown * @param string $type the type of URL, image | link - * @param null $absolute if null, will use system default, if true will use absolute links internally + * @param bool $absolute if null, will use system default, if true will use absolute links internally * * @return string the more friendly formatted url */ @@ -749,6 +749,7 @@ class Uri $external = false; $base = $grav['base_url_relative']; $base_url = rtrim($base . $grav['pages']->base(), '/') . $language_append; + // TODO: Add streams support for pages. $pages_dir = $grav['locator']->findResource('page://'); // if absolute and starts with a base_url move on @@ -939,7 +940,7 @@ class Uri if ($type == 'link' && $language->enabled()) { $language_append = $language->getLanguageURLPrefix(); } - + // TODO: Add streams support for pages. $pages_dir = $grav['locator']->findResource('page://'); if (is_null($relative)) { $base = $grav['base_url']; diff --git a/system/src/Grav/Common/User/Group.php b/system/src/Grav/Common/User/Group.php index d1b4dde18..476d4e060 100644 --- a/system/src/Grav/Common/User/Group.php +++ b/system/src/Grav/Common/User/Group.php @@ -69,18 +69,21 @@ class Group extends Data */ public function save() { + $grav = Grav::instance(); + $config = $grav['config']; + $blueprints = new Blueprints; $blueprint = $blueprints->get('user/group'); $fields = $blueprint->fields(); - Grav::instance()['config']->set("groups.$this->groupname", []); + $config->set("groups.$this->groupname", []); foreach ($fields as $field) { if ($field['type'] == 'text') { $value = $field['name']; if (isset($this->items[$value])) { - Grav::instance()['config']->set("groups.$this->groupname.$value", $this->items[$value]); + $config->set("groups.$this->groupname.$value", $this->items[$value]); } } if ($field['type'] == 'array') { @@ -89,7 +92,7 @@ class Group extends Data if ($arrayValues) { foreach ($arrayValues as $arrayIndex => $arrayValue) { - Grav::instance()['config']->set("groups.$this->groupname.$value.$arrayIndex", $arrayValue); + $config->set("groups.$this->groupname.$value.$arrayIndex", $arrayValue); } } } @@ -97,8 +100,8 @@ class Group extends Data $type = 'groups'; $blueprints = $this->blueprints("config/{$type}"); - $obj = new Data(Grav::instance()['config']->get($type), $blueprints); - $file = CompiledYamlFile::instance(Grav::instance()['locator']->findResource("config://{$type}.yaml")); + $obj = new Data($config->get($type), $blueprints); + $file = CompiledYamlFile::instance($grav['locator']->findResource("config://{$type}.yaml")); $obj->file($file); $obj->save(); } @@ -112,16 +115,18 @@ class Group extends Data */ public static function remove($groupname) { + $grav = Grav::instance(); + $config = $grav['config']; $blueprints = new Blueprints; $blueprint = $blueprints->get('user/group'); - $groups = Grav::instance()['config']->get("groups"); + $groups = $config->get("groups"); unset($groups[$groupname]); - Grav::instance()['config']->set("groups", $groups); + $config->set("groups", $groups); $type = 'groups'; - $obj = new Data(Grav::instance()['config']->get($type), $blueprint); - $file = CompiledYamlFile::instance(Grav::instance()['locator']->findResource("config://{$type}.yaml")); + $obj = new Data($config->get($type), $blueprint); + $file = CompiledYamlFile::instance($grav['locator']->findResource("config://{$type}.yaml")); $obj->file($file); $obj->save(); From 7e4f4319d5704f7c21222f6bdaa65fbf7d08b3d0 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 3 Mar 2016 15:16:33 +0200 Subject: [PATCH 53/59] Minor refactoring --- system/src/Grav/Common/Theme.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/system/src/Grav/Common/Theme.php b/system/src/Grav/Common/Theme.php index 261c2ec4e..82cab5111 100644 --- a/system/src/Grav/Common/Theme.php +++ b/system/src/Grav/Common/Theme.php @@ -10,8 +10,6 @@ use RocketTheme\Toolbox\File\YamlFile; */ class Theme extends Plugin { - public $name; - /** * Constructor. * @@ -21,8 +19,6 @@ class Theme extends Plugin */ public function __construct(Grav $grav, Config $config, $name) { - $this->name = $name; - parent::__construct($name, $grav, $config); } From e0c579d513ea252e492de2fe5416c6ea37c86024 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 3 Mar 2016 15:26:01 +0200 Subject: [PATCH 54/59] Fix plugin/theme names in admin --- system/src/Grav/Common/Plugins.php | 1 - system/src/Grav/Common/Themes.php | 1 - 2 files changed, 2 deletions(-) diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index de7b72c97..ff52e3eed 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -153,7 +153,6 @@ class Plugins extends Iterator { $blueprints = new Blueprints('plugins://'); $blueprint = $blueprints->get("{$name}/blueprints"); - $blueprint->name = $name; // Load default configuration. $file = CompiledYamlFile::instance("plugins://{$name}/{$name}" . YAML_EXT); diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php index 505dd4465..e3497f542 100644 --- a/system/src/Grav/Common/Themes.php +++ b/system/src/Grav/Common/Themes.php @@ -119,7 +119,6 @@ class Themes extends Iterator $blueprints = new Blueprints('themes://'); $blueprint = $blueprints->get("{$name}/blueprints"); - $blueprint->name = $name; // Load default configuration. $file = CompiledYamlFile::instance("themes://{$name}/{$name}" . YAML_EXT); From ed0d562a3e0145f959e02e0e91fd256ae4b3cc57 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 3 Mar 2016 20:52:10 +0200 Subject: [PATCH 55/59] Remove todos from code --- system/src/Grav/Common/Page/Pages.php | 8 +------- system/src/Grav/Common/Plugin.php | 1 - system/src/Grav/Common/Service/LoggerServiceProvider.php | 1 - system/src/Grav/Common/Session.php | 2 -- system/src/Grav/Common/Uri.php | 2 -- 5 files changed, 1 insertion(+), 13 deletions(-) diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 569524151..fb98932db 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -682,7 +682,7 @@ class Pages /** @var UniformResourceLocator $locator */ $locator = $this->grav['locator']; - // TODO: Use streams to allow page overrides. Right now only one folder gets looked at. + $pages_dir = $locator->findResource('page://'); if ($config->get('system.cache.enabled')) { @@ -719,7 +719,6 @@ class Pages $taxonomy->taxonomy($taxonomy_map); } } else { - // TODO: This function needs to be streams safe if we want to allow page overrides. $this->recurse($pages_dir); $this->buildRoutes(); } @@ -760,7 +759,6 @@ class Pages */ protected function recurse($directory, Page &$parent = null) { - // TODO: Cannot do this with streams. $directory = rtrim($directory, DS); $page = new Page; @@ -779,7 +777,6 @@ class Pages } } - // TODO: Do we want to use real folders or streams as page path? $page->path($directory); if ($parent) { $page->parent($parent); @@ -799,7 +796,6 @@ class Pages } $content_exists = false; - // TODO: Another solution needed for streams support. $pages_found = glob($directory . '/*' . CONTENT_EXT); $page_extension = ''; @@ -830,7 +826,6 @@ class Pages // set current modified of page $last_modified = $page->modified(); - // TODO: Add iterator from streams. $iterator = new \FilesystemIterator($directory); /** @var \DirectoryIterator $file */ @@ -851,7 +846,6 @@ class Pages } } elseif ($file->isDir() && !in_array($file->getFilename(), $this->ignore_folders)) { if (!$page->path()) { - // TODO: Do we want to use real folders or streams as page path? $page->path($file->getPath()); } diff --git a/system/src/Grav/Common/Plugin.php b/system/src/Grav/Common/Plugin.php index d07c3f1b1..74e9571f7 100644 --- a/system/src/Grav/Common/Plugin.php +++ b/system/src/Grav/Common/Plugin.php @@ -171,7 +171,6 @@ class Plugin implements EventSubscriberInterface */ protected function mergeConfig(Page $page, $deep = false, $params = []) { - // FIXME: This should be done with Config class; it has configuration merging with blueprints. $class_name = $this->name; $class_name_merged = $class_name . '.merged'; $defaults = $this->config->get('plugins.' . $class_name, []); diff --git a/system/src/Grav/Common/Service/LoggerServiceProvider.php b/system/src/Grav/Common/Service/LoggerServiceProvider.php index a85e3c6f0..edaf92178 100644 --- a/system/src/Grav/Common/Service/LoggerServiceProvider.php +++ b/system/src/Grav/Common/Service/LoggerServiceProvider.php @@ -11,7 +11,6 @@ class LoggerServiceProvider implements ServiceProviderInterface public function register(Container $container) { $log = new Logger('grav'); - // TODO: Use streams. $log_file = LOG_DIR.'grav.log'; $log->pushHandler(new StreamHandler($log_file, Logger::DEBUG)); diff --git a/system/src/Grav/Common/Session.php b/system/src/Grav/Common/Session.php index 4f9faa17c..e99151f3f 100644 --- a/system/src/Grav/Common/Session.php +++ b/system/src/Grav/Common/Session.php @@ -18,7 +18,6 @@ class Session extends BaseSession */ public function __construct(Grav $grav) { - // FIXME: We really should have wrapper and not to extend the class!! $this->grav = $grav; } @@ -48,7 +47,6 @@ class Session extends BaseSession if ($config->get('system.session.enabled') || $is_admin) { // Define session service. - // FIXME: NOT LIKE THIS! parent::__construct($session_timeout, $session_path); $domain = $uri->host(); diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index d8fcf46d1..5bdbfea7f 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -749,7 +749,6 @@ class Uri $external = false; $base = $grav['base_url_relative']; $base_url = rtrim($base . $grav['pages']->base(), '/') . $language_append; - // TODO: Add streams support for pages. $pages_dir = $grav['locator']->findResource('page://'); // if absolute and starts with a base_url move on @@ -940,7 +939,6 @@ class Uri if ($type == 'link' && $language->enabled()) { $language_append = $language->getLanguageURLPrefix(); } - // TODO: Add streams support for pages. $pages_dir = $grav['locator']->findResource('page://'); if (is_null($relative)) { $base = $grav['base_url']; From 7fe50f454efcbae3f4f3d30cbc4f24832bca4fe2 Mon Sep 17 00:00:00 2001 From: Djamil Legato Date: Thu, 3 Mar 2016 10:55:50 -0800 Subject: [PATCH 56/59] Updated yamls in view of the new admin --- system/blueprints/pages/default.yaml | 1 - system/blueprints/pages/modular_raw.yaml | 14 +++++++++++--- system/blueprints/pages/raw.yaml | 12 ++++++++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/system/blueprints/pages/default.yaml b/system/blueprints/pages/default.yaml index 1b9b166ee..472fb3b62 100644 --- a/system/blueprints/pages/default.yaml +++ b/system/blueprints/pages/default.yaml @@ -29,7 +29,6 @@ form: content: type: markdown - showPreview: true validate: type: textarea diff --git a/system/blueprints/pages/modular_raw.yaml b/system/blueprints/pages/modular_raw.yaml index 393cde5fd..cd18d7f26 100644 --- a/system/blueprints/pages/modular_raw.yaml +++ b/system/blueprints/pages/modular_raw.yaml @@ -19,13 +19,21 @@ form: fields: frontmatter: - type: frontmatter + classes: frontmatter + type: editor label: PLUGIN_ADMIN.FRONTMATTER - + autofocus: true + codemirror: + mode: 'yaml' + indentUnit: 4 + autofocus: true + indentWithTabs: false + lineNumbers: true + gutters: ['CodeMirror-lint-markers'] + lint: true content: type: markdown - showPreview: true uploads: type: pagemedia diff --git a/system/blueprints/pages/raw.yaml b/system/blueprints/pages/raw.yaml index bed82d593..4c9a8d192 100644 --- a/system/blueprints/pages/raw.yaml +++ b/system/blueprints/pages/raw.yaml @@ -19,13 +19,21 @@ form: fields: frontmatter: - type: frontmatter + classes: frontmatter + type: editor label: PLUGIN_ADMIN.FRONTMATTER autofocus: true + codemirror: + mode: 'yaml' + indentUnit: 4 + autofocus: true + indentWithTabs: false + lineNumbers: true + gutters: ['CodeMirror-lint-markers'] + lint: true content: type: markdown - showPreview: true uploads: type: pagemedia From b040596aabdaf1e1d9ebe4a1c728e5f25f2629bd Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Thu, 3 Mar 2016 21:07:44 +0200 Subject: [PATCH 57/59] Composer update (`input@: false` property for blueprints) --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 280ebd4f7..ae991c0e2 100644 --- a/composer.lock +++ b/composer.lock @@ -638,12 +638,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "958e5ff3e184195327a4a59f1860f62b244e2268" + "reference": "88c9e928a5e4fee08ceb606265f02b1e89d37e1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/958e5ff3e184195327a4a59f1860f62b244e2268", - "reference": "958e5ff3e184195327a4a59f1860f62b244e2268", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/88c9e928a5e4fee08ceb606265f02b1e89d37e1e", + "reference": "88c9e928a5e4fee08ceb606265f02b1e89d37e1e", "shasum": "" }, "require": { @@ -678,7 +678,7 @@ "php", "rockettheme" ], - "time": "2016-03-03 09:32:40" + "time": "2016-03-03 19:03:07" }, { "name": "symfony/console", From c304c40dbf165b32e5cbc9096def0da530afbf9f Mon Sep 17 00:00:00 2001 From: Djamil Legato Date: Fri, 4 Mar 2016 17:03:04 -0800 Subject: [PATCH 58/59] Enable active line for frontmatter --- system/blueprints/pages/modular_raw.yaml | 1 + system/blueprints/pages/raw.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/system/blueprints/pages/modular_raw.yaml b/system/blueprints/pages/modular_raw.yaml index cd18d7f26..020ab4a1d 100644 --- a/system/blueprints/pages/modular_raw.yaml +++ b/system/blueprints/pages/modular_raw.yaml @@ -29,6 +29,7 @@ form: autofocus: true indentWithTabs: false lineNumbers: true + styleActiveLine: true gutters: ['CodeMirror-lint-markers'] lint: true diff --git a/system/blueprints/pages/raw.yaml b/system/blueprints/pages/raw.yaml index 4c9a8d192..a195ab7ed 100644 --- a/system/blueprints/pages/raw.yaml +++ b/system/blueprints/pages/raw.yaml @@ -29,6 +29,7 @@ form: autofocus: true indentWithTabs: false lineNumbers: true + styleActiveLine: true gutters: ['CodeMirror-lint-markers'] lint: true From 2db4b519c854f6e6050cbc26450117c9b11715ca Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 4 Mar 2016 15:44:32 -0700 Subject: [PATCH 59/59] manually merged the newer user profile blueprint --- system/blueprints/user/account.yaml | 143 +++++++++++++++------------- 1 file changed, 75 insertions(+), 68 deletions(-) diff --git a/system/blueprints/user/account.yaml b/system/blueprints/user/account.yaml index 669f5c7bb..33c032607 100644 --- a/system/blueprints/user/account.yaml +++ b/system/blueprints/user/account.yaml @@ -1,85 +1,92 @@ title: Site form: validation: loose + fields: - content: - type: section - title: PLUGIN_ADMIN.ACCOUNT + info: + type: userinfo + size: large - fields: - username: - type: text - size: large - label: PLUGIN_ADMIN.USERNAME - disabled: true - readonly: true + content: + type: section + title: PLUGIN_ADMIN.ACCOUNT + underline: true - email: - type: email - size: large - label: PLUGIN_ADMIN.EMAIL - validate: - type: email - message: PLUGIN_ADMIN.EMAIL_VALIDATION_MESSAGE - required: true - password: - type: password - size: large - label: PLUGIN_ADMIN.PASSWORD - validate: - required: false - message: PLUGIN_ADMIN.PASSWORD_VALIDATION_MESSAGE - pattern: '(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}' + username: + type: text + size: large + label: PLUGIN_ADMIN.USERNAME + disabled: true + readonly: true - fullname: - type: text - size: large - label: PLUGIN_ADMIN.FULL_NAME - validate: - required: true + email: + type: email + size: large + label: PLUGIN_ADMIN.EMAIL + validate: + type: email + message: PLUGIN_ADMIN.EMAIL_VALIDATION_MESSAGE + required: true - title: - type: text - size: large - label: PLUGIN_ADMIN.TITLE + password: + type: password + size: large + label: PLUGIN_ADMIN.PASSWORD + validate: + required: false + message: PLUGIN_ADMIN.PASSWORD_VALIDATION_MESSAGE + pattern: '(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}' - language: - type: select - label: PLUGIN_ADMIN.LANGUAGE - size: medium - classes: fancy - '@data-options': '\Grav\Plugin\admin::adminLanguages' - default: 'en' - help: PLUGIN_ADMIN.LANGUAGE_HELP + fullname: + type: text + size: large + label: PLUGIN_ADMIN.FULL_NAME + validate: + required: true - security: - title: PLUGIN_ADMIN.ACCESS_LEVELS - type: section - security: admin.super + title: + type: text + size: large + label: PLUGIN_ADMIN.TITLE - fields: - groups: - type: selectize - size: large - label: PLUGIN_ADMIN.GROUPS - '@data-options': '\Grav\User\Groups::groups' - classes: fancy - help: PLUGIN_ADMIN.GROUPS_HELP - validate: - type: commalist + language: + type: select + label: PLUGIN_ADMIN.LANGUAGE + size: medium + classes: fancy + '@data-options': '\Grav\Plugin\admin::adminLanguages' + default: 'en' + help: PLUGIN_ADMIN.LANGUAGE_HELP - access.admin: + security: + title: PLUGIN_ADMIN.ACCESS_LEVELS + type: section + security: admin.super + underline: true + + fields: + groups: + type: selectize + size: large + label: PLUGIN_ADMIN.GROUPS + '@data-options': '\Grav\User\Groups::groups' + classes: fancy + help: PLUGIN_ADMIN.GROUPS_HELP + validate: + type: commalist + + access.admin: + type: array + label: PLUGIN_ADMIN.ADMIN_ACCESS + multiple: false + validate: type: array - label: PLUGIN_ADMIN.ADMIN_ACCESS - multiple: false - validate: - type: array - access.site: + access.site: + type: array + label: PLUGIN_ADMIN.SITE_ACCESS + multiple: false + validate: type: array - label: PLUGIN_ADMIN.SITE_ACCESS - multiple: false - validate: - type: array