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 @@ class Grav extends Container 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 @@ class InitializeProcessor extends ProcessorBase 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 @@ class ConsoleCommand extends Command } /** - * + * 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('');