Ajout des vendor

This commit is contained in:
2022-04-07 13:06:23 +02:00
parent ea47c93aa7
commit 5c116e15b1
1348 changed files with 184572 additions and 1 deletions

14
vendor/symfony/runtime/CHANGELOG.md vendored Normal file
View File

@ -0,0 +1,14 @@
CHANGELOG
=========
5.4
---
* The component is not experimental anymore
* Add options "env_var_name" and "debug_var_name" to `GenericRuntime` and `SymfonyRuntime`
* Add option "dotenv_overload" to `SymfonyRuntime`
5.3.0
-----
* Add the component

View File

@ -0,0 +1,237 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime;
use Symfony\Component\Runtime\Internal\BasicErrorHandler;
use Symfony\Component\Runtime\Resolver\ClosureResolver;
use Symfony\Component\Runtime\Resolver\DebugClosureResolver;
use Symfony\Component\Runtime\Runner\ClosureRunner;
// Help opcache.preload discover always-needed symbols
class_exists(ClosureResolver::class);
/**
* A runtime to do bare-metal PHP without using superglobals.
*
* It supports the following options:
* - "debug" toggles displaying errors and defaults
* to the "APP_DEBUG" environment variable;
* - "runtimes" maps types to a GenericRuntime implementation
* that knows how to deal with each of them;
* - "error_handler" defines the class to use to handle PHP errors;
* - "env_var_name" and "debug_var_name" define the name of the env
* vars that hold the Symfony env and the debug flag respectively.
*
* The app-callable can declare arguments among either:
* - "array $context" to get a local array similar to $_SERVER;
* - "array $argv" to get the command line arguments when running on the CLI;
* - "array $request" to get a local array with keys "query", "body", "files" and
* "session", which map to $_GET, $_POST, $FILES and &$_SESSION respectively.
*
* It should return a Closure():int|string|null or an instance of RunnerInterface.
*
* In debug mode, the runtime registers a strict error handler
* that throws exceptions when a PHP warning/notice is raised.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class GenericRuntime implements RuntimeInterface
{
protected $options;
/**
* @param array {
* debug?: ?bool,
* runtimes?: ?array,
* error_handler?: string|false,
* env_var_name?: string,
* debug_var_name?: string,
* } $options
*/
public function __construct(array $options = [])
{
$options['env_var_name'] ?? $options['env_var_name'] = 'APP_ENV';
$debugKey = $options['debug_var_name'] ?? $options['debug_var_name'] = 'APP_DEBUG';
$debug = $options['debug'] ?? $_SERVER[$debugKey] ?? $_ENV[$debugKey] ?? true;
if (!\is_bool($debug)) {
$debug = filter_var($debug, \FILTER_VALIDATE_BOOLEAN);
}
if ($debug) {
umask(0000);
$_SERVER[$debugKey] = $_ENV[$debugKey] = '1';
if (false !== $errorHandler = ($options['error_handler'] ?? BasicErrorHandler::class)) {
$errorHandler::register($debug);
$options['error_handler'] = false;
}
} else {
$_SERVER[$debugKey] = $_ENV[$debugKey] = '0';
}
$this->options = $options;
}
/**
* {@inheritdoc}
*/
public function getResolver(callable $callable, \ReflectionFunction $reflector = null): ResolverInterface
{
if (!$callable instanceof \Closure) {
$callable = \Closure::fromCallable($callable);
}
$parameters = ($reflector ?? new \ReflectionFunction($callable))->getParameters();
$arguments = function () use ($parameters) {
$arguments = [];
try {
foreach ($parameters as $parameter) {
$type = $parameter->getType();
$arguments[] = $this->getArgument($parameter, $type instanceof \ReflectionNamedType ? $type->getName() : null);
}
} catch (\InvalidArgumentException $e) {
if (!$parameter->isOptional()) {
throw $e;
}
}
return $arguments;
};
if ($_SERVER[$this->options['debug_var_name']]) {
return new DebugClosureResolver($callable, $arguments);
}
return new ClosureResolver($callable, $arguments);
}
/**
* {@inheritdoc}
*/
public function getRunner(?object $application): RunnerInterface
{
if (null === $application) {
$application = static function () { return 0; };
}
if ($application instanceof RunnerInterface) {
return $application;
}
if (!$application instanceof \Closure) {
if ($runtime = $this->resolveRuntime(\get_class($application))) {
return $runtime->getRunner($application);
}
if (!\is_callable($application)) {
throw new \LogicException(sprintf('"%s" doesn\'t know how to handle apps of type "%s".', get_debug_type($this), get_debug_type($application)));
}
$application = \Closure::fromCallable($application);
}
if ($_SERVER[$this->options['debug_var_name']] && ($r = new \ReflectionFunction($application)) && $r->getNumberOfRequiredParameters()) {
throw new \ArgumentCountError(sprintf('Zero argument should be required by the runner callable, but at least one is in "%s" on line "%d.', $r->getFileName(), $r->getStartLine()));
}
return new ClosureRunner($application);
}
/**
* @return mixed
*/
protected function getArgument(\ReflectionParameter $parameter, ?string $type)
{
if ('array' === $type) {
switch ($parameter->name) {
case 'context':
$context = $_SERVER;
if ($_ENV && !isset($_SERVER['PATH']) && !isset($_SERVER['Path'])) {
$context += $_ENV;
}
return $context;
case 'argv':
return $_SERVER['argv'] ?? [];
case 'request':
return [
'query' => $_GET,
'body' => $_POST,
'files' => $_FILES,
'session' => &$_SESSION,
];
}
}
if (RuntimeInterface::class === $type) {
return $this;
}
if (!$runtime = $this->getRuntime($type)) {
$r = $parameter->getDeclaringFunction();
throw new \InvalidArgumentException(sprintf('Cannot resolve argument "%s $%s" in "%s" on line "%d": "%s" supports only arguments "array $context", "array $argv" and "array $request", or a runtime named "Symfony\Runtime\%1$sRuntime".', $type, $parameter->name, $r->getFileName(), $r->getStartLine(), get_debug_type($this)));
}
return $runtime->getArgument($parameter, $type);
}
protected static function register(self $runtime): self
{
return $runtime;
}
private function getRuntime(string $type): ?self
{
if (null === $runtime = ($this->options['runtimes'][$type] ?? null)) {
$runtime = 'Symfony\Runtime\\'.$type.'Runtime';
$runtime = class_exists($runtime) ? $runtime : $this->options['runtimes'][$type] = false;
}
if (\is_string($runtime)) {
$runtime = $runtime::register($this);
}
if ($this === $runtime) {
return null;
}
return $runtime ?: null;
}
private function resolveRuntime(string $class): ?self
{
if ($runtime = $this->getRuntime($class)) {
return $runtime;
}
foreach (class_parents($class) as $type) {
if ($runtime = $this->getRuntime($type)) {
return $runtime;
}
}
foreach (class_implements($class) as $type) {
if ($runtime = $this->getRuntime($type)) {
return $runtime;
}
}
return null;
}
}

View File

@ -0,0 +1,54 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime\Internal;
/**
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
class BasicErrorHandler
{
public static function register(bool $debug): void
{
error_reporting(-1);
if (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
ini_set('display_errors', $debug);
} elseif (!filter_var(ini_get('log_errors'), \FILTER_VALIDATE_BOOLEAN) || ini_get('error_log')) {
// CLI - display errors only if they're not already logged to STDERR
ini_set('display_errors', 1);
}
if (0 <= ini_get('zend.assertions')) {
ini_set('zend.assertions', 1);
ini_set('assert.active', $debug);
ini_set('assert.warning', 0);
ini_set('assert.exception', 1);
}
set_error_handler(new self());
}
public function __invoke(int $type, string $message, string $file, int $line): bool
{
if ((\E_DEPRECATED | \E_USER_DEPRECATED) & $type) {
return true;
}
if ((error_reporting() | \E_ERROR | \E_RECOVERABLE_ERROR | \E_PARSE | \E_CORE_ERROR | \E_COMPILE_ERROR | \E_USER_ERROR) & $type) {
throw new \ErrorException($message, 0, $type, $file, $line);
}
return false;
}
}

View File

@ -0,0 +1,121 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime\Internal;
use Composer\Composer;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\Factory;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
use Composer\Script\ScriptEvents;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Runtime\SymfonyRuntime;
/**
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
class ComposerPlugin implements PluginInterface, EventSubscriberInterface
{
/**
* @var Composer
*/
private $composer;
/**
* @var IOInterface
*/
private $io;
private static $activated = false;
public function activate(Composer $composer, IOInterface $io): void
{
self::$activated = true;
$this->composer = $composer;
$this->io = $io;
}
public function deactivate(Composer $composer, IOInterface $io): void
{
self::$activated = false;
}
public function uninstall(Composer $composer, IOInterface $io): void
{
@unlink($composer->getConfig()->get('vendor-dir').'/autoload_runtime.php');
}
public function updateAutoloadFile(): void
{
$vendorDir = $this->composer->getConfig()->get('vendor-dir');
if (!is_file($autoloadFile = $vendorDir.'/autoload.php')
|| false === $extra = $this->composer->getPackage()->getExtra()['runtime'] ?? []
) {
return;
}
$fs = new Filesystem();
$projectDir = \dirname(realpath(Factory::getComposerFile()));
if (null === $autoloadTemplate = $extra['autoload_template'] ?? null) {
$autoloadTemplate = __DIR__.'/autoload_runtime.template';
} else {
if (!$fs->isAbsolutePath($autoloadTemplate)) {
$autoloadTemplate = $projectDir.'/'.$autoloadTemplate;
}
if (!is_file($autoloadTemplate)) {
throw new \InvalidArgumentException(sprintf('File "%s" defined under "extra.runtime.autoload_template" in your composer.json file not found.', $this->composer->getPackage()->getExtra()['runtime']['autoload_template']));
}
}
$projectDir = $fs->makePathRelative($projectDir, $vendorDir);
$nestingLevel = 0;
while (0 === strpos($projectDir, '../')) {
++$nestingLevel;
$projectDir = substr($projectDir, 3);
}
if (!$nestingLevel) {
$projectDir = '__'.'DIR__.'.var_export('/'.$projectDir, true);
} else {
$projectDir = 'dirname(__'."DIR__, $nestingLevel)".('' !== $projectDir ? '.'.var_export('/'.$projectDir, true) : '');
}
$runtimeClass = $extra['class'] ?? SymfonyRuntime::class;
unset($extra['class'], $extra['autoload_template']);
$code = strtr(file_get_contents($autoloadTemplate), [
'%project_dir%' => $projectDir,
'%runtime_class%' => var_export($runtimeClass, true),
'%runtime_options%' => '['.substr(var_export($extra, true), 7, -1)." 'project_dir' => {$projectDir},\n]",
]);
file_put_contents(substr_replace($autoloadFile, '_runtime', -4, 0), $code);
}
public static function getSubscribedEvents(): array
{
if (!self::$activated) {
return [];
}
return [
ScriptEvents::POST_AUTOLOAD_DUMP => 'updateAutoloadFile',
];
}
}

View File

@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Runtime\Symfony\Component\Console;
use Symfony\Component\Runtime\SymfonyRuntime;
/**
* @internal
*/
class ApplicationRuntime extends SymfonyRuntime
{
}

View File

@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Runtime\Symfony\Component\Console\Command;
use Symfony\Component\Runtime\SymfonyRuntime;
/**
* @internal
*/
class CommandRuntime extends SymfonyRuntime
{
}

View File

@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Runtime\Symfony\Component\Console\Input;
use Symfony\Component\Runtime\SymfonyRuntime;
/**
* @internal
*/
class InputInterfaceRuntime extends SymfonyRuntime
{
}

View File

@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Runtime\Symfony\Component\Console\Output;
use Symfony\Component\Runtime\SymfonyRuntime;
/**
* @internal
*/
class OutputInterfaceRuntime extends SymfonyRuntime
{
}

View File

@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Runtime\Symfony\Component\HttpFoundation;
use Symfony\Component\Runtime\SymfonyRuntime;
/**
* @internal
*/
class RequestRuntime extends SymfonyRuntime
{
}

View File

@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Runtime\Symfony\Component\HttpFoundation;
use Symfony\Component\Runtime\SymfonyRuntime;
/**
* @internal
*/
class ResponseRuntime extends SymfonyRuntime
{
}

View File

@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Runtime\Symfony\Component\HttpKernel;
use Symfony\Component\Runtime\SymfonyRuntime;
/**
* @internal
*/
class HttpKernelInterfaceRuntime extends SymfonyRuntime
{
}

View File

@ -0,0 +1,19 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime\Internal;
/**
* @internal class that should be loaded only when symfony/dotenv is not installed
*/
class MissingDotenv
{
}

View File

@ -0,0 +1,35 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime\Internal;
use Symfony\Component\ErrorHandler\BufferingLogger;
use Symfony\Component\ErrorHandler\DebugClassLoader;
use Symfony\Component\ErrorHandler\ErrorHandler;
/**
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
class SymfonyErrorHandler
{
public static function register(bool $debug): void
{
BasicErrorHandler::register($debug);
if (class_exists(ErrorHandler::class)) {
DebugClassLoader::enable();
restore_error_handler();
ErrorHandler::register(new ErrorHandler(new BufferingLogger(), $debug));
}
}
}

View File

@ -0,0 +1,34 @@
<?php
// autoload_runtime.php @generated by Symfony Runtime
if (true === (require_once __DIR__.'/autoload.php') || empty($_SERVER['SCRIPT_FILENAME'])) {
return;
}
if (PHP_VERSION_ID < 80000 && in_array(PHP_SAPI, ['cli', 'phpdbg'], true)) {
ob_start();
$app = require $_SERVER['SCRIPT_FILENAME'];
ob_end_clean();
} else {
$app = require $_SERVER['SCRIPT_FILENAME'];
}
if (!is_object($app)) {
throw new TypeError(sprintf('Invalid return value: callable object expected, "%s" returned from "%s".', get_debug_type($app), $_SERVER['SCRIPT_FILENAME']));
}
$runtime = $_SERVER['APP_RUNTIME'] ?? $_ENV['APP_RUNTIME'] ?? %runtime_class%;
$runtime = new $runtime(($_SERVER['APP_RUNTIME_OPTIONS'] ?? $_ENV['APP_RUNTIME_OPTIONS'] ?? []) + %runtime_options%);
[$app, $args] = $runtime
->getResolver($app)
->resolve();
$app = $app(...$args);
exit(
$runtime
->getRunner($app)
->run()
);

19
vendor/symfony/runtime/LICENSE vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2021-2022 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

13
vendor/symfony/runtime/README.md vendored Normal file
View File

@ -0,0 +1,13 @@
Runtime Component
=================
Symfony Runtime enables decoupling applications from global state.
Resources
---------
* [Documentation](https://symfony.com/doc/current/components/runtime.html)
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)
in the [main Symfony repository](https://github.com/symfony/symfony)

View File

@ -0,0 +1,37 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime\Resolver;
use Symfony\Component\Runtime\ResolverInterface;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class ClosureResolver implements ResolverInterface
{
private $closure;
private $arguments;
public function __construct(\Closure $closure, \Closure $arguments)
{
$this->closure = $closure;
$this->arguments = $arguments;
}
/**
* {@inheritdoc}
*/
public function resolve(): array
{
return [$this->closure, ($this->arguments)()];
}
}

View File

@ -0,0 +1,39 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime\Resolver;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class DebugClosureResolver extends ClosureResolver
{
/**
* {@inheritdoc}
*/
public function resolve(): array
{
[$closure, $arguments] = parent::resolve();
return [
static function (...$arguments) use ($closure) {
if (\is_object($app = $closure(...$arguments)) || null === $app) {
return $app;
}
$r = new \ReflectionFunction($closure);
throw new \TypeError(sprintf('Unexpected value of type "%s" returned, "object" expected from "%s" on line "%d".', get_debug_type($app), $r->getFileName(), $r->getStartLine()));
},
$arguments,
];
}
}

View File

@ -0,0 +1,23 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
interface ResolverInterface
{
/**
* @return array{0: callable, 1: mixed[]}
*/
public function resolve(): array;
}

View File

@ -0,0 +1,46 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime\Runner;
use Symfony\Component\Runtime\RunnerInterface;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class ClosureRunner implements RunnerInterface
{
private $closure;
public function __construct(\Closure $closure)
{
$this->closure = $closure;
}
public function run(): int
{
$exitStatus = ($this->closure)();
if (\is_string($exitStatus)) {
echo $exitStatus;
return 0;
}
if (null !== $exitStatus && !\is_int($exitStatus)) {
$r = new \ReflectionFunction($this->closure);
throw new \TypeError(sprintf('Unexpected value of type "%s" returned, "string|int|null" expected from "%s" on line "%d".', get_debug_type($exitStatus), $r->getFileName(), $r->getStartLine()));
}
return $exitStatus ?? 0;
}
}

View File

@ -0,0 +1,56 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime\Runner\Symfony;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Runtime\RunnerInterface;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class ConsoleApplicationRunner implements RunnerInterface
{
private $application;
private $defaultEnv;
private $input;
private $output;
public function __construct(Application $application, ?string $defaultEnv, InputInterface $input, OutputInterface $output = null)
{
$this->application = $application;
$this->defaultEnv = $defaultEnv;
$this->input = $input;
$this->output = $output;
}
public function run(): int
{
if (null === $this->defaultEnv) {
return $this->application->run($this->input, $this->output);
}
$definition = $this->application->getDefinition();
if (!$definition->hasOption('env') && !$definition->hasOption('e') && !$definition->hasShortcut('e')) {
$definition->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'The Environment name.', $this->defaultEnv));
}
if (!$definition->hasOption('no-debug')) {
$definition->addOption(new InputOption('--no-debug', null, InputOption::VALUE_NONE, 'Switches off debug mode.'));
}
return $this->application->run($this->input, $this->output);
}
}

View File

@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime\Runner\Symfony;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\TerminableInterface;
use Symfony\Component\Runtime\RunnerInterface;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class HttpKernelRunner implements RunnerInterface
{
private $kernel;
private $request;
public function __construct(HttpKernelInterface $kernel, Request $request)
{
$this->kernel = $kernel;
$this->request = $request;
}
public function run(): int
{
$response = $this->kernel->handle($this->request);
$response->send();
if ($this->kernel instanceof TerminableInterface) {
$this->kernel->terminate($this->request, $response);
}
return 0;
}
}

View File

@ -0,0 +1,35 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime\Runner\Symfony;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Runtime\RunnerInterface;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class ResponseRunner implements RunnerInterface
{
private $response;
public function __construct(Response $response)
{
$this->response = $response;
}
public function run(): int
{
$this->response->send();
return 0;
}
}

View File

@ -0,0 +1,20 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
interface RunnerInterface
{
public function run(): int;
}

View File

@ -0,0 +1,34 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime;
/**
* Enables decoupling applications from global state.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
interface RuntimeInterface
{
/**
* Returns a resolver that should compute the arguments of a callable.
*
* The callable itself should return an object that represents the application to pass to the getRunner() method.
*/
public function getResolver(callable $callable, \ReflectionFunction $reflector = null): ResolverInterface;
/**
* Returns a callable that knows how to run the passed object and that returns its exit status as int.
*
* The passed object is typically created by calling ResolverInterface::resolve().
*/
public function getRunner(?object $application): RunnerInterface;
}

View File

@ -0,0 +1,239 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Runtime;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Runtime\Internal\MissingDotenv;
use Symfony\Component\Runtime\Internal\SymfonyErrorHandler;
use Symfony\Component\Runtime\Runner\Symfony\ConsoleApplicationRunner;
use Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner;
use Symfony\Component\Runtime\Runner\Symfony\ResponseRunner;
// Help opcache.preload discover always-needed symbols
class_exists(MissingDotenv::class, false) || class_exists(Dotenv::class) || class_exists(MissingDotenv::class);
/**
* Knows the basic conventions to run Symfony apps.
*
* In addition to the options managed by GenericRuntime, it accepts the following options:
* - "env" to define the name of the environment the app runs in;
* - "disable_dotenv" to disable looking for .env files;
* - "dotenv_path" to define the path of dot-env files - defaults to ".env";
* - "prod_envs" to define the names of the production envs - defaults to ["prod"];
* - "test_envs" to define the names of the test envs - defaults to ["test"];
* - "use_putenv" to tell Dotenv to set env vars using putenv() (NOT RECOMMENDED.)
* - "dotenv_overload" to tell Dotenv to override existing vars
*
* When the "debug" / "env" options are not defined, they will fallback to the
* "APP_DEBUG" / "APP_ENV" environment variables, and to the "--env|-e" / "--no-debug"
* command line arguments if "symfony/console" is installed.
*
* When the "symfony/dotenv" component is installed, .env files are loaded.
* When "symfony/error-handler" is installed, it is registered in debug mode.
*
* On top of the base arguments provided by GenericRuntime,
* this runtime can feed the app-callable with arguments of type:
* - Request from "symfony/http-foundation" if the component is installed;
* - Application, Command, InputInterface and/or OutputInterface
* from "symfony/console" if the component is installed.
*
* This runtime can handle app-callables that return instances of either:
* - HttpKernelInterface,
* - Response,
* - Application,
* - Command,
* - int|string|null as handled by GenericRuntime.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class SymfonyRuntime extends GenericRuntime
{
private $input;
private $output;
private $console;
private $command;
/**
* @param array {
* debug?: ?bool,
* env?: ?string,
* disable_dotenv?: ?bool,
* project_dir?: ?string,
* prod_envs?: ?string[],
* dotenv_path?: ?string,
* test_envs?: ?string[],
* use_putenv?: ?bool,
* runtimes?: ?array,
* error_handler?: string|false,
* env_var_name?: string,
* debug_var_name?: string,
* dotenv_overload?: ?bool,
* } $options
*/
public function __construct(array $options = [])
{
$envKey = $options['env_var_name'] ?? $options['env_var_name'] = 'APP_ENV';
$debugKey = $options['debug_var_name'] ?? $options['debug_var_name'] = 'APP_DEBUG';
if (isset($options['env'])) {
$_SERVER[$envKey] = $options['env'];
} elseif (isset($_SERVER['argv']) && class_exists(ArgvInput::class)) {
$this->options = $options;
$this->getInput();
}
if (!($options['disable_dotenv'] ?? false) && isset($options['project_dir']) && !class_exists(MissingDotenv::class, false)) {
(new Dotenv($envKey, $debugKey))
->setProdEnvs((array) ($options['prod_envs'] ?? ['prod']))
->usePutenv($options['use_putenv'] ?? false)
->bootEnv($options['project_dir'].'/'.($options['dotenv_path'] ?? '.env'), 'dev', (array) ($options['test_envs'] ?? ['test']), $options['dotenv_overload'] ?? false);
if ($this->input && ($options['dotenv_overload'] ?? false)) {
if ($this->input->getParameterOption(['--env', '-e'], $_SERVER[$envKey], true) !== $_SERVER[$envKey]) {
throw new \LogicException(sprintf('Cannot use "--env" or "-e" when the "%s" file defines "%s" and the "dotenv_overload" runtime option is true.', $options['dotenv_path'] ?? '.env', $envKey));
}
if ($_SERVER[$debugKey] && $this->input->hasParameterOption('--no-debug', true)) {
putenv($debugKey.'='.$_SERVER[$debugKey] = $_ENV[$debugKey] = '0');
}
}
$options['debug'] ?? $options['debug'] = '1' === $_SERVER[$debugKey];
$options['disable_dotenv'] = true;
} else {
$_SERVER[$envKey] ?? $_SERVER[$envKey] = $_ENV[$envKey] ?? 'dev';
$_SERVER[$debugKey] ?? $_SERVER[$debugKey] = $_ENV[$debugKey] ?? !\in_array($_SERVER[$envKey], (array) ($options['prod_envs'] ?? ['prod']), true);
}
$options['error_handler'] ?? $options['error_handler'] = SymfonyErrorHandler::class;
parent::__construct($options);
}
public function getRunner(?object $application): RunnerInterface
{
if ($application instanceof HttpKernelInterface) {
return new HttpKernelRunner($application, Request::createFromGlobals());
}
if ($application instanceof Response) {
return new ResponseRunner($application);
}
if ($application instanceof Command) {
$console = $this->console ?? $this->console = new Application();
$console->setName($application->getName() ?: $console->getName());
if (!$application->getName() || !$console->has($application->getName())) {
$application->setName($_SERVER['argv'][0]);
$console->add($application);
}
$console->setDefaultCommand($application->getName(), true);
$console->getDefinition()->addOptions($application->getDefinition()->getOptions());
return $this->getRunner($console);
}
if ($application instanceof Application) {
if (!\in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true)) {
echo 'Warning: The console should be invoked via the CLI version of PHP, not the '.\PHP_SAPI.' SAPI'.\PHP_EOL;
}
set_time_limit(0);
$defaultEnv = !isset($this->options['env']) ? ($_SERVER[$this->options['env_var_name']] ?? 'dev') : null;
$output = $this->output ?? $this->output = new ConsoleOutput();
return new ConsoleApplicationRunner($application, $defaultEnv, $this->getInput(), $output);
}
if ($this->command) {
$this->getInput()->bind($this->command->getDefinition());
}
return parent::getRunner($application);
}
/**
* @return mixed
*/
protected function getArgument(\ReflectionParameter $parameter, ?string $type)
{
switch ($type) {
case Request::class:
return Request::createFromGlobals();
case InputInterface::class:
return $this->getInput();
case OutputInterface::class:
return $this->output ?? $this->output = new ConsoleOutput();
case Application::class:
return $this->console ?? $this->console = new Application();
case Command::class:
return $this->command ?? $this->command = new Command();
}
return parent::getArgument($parameter, $type);
}
protected static function register(GenericRuntime $runtime): GenericRuntime
{
$self = new self($runtime->options + ['runtimes' => []]);
$self->options['runtimes'] += [
HttpKernelInterface::class => $self,
Request::class => $self,
Response::class => $self,
Application::class => $self,
Command::class => $self,
InputInterface::class => $self,
OutputInterface::class => $self,
];
$runtime->options = $self->options;
return $self;
}
private function getInput(): ArgvInput
{
if (null !== $this->input) {
return $this->input;
}
$input = new ArgvInput();
if (isset($this->options['env'])) {
return $this->input = $input;
}
if (null !== $env = $input->getParameterOption(['--env', '-e'], null, true)) {
putenv($this->options['env_var_name'].'='.$_SERVER[$this->options['env_var_name']] = $_ENV[$this->options['env_var_name']] = $env);
}
if ($input->hasParameterOption('--no-debug', true)) {
putenv($this->options['debug_var_name'].'='.$_SERVER[$this->options['debug_var_name']] = $_ENV[$this->options['debug_var_name']] = '0');
}
return $this->input = $input;
}
}

45
vendor/symfony/runtime/composer.json vendored Normal file
View File

@ -0,0 +1,45 @@
{
"name": "symfony/runtime",
"type": "composer-plugin",
"description": "Enables decoupling PHP applications from global state",
"homepage": "https://symfony.com",
"license" : "MIT",
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"require": {
"php": ">=7.2.5",
"composer-plugin-api": "^1.0|^2.0",
"symfony/polyfill-php80": "^1.15"
},
"require-dev": {
"composer/composer": "^1.0.2|^2.0",
"symfony/console": "^4.4.30|^5.3.7|^6.0",
"symfony/dotenv": "^5.1|^6.0",
"symfony/http-foundation": "^4.4.30|^5.3.7|^6.0",
"symfony/http-kernel": "^4.4.30|^5.3.7|^6.0"
},
"conflict": {
"symfony/dotenv": "<5.1"
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Runtime\\": "",
"Symfony\\Runtime\\Symfony\\Component\\": "Internal/"
},
"exclude-from-classmap": [
"/Tests/"
]
},
"minimum-stability": "dev",
"extra": {
"class": "Symfony\\Component\\Runtime\\Internal\\ComposerPlugin"
}
}