diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4ed06a187..324eb7318 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,12 @@
-# v1.6.0-beta.3
+# v1.6.0-beta.4
## mm/dd/2018
+1. [](#improved)
+ * Added apcu autoloader optimization
+
+# v1.6.0-beta.3
+## 10/15/2018
+
1. [](#improved)
* Call `onFatalException` event also on internal PHP errors
* Built-in PHP Webserver: log requests before handling them
diff --git a/bin/gpm b/bin/gpm
index d4932a20e..e8eff5a00 100755
--- a/bin/gpm
+++ b/bin/gpm
@@ -1,6 +1,7 @@
#!/usr/bin/env php
$autoload));
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
diff --git a/bin/plugin b/bin/plugin
index a8b089a89..a219655b6 100755
--- a/bin/plugin
+++ b/bin/plugin
@@ -1,6 +1,7 @@
#!/usr/bin/env php
getFormatter()->setStyle('white', new OutputFormatterStyle('white', nul
if (!$name) {
$output->writeln('');
- $output->writeln("Usage:");
+ $output->writeln('Usage:');
$output->writeln(" {$bin} [slug] [command] [arguments]");
$output->writeln('');
- $output->writeln("Example:");
+ $output->writeln('Example:');
$output->writeln(" {$bin} error log -l 1 --trace");
$list = Folder::all('plugins://', ['compare' => 'Pathname', 'pattern' => '/\/cli\/' . $pattern . '$/usm', 'levels' => 2]);
@@ -104,7 +105,7 @@ if (!$name) {
}
$available[] = $entry;
- $output->writeln(' ' . $index . ". " . str_pad($entry, 15) . " ${bin} ${entry} list");
+ $output->writeln(' ' . $index . '. ' . str_pad($entry, 15) . " ${bin} ${entry} list");
}
}
diff --git a/composer.json b/composer.json
index c5dc10538..c194d2ca4 100644
--- a/composer.json
+++ b/composer.json
@@ -53,6 +53,7 @@
"victorjonsson/markdowndocs": "dev-master"
},
"config": {
+ "apcu-autoloader": true,
"platform": {
"php": "7.1.3"
}
diff --git a/index.php b/index.php
index 4a9c64984..64154df89 100644
--- a/index.php
+++ b/index.php
@@ -9,6 +9,7 @@
namespace Grav;
+\define('GRAV_REQUEST_TIME', microtime(true));
\define('GRAV_PHP_MIN', '7.1.3');
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
diff --git a/system/defines.php b/system/defines.php
index 7c3039f5d..bf375371a 100644
--- a/system/defines.php
+++ b/system/defines.php
@@ -8,7 +8,7 @@
// Some standard defines
define('GRAV', true);
-define('GRAV_VERSION', '1.6.0-beta.2');
+define('GRAV_VERSION', '1.6.0-beta.4');
define('GRAV_TESTING', true);
define('DS', '/');
diff --git a/system/src/Grav/Common/Assets.old.php b/system/src/Grav/Common/Assets.old.php
deleted file mode 100644
index 247605ba6..000000000
--- a/system/src/Grav/Common/Assets.old.php
+++ /dev/null
@@ -1,1438 +0,0 @@
- or \n";
- }
-
-
- return $output;
- }
-
- /**
- * Build the JavaScript script tags.
- *
- * @param string $group name of the group
- * @param array $attributes
- *
- * @return string
- */
- public function js($group = 'head', $attributes = [])
- {
- if (!$this->js && !$this->inline_js) {
- return null;
- }
-
- // Sort array by priorities (larger priority first)
- uasort($this->js, array($this, 'sortAssetsByPriorityThenOrder'));
- uasort($this->inline_js, array($this, 'sortAssetsByPriorityThenOrder'));
-
- $inlineGroup = array_key_exists('loading', $attributes) && $attributes['loading'] === 'inline';
-
- $attributes = $this->attributes($attributes);
-
- $output = '';
- $inline_js = '';
-
- if ($this->js_pipeline) {
- $pipeline_result = $this->pipelineJs($group, !$inlineGroup);
- $pipeline_html = ($inlineGroup ? '' : '' . "\n");
-
- if ($this->js_pipeline_before_excludes && $pipeline_result) {
- if ($inlineGroup) {
- $inline_js .= $pipeline_result;
- }
- else {
- $output .= $pipeline_html;
- }
- }
- foreach ($this->js_no_pipeline as $file) {
- if ($group && $file['group'] == $group) {
- if ($file['loading'] === 'inline') {
- $inline_js .= $this->gatherLinks([$file], JS_ASSET) . "\n";
- }
- else {
- $output .= '' . "\n";
- }
- }
- }
- if (!$this->js_pipeline_before_excludes && $pipeline_result) {
- if ($inlineGroup) {
- $inline_js .= $pipeline_result;
- }
- else {
- $output .= $pipeline_html;
- }
- }
- } else {
- foreach ($this->js as $file) {
- if ($group && $file['group'] == $group) {
- if ($inlineGroup || $file['loading'] === 'inline') {
- $inline_js .= $this->gatherLinks([$file], JS_ASSET) . "\n";
- }
- else {
- $output .= '' . "\n";
- }
- }
- }
- }
-
- // Render Inline JS
- foreach ($this->inline_js as $inline) {
- if ($group && $inline['group'] == $group) {
- $inline_js .= $inline['asset'] . "\n";
- }
- }
-
- if ($inline_js) {
- $attribute_string = isset($inline) && $inline['type'] ? " type=\"" . $inline['type'] . "\"" : '';
- $output .= "\n\n";
- }
-
- return $output;
- }
-
- /**
- * Minify and concatenate CSS
- *
- * @param string $group
- * @param bool $returnURL true if pipeline should return the URL, otherwise the content
- *
- * @return bool|string URL or generated content if available, else false
- */
- protected function pipelineCss($group = 'head', $returnURL = true)
- {
- // temporary list of assets to pipeline
- $temp_css = [];
-
- // clear no-pipeline assets lists
- $this->css_no_pipeline = [];
-
- // Compute uid based on assets and timestamp
- $uid = md5(json_encode($this->css) . $this->css_minify . $this->css_rewrite . $group);
- $file = $uid . '.css';
- $inline_file = $uid . '-inline.css';
-
- $relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
-
- // If inline files exist set them on object
- if (file_exists($this->assets_dir . $inline_file)) {
- $this->css_no_pipeline = json_decode(file_get_contents($this->assets_dir . $inline_file), true);
- }
-
- // If pipeline exist return its URL or content
- if (file_exists($this->assets_dir . $file)) {
- if ($returnURL) {
- return $relative_path . $this->getTimestamp();
- }
- else {
- return file_get_contents($this->assets_dir . $file) . "\n";
- }
- }
-
- // Remove any non-pipeline files
- foreach ($this->css as $id => $asset) {
- if ($asset['group'] == $group) {
- if (!$asset['pipeline'] ||
- ($asset['remote'] && $this->css_pipeline_include_externals === false)) {
- $this->css_no_pipeline[$id] = $asset;
- } else {
- $temp_css[$id] = $asset;
- }
- }
- }
-
- //if nothing found get out of here!
- if (count($temp_css) == 0) {
- return false;
- }
-
- // Write non-pipeline files out
- if (!empty($this->css_no_pipeline)) {
- file_put_contents($this->assets_dir . $inline_file, json_encode($this->css_no_pipeline));
- }
-
-
- $css_minify = $this->css_minify;
-
- // If this is a Windows server, and minify_windows is false (default value) skip the
- // minification process because it will cause Apache to die/crash due to insufficient
- // ThreadStackSize in httpd.conf - See: https://bugs.php.net/bug.php?id=47689
- if (strtoupper(substr(php_uname('s'), 0, 3)) === 'WIN' && !$this->css_minify_windows) {
- $css_minify = false;
- }
-
- // Concatenate files
- $buffer = $this->gatherLinks($temp_css, CSS_ASSET);
- if ($css_minify) {
- $minifier = new \MatthiasMullie\Minify\CSS();
- $minifier->add($buffer);
- $buffer = $minifier->minify();
- }
-
- // Write file
- if (strlen(trim($buffer)) > 0) {
- file_put_contents($this->assets_dir . $file, $buffer);
-
- if ($returnURL) {
- return $relative_path . $this->getTimestamp();
- }
- else {
- return $buffer . "\n";
- }
- } else {
- return false;
- }
- }
-
- /**
- * Minify and concatenate JS files.
- *
- * @param string $group
- * @param bool $returnURL true if pipeline should return the URL, otherwise the content
- *
- * @return bool|string URL or generated content if available, else false
- */
- protected function pipelineJs($group = 'head', $returnURL = true)
- {
- // temporary list of assets to pipeline
- $temp_js = [];
-
- // clear no-pipeline assets lists
- $this->js_no_pipeline = [];
-
- // Compute uid based on assets and timestamp
- $uid = md5(json_encode($this->js) . $this->js_minify . $group);
- $file = $uid . '.js';
- $inline_file = $uid . '-inline.js';
-
- $relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
-
- // If inline files exist set them on object
- if (file_exists($this->assets_dir . $inline_file)) {
- $this->js_no_pipeline = json_decode(file_get_contents($this->assets_dir . $inline_file), true);
- }
-
- // If pipeline exist return its URL or content
- if (file_exists($this->assets_dir . $file)) {
- if ($returnURL) {
- return $relative_path . $this->getTimestamp();
- }
- else {
- return file_get_contents($this->assets_dir . $file) . "\n";
- }
- }
-
- // Remove any non-pipeline files
- foreach ($this->js as $id => $asset) {
- if ($asset['group'] == $group) {
- if (!$asset['pipeline'] ||
- ($asset['remote'] && $this->js_pipeline_include_externals === false)) {
- $this->js_no_pipeline[] = $asset;
- } else {
- $temp_js[$id] = $asset;
- }
- }
- }
-
- //if nothing found get out of here!
- if (count($temp_js) == 0) {
- return false;
- }
-
- // Write non-pipeline files out
- if (!empty($this->js_no_pipeline)) {
- file_put_contents($this->assets_dir . $inline_file, json_encode($this->js_no_pipeline));
- }
-
- // Concatenate files
- $buffer = $this->gatherLinks($temp_js, JS_ASSET);
- if ($this->js_minify) {
- $minifier = new \MatthiasMullie\Minify\JS();
- $minifier->add($buffer);
- $buffer = $minifier->minify();
- }
-
- // Write file
- if (strlen(trim($buffer)) > 0) {
- file_put_contents($this->assets_dir . $file, $buffer);
-
- if ($returnURL) {
- return $relative_path . $this->getTimestamp();
- }
- else {
- return $buffer . "\n";
- }
- } else {
- return false;
- }
- }
-
- /**
- * Return the array of all the registered CSS assets
- * If a $key is provided, it will try to return only that asset
- * else it will return null
- *
- * @param null|string $key the asset key
- * @return array
- */
- public function getCss($key = null)
- {
- if (!empty($key)) {
- $asset_key = md5($key);
- if (isset($this->css[$asset_key])) {
- return $this->css[$asset_key];
- } else {
- return null;
- }
- }
-
- return $this->css;
- }
-
- /**
- * Return the array of all the registered JS assets
- * If a $key is provided, it will try to return only that asset
- * else it will return null
- *
- * @param null|string $key the asset key
- * @return array
- */
- public function getJs($key = null)
- {
- if (!empty($key)) {
- $asset_key = md5($key);
- if (isset($this->js[$asset_key])) {
- return $this->js[$asset_key];
- } else {
- return null;
- }
- }
-
- return $this->js;
- }
-
- /**
- * Set the whole array of CSS assets
- *
- * @param $css
- */
- public function setCss($css)
- {
- $this->css = $css;
- }
-
- /**
- * Set the whole array of JS assets
- *
- * @param $js
- */
- public function setJs($js)
- {
- $this->js = $js;
- }
-
- /**
- * Removes an item from the CSS array if set
- *
- * @param string $key The asset key
- */
- public function removeCss($key)
- {
- $asset_key = md5($key);
- if (isset($this->css[$asset_key])) {
- unset($this->css[$asset_key]);
- }
- }
-
- /**
- * Removes an item from the JS array if set
- *
- * @param string $key The asset key
- */
- public function removeJs($key)
- {
- $asset_key = md5($key);
- if (isset($this->js[$asset_key])) {
- unset($this->js[$asset_key]);
- }
- }
-
- /**
- * Return the array of all the registered collections
- *
- * @return array
- */
- public function getCollections()
- {
- return $this->collections;
- }
-
- /**
- * Set the array of collections explicitly
- *
- * @param $collections
- */
- public function setCollection($collections)
- {
- $this->collections = $collections;
- }
-
- /**
- * Determines if an asset exists as a collection, CSS or JS reference
- *
- * @param $asset
- *
- * @return bool
- */
- public function exists($asset)
- {
- if (isset($this->collections[$asset]) || isset($this->css[$asset]) || isset($this->js[$asset])) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Add/replace collection.
- *
- * @param string $collectionName
- * @param array $assets
- * @param bool $overwrite
- *
- * @return $this
- */
- public function registerCollection($collectionName, Array $assets, $overwrite = false)
- {
- if ($overwrite || !isset($this->collections[$collectionName])) {
- $this->collections[$collectionName] = $assets;
- }
-
- return $this;
- }
-
- /**
- * Reset all assets.
- *
- * @return $this
- */
- public function reset()
- {
- return $this->resetCss()->resetJs();
- }
-
- /**
- * Reset JavaScript assets.
- *
- * @return $this
- */
- public function resetJs()
- {
- $this->js = [];
- $this->inline_js = [];
-
- return $this;
- }
-
- /**
- * Reset CSS assets.
- *
- * @return $this
- */
- public function resetCss()
- {
- $this->css = [];
- $this->inline_css = [];
-
- return $this;
- }
-
- /**
- * Add all JavaScript assets within $directory
- *
- * @param string $directory Relative to the Grav root path, or a stream identifier
- *
- * @return $this
- */
- public function addDirJs($directory)
- {
- return $this->addDir($directory, self::JS_REGEX);
- }
-
- /**
- * Add all CSS assets within $directory
- *
- * @param string $directory Relative to the Grav root path, or a stream identifier
- *
- * @return $this
- */
- public function addDirCss($directory)
- {
- return $this->addDir($directory, self::CSS_REGEX);
- }
-
- /**
- * Add all assets matching $pattern within $directory.
- *
- * @param string $directory Relative to the Grav root path, or a stream identifier
- * @param string $pattern (regex)
- *
- * @return $this
- * @throws Exception
- */
- public function addDir($directory, $pattern = self::DEFAULT_REGEX)
- {
- $root_dir = rtrim(ROOT_DIR, '/');
-
- // Check if $directory is a stream.
- if (strpos($directory, '://')) {
- $directory = Grav::instance()['locator']->findResource($directory, null);
- }
-
- // Get files
- $files = $this->rglob($root_dir . DIRECTORY_SEPARATOR . $directory, $pattern, $root_dir . '/');
-
- // No luck? Nothing to do
- if (!$files) {
- return $this;
- }
-
- // Add CSS files
- if ($pattern === self::CSS_REGEX) {
- foreach ($files as $file) {
- $this->addCss($file);
- }
-
- return $this;
- }
-
- // Add JavaScript files
- if ($pattern === self::JS_REGEX) {
- foreach ($files as $file) {
- $this->addJs($file);
- }
-
- return $this;
- }
-
- // Unknown pattern.
- foreach ($files as $asset) {
- $this->add($asset);
- }
-
- return $this;
- }
-
- /**
- * Determine whether a link is local or remote.
- *
- * Understands both "http://" and "https://" as well as protocol agnostic links "//"
- *
- * @param string $link
- *
- * @return bool
- */
- protected function isRemoteLink($link)
- {
- $base = Grav::instance()['uri']->rootUrl(true);
-
- // sanity check for local URLs with absolute URL's enabled
- if (Utils::startsWith($link, $base)) {
- return false;
- }
-
- return ('http://' === substr($link, 0, 7) || 'https://' === substr($link, 0, 8) || '//' === substr($link, 0,
- 2));
- }
-
- /**
- * Build local links including grav asset shortcodes
- *
- * @param string $asset the asset string reference
- * @param bool $absolute build absolute asset link
- *
- * @return string the final link url to the asset
- */
- protected function buildLocalLink($asset, $absolute = false)
- {
- try {
- $asset = Grav::instance()['locator']->findResource($asset, $absolute);
- } catch (\Exception $e) {
- }
-
- $uri = $absolute ? $asset : $this->base_url . ltrim($asset, '/');
- return $asset ? $uri : false;
- }
-
- /**
- * Get the last modification time of asset
- *
- * @param string $asset the asset string reference
- *
- * @return string the last modifcation time or false on error
- */
- protected function getLastModificationTime($asset)
- {
- $file = GRAV_ROOT . $asset;
- if (Grav::instance()['locator']->isStream($asset)) {
- $file = $this->buildLocalLink($asset, true);
- }
-
- return file_exists($file) ? filemtime($file) : false;
- }
-
- /**
- * Build an HTML attribute string from an array.
- *
- * @param array $attributes
- *
- * @return string
- */
- protected function attributes(array $attributes)
- {
- $html = '';
- $no_key = ['loading'];
-
- foreach ($attributes as $key => $value) {
- // For numeric keys we will assume that the key and the value are the same
- // as this will convert HTML attributes such as "required" to a correct
- // form like required="required" instead of using incorrect numerics.
- if (is_numeric($key)) {
- $key = $value;
- }
- if (is_array($value)) {
- $value = implode(' ', $value);
- }
-
- if (in_array($key, $no_key)) {
- $element = htmlentities($value, ENT_QUOTES, 'UTF-8', false);
- } else {
- $element = $key . '="' . htmlentities($value, ENT_QUOTES, 'UTF-8', false) . '"';
- }
-
- $html .= ' ' . $element;
- }
-
- return $html;
- }
-
- /**
- * Download and concatenate the content of several links.
- *
- * @param array $links
- * @param bool $css
- *
- * @return string
- */
- protected function gatherLinks(array $links, $css = true)
- {
- $buffer = '';
-
-
- foreach ($links as $asset) {
- $relative_dir = '';
- $local = true;
-
- $link = $asset['asset'];
- $relative_path = $link;
-
- if ($this->isRemoteLink($link)) {
- $local = false;
- if ('//' === substr($link, 0, 2)) {
- $link = 'http:' . $link;
- }
- } else {
- // Fix to remove relative dir if grav is in one
- if (($this->base_url != '/') && (strpos($this->base_url, $link) == 0)) {
- $base_url = '#' . preg_quote($this->base_url, '#') . '#';
- $relative_path = ltrim(preg_replace($base_url, '/', $link, 1), '/');
- }
-
- $relative_dir = dirname($relative_path);
- $link = ROOT_DIR . $relative_path;
- }
-
- $file = ($this->fetch_command instanceof Closure) ? @$this->fetch_command->__invoke($link) : @file_get_contents($link);
-
- // No file found, skip it...
- if ($file === false) {
- continue;
- }
-
- // Double check last character being
- if (!$css) {
- $file = rtrim($file, ' ;') . ';';
- }
-
- // If this is CSS + the file is local + rewrite enabled
- if ($css && $local && $this->css_rewrite) {
- $file = $this->cssRewrite($file, $relative_dir);
- }
-
- $file = rtrim($file) . PHP_EOL;
- $buffer .= $file;
- }
-
- // Pull out @imports and move to top
- if ($css) {
- $buffer = $this->moveImports($buffer);
- }
-
- return $buffer;
- }
-
- /**
- * Finds relative CSS urls() and rewrites the URL with an absolute one
- *
- * @param string $file the css source file
- * @param string $relative_path relative path to the css file
- *
- * @return mixed
- */
- protected function cssRewrite($file, $relative_path)
- {
- // Strip any sourcemap comments
- $file = preg_replace(self::CSS_SOURCEMAP_REGEX, '', $file);
-
- // Find any css url() elements, grab the URLs and calculate an absolute path
- // Then replace the old url with the new one
- $file = preg_replace_callback(self::CSS_URL_REGEX, function ($matches) use ($relative_path) {
-
- $old_url = $matches[2];
-
- // Ensure link is not rooted to webserver, a data URL, or to a remote host
- if (Utils::startsWith($old_url, '/') || Utils::startsWith($old_url, 'data:') || $this->isRemoteLink($old_url)) {
- return $matches[0];
- }
-
- $new_url = $this->base_url . ltrim(Utils::normalizePath($relative_path . '/' . $old_url), '/');
-
- return str_replace($old_url, $new_url, $matches[0]);
- }, $file);
-
- return $file;
- }
-
- /**
- * Moves @import statements to the top of the file per the CSS specification
- *
- * @param string $file the file containing the combined CSS files
- *
- * @return string the modified file with any @imports at the top of the file
- */
- protected function moveImports($file)
- {
- $this->imports = [];
-
- $file = preg_replace_callback(self::CSS_IMPORT_REGEX, function ($matches) {
- $this->imports[] = $matches[0];
-
- return '';
- }, $file);
-
- return implode("\n", $this->imports) . "\n\n" . $file;
- }
-
- /**
- * Recursively get files matching $pattern within $directory.
- *
- * @param string $directory
- * @param string $pattern (regex)
- * @param string $ltrim Will be trimmed from the left of the file path
- *
- * @return array
- */
- protected function rglob($directory, $pattern, $ltrim = null)
- {
- $iterator = new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory,
- FilesystemIterator::SKIP_DOTS)), $pattern);
- $offset = strlen($ltrim);
- $files = [];
-
- foreach ($iterator as $file) {
- $files[] = substr($file->getPathname(), $offset);
- }
-
- return $files;
- }
-
- /**
- * Sets the state of CSS Pipeline
- *
- * @param boolean $value
- */
- public function setCssPipeline($value)
- {
- $this->css_pipeline = (bool)$value;
- }
-
- /**
- * Sets the state of JS Pipeline
- *
- * @param boolean $value
- */
- public function setJsPipeline($value)
- {
- $this->js_pipeline = (bool)$value;
- }
-
- /**
- * Explicitly set's a timestamp for assets
- *
- * @param $value
- */
- public function setTimestamp($value)
- {
- $this->timestamp = $value;
- }
-
- /**
- * Get the timestamp for assets
- *
- * @return string
- */
- public function getTimestamp($include_join = true)
- {
- if ($this->timestamp) {
- $timestamp = $include_join ? '?' . $this->timestamp : $this->timestamp;
- return $timestamp;
- }
- return;
- }
-
- /**
- *
- *
- * @param $asset
- * @return string
- */
- public function getQuerystring($asset)
- {
- $querystring = '';
-
- if (!empty($asset['query'])) {
- if (Utils::contains($asset['asset'], '?')) {
- $querystring .= '&' . $asset['query'];
- } else {
- $querystring .= '?' . $asset['query'];
- }
- }
-
- if ($this->timestamp) {
- if (Utils::contains($asset['asset'], '?') || $querystring) {
- $querystring .= '&' . $this->timestamp;
- } else {
- $querystring .= '?' . $this->timestamp;
- }
- }
-
- return $querystring;
- }
-
- /**
- * @return string
- */
- public function __toString()
- {
- return '';
- }
-
- /**
- * @param $a
- * @param $b
- *
- * @return mixed
- */
- protected function sortAssetsByPriorityThenOrder($a, $b)
- {
- if ($a['priority'] == $b['priority']) {
- return $a['order'] - $b['order'];
- }
-
- return $b['priority'] - $a['priority'];
- }
-
-}
diff --git a/system/src/Grav/Common/Composer.php b/system/src/Grav/Common/Composer.php
index 26719252c..65c994564 100644
--- a/system/src/Grav/Common/Composer.php
+++ b/system/src/Grav/Common/Composer.php
@@ -11,7 +11,7 @@ namespace Grav\Common;
class Composer
{
/** @const Default composer location */
- const DEFAULT_PATH = "bin/composer.phar";
+ const DEFAULT_PATH = 'bin/composer.phar';
/**
* Returns the location of composer.
@@ -20,12 +20,12 @@ class Composer
*/
public static function getComposerLocation()
{
- if (!function_exists('shell_exec') || strtolower(substr(PHP_OS, 0, 3)) === 'win') {
+ if (!\function_exists('shell_exec') || stripos(PHP_OS, 'win') === 0) {
return self::DEFAULT_PATH;
}
// check for global composer install
- $path = trim(shell_exec("command -v composer"));
+ $path = trim(shell_exec('command -v composer'));
// fall back to grav bundled composer
if (!$path || !preg_match('/(composer|composer\.phar)$/', $path)) {
diff --git a/system/src/Grav/Common/Data/BlueprintSchema.php b/system/src/Grav/Common/Data/BlueprintSchema.php
index 67a8021de..3e389e7b5 100644
--- a/system/src/Grav/Common/Data/BlueprintSchema.php
+++ b/system/src/Grav/Common/Data/BlueprintSchema.php
@@ -26,6 +26,23 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
'fields' => true
];
+ /**
+ * @return array
+ */
+ public function getTypes()
+ {
+ return $this->types;
+ }
+
+ /**
+ * @param string $name
+ * @return array
+ */
+ public function getType($name)
+ {
+ return $this->types[$name] ?? [];
+ }
+
/**
* Validate data against blueprints.
*
diff --git a/system/src/Grav/Common/Debugger.php b/system/src/Grav/Common/Debugger.php
index 8fee09fa7..50c77bbe4 100644
--- a/system/src/Grav/Common/Debugger.php
+++ b/system/src/Grav/Common/Debugger.php
@@ -9,7 +9,13 @@
namespace Grav\Common;
use DebugBar\DataCollector\ConfigCollector;
+use DebugBar\DataCollector\ExceptionsCollector;
+use DebugBar\DataCollector\MemoryCollector;
use DebugBar\DataCollector\MessagesCollector;
+use DebugBar\DataCollector\PhpInfoCollector;
+use DebugBar\DataCollector\RequestDataCollector;
+use DebugBar\DataCollector\TimeDataCollector;
+use DebugBar\DebugBar;
use DebugBar\JavascriptRenderer;
use DebugBar\StandardDebugBar;
use Grav\Common\Config\Config;
@@ -28,13 +34,16 @@ class Debugger
/** @var StandardDebugBar $debugbar */
protected $debugbar;
+ /** @var bool */
protected $enabled;
+ /** @var array */
protected $timers = [];
/** @var string[] $deprecations */
protected $deprecations = [];
+ /** @var callable */
protected $errorHandler;
/**
@@ -42,11 +51,26 @@ class Debugger
*/
public function __construct()
{
+ $currentTime = microtime(true);
+
+ if (!\defined('GRAV_REQUEST_TIME')) {
+ \define('GRAV_REQUEST_TIME', $currentTime);
+ }
+
// Enable debugger until $this->init() gets called.
$this->enabled = true;
- $this->debugbar = new StandardDebugBar();
- $this->debugbar['time']->addMeasure('Loading', $this->debugbar['time']->getRequestStartTime(), microtime(true));
+ $debugbar = new DebugBar();
+ $debugbar->addCollector(new PhpInfoCollector());
+ $debugbar->addCollector(new MessagesCollector());
+ $debugbar->addCollector(new RequestDataCollector());
+ $debugbar->addCollector(new TimeDataCollector($_SERVER['REQUEST_TIME_FLOAT'] ?? GRAV_REQUEST_TIME));
+
+ $debugbar['time']->addMeasure('Server', $debugbar['time']->getRequestStartTime(), GRAV_REQUEST_TIME);
+ $debugbar['time']->addMeasure('Loading', GRAV_REQUEST_TIME, $currentTime);
+ $debugbar['time']->addMeasure('Debugger', $currentTime, microtime(true));
+
+ $this->debugbar = $debugbar;
// Set deprecation collector.
$this->setErrorHandler();
@@ -72,9 +96,11 @@ class Debugger
ksort($plugins_config);
-
- $this->debugbar->addCollector(new ConfigCollector((array)$this->config->get('system'), 'Config'));
- $this->debugbar->addCollector(new ConfigCollector($plugins_config, 'Plugins'));
+ $debugbar = $this->debugbar;
+ $debugbar->addCollector(new MemoryCollector());
+ $debugbar->addCollector(new ExceptionsCollector());
+ $debugbar->addCollector(new ConfigCollector((array)$this->config->get('system'), 'Config'));
+ $debugbar->addCollector(new ConfigCollector($plugins_config, 'Plugins'));
$this->addMessage('Grav v' . GRAV_VERSION);
}
@@ -229,7 +255,7 @@ class Debugger
/**
* Start a timer with an associated name and description
*
- * @param $name
+ * @param string $name
* @param string|null $description
*
* @return $this
@@ -253,7 +279,7 @@ class Debugger
*/
public function stopTimer($name)
{
- if (in_array($name, $this->timers, true) && ($name[0] === '_' || $this->enabled())) {
+ if (\in_array($name, $this->timers, true) && ($name[0] === '_' || $this->enabled())) {
$this->debugbar['time']->stopMeasure($name);
}
@@ -411,8 +437,8 @@ class Debugger
$trace = [];
foreach ($deprecated['trace'] as $current) {
- $class = isset($current['class']) ? $current['class'] : '';
- $type = isset($current['type']) ? $current['type'] : '';
+ $class = $current['class'] ?? '';
+ $type = $current['type'] ?? '';
$function = $this->getFunction($current);
if (isset($current['file'])) {
$current['file'] = str_replace(GRAV_ROOT . '/', '', $current['file']);