From 29c6a70611074467c67bf170f65132285d316d74 Mon Sep 17 00:00:00 2001 From: Florian Schlittenbauer Date: Sat, 8 Feb 2020 21:47:17 +0100 Subject: [PATCH 01/10] [BUGFIX] .editorconfig not picking up .yml files (#2808) --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 3b95e6dba..da1477309 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,5 +13,5 @@ indent_style = space indent_size = 4 # 2 space indentation -[*.{yaml,.yml}] +[*.{yaml,yml}] indent_size = 2 From c2f374f0db4a61b964fe9022cca0b804a73ec82c Mon Sep 17 00:00:00 2001 From: Andreas Amos Date: Fri, 7 Feb 2020 18:35:29 +0100 Subject: [PATCH 02/10] Truncator: encoding problems solves #2154 As I am not a developer somebody should review the change. --- system/src/Grav/Common/Page/Page.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 75bf45340..2b64360a2 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -613,7 +613,7 @@ public function summary($size = null, $textOnly = false) $summary = Utils::truncateHtml($content, $size); - return html_entity_decode($summary); + return html_entity_decode($summary,ENT_COMPAT | ENT_HTML401, 'utf-8'); } /** From e55b239536cb8c1bd76a780991ecbd318e850190 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 10 Feb 2020 09:50:39 +0200 Subject: [PATCH 03/10] Fixed encoding problems when PHP INI setting `default_charset` is not `utf-8` [#2154] --- CHANGELOG.md | 8 +++++++- bin/gpm | 7 +++++++ bin/grav | 15 +++++++++++---- bin/plugin | 7 +++++++ index.php | 19 ++++++++++--------- .../Common/Assets/Traits/AssetUtilsTrait.php | 4 ++-- .../Grav/Common/Page/Markdown/Excerpts.php | 4 ++-- system/src/Grav/Common/Page/Page.php | 14 +++++++------- system/src/Grav/Common/Twig/TwigExtension.php | 2 +- system/src/Grav/Common/Uri.php | 2 +- 10 files changed, 55 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7e59d92a..fcd8cec11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ +# v1.6.21 +## mm/dd/2020 + +1. [](#bugfix) + * Fixed encoding problems when PHP INI setting `default_charset` is not `utf-8` [#2154](https://github.com/getgrav/grav/issues/2154) + # v1.6.20 -## 03/02/2020 +## 02/03/2020 1. [](#bugfix) * Fixed incorrect routing caused by `str_replace()` in `Uri::init()` [#2754](https://github.com/getgrav/grav/issues/2754) diff --git a/bin/gpm b/bin/gpm index 7ad1e4ac5..88b2ee8dd 100755 --- a/bin/gpm +++ b/bin/gpm @@ -28,6 +28,13 @@ if (!ini_get('date.timezone')) { date_default_timezone_set('UTC'); } +// Set internal encoding. +if (!\extension_loaded('mbstring')) { + die("'mbstring' extension is not loaded. This is required for Grav to run correctly"); +} +@ini_set('default_charset', 'UTF-8'); +mb_internal_encoding('UTF-8'); + if (!file_exists(GRAV_ROOT . '/index.php')) { exit('FATAL: Must be run from ROOT directory of Grav!'); } diff --git a/bin/grav b/bin/grav index 7120218c0..b1e4c90e5 100755 --- a/bin/grav +++ b/bin/grav @@ -25,6 +25,17 @@ if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) { exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req)); } +if (!ini_get('date.timezone')) { + date_default_timezone_set('UTC'); +} + +// Set internal encoding. +if (!\extension_loaded('mbstring')) { + die("'mbstring' extension is not loaded. This is required for Grav to run correctly"); +} +@ini_set('default_charset', 'UTF-8'); +mb_internal_encoding('UTF-8'); + $climate = new League\CLImate\CLImate; $climate->arguments->add([ 'environment' => [ @@ -42,10 +53,6 @@ $environment = $climate->arguments->get('environment'); $grav = Grav::instance(array('loader' => $autoload)); $grav->setup($environment); -if (!ini_get('date.timezone')) { - date_default_timezone_set('UTC'); -} - if (!file_exists(GRAV_ROOT . '/index.php')) { exit('FATAL: Must be run from ROOT directory of Grav!'); } diff --git a/bin/plugin b/bin/plugin index 3c431e379..925549fa0 100755 --- a/bin/plugin +++ b/bin/plugin @@ -32,6 +32,13 @@ if (!ini_get('date.timezone')) { date_default_timezone_set('UTC'); } +// Set internal encoding. +if (!\extension_loaded('mbstring')) { + die("'mbstring' extension is not loaded. This is required for Grav to run correctly"); +} +@ini_set('default_charset', 'UTF-8'); +mb_internal_encoding('UTF-8'); + if (!file_exists(GRAV_ROOT . '/index.php')) { exit('FATAL: Must be run from ROOT directory of Grav!'); } diff --git a/index.php b/index.php index 64154df89..7be4df1c6 100644 --- a/index.php +++ b/index.php @@ -20,6 +20,16 @@ die("PHP webserver requires a router to run Grav, please use:
php -S {$_SERVER['SERVER_NAME']}:{$_SERVER['SERVER_PORT']} system/router.php
"); } +// Set timezone to default, falls back to system if php.ini not set +date_default_timezone_set(@date_default_timezone_get()); + +// Set internal encoding. +if (!\extension_loaded('mbstring')) { + die("'mbstring' extension is not loaded. This is required for Grav to run correctly"); +} +@ini_set('default_charset', 'UTF-8'); +mb_internal_encoding('UTF-8'); + // Ensure vendor libraries exist $autoload = __DIR__ . '/vendor/autoload.php'; if (!is_file($autoload)) { @@ -32,15 +42,6 @@ use Grav\Common\Grav; use RocketTheme\Toolbox\Event\Event; -// Set timezone to default, falls back to system if php.ini not set -date_default_timezone_set(@date_default_timezone_get()); - -// Set internal encoding if mbstring loaded -if (!\extension_loaded('mbstring')) { - die("'mbstring' extension is not loaded. This is required for Grav to run correctly"); -} -mb_internal_encoding('UTF-8'); - // Get the Grav instance $grav = Grav::instance( array( diff --git a/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php b/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php index 0a1d149de..ce6183737 100644 --- a/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php +++ b/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php @@ -138,9 +138,9 @@ protected function renderAttributes() } if (\in_array($key, $no_key, true)) { - $element = htmlentities($value, ENT_QUOTES, 'UTF-8', false); + $element = htmlentities($value, ENT_QUOTES | ENT_HTML5, 'UTF-8', false); } else { - $element = $key . '="' . htmlentities($value, ENT_QUOTES, 'UTF-8', false) . '"'; + $element = $key . '="' . htmlentities($value, ENT_QUOTES | ENT_HTML5, 'UTF-8', false) . '"'; } $html .= ' ' . $element; diff --git a/system/src/Grav/Common/Page/Markdown/Excerpts.php b/system/src/Grav/Common/Page/Markdown/Excerpts.php index eaa13cbe8..798ce082d 100644 --- a/system/src/Grav/Common/Page/Markdown/Excerpts.php +++ b/system/src/Grav/Common/Page/Markdown/Excerpts.php @@ -68,7 +68,7 @@ public function fireInitializedEvent($markdown): void */ public function processLinkExcerpt(array $excerpt, string $type = 'link'): array { - $url = htmlspecialchars_decode(rawurldecode($excerpt['element']['attributes']['href'])); + $url = htmlspecialchars_decode(rawurldecode($excerpt['element']['attributes']['href']), ENT_QUOTES | ENT_HTML5); $url_parts = $this->parseUrl($url); @@ -152,7 +152,7 @@ static function ($carry, $item) { */ public function processImageExcerpt(array $excerpt): array { - $url = htmlspecialchars_decode(urldecode($excerpt['element']['attributes']['src'])); + $url = htmlspecialchars_decode(urldecode($excerpt['element']['attributes']['src']), ENT_QUOTES | ENT_HTML5); $url_parts = $this->parseUrl($url); $media = null; diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 2b64360a2..17a7d4a73 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -608,12 +608,12 @@ public function summary($size = null, $textOnly = false) return $content; } - return mb_strimwidth($content, 0, $size, '...', 'utf-8'); + return mb_strimwidth($content, 0, $size, '...', 'UTF-8'); } $summary = Utils::truncateHtml($content, $size); - return html_entity_decode($summary,ENT_COMPAT | ENT_HTML401, 'utf-8'); + return html_entity_decode($summary, ENT_COMPAT | ENT_HTML5, 'UTF-8'); } /** @@ -1713,7 +1713,7 @@ public function metadata($var = null) $this->metadata[$prop_key] = [ 'name' => $prop_key, 'property' => $prop_key, - 'content' => htmlspecialchars($prop_value, ENT_QUOTES, 'UTF-8') + 'content' => htmlspecialchars($prop_value, ENT_QUOTES | ENT_HTML5, 'UTF-8') ]; } } else { @@ -1722,16 +1722,16 @@ public function metadata($var = null) if (\in_array($key, $header_tag_http_equivs, true)) { $this->metadata[$key] = [ 'http_equiv' => $key, - 'content' => htmlspecialchars($value, ENT_QUOTES, 'UTF-8') + 'content' => htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8') ]; } elseif ($key === 'charset') { - $this->metadata[$key] = ['charset' => htmlspecialchars($value, ENT_QUOTES, 'UTF-8')]; + $this->metadata[$key] = ['charset' => htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8')]; } else { // if it's a social metadata with separator, render as property $separator = strpos($key, ':'); $hasSeparator = $separator && $separator < strlen($key) - 1; $entry = [ - 'content' => htmlspecialchars($value, ENT_QUOTES, 'UTF-8') + 'content' => htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8') ]; if ($hasSeparator && !Utils::startsWith($key, 'twitter')) { @@ -2718,7 +2718,7 @@ public function collection($params = 'content', $pagination = true) } foreach ($items as $item) { $item = rawurldecode($item); - if (empty($page->taxonomy[$taxonomy]) || !\in_array(htmlspecialchars_decode($item, ENT_QUOTES), $page->taxonomy[$taxonomy], true) + if (empty($page->taxonomy[$taxonomy]) || !\in_array(htmlspecialchars_decode($item, ENT_QUOTES | ENT_HTML5), $page->taxonomy[$taxonomy], true) ) { $collection->remove($page->path()); } diff --git a/system/src/Grav/Common/Twig/TwigExtension.php b/system/src/Grav/Common/Twig/TwigExtension.php index f84923ebd..62ee0c2b3 100644 --- a/system/src/Grav/Common/Twig/TwigExtension.php +++ b/system/src/Grav/Common/Twig/TwigExtension.php @@ -1055,7 +1055,7 @@ public function nonceFieldFunc($action, $nonceParamName = 'nonce') */ public function jsonDecodeFilter($str, $assoc = false, $depth = 512, $options = 0) { - return json_decode(html_entity_decode($str), $assoc, $depth, $options); + return json_decode(html_entity_decode($str, ENT_COMPAT | ENT_HTML5, 'UTF-8'), $assoc, $depth, $options); } /** diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index f875ab3de..4d7936e91 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -306,7 +306,7 @@ public function params($id = null, $array = false) public function param($id) { if (isset($this->params[$id])) { - return html_entity_decode(rawurldecode($this->params[$id])); + return html_entity_decode(rawurldecode($this->params[$id]), ENT_COMPAT | ENT_HTML5, 'UTF-8'); } return false; From ef80e28d1db6a8d59581d77b26231169a7194c8b Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 10 Feb 2020 17:41:13 +0200 Subject: [PATCH 04/10] Fixed regression (#2154) --- .../Grav/Common/Assets/Traits/AssetUtilsTrait.php | 4 ++-- system/src/Grav/Common/Page/Markdown/Excerpts.php | 4 ++-- system/src/Grav/Common/Page/Page.php | 12 ++++++------ system/src/Grav/Common/Twig/TwigExtension.php | 2 +- system/src/Grav/Common/Uri.php | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php b/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php index ce6183737..0a1d149de 100644 --- a/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php +++ b/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php @@ -138,9 +138,9 @@ protected function renderAttributes() } if (\in_array($key, $no_key, true)) { - $element = htmlentities($value, ENT_QUOTES | ENT_HTML5, 'UTF-8', false); + $element = htmlentities($value, ENT_QUOTES, 'UTF-8', false); } else { - $element = $key . '="' . htmlentities($value, ENT_QUOTES | ENT_HTML5, 'UTF-8', false) . '"'; + $element = $key . '="' . htmlentities($value, ENT_QUOTES, 'UTF-8', false) . '"'; } $html .= ' ' . $element; diff --git a/system/src/Grav/Common/Page/Markdown/Excerpts.php b/system/src/Grav/Common/Page/Markdown/Excerpts.php index 798ce082d..eaa13cbe8 100644 --- a/system/src/Grav/Common/Page/Markdown/Excerpts.php +++ b/system/src/Grav/Common/Page/Markdown/Excerpts.php @@ -68,7 +68,7 @@ public function fireInitializedEvent($markdown): void */ public function processLinkExcerpt(array $excerpt, string $type = 'link'): array { - $url = htmlspecialchars_decode(rawurldecode($excerpt['element']['attributes']['href']), ENT_QUOTES | ENT_HTML5); + $url = htmlspecialchars_decode(rawurldecode($excerpt['element']['attributes']['href'])); $url_parts = $this->parseUrl($url); @@ -152,7 +152,7 @@ static function ($carry, $item) { */ public function processImageExcerpt(array $excerpt): array { - $url = htmlspecialchars_decode(urldecode($excerpt['element']['attributes']['src']), ENT_QUOTES | ENT_HTML5); + $url = htmlspecialchars_decode(urldecode($excerpt['element']['attributes']['src'])); $url_parts = $this->parseUrl($url); $media = null; diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 17a7d4a73..d7531df97 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -613,7 +613,7 @@ public function summary($size = null, $textOnly = false) $summary = Utils::truncateHtml($content, $size); - return html_entity_decode($summary, ENT_COMPAT | ENT_HTML5, 'UTF-8'); + return html_entity_decode($summary, ENT_COMPAT | ENT_HTML401, 'UTF-8'); } /** @@ -1713,7 +1713,7 @@ public function metadata($var = null) $this->metadata[$prop_key] = [ 'name' => $prop_key, 'property' => $prop_key, - 'content' => htmlspecialchars($prop_value, ENT_QUOTES | ENT_HTML5, 'UTF-8') + 'content' => htmlspecialchars($prop_value, ENT_QUOTES, 'UTF-8') ]; } } else { @@ -1722,16 +1722,16 @@ public function metadata($var = null) if (\in_array($key, $header_tag_http_equivs, true)) { $this->metadata[$key] = [ 'http_equiv' => $key, - 'content' => htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8') + 'content' => htmlspecialchars($value, ENT_QUOTES, 'UTF-8') ]; } elseif ($key === 'charset') { - $this->metadata[$key] = ['charset' => htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8')]; + $this->metadata[$key] = ['charset' => htmlspecialchars($value, ENT_QUOTES, 'UTF-8')]; } else { // if it's a social metadata with separator, render as property $separator = strpos($key, ':'); $hasSeparator = $separator && $separator < strlen($key) - 1; $entry = [ - 'content' => htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8') + 'content' => htmlspecialchars($value, ENT_QUOTES, 'UTF-8') ]; if ($hasSeparator && !Utils::startsWith($key, 'twitter')) { @@ -2718,7 +2718,7 @@ public function collection($params = 'content', $pagination = true) } foreach ($items as $item) { $item = rawurldecode($item); - if (empty($page->taxonomy[$taxonomy]) || !\in_array(htmlspecialchars_decode($item, ENT_QUOTES | ENT_HTML5), $page->taxonomy[$taxonomy], true) + if (empty($page->taxonomy[$taxonomy]) || !\in_array(htmlspecialchars_decode($item, ENT_QUOTES), $page->taxonomy[$taxonomy], true) ) { $collection->remove($page->path()); } diff --git a/system/src/Grav/Common/Twig/TwigExtension.php b/system/src/Grav/Common/Twig/TwigExtension.php index 62ee0c2b3..58b1d6d68 100644 --- a/system/src/Grav/Common/Twig/TwigExtension.php +++ b/system/src/Grav/Common/Twig/TwigExtension.php @@ -1055,7 +1055,7 @@ public function nonceFieldFunc($action, $nonceParamName = 'nonce') */ public function jsonDecodeFilter($str, $assoc = false, $depth = 512, $options = 0) { - return json_decode(html_entity_decode($str, ENT_COMPAT | ENT_HTML5, 'UTF-8'), $assoc, $depth, $options); + return json_decode(html_entity_decode($str, ENT_COMPAT | ENT_HTML401, 'UTF-8'), $assoc, $depth, $options); } /** diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index 4d7936e91..10e85a5cc 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -306,7 +306,7 @@ public function params($id = null, $array = false) public function param($id) { if (isset($this->params[$id])) { - return html_entity_decode(rawurldecode($this->params[$id]), ENT_COMPAT | ENT_HTML5, 'UTF-8'); + return html_entity_decode(rawurldecode($this->params[$id]), ENT_COMPAT | ENT_HTML401, 'UTF-8'); } return false; From 48170d2fa01cdeab8d60d0dd6cd563ba9316970b Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 11 Feb 2020 19:41:28 +0200 Subject: [PATCH 05/10] Fixed `bin/plugin` CLI calling `$themes->init()` way too early Added `ConsoleCommand::setLanguage()` method to set language to be used from CLI Added `ConsoleCommand::initializeGrav()` method to properly set up Grav instance to be used from CLI Added `ConsoleCommand::initializePlugins()`method to properly set up all plugins to be used from CLI Added `ConsoleCommand::initializeThemes()`method to properly set up current theme to be used from CLI Added `ConsoleCommand::initializePages()` method to properly set up pages to be used from CLI --- CHANGELOG.md | 7 + bin/gpm | 2 +- bin/plugin | 7 +- system/src/Grav/Common/Grav.php | 23 +++ .../Common/Processors/InitializeProcessor.php | 48 ++++++ system/src/Grav/Console/ConsoleCommand.php | 142 +++++++++++++++++- 6 files changed, 220 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcd8cec11..b2a3996c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,14 @@ # v1.6.21 ## mm/dd/2020 +1. [](#new) + * Added `ConsoleCommand::setLanguage()` method to set language to be used from CLI + * Added `ConsoleCommand::initializeGrav()` method to properly set up Grav instance to be used from CLI + * Added `ConsoleCommand::initializePlugins()`method to properly set up all plugins to be used from CLI + * Added `ConsoleCommand::initializeThemes()`method to properly set up current theme to be used from CLI + * Added `ConsoleCommand::initializePages()` method to properly set up pages to be used from CLI 1. [](#bugfix) + * Fixed `bin/plugin` CLI calling `$themes->init()` way too early * Fixed encoding problems when PHP INI setting `default_charset` is not `utf-8` [#2154](https://github.com/getgrav/grav/issues/2154) # v1.6.20 diff --git a/bin/gpm b/bin/gpm index 88b2ee8dd..592bb833e 100755 --- a/bin/gpm +++ b/bin/gpm @@ -62,7 +62,7 @@ $grav->setup($environment); $grav['config']->init(); $grav['uri']->init(); -$grav['users']; +$grav['accounts']; $app = new Application('Grav Package Manager', GRAV_VERSION); $app->addCommands(array( diff --git a/bin/plugin b/bin/plugin index 925549fa0..737eb9105 100755 --- a/bin/plugin +++ b/bin/plugin @@ -58,12 +58,7 @@ $environment = $climate->arguments->get('environment'); $grav = Grav::instance(array('loader' => $autoload)); $grav->setup($environment); - -$grav['config']->init(); -$grav['uri']->init(); -$grav['users']; -$grav['plugins']->init(); -$grav['themes']->init(); +$grav->initializeCli(); $app = new Application('Grav Plugins Commands', GRAV_VERSION); $pattern = '([A-Z]\w+Command\.php)'; diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 2ad278e6c..2f9b37329 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -170,6 +170,29 @@ public function setup(string $environment = null) return $this; } + /** + * Initialize CLI environment. + * + * Call after `$grav->setup($environment)` + * + * - Load configuration + * - Disable debugger + * - Set timezone, locale + * - Load plugins + * - Set Users type to be used in the site + * + * This method WILL NOT initialize assets, twig or pages. + * + * @param string|null $environment + * @return $this + */ + public function initializeCli() + { + InitializeProcessor::initializeCli($this); + + return $this; + } + /** * Process a request */ diff --git a/system/src/Grav/Common/Processors/InitializeProcessor.php b/system/src/Grav/Common/Processors/InitializeProcessor.php index fe2869ce7..eca7c5442 100644 --- a/system/src/Grav/Common/Processors/InitializeProcessor.php +++ b/system/src/Grav/Common/Processors/InitializeProcessor.php @@ -10,6 +10,7 @@ namespace Grav\Common\Processors; use Grav\Common\Config\Config; +use Grav\Common\Grav; use Grav\Common\Uri; use Grav\Common\Utils; use Grav\Framework\Session\Exceptions\SessionException; @@ -22,6 +23,22 @@ class InitializeProcessor extends ProcessorBase public $id = 'init'; public $title = 'Initialize'; + /** @var bool */ + private static $cli_initialized = false; + + /** + * @param Grav $grav + */ + public static function initializeCli(Grav $grav) + { + if (!static::$cli_initialized) { + static::$cli_initialized = true; + + $instance = new static($grav); + $instance->processCli(); + } + } + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface { $this->startTimer(); @@ -77,4 +94,35 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface return $handler->handle($request); } + + public function processCli(): void + { + // Load configuration. + $this->container['config']->init(); + $this->container['plugins']->setup(); + + // Disable debugger. + $this->container['debugger']->enabled(false); + + // Set timezone, locale. + /** @var Config $config */ + $config = $this->container['config']; + $timezone = $config->get('system.timezone'); + if ($timezone) { + date_default_timezone_set($timezone); + } + $this->container->setLocale(); + + // Load plugins. + $this->container['plugins']->init(); + + // Initialize URI. + /** @var Uri $uri */ + $uri = $this->container['uri']; + $uri->init(); + + // Load accounts. + // TODO: remove in 2.0. + $this->container['accounts']; + } } diff --git a/system/src/Grav/Console/ConsoleCommand.php b/system/src/Grav/Console/ConsoleCommand.php index 2c63eaf54..bc65f3dd3 100644 --- a/system/src/Grav/Console/ConsoleCommand.php +++ b/system/src/Grav/Console/ConsoleCommand.php @@ -10,6 +10,9 @@ namespace Grav\Console; use Grav\Common\Grav; +use Grav\Common\Language\Language; +use Grav\Common\Processors\InitializeProcessor; +use RocketTheme\Toolbox\Event\Event; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -18,7 +21,14 @@ class ConsoleCommand extends Command { use ConsoleTrait; - /** + /** @var bool */ + private $plugins_initialized = false; + /** @var bool */ + private $themes_initialized = false; + /** @var bool */ + private $pages_initialized = false; + + /** * @param InputInterface $input * @param OutputInterface $output * @@ -31,12 +41,140 @@ protected function execute(InputInterface $input, OutputInterface $output) } /** - * + * Override with your implementation. */ protected function serve() { } + /** + * Initialize Grav. + * + * - Load configuration + * - Disable debugger + * - Set timezone, locale + * - Load plugins + * - Set Users type to be used in the site + * + * Safe to be called multiple times. + * + * @return $this + */ + final protected function initializeGrav() + { + InitializeProcessor::initializeCli(Grav::instance()); + + return $this; + } + + /** + * Set language to be used in CLI. + * + * @param string|null $code + */ + final protected function setLanguage(string $code = null) + { + $this->initializeGrav(); + + $grav = Grav::instance(); + /** @var Language $language */ + $language = $grav['language']; + if ($language->enabled()) { + if ($code && $language->validate($code)) { + $language->setActive($code); + } else { + $language->setActive($language->getDefault()); + } + } + } + + /** + * Properly initialize plugins. + * + * - call $this->initializeGrav() + * - call onPluginsInitialized event + * + * Safe to be called multiple times. + * + * @return $this + */ + final protected function initializePlugins() + { + if (!$this->plugins_initialized) { + $this->plugins_initialized = true; + + $this->initializeGrav(); + + // Initialize plugins. + $grav = Grav::instance(); + $grav->fireEvent('onPluginsInitialized'); + } + + return $this; + } + + /** + * Properly initialize themes. + * + * - call $this->initializePlugins() + * - initialize theme (call onThemeInitialized event) + * + * Safe to be called multiple times. + * + * @return $this + */ + final protected function initializeThemes() + { + if (!$this->themes_initialized) { + $this->themes_initialized = true; + + $this->initializePlugins(); + + // Initialize themes. + $grav = Grav::instance(); + $grav['themes']->init(); + } + + return $this; + } + + /** + * Properly initialize pages. + * + * - call $this->initializeThemes() + * - initialize assets (call onAssetsInitialized event) + * - initialize twig (calls the twig events) + * - initialize pages (calls onPagesInitialized event) + * + * Safe to be called multiple times. + * + * @return $this + */ + final protected function initializePages() + { + if (!$this->pages_initialized) { + $this->pages_initialized = true; + + $this->initializeThemes(); + + $grav = Grav::instance(); + + // Initialize assets. + $grav['assets']->init(); + $grav->fireEvent('onAssetsInitialized'); + + // Initialize twig. + $grav['twig']->init(); + + // Initialize pages. + $pages = $grav['pages']; + $pages->init(); + $grav->fireEvent('onPagesInitialized', new Event(['pages' => $pages])); + } + + return $this; + } + protected function displayGPMRelease() { $this->output->writeln(''); From f81503dd70895633b309f6836622d217cb742025 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 11 Feb 2020 20:27:57 +0200 Subject: [PATCH 06/10] Fixed page initialization in CLI --- system/src/Grav/Console/ConsoleCommand.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Console/ConsoleCommand.php b/system/src/Grav/Console/ConsoleCommand.php index bc65f3dd3..0f7501478 100644 --- a/system/src/Grav/Console/ConsoleCommand.php +++ b/system/src/Grav/Console/ConsoleCommand.php @@ -11,6 +11,7 @@ use Grav\Common\Grav; use Grav\Common\Language\Language; +use Grav\Common\Page\Page; use Grav\Common\Processors\InitializeProcessor; use RocketTheme\Toolbox\Event\Event; use Symfony\Component\Console\Command\Command; @@ -28,7 +29,7 @@ class ConsoleCommand extends Command /** @var bool */ private $pages_initialized = false; - /** + /** * @param InputInterface $input * @param OutputInterface $output * @@ -170,6 +171,12 @@ final protected function initializePages() $pages = $grav['pages']; $pages->init(); $grav->fireEvent('onPagesInitialized', new Event(['pages' => $pages])); + if (!isset($grav['page'])) { + $page = new Page(); + $page->routable(false); + $page->title('404 Not Found'); + $grav['page'] = $page; + } } return $this; From 95442ef0b578db37488e0a19c4e4d4a8a86b7b16 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 11 Feb 2020 20:53:02 +0200 Subject: [PATCH 07/10] Fixed page initialization in CLI --- CHANGELOG.md | 3 ++- .../Grav/Common/Service/PagesServiceProvider.php | 13 +++++++++++++ system/src/Grav/Console/ConsoleCommand.php | 6 ------ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2a3996c5..b5517aa37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ * Added `ConsoleCommand::initializeThemes()`method to properly set up current theme to be used from CLI * Added `ConsoleCommand::initializePages()` method to properly set up pages to be used from CLI 1. [](#bugfix) - * Fixed `bin/plugin` CLI calling `$themes->init()` way too early + * Fixed `bin/plugin` CLI calling `$themes->init()` way too early (removed it, use above methods instead) + * Fixed call to `$grav['page']` crashing CLI * Fixed encoding problems when PHP INI setting `default_charset` is not `utf-8` [#2154](https://github.com/getgrav/grav/issues/2154) # v1.6.20 diff --git a/system/src/Grav/Common/Service/PagesServiceProvider.php b/system/src/Grav/Common/Service/PagesServiceProvider.php index 0a37e831d..80142e5bf 100644 --- a/system/src/Grav/Common/Service/PagesServiceProvider.php +++ b/system/src/Grav/Common/Service/PagesServiceProvider.php @@ -26,6 +26,19 @@ public function register(Container $container) return new Pages($c); }; + if (GRAV_CLI) { + $container['page'] = static function ($c) { + $path = $c['locator']->findResource('system://pages/notfound.md'); + $page = new Page(); + $page->init(new \SplFileInfo($path)); + $page->routable(false); + + return $page; + }; + + return; + } + $container['page'] = function ($c) { /** @var Grav $c */ diff --git a/system/src/Grav/Console/ConsoleCommand.php b/system/src/Grav/Console/ConsoleCommand.php index 0f7501478..c0fd9ad42 100644 --- a/system/src/Grav/Console/ConsoleCommand.php +++ b/system/src/Grav/Console/ConsoleCommand.php @@ -171,12 +171,6 @@ final protected function initializePages() $pages = $grav['pages']; $pages->init(); $grav->fireEvent('onPagesInitialized', new Event(['pages' => $pages])); - if (!isset($grav['page'])) { - $page = new Page(); - $page->routable(false); - $page->title('404 Not Found'); - $grav['page'] = $page; - } } return $this; From fa3c9095c7cea6abb328f334b4173dbb42176a76 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 11 Feb 2020 17:09:54 -0700 Subject: [PATCH 08/10] caught silly bug that broke routing --- system/src/Grav/Common/Service/PagesServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Service/PagesServiceProvider.php b/system/src/Grav/Common/Service/PagesServiceProvider.php index 80142e5bf..f425b6d9c 100644 --- a/system/src/Grav/Common/Service/PagesServiceProvider.php +++ b/system/src/Grav/Common/Service/PagesServiceProvider.php @@ -26,7 +26,7 @@ public function register(Container $container) return new Pages($c); }; - if (GRAV_CLI) { + if (\defined('GRAV_CLI')) { $container['page'] = static function ($c) { $path = $c['locator']->findResource('system://pages/notfound.md'); $page = new Page(); From ea5935b1d1a72a972f7f8dfaf4d51175b6df5b46 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 11 Feb 2020 17:15:07 -0700 Subject: [PATCH 09/10] vendor updates --- CHANGELOG.md | 2 ++ composer.lock | 38 ++++++++++++++++++-------------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5517aa37..c17c172ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ * Added `ConsoleCommand::initializePlugins()`method to properly set up all plugins to be used from CLI * Added `ConsoleCommand::initializeThemes()`method to properly set up current theme to be used from CLI * Added `ConsoleCommand::initializePages()` method to properly set up pages to be used from CLI +1. [](#improved) + * Vendor updates 1. [](#bugfix) * Fixed `bin/plugin` CLI calling `$themes->init()` way too early (removed it, use above methods instead) * Fixed call to `$grav['page']` crashing CLI diff --git a/composer.lock b/composer.lock index a500e73f1..1d740434c 100644 --- a/composer.lock +++ b/composer.lock @@ -2518,16 +2518,16 @@ }, { "name": "twig/twig", - "version": "v1.42.4", + "version": "v1.42.5", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "e587180584c3d2d6cb864a0454e777bb6dcb6152" + "reference": "87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/e587180584c3d2d6cb864a0454e777bb6dcb6152", - "reference": "e587180584c3d2d6cb864a0454e777bb6dcb6152", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e", + "reference": "87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e", "shasum": "" }, "require": { @@ -2536,8 +2536,7 @@ }, "require-dev": { "psr/container": "^1.0", - "symfony/debug": "^3.4|^4.2", - "symfony/phpunit-bridge": "^4.4@dev|^5.0" + "symfony/phpunit-bridge": "^4.4|^5.0" }, "type": "library", "extra": { @@ -2566,7 +2565,6 @@ }, { "name": "Twig Team", - "homepage": "https://twig.symfony.com/contributors", "role": "Contributors" }, { @@ -2580,7 +2578,7 @@ "keywords": [ "templating" ], - "time": "2019-11-11T16:49:32+00:00" + "time": "2020-02-11T05:59:23+00:00" }, { "name": "willdurand/negotiation", @@ -3562,16 +3560,16 @@ }, { "name": "nette/php-generator", - "version": "v3.3.3", + "version": "v3.3.4", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "a4ff22c91681fefaa774cf952a2b69c2ec9477c1" + "reference": "8fe7e699dca7db186f56d75800cb1ec32e39c856" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/a4ff22c91681fefaa774cf952a2b69c2ec9477c1", - "reference": "a4ff22c91681fefaa774cf952a2b69c2ec9477c1", + "url": "https://api.github.com/repos/nette/php-generator/zipball/8fe7e699dca7db186f56d75800cb1ec32e39c856", + "reference": "8fe7e699dca7db186f56d75800cb1ec32e39c856", "shasum": "" }, "require": { @@ -3618,7 +3616,7 @@ "php", "scaffolding" ], - "time": "2020-01-20T11:40:42+00:00" + "time": "2020-02-09T14:39:09+00:00" }, { "name": "nette/robot-loader", @@ -3741,16 +3739,16 @@ }, { "name": "nette/utils", - "version": "v3.1.0", + "version": "v3.1.1", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "d6cd63d77dd9a85c3a2fae707e1255e44c2bc182" + "reference": "2c17d16d8887579ae1c0898ff94a3668997fd3eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/d6cd63d77dd9a85c3a2fae707e1255e44c2bc182", - "reference": "d6cd63d77dd9a85c3a2fae707e1255e44c2bc182", + "url": "https://api.github.com/repos/nette/utils/zipball/2c17d16d8887579ae1c0898ff94a3668997fd3eb", + "reference": "2c17d16d8887579ae1c0898ff94a3668997fd3eb", "shasum": "" }, "require": { @@ -3784,8 +3782,8 @@ "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" + "GPL-2.0-only", + "GPL-3.0-only" ], "authors": [ { @@ -3815,7 +3813,7 @@ "utility", "validation" ], - "time": "2020-01-03T18:13:31+00:00" + "time": "2020-02-09T14:10:55+00:00" }, { "name": "nikic/php-parser", From 432b4b1e6857c51ef21f6b28da9502b757a42be6 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 11 Feb 2020 17:17:20 -0700 Subject: [PATCH 10/10] prepare for release --- CHANGELOG.md | 2 +- system/defines.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c17c172ec..bc889c147 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # v1.6.21 -## mm/dd/2020 +## 02/11/2020 1. [](#new) * Added `ConsoleCommand::setLanguage()` method to set language to be used from CLI diff --git a/system/defines.php b/system/defines.php index c472c958b..1dfa66890 100644 --- a/system/defines.php +++ b/system/defines.php @@ -8,7 +8,7 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '1.6.20'); +define('GRAV_VERSION', '1.6.21'); define('GRAV_TESTING', false); define('DS', '/');