0
0
Fork 0
mirror of https://github.com/getgrav/grav.git synced 2025-03-15 20:54:45 +00:00

Added $grav->setup() to simplify CLI and custom access points

This commit is contained in:
Matias Griese 2018-11-12 12:21:44 +02:00
parent c151043c70
commit 380b3be928
13 changed files with 187 additions and 120 deletions

View file

@ -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

29
bin/gpm
View file

@ -1,26 +1,23 @@
#!/usr/bin/env php
<?php
use Grav\Common\Composer;
use Symfony\Component\Console\Application;
use Grav\Common\Grav;
\define('GRAV_CLI', true);
\define('GRAV_REQUEST_TIME', microtime(true));
if (!file_exists(__DIR__ . '/../vendor')){
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
}
use Grav\Common\Composer;
use Grav\Common\Config\Setup;
if (!file_exists(__DIR__ . '/../vendor')){
if (!file_exists(__DIR__ . '/../vendor/autoload.php')){
// Before we can even start, we need to run composer first
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
$composer = Composer::getComposerExecutor();
echo "Preparing to install vendor dependencies...\n\n";
echo system($composer.' --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install');
echo "\n\n";
}
use Symfony\Component\Console\Application;
use Grav\Common\Grav;
$autoload = require __DIR__ . '/../vendor/autoload.php';
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
@ -31,7 +28,7 @@ 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!');
}
@ -49,15 +46,15 @@ $climate->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(

View file

@ -1,18 +1,17 @@
#!/usr/bin/env php
<?php
use Grav\Common\Composer;
use Grav\Common\Grav;
use Symfony\Component\Console\Application;
\define('GRAV_CLI', true);
\define('GRAV_REQUEST_TIME', microtime(true));
if (!file_exists(__DIR__ . '/../vendor')){
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
}
use Grav\Common\Grav;
use Grav\Common\Composer;
use Symfony\Component\Console\Application;
if (!file_exists(__DIR__ . '/../vendor')){
if (!file_exists(__DIR__ . '/../vendor/autoload.php')){
// Before we can even start, we need to run composer first
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
$composer = Composer::getComposerExecutor();
echo "Preparing to install vendor dependencies...\n\n";
echo system($composer.' --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install');
@ -20,17 +19,18 @@ if (!file_exists(__DIR__ . '/../vendor')){
}
$autoload = require __DIR__ . '/../vendor/autoload.php';
Grav::instance(array('loader' => $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!');
}

View file

@ -1,30 +1,27 @@
#!/usr/bin/env php
<?php
\define('GRAV_CLI', true);
\define('GRAV_REQUEST_TIME', microtime(true));
if (!file_exists(__DIR__ . '/../vendor')) {
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
}
use Grav\Common\Composer;
if (!file_exists(__DIR__ . '/../vendor')) {
// Before we can even start, we need to run composer first
$composer = Composer::getComposerExecutor();
echo "Preparing to install vendor dependencies...\n\n";
echo system($composer . ' --working-dir="' . __DIR__ . '/../" --no-interaction --no-dev --prefer-dist -o install');
echo "\n\n";
}
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Grav\Common\Grav;
use Grav\Common\Config\Setup;
use Grav\Common\Filesystem\Folder;
\define('GRAV_CLI', true);
\define('GRAV_REQUEST_TIME', microtime(true));
if (!file_exists(__DIR__ . '/../vendor/autoload.php')){
// Before we can even start, we need to run composer first
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
$composer = Composer::getComposerExecutor();
echo "Preparing to install vendor dependencies...\n\n";
echo system($composer.' --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install');
echo "\n\n";
}
$autoload = require __DIR__ . '/../vendor/autoload.php';
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
@ -35,7 +32,7 @@ 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!');
}
@ -49,15 +46,14 @@ $climate->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 . '. <red>' . str_pad($entry, 15) . "</red> <white>${bla} ${bin} ${entry} list</white>");
$output->writeln(' ' . $total . '. <red>' . str_pad($entry, 15) . "</red> <white>{$bin} {$entry} list</white>");
}
}

View file

@ -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)]);

View file

@ -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) {

View file

@ -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.

View file

@ -1,31 +0,0 @@
<?php
/**
* @package Grav.Common.Processors
*
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Processors;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class SiteSetupProcessor extends ProcessorBase
{
public $id = '_setup';
public $title = 'Site Setup';
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
{
$this->startTimer();
$this->container['request'];
$this->container['setup']->init();
$this->container['streams'];
$this->stopTimer();
return $handler->handle($request);
}
}

View file

@ -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)

View file

@ -0,0 +1,26 @@
<?php
/**
* @package Grav.Common.Service
*
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Service;
use Grav\Common\Config\Setup;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class SetupServiceProvider implements ServiceProviderInterface
{
public function register(Container $container)
{
$container['setup'] = function (Container $container) {
$setup = new Setup($container);
$setup->init();
return $setup;
};
}
}

View file

@ -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);

View file

@ -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();

View file

@ -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();