diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4d34a009c..2a130268f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
1. [](#new)
* Added `CsvFormatter` and `CsvFile` classes
* Register theme prefixes as namespaces in Twig [#2210](https://github.com/getgrav/grav/pull/2210)
+ * Added `$grav->setup()` to simplify CLI and custom access points
1. [](#improved)
* Support negotiated content types set via the Request `Accept:` header
* Support negotiated language types set via the Request `Accept-Language:` header
@@ -14,6 +15,7 @@
* Fixed `Uri::hasStandardPort()` to support reverse proxy configurations [#1786](https://github.com/getgrav/grav/issues/1786)
* Use `append_url_extension` from page header to set template format if set [#2604](https://github.com/getgrav/grav/pull/2064)
* Remove hardcoded `302` when redirecting trailing slash [#2155](https://github.com/getgrav/grav/pull/2155)
+ * Fixed some bugs in environment selection
# v1.6.0-beta.5
## 11/05/2018
diff --git a/bin/gpm b/bin/gpm
index e8eff5a00..d17d73428 100755
--- a/bin/gpm
+++ b/bin/gpm
@@ -1,26 +1,23 @@
#!/usr/bin/env php
arguments->add([
]
]);
$climate->arguments->parse();
-$environment = $climate->arguments->get('environment');
// Set up environment based on params.
-Setup::$environment = $environment;
+$environment = $climate->arguments->get('environment');
$grav = Grav::instance(array('loader' => $autoload));
-$grav['uri']->init();
+$grav->setup($environment);
+
$grav['config']->init();
-$grav['streams'];
+$grav['uri']->init();
$app = new Application('Grav Package Manager', GRAV_VERSION);
$app->addCommands(array(
diff --git a/bin/grav b/bin/grav
index d68be7c04..4fef12faf 100755
--- a/bin/grav
+++ b/bin/grav
@@ -1,18 +1,17 @@
#!/usr/bin/env php
$autoload));
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));
}
+Grav::instance(array('loader' => $autoload));
+
if (!ini_get('date.timezone')) {
date_default_timezone_set('UTC');
}
-if (!file_exists(ROOT_DIR . 'index.php')) {
+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 9cb75666f..f1fb775c7 100755
--- a/bin/plugin
+++ b/bin/plugin
@@ -1,30 +1,27 @@
#!/usr/bin/env php
arguments->add([
]
]);
$climate->arguments->parse();
+
$environment = $climate->arguments->get('environment');
-// Set up environment based on params.
-Setup::$environment = $environment;
-
$grav = Grav::instance(array('loader' => $autoload));
-$grav['uri']->init();
+$grav->setup($environment);
+
$grav['config']->init();
-$grav['streams'];
+$grav['uri']->init();
$grav['plugins']->init();
$grav['themes']->init();
@@ -101,14 +97,14 @@ if (!$name) {
$entry = array_shift($split);
$index = str_pad($index++ + 1, 2, '0', STR_PAD_LEFT);
$total = str_pad($total++ + 1, 2, '0', STR_PAD_LEFT);
- if (in_array($entry, $available)) {
- $total -= 1;
+ if (\in_array($entry, $available, true)) {
+ $total--;
continue;
}
$available[] = $entry;
$commands_count = $index - $total + 1;
- $output->writeln(' ' . $total . '. ' . str_pad($entry, 15) . " ${bla} ${bin} ${entry} list");
+ $output->writeln(' ' . $total . '. ' . str_pad($entry, 15) . " {$bin} {$entry} list");
}
}
diff --git a/system/src/Grav/Common/Config/Setup.php b/system/src/Grav/Common/Config/Setup.php
index 5b3b4226c..d67541716 100644
--- a/system/src/Grav/Common/Config/Setup.php
+++ b/system/src/Grav/Common/Config/Setup.php
@@ -11,12 +11,24 @@ namespace Grav\Common\Config;
use Grav\Common\File\CompiledYamlFile;
use Grav\Common\Data\Data;
use Grav\Common\Utils;
+use Grav\Framework\Psr7\ServerRequest;
use Pimple\Container;
-use RocketTheme\Toolbox\File\YamlFile;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
class Setup extends Data
{
+ /**
+ * @var array Environment aliases normalized to lower case.
+ */
+ public static $environments = [
+ '' => 'unknown',
+ '127.0.0.1' => 'localhost',
+ '::1' => 'localhost'
+ ];
+
+ /**
+ * @var string Current environment normalized to lower case.
+ */
public static $environment;
protected $streams = [
@@ -133,11 +145,25 @@ class Setup extends Data
*/
public function __construct($container)
{
- $environment = static::$environment ?? $container['uri']->environment() ?: 'localhost';
+ // If no environment is set, make sure we get one (CLI or hostname).
+ if (!static::$environment) {
+ if (\defined('GRAV_CLI')) {
+ static::$environment = 'cli';
+ } else {
+ /** @var ServerRequest $request */
+ $request = $container['request'];
+ $host = $request->getUri()->getHost();
+
+ static::$environment = $host;
+ }
+ }
+
+ // Resolve server aliases to the proper environment.
+ $environment = $this->environments[static::$environment] ?? static::$environment;
// Pre-load setup.php which contains our initial configuration.
// Configuration may contain dynamic parts, which is why we need to always load it.
- // If "GRAVE_SETUP_PATH" has been defined, use it, otherwise use defaults.
+ // If "GRAV_SETUP_PATH" has been defined, use it, otherwise use defaults.
$file = \defined('GRAV_SETUP_PATH') ? GRAV_SETUP_PATH : GRAV_ROOT . '/setup.php';
$setup = is_file($file) ? (array) include $file : [];
@@ -151,8 +177,8 @@ class Setup extends Data
parent::__construct($setup);
// Set up environment.
- $this->def('environment', $environment ?: 'cli');
- $this->def('streams.schemes.environment.prefixes', ['' => $environment ? ["user://{$environment}"] : []]);
+ $this->def('environment', $environment);
+ $this->def('streams.schemes.environment.prefixes', ['' => ["user://{$this->get('environment')}"]]);
}
/**
@@ -272,7 +298,7 @@ class Setup extends Data
// Create security.yaml if it doesn't exist.
$filename = $locator->findResource('config://security.yaml', true, true);
$security_file = CompiledYamlFile::instance($filename);
- $security_content = $security_file->content();
+ $security_content = (array)$security_file->content();
if (!isset($security_content['salt'])) {
$security_content = array_merge($security_content, ['salt' => Utils::generateRandomString(14)]);
diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php
index fafe29a67..a67e4e43b 100644
--- a/system/src/Grav/Common/Grav.php
+++ b/system/src/Grav/Common/Grav.php
@@ -9,6 +9,7 @@
namespace Grav\Common;
use Grav\Common\Config\Config;
+use Grav\Common\Config\Setup;
use Grav\Common\Page\Medium\ImageMedium;
use Grav\Common\Page\Medium\Medium;
use Grav\Common\Page\Page;
@@ -25,7 +26,6 @@ use Grav\Common\Processors\PluginsProcessor;
use Grav\Common\Processors\RenderProcessor;
use Grav\Common\Processors\RequestProcessor;
use Grav\Common\Processors\SchedulerProcessor;
-use Grav\Common\Processors\SiteSetupProcessor;
use Grav\Common\Processors\TasksProcessor;
use Grav\Common\Processors\ThemesProcessor;
use Grav\Common\Processors\TwigProcessor;
@@ -64,6 +64,7 @@ class Grav extends Container
'Grav\Common\Service\PageServiceProvider',
'Grav\Common\Service\RequestServiceProvider',
'Grav\Common\Service\SessionServiceProvider',
+ 'Grav\Common\Service\SetupServiceProvider',
'Grav\Common\Service\StreamsServiceProvider',
'Grav\Common\Service\TaskServiceProvider',
'browser' => 'Grav\Common\Browser',
@@ -85,7 +86,6 @@ class Grav extends Container
* @var array All middleware processors that are processed in $this->process()
*/
protected $middleware = [
- 'siteSetupProcessor',
'configurationProcessor',
'loggerProcessor',
'errorsProcessor',
@@ -104,6 +104,8 @@ class Grav extends Container
'renderProcessor',
];
+ protected $initialized = [];
+
/**
* Reset the Grav instance.
*/
@@ -135,16 +137,51 @@ class Grav extends Container
return self::$instance;
}
+ /**
+ * Setup Grav instance using specific environment.
+ *
+ * Initializes Grav streams by
+ *
+ * @param string|null $environment
+ * @return $this
+ */
+ public function setup(string $environment = null)
+ {
+ if (isset($this->initialized['setup'])) {
+ return $this;
+ }
+
+ $this->initialized['setup'] = true;
+
+ $this->measureTime('_setup', 'Site Setup', function () use ($environment) {
+ // Force environment if passed to the method.
+ if ($environment) {
+ Setup::$environment = $environment;
+ }
+
+ $this['setup'];
+ $this['streams'];
+ });
+
+ return $this;
+ }
+
/**
* Process a request
*/
public function process()
{
+ if (isset($this->initialized['process'])) {
+ return;
+ }
+
+ // Initialize Grav if needed.
+ $this->setup();
+
+ $this->initialized['process'] = true;
+
$container = new Container(
[
- 'siteSetupProcessor' => function () {
- return new SiteSetupProcessor($this);
- },
'configurationProcessor' => function () {
return new ConfigurationProcessor($this);
},
@@ -382,7 +419,9 @@ class Grav extends Container
/**
* Magic Catch All Function
- * Used to call closures like measureTime on the instance.
+ *
+ * Used to call closures.
+ *
* Source: http://stackoverflow.com/questions/419804/closures-as-class-members
*/
public function __call($method, $args)
@@ -391,6 +430,24 @@ class Grav extends Container
\call_user_func_array($closure, $args);
}
+ /**
+ * Measure how long it takes to do an action.
+ *
+ * @param string $timerId
+ * @param string $timerTitle
+ * @param callable $callback
+ * @return mixed Returns value returned by the callable.
+ */
+ public function measureTime(string $timerId, string $timerTitle, callable $callback)
+ {
+ $debugger = $this['debugger'];
+ $debugger->startTimer($timerId, $timerTitle);
+ $result = $callback();
+ $debugger->stopTimer($timerId);
+
+ return $result;
+ }
+
/**
* Initialize and return a Grav instance
*
@@ -402,18 +459,11 @@ class Grav extends Container
{
$container = new static($values);
- $container['grav'] = $container;
-
$container['debugger'] = new Debugger();
- $debugger = $container['debugger'];
+ $container['grav'] = function (Container $container) {
+ user_error('Calling $grav[\'grav\'] or {{ grav.grav }} is deprecated since Grav 1.6, just use $grav or {{ grav }}', E_USER_DEPRECATED);
- // closure that measures time by wrapping a function into startTimer and stopTimer
- // The debugger can be passed to the closure. Should be more performant
- // then to get it from the container all time.
- $container->measureTime = function ($timerId, $timerTitle, $callback) use ($debugger) {
- $debugger->startTimer($timerId, $timerTitle);
- $callback();
- $debugger->stopTimer($timerId);
+ return $container;
};
$container->measureTime('_services', 'Services', function () use ($container) {
diff --git a/system/src/Grav/Common/Processors/InitializeProcessor.php b/system/src/Grav/Common/Processors/InitializeProcessor.php
index 64863d71d..9cf7321f1 100644
--- a/system/src/Grav/Common/Processors/InitializeProcessor.php
+++ b/system/src/Grav/Common/Processors/InitializeProcessor.php
@@ -37,8 +37,9 @@ class InitializeProcessor extends ProcessorBase
}
// Initialize the timezone.
- if ($config->get('system.timezone')) {
- date_default_timezone_set($this->container['config']->get('system.timezone'));
+ $timezone = $config->get('system.timezone');
+ if ($timezone) {
+ date_default_timezone_set($timezone);
}
// FIXME: Initialize session should happen later after plugins have been loaded. This is a workaround to fix session issues in AWS.
diff --git a/system/src/Grav/Common/Processors/SiteSetupProcessor.php b/system/src/Grav/Common/Processors/SiteSetupProcessor.php
deleted file mode 100644
index 4e32a5632..000000000
--- a/system/src/Grav/Common/Processors/SiteSetupProcessor.php
+++ /dev/null
@@ -1,31 +0,0 @@
-startTimer();
- $this->container['request'];
- $this->container['setup']->init();
- $this->container['streams'];
- $this->stopTimer();
-
- return $handler->handle($request);
- }
-}
diff --git a/system/src/Grav/Common/Service/ConfigServiceProvider.php b/system/src/Grav/Common/Service/ConfigServiceProvider.php
index 379c042e7..54e31f4f2 100644
--- a/system/src/Grav/Common/Service/ConfigServiceProvider.php
+++ b/system/src/Grav/Common/Service/ConfigServiceProvider.php
@@ -93,12 +93,15 @@ class ConfigServiceProvider implements ServiceProviderInterface
$paths = $locator->findResources('plugins://');
$files += (new ConfigFileFinder)->setBase('plugins')->locateInFolders($paths);
- $config = new CompiledConfig($cache, $files, GRAV_ROOT);
- $config->setBlueprints(function() use ($container) {
+ $compiled = new CompiledConfig($cache, $files, GRAV_ROOT);
+ $compiled->setBlueprints(function() use ($container) {
return $container['blueprints'];
});
- return $config->name("master-{$setup->environment}")->load();
+ $config = $compiled->name("master-{$setup->environment}")->load();
+ $config->environment = $setup->environment;
+
+ return $config;
}
public static function languages(Container $container)
diff --git a/system/src/Grav/Common/Service/SetupServiceProvider.php b/system/src/Grav/Common/Service/SetupServiceProvider.php
new file mode 100644
index 000000000..37180f783
--- /dev/null
+++ b/system/src/Grav/Common/Service/SetupServiceProvider.php
@@ -0,0 +1,26 @@
+init();
+
+ return $setup;
+ };
+ }
+}
diff --git a/system/src/Grav/Common/Service/StreamsServiceProvider.php b/system/src/Grav/Common/Service/StreamsServiceProvider.php
index a2ebcc671..bfd826919 100644
--- a/system/src/Grav/Common/Service/StreamsServiceProvider.php
+++ b/system/src/Grav/Common/Service/StreamsServiceProvider.php
@@ -20,22 +20,22 @@ class StreamsServiceProvider implements ServiceProviderInterface
{
public function register(Container $container)
{
- $container['locator'] = function($c) {
+ $container['locator'] = function(Container $container) {
$locator = new UniformResourceLocator(GRAV_ROOT);
/** @var Setup $setup */
- $setup = $c['setup'];
+ $setup = $container['setup'];
$setup->initializeLocator($locator);
return $locator;
};
- $container['streams'] = function($c) {
+ $container['streams'] = function(Container $container) {
/** @var Setup $setup */
- $setup = $c['setup'];
+ $setup = $container['setup'];
/** @var UniformResourceLocator $locator */
- $locator = $c['locator'];
+ $locator = $container['locator'];
// Set locator to both streams.
Stream::setLocator($locator);
diff --git a/system/src/Grav/Console/Cli/SchedulerCommand.php b/system/src/Grav/Console/Cli/SchedulerCommand.php
index b75fb1bf5..e115eb04a 100644
--- a/system/src/Grav/Console/Cli/SchedulerCommand.php
+++ b/system/src/Grav/Console/Cli/SchedulerCommand.php
@@ -53,10 +53,10 @@ class SchedulerCommand extends ConsoleCommand
{
// error_reporting(1);
$grav = Grav::instance();
+ $grav->setup();
$grav['uri']->init();
$grav['config']->init();
- $grav['streams'];
$grav['plugins']->init();
$grav['themes']->init();
$grav['backups']->init();
diff --git a/system/src/Grav/Console/Cli/SecurityCommand.php b/system/src/Grav/Console/Cli/SecurityCommand.php
index 8e8cf6313..81e3020a7 100644
--- a/system/src/Grav/Console/Cli/SecurityCommand.php
+++ b/system/src/Grav/Console/Cli/SecurityCommand.php
@@ -38,19 +38,16 @@ class SecurityCommand extends ConsoleCommand
*/
protected function serve()
{
-
-
/** @var Grav $grav */
$grav = Grav::instance();
+ $grav->setup();
$grav['uri']->init();
$grav['config']->init();
$grav['debugger']->enabled(false);
- $grav['streams'];
$grav['plugins']->init();
$grav['themes']->init();
-
$grav['twig']->init();
$grav['pages']->init();