SymfonyExtension v2.0: proof of concept
This commit is contained in:
@@ -11,26 +11,32 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.1",
|
"php": "^7.1",
|
||||||
|
|
||||||
"behat/behat": "^3.4",
|
"behat/behat": "^3.4",
|
||||||
|
"symfony/dotenv": "^3.4|^4.1",
|
||||||
"symfony/http-kernel": "^3.4|^4.1",
|
"symfony/http-kernel": "^3.4|^4.1",
|
||||||
"symfony/dotenv": "^3.4|^4.1"
|
"symfony/proxy-manager-bridge": "^3.4|^4.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"behat/mink": "^1.7",
|
"behat/mink": "^1.7",
|
||||||
"behat/mink-browserkit-driver": "^1.3",
|
"behat/mink-browserkit-driver": "^1.3",
|
||||||
"behat/mink-extension": "^2.2",
|
"behat/mink-extension": "^2.2",
|
||||||
"friends-of-behat/cross-container-extension": "^1.0",
|
|
||||||
"friends-of-behat/test-context": "^1.0",
|
"friends-of-behat/test-context": "^1.0",
|
||||||
"phpstan/phpstan-shim": "^0.10",
|
"phpstan/phpstan-shim": "^0.10",
|
||||||
"sylius-labs/coding-standard": "^3.0",
|
"sylius-labs/coding-standard": "^3.0",
|
||||||
"symfony/framework-bundle": "^3.4|^4.1"
|
"symfony/framework-bundle": "^3.4|^4.1"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"behat/mink-browserkit-driver": "^1.3",
|
"behat/mink-browserkit-driver": "^1.3"
|
||||||
"friends-of-behat/cross-container-extension": "^1.0"
|
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": { "FriendsOfBehat\\SymfonyExtension\\": "src/" }
|
"psr-4": { "FriendsOfBehat\\SymfonyExtension\\": "src/" }
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"sort-packages": true
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "2.0-dev"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ Feature: Not crashing Behat
|
|||||||
extensions:
|
extensions:
|
||||||
FriendsOfBehat\SymfonyExtension:
|
FriendsOfBehat\SymfonyExtension:
|
||||||
kernel:
|
kernel:
|
||||||
bootstrap: app/autoload.php
|
|
||||||
path: app/MyKernel.php
|
path: app/MyKernel.php
|
||||||
class: MyKernel
|
class: MyKernel
|
||||||
env: test
|
env: test
|
||||||
@@ -108,7 +107,6 @@ Feature: Not crashing Behat
|
|||||||
kernel:
|
kernel:
|
||||||
path: src/MyKernel.php
|
path: src/MyKernel.php
|
||||||
class: MyKernel
|
class: MyKernel
|
||||||
bootstrap: ~
|
|
||||||
"""
|
"""
|
||||||
And a file "../config/.env_in_memory" containing:
|
And a file "../config/.env_in_memory" containing:
|
||||||
"""
|
"""
|
||||||
@@ -139,7 +137,6 @@ Feature: Not crashing Behat
|
|||||||
FriendsOfBehat\SymfonyExtension:
|
FriendsOfBehat\SymfonyExtension:
|
||||||
env_file: .env_in_memory
|
env_file: .env_in_memory
|
||||||
kernel:
|
kernel:
|
||||||
bootstrap: ~
|
|
||||||
path: src/MyKernel.php
|
path: src/MyKernel.php
|
||||||
class: MyKernel
|
class: MyKernel
|
||||||
env: dev
|
env: dev
|
||||||
@@ -165,33 +162,3 @@ Feature: Not crashing Behat
|
|||||||
And a feature file with passing scenario
|
And a feature file with passing scenario
|
||||||
When I run Behat
|
When I run Behat
|
||||||
Then it should pass
|
Then it should pass
|
||||||
|
|
||||||
Scenario: Not crashing Behat with CrossContainerExtension
|
|
||||||
Given a Behat configuration containing:
|
|
||||||
"""
|
|
||||||
default:
|
|
||||||
extensions:
|
|
||||||
FriendsOfBehat\SymfonyExtension: ~
|
|
||||||
FriendsOfBehat\CrossContainerExtension: ~
|
|
||||||
"""
|
|
||||||
And a file "app/autoload.php" containing:
|
|
||||||
"""
|
|
||||||
<?php
|
|
||||||
|
|
||||||
"""
|
|
||||||
And a file "app/AppKernel.php" containing:
|
|
||||||
"""
|
|
||||||
<?php
|
|
||||||
|
|
||||||
use Symfony\Component\HttpKernel\Kernel;
|
|
||||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
|
||||||
|
|
||||||
class AppKernel extends Kernel
|
|
||||||
{
|
|
||||||
public function registerBundles() { return []; }
|
|
||||||
public function registerContainerConfiguration(LoaderInterface $loader) {}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
And a feature file with passing scenario
|
|
||||||
When I run Behat
|
|
||||||
Then it should pass
|
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FriendsOfBehat\SymfonyExtension\Bundle\DependencyInjection;
|
||||||
|
|
||||||
|
use Behat\Behat\Context\Context;
|
||||||
|
use Behat\Mink\Mink;
|
||||||
|
use Behat\Mink\Session;
|
||||||
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
|
||||||
|
|
||||||
|
final class FriendsOfBehatSymfonyExtensionExtension extends Extension implements CompilerPassInterface
|
||||||
|
{
|
||||||
|
public function load(array $configs, ContainerBuilder $container): void
|
||||||
|
{
|
||||||
|
$this->registerBehatContainer($container);
|
||||||
|
$this->provideMinkIntegration($container);
|
||||||
|
|
||||||
|
$container
|
||||||
|
->registerForAutoconfiguration(Context::class)
|
||||||
|
->addTag('fob.context')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function process(ContainerBuilder $container): void
|
||||||
|
{
|
||||||
|
foreach ($container->findTaggedServiceIds('fob.context') as $serviceId => $attributes) {
|
||||||
|
$container->findDefinition($serviceId)->setPublic(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function registerBehatContainer(ContainerBuilder $container): void
|
||||||
|
{
|
||||||
|
$behatServiceContainerDefinition = new Definition(ContainerInterface::class);
|
||||||
|
$behatServiceContainerDefinition->setPublic(true);
|
||||||
|
$behatServiceContainerDefinition->setSynthetic(true);
|
||||||
|
|
||||||
|
$container->setDefinition('behat.service_container', $behatServiceContainerDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function provideMinkIntegration(ContainerBuilder $container): void
|
||||||
|
{
|
||||||
|
$minkDefinition = new Definition(Mink::class, ['mink']);
|
||||||
|
$minkDefinition->setPublic(true);
|
||||||
|
$minkDefinition->setFactory([new Reference('behat.service_container'), 'get']);
|
||||||
|
|
||||||
|
$container->setDefinition('behat.mink', $minkDefinition);
|
||||||
|
|
||||||
|
$minkDefaultSessionDefinition = new Definition(Session::class);
|
||||||
|
$minkDefaultSessionDefinition->setPublic(true);
|
||||||
|
$minkDefaultSessionDefinition->setLazy(true);
|
||||||
|
$minkDefaultSessionDefinition->setFactory([new Reference('behat.mink'), 'getSession']);
|
||||||
|
|
||||||
|
$container->setDefinition('behat.mink.default_session', $minkDefaultSessionDefinition);
|
||||||
|
$container->setAlias(Session::class, 'behat.mink.default_session');
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/Bundle/FriendsOfBehatSymfonyExtensionBundle.php
Normal file
11
src/Bundle/FriendsOfBehatSymfonyExtensionBundle.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FriendsOfBehat\SymfonyExtension\Bundle;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||||
|
|
||||||
|
final class FriendsOfBehatSymfonyExtensionBundle extends Bundle
|
||||||
|
{
|
||||||
|
}
|
||||||
24
src/Context/Environment/ContextServiceEnvironment.php
Normal file
24
src/Context/Environment/ContextServiceEnvironment.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the SymfonyExtension package.
|
||||||
|
*
|
||||||
|
* (c) Kamil Kokot <kamil@kokot.me>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FriendsOfBehat\SymfonyExtension\Context\Environment;
|
||||||
|
|
||||||
|
use Behat\Behat\Context\Environment\ContextEnvironment;
|
||||||
|
use FriendsOfBehat\SymfonyExtension\Context\Environment\Handler\ContextServiceEnvironmentHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ContextServiceEnvironmentHandler
|
||||||
|
*/
|
||||||
|
interface ContextServiceEnvironment extends ContextEnvironment
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the SymfonyExtension package.
|
||||||
|
*
|
||||||
|
* (c) Kamil Kokot <kamil@kokot.me>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FriendsOfBehat\SymfonyExtension\Context\Environment\Handler;
|
||||||
|
|
||||||
|
use Behat\Behat\Context\Context;
|
||||||
|
use Behat\Behat\Context\Initializer\ContextInitializer;
|
||||||
|
use Behat\Testwork\Environment\Environment;
|
||||||
|
use Behat\Testwork\Environment\Exception\EnvironmentIsolationException;
|
||||||
|
use Behat\Testwork\Environment\Handler\EnvironmentHandler;
|
||||||
|
use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
|
||||||
|
use Behat\Testwork\Suite\Suite;
|
||||||
|
use FriendsOfBehat\SymfonyExtension\Context\Environment\InitialisedContextServiceEnvironment;
|
||||||
|
use FriendsOfBehat\SymfonyExtension\Context\Environment\UninitialisedContextServiceEnvironment;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
|
use Symfony\Component\HttpKernel\KernelInterface;
|
||||||
|
|
||||||
|
final class ContextServiceEnvironmentHandler implements EnvironmentHandler
|
||||||
|
{
|
||||||
|
/** @var KernelInterface */
|
||||||
|
private $symfonyKernel;
|
||||||
|
|
||||||
|
/** @var ContextInitializer[] */
|
||||||
|
private $contextInitializers = [];
|
||||||
|
|
||||||
|
public function __construct(KernelInterface $symfonyKernel)
|
||||||
|
{
|
||||||
|
$this->symfonyKernel = $symfonyKernel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsSuite(Suite $suite): bool
|
||||||
|
{
|
||||||
|
return $suite->hasSetting('contexts');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildEnvironment(Suite $suite): Environment
|
||||||
|
{
|
||||||
|
$environment = new UninitialisedContextServiceEnvironment($suite);
|
||||||
|
foreach ($this->getSuiteContextsServices($suite) as $contextId) {
|
||||||
|
$environment->registerContextService($contextId, $this->getContextClass($contextId));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsEnvironmentAndSubject(Environment $environment, $testSubject = null): bool
|
||||||
|
{
|
||||||
|
return $environment instanceof UninitialisedContextServiceEnvironment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws EnvironmentIsolationException
|
||||||
|
*/
|
||||||
|
public function isolateEnvironment(Environment $uninitializedEnvironment, $testSubject = null): Environment
|
||||||
|
{
|
||||||
|
/** @var UninitialisedContextServiceEnvironment $uninitializedEnvironment */
|
||||||
|
$this->assertEnvironmentCanBeIsolated($uninitializedEnvironment, $testSubject);
|
||||||
|
|
||||||
|
$environment = new InitialisedContextServiceEnvironment($uninitializedEnvironment->getSuite());
|
||||||
|
foreach ($uninitializedEnvironment->getContextServices() as $contextId) {
|
||||||
|
/** @var Context $context */
|
||||||
|
$context = $this->getContext($contextId);
|
||||||
|
$this->initializeInstance($context);
|
||||||
|
$environment->registerContext($context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerContextInitializer(ContextInitializer $initializer): void
|
||||||
|
{
|
||||||
|
$this->contextInitializers[] = $initializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*
|
||||||
|
* @throws SuiteConfigurationException If "contexts" setting is not an array
|
||||||
|
*/
|
||||||
|
private function getSuiteContextsServices(Suite $suite): array
|
||||||
|
{
|
||||||
|
$contextsServices = $suite->getSetting('contexts');
|
||||||
|
|
||||||
|
if (!is_array($contextsServices)) {
|
||||||
|
throw new SuiteConfigurationException(sprintf(
|
||||||
|
'"contexts" setting of the "%s" suite is expected to be an array, %s given.',
|
||||||
|
$suite->getName(),
|
||||||
|
gettype($contextsServices)
|
||||||
|
), $suite->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $contextsServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws EnvironmentIsolationException
|
||||||
|
*/
|
||||||
|
private function assertEnvironmentCanBeIsolated(Environment $uninitializedEnvironment, $testSubject): void
|
||||||
|
{
|
||||||
|
if (!$this->supportsEnvironmentAndSubject($uninitializedEnvironment, $testSubject)) {
|
||||||
|
throw new EnvironmentIsolationException(sprintf(
|
||||||
|
'"%s" does not support isolation of "%s" environment.',
|
||||||
|
static::class,
|
||||||
|
get_class($uninitializedEnvironment)
|
||||||
|
), $uninitializedEnvironment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function initializeInstance(Context $context): void
|
||||||
|
{
|
||||||
|
foreach ($this->contextInitializers as $initializer) {
|
||||||
|
$initializer->initializeContext($context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getContextClass(string $contextId): string
|
||||||
|
{
|
||||||
|
if ($this->getContainer()->has($contextId)) {
|
||||||
|
return get_class($this->getContainer()->get($contextId));
|
||||||
|
}
|
||||||
|
|
||||||
|
$class = '\\' . ltrim($contextId, '\\');
|
||||||
|
|
||||||
|
if (class_exists($class)) {
|
||||||
|
return $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \Exception('wtf?');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getContext(string $contextId): Context
|
||||||
|
{
|
||||||
|
if ($this->getContainer()->has($contextId)) {
|
||||||
|
return $this->getContainer()->get($contextId);
|
||||||
|
}
|
||||||
|
|
||||||
|
$class = '\\' . ltrim($contextId, '\\');
|
||||||
|
|
||||||
|
if (class_exists($class)) {
|
||||||
|
return new $class();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \Exception('wtf?');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getContainer(): ContainerInterface
|
||||||
|
{
|
||||||
|
return $this->symfonyKernel->getContainer();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the SymfonyExtension package.
|
||||||
|
*
|
||||||
|
* (c) Kamil Kokot <kamil@kokot.me>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FriendsOfBehat\SymfonyExtension\Context\Environment;
|
||||||
|
|
||||||
|
use Behat\Behat\Context\Context;
|
||||||
|
use Behat\Behat\Context\Exception\ContextNotFoundException;
|
||||||
|
use Behat\Testwork\Call\Callee;
|
||||||
|
use Behat\Testwork\Suite\Suite;
|
||||||
|
use FriendsOfBehat\SymfonyExtension\Context\Environment\Handler\ContextServiceEnvironmentHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ContextServiceEnvironmentHandler
|
||||||
|
*/
|
||||||
|
final class InitialisedContextServiceEnvironment implements ContextServiceEnvironment
|
||||||
|
{
|
||||||
|
/** @var Suite */
|
||||||
|
private $suite;
|
||||||
|
|
||||||
|
/** @var Context[] */
|
||||||
|
private $contexts = [];
|
||||||
|
|
||||||
|
public function __construct(Suite $suite)
|
||||||
|
{
|
||||||
|
$this->suite = $suite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerContext(Context $context): void
|
||||||
|
{
|
||||||
|
$this->contexts[get_class($context)] = $context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSuite(): Suite
|
||||||
|
{
|
||||||
|
return $this->suite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function bindCallee(Callee $callee): callable
|
||||||
|
{
|
||||||
|
$callable = $callee->getCallable();
|
||||||
|
|
||||||
|
if ($callee->isAnInstanceMethod()) {
|
||||||
|
return [$this->getContext($callable[0]), $callable[1]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasContexts(): bool
|
||||||
|
{
|
||||||
|
return count($this->contexts) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContextClasses(): array
|
||||||
|
{
|
||||||
|
return array_keys($this->contexts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasContextClass($class): bool
|
||||||
|
{
|
||||||
|
return isset($this->contexts[$class]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ContextNotFoundException
|
||||||
|
*/
|
||||||
|
private function getContext(string $class): Context
|
||||||
|
{
|
||||||
|
if (!isset($this->contexts[$class])) {
|
||||||
|
throw new ContextNotFoundException(sprintf(
|
||||||
|
'`%s` context is not found in the suite environment. Have you registered it?',
|
||||||
|
$class
|
||||||
|
), $class);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->contexts[$class];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the SymfonyExtension package.
|
||||||
|
*
|
||||||
|
* (c) Kamil Kokot <kamil@kokot.me>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FriendsOfBehat\SymfonyExtension\Context\Environment;
|
||||||
|
|
||||||
|
use Behat\Testwork\Environment\StaticEnvironment;
|
||||||
|
use FriendsOfBehat\SymfonyExtension\Context\Environment\Handler\ContextServiceEnvironmentHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ContextServiceEnvironmentHandler
|
||||||
|
*/
|
||||||
|
final class UninitialisedContextServiceEnvironment extends StaticEnvironment implements ContextServiceEnvironment
|
||||||
|
{
|
||||||
|
/** @var string[] */
|
||||||
|
private $contextServices = [];
|
||||||
|
|
||||||
|
public function registerContextService(string $serviceId, string $serviceClass): void
|
||||||
|
{
|
||||||
|
$this->contextServices[$serviceId] = $serviceClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContextServices(): array
|
||||||
|
{
|
||||||
|
return array_keys($this->contextServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasContexts(): bool
|
||||||
|
{
|
||||||
|
return count($this->contextServices) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContextClasses(): array
|
||||||
|
{
|
||||||
|
return array_values($this->contextServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasContextClass($class): bool
|
||||||
|
{
|
||||||
|
return in_array($class, $this->contextServices, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,52 +12,32 @@ use Symfony\Component\DependencyInjection\Reference;
|
|||||||
|
|
||||||
final class SymfonyDriverFactory implements DriverFactory
|
final class SymfonyDriverFactory implements DriverFactory
|
||||||
{
|
{
|
||||||
/**
|
/** @var string */
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
/**
|
/** @var Reference */
|
||||||
* @var Reference
|
|
||||||
*/
|
|
||||||
private $kernel;
|
private $kernel;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $name
|
|
||||||
* @param Reference $kernel
|
|
||||||
*/
|
|
||||||
public function __construct(string $name, Reference $kernel)
|
public function __construct(string $name, Reference $kernel)
|
||||||
{
|
{
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->kernel = $kernel;
|
$this->kernel = $kernel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getDriverName(): string
|
public function getDriverName(): string
|
||||||
{
|
{
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function supportsJavascript(): bool
|
public function supportsJavascript(): bool
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function configure(ArrayNodeDefinition $builder): void
|
public function configure(ArrayNodeDefinition $builder): void
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function buildDriver(array $config): Definition
|
public function buildDriver(array $config): Definition
|
||||||
{
|
{
|
||||||
return new Definition(SymfonyDriver::class, [
|
return new Definition(SymfonyDriver::class, [
|
||||||
|
|||||||
@@ -10,10 +10,6 @@ use Symfony\Component\HttpKernel\KernelInterface;
|
|||||||
|
|
||||||
final class SymfonyDriver extends BrowserKitDriver
|
final class SymfonyDriver extends BrowserKitDriver
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @param KernelInterface $kernel
|
|
||||||
* @param string $baseUrl
|
|
||||||
*/
|
|
||||||
public function __construct(KernelInterface $kernel, string $baseUrl)
|
public function __construct(KernelInterface $kernel, string $baseUrl)
|
||||||
{
|
{
|
||||||
$testClient = $kernel->getContainer()->get('test.client');
|
$testClient = $kernel->getContainer()->get('test.client');
|
||||||
|
|||||||
@@ -6,38 +6,44 @@ namespace FriendsOfBehat\SymfonyExtension\Listener;
|
|||||||
|
|
||||||
use Behat\Behat\EventDispatcher\Event\ExampleTested;
|
use Behat\Behat\EventDispatcher\Event\ExampleTested;
|
||||||
use Behat\Behat\EventDispatcher\Event\ScenarioTested;
|
use Behat\Behat\EventDispatcher\Event\ScenarioTested;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
use Symfony\Component\HttpKernel\KernelInterface;
|
use Symfony\Component\HttpKernel\KernelInterface;
|
||||||
|
|
||||||
final class KernelRebooter implements EventSubscriberInterface
|
final class KernelRebooter implements EventSubscriberInterface
|
||||||
{
|
{
|
||||||
/**
|
/** @var KernelInterface */
|
||||||
* @var KernelInterface
|
private $symfonyKernel;
|
||||||
*/
|
|
||||||
private $kernel;
|
|
||||||
|
|
||||||
/**
|
/** @var ContainerInterface */
|
||||||
* @param KernelInterface $kernel
|
private $behatContainer;
|
||||||
*/
|
|
||||||
public function __construct(KernelInterface $kernel)
|
public function __construct(KernelInterface $symfonyKernel, ContainerInterface $behatContainer)
|
||||||
{
|
{
|
||||||
$this->kernel = $kernel;
|
$this->symfonyKernel = $symfonyKernel;
|
||||||
|
$this->behatContainer = $behatContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public static function getSubscribedEvents(): array
|
public static function getSubscribedEvents(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
ScenarioTested::AFTER => ['rebootKernel', -15],
|
ScenarioTested::AFTER => ['rebootSymfonyKernel', -15],
|
||||||
ExampleTested::AFTER => ['rebootKernel', -15],
|
ExampleTested::AFTER => ['rebootSymfonyKernel', -15],
|
||||||
|
ScenarioTested::BEFORE => ['transferBehatContainer', 15],
|
||||||
|
ExampleTested::BEFORE => ['transferBehatContainer', 15],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rebootKernel(): void
|
public function transferBehatContainer(): void
|
||||||
{
|
{
|
||||||
$this->kernel->shutdown();
|
$symfonyContainer = $this->symfonyKernel->getContainer();
|
||||||
$this->kernel->boot();
|
|
||||||
|
$symfonyContainer->set('behat.service_container', $this->behatContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rebootSymfonyKernel(): void
|
||||||
|
{
|
||||||
|
$this->symfonyKernel->shutdown();
|
||||||
|
$this->symfonyKernel->boot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,22 +4,20 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FriendsOfBehat\SymfonyExtension\ServiceContainer;
|
namespace FriendsOfBehat\SymfonyExtension\ServiceContainer;
|
||||||
|
|
||||||
|
use Behat\Behat\Context\ServiceContainer\ContextExtension;
|
||||||
use Behat\MinkExtension\ServiceContainer\MinkExtension;
|
use Behat\MinkExtension\ServiceContainer\MinkExtension;
|
||||||
|
use Behat\Testwork\Environment\ServiceContainer\EnvironmentExtension;
|
||||||
use Behat\Testwork\EventDispatcher\ServiceContainer\EventDispatcherExtension;
|
use Behat\Testwork\EventDispatcher\ServiceContainer\EventDispatcherExtension;
|
||||||
use Behat\Testwork\ServiceContainer\Extension;
|
use Behat\Testwork\ServiceContainer\Extension;
|
||||||
use Behat\Testwork\ServiceContainer\ExtensionManager;
|
use Behat\Testwork\ServiceContainer\ExtensionManager;
|
||||||
use FriendsOfBehat\CrossContainerExtension\CrossContainerProcessor;
|
use FriendsOfBehat\SymfonyExtension\Context\Environment\Handler\ContextServiceEnvironmentHandler;
|
||||||
use FriendsOfBehat\CrossContainerExtension\KernelBasedContainerAccessor;
|
|
||||||
use FriendsOfBehat\CrossContainerExtension\ServiceContainer\CrossContainerExtension;
|
|
||||||
use FriendsOfBehat\SymfonyExtension\Driver\Factory\SymfonyDriverFactory;
|
use FriendsOfBehat\SymfonyExtension\Driver\Factory\SymfonyDriverFactory;
|
||||||
use FriendsOfBehat\SymfonyExtension\Listener\KernelRebooter;
|
use FriendsOfBehat\SymfonyExtension\Listener\KernelRebooter;
|
||||||
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
|
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
|
||||||
use Symfony\Component\DependencyInjection\Container;
|
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Definition;
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
use Symfony\Component\Dotenv\Dotenv;
|
use Symfony\Component\Dotenv\Dotenv;
|
||||||
use Symfony\Component\HttpKernel\KernelInterface;
|
|
||||||
|
|
||||||
final class SymfonyExtension implements Extension
|
final class SymfonyExtension implements Extension
|
||||||
{
|
{
|
||||||
@@ -27,41 +25,13 @@ final class SymfonyExtension implements Extension
|
|||||||
* Kernel used inside Behat contexts or to create services injected to them.
|
* Kernel used inside Behat contexts or to create services injected to them.
|
||||||
* Container is built before every scenario.
|
* Container is built before every scenario.
|
||||||
*/
|
*/
|
||||||
const KERNEL_ID = 'sylius_symfony_extension.kernel';
|
public const KERNEL_ID = 'sylius_symfony_extension.kernel';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current container used in scenario contexts.
|
* Kernel used by Symfony driver to isolate web container from contexts' container.
|
||||||
* To be used as a factory for current injected application services.
|
|
||||||
*/
|
|
||||||
const KERNEL_CONTAINER_ID = 'sylius_symfony_extension.kernel.container';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Kernel used by Symfony2 driver to isolate web container from contexts' container.
|
|
||||||
* Container is built before every request.
|
* Container is built before every request.
|
||||||
*/
|
*/
|
||||||
const DRIVER_KERNEL_ID = 'sylius_symfony_extension.driver_kernel';
|
private const DRIVER_KERNEL_ID = 'sylius_symfony_extension.driver_kernel';
|
||||||
|
|
||||||
/**
|
|
||||||
* Kernel that should be used by extensions only.
|
|
||||||
* Container is built only once at the first use.
|
|
||||||
*/
|
|
||||||
const SHARED_KERNEL_ID = 'sylius_symfony_extension.shared_kernel';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The only container built by shared kernel.
|
|
||||||
* To be used as a factory for shared injected application services.
|
|
||||||
*/
|
|
||||||
const SHARED_KERNEL_CONTAINER_ID = 'sylius_symfony_extension.shared_kernel.container';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default symfony environment used to run your suites.
|
|
||||||
*/
|
|
||||||
private const DEFAULT_ENV = 'test';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable or disable the debug mode
|
|
||||||
*/
|
|
||||||
private const DEFAULT_DEBUG_MODE = true;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Symfony configuration
|
* Default Symfony configuration
|
||||||
@@ -69,53 +39,22 @@ final class SymfonyExtension implements Extension
|
|||||||
private const SYMFONY_DEFAULTS = [
|
private const SYMFONY_DEFAULTS = [
|
||||||
'env_file' => null,
|
'env_file' => null,
|
||||||
'kernel' => [
|
'kernel' => [
|
||||||
'bootstrap' => 'app/autoload.php',
|
|
||||||
'path' => 'app/AppKernel.php',
|
|
||||||
'class' => 'AppKernel',
|
'class' => 'AppKernel',
|
||||||
'env' => self::DEFAULT_ENV,
|
'env' => 'test',
|
||||||
'debug' => self::DEFAULT_DEBUG_MODE,
|
'debug' => true,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* Default Symfony 4 configuration
|
|
||||||
*/
|
|
||||||
private const SYMFONY_4_DEFAULTS = [
|
|
||||||
'env_file' => '.env',
|
|
||||||
'kernel' => [
|
|
||||||
'bootstrap' => null,
|
|
||||||
'path' => 'src/Kernel.php',
|
|
||||||
'class' => 'App\Kernel',
|
|
||||||
'env' => self::DEFAULT_ENV,
|
|
||||||
'debug' => self::DEFAULT_DEBUG_MODE,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var CrossContainerProcessor|null
|
|
||||||
*/
|
|
||||||
private $crossContainerProcessor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getConfigKey(): string
|
public function getConfigKey(): string
|
||||||
{
|
{
|
||||||
return 'fob_symfony';
|
return 'fob_symfony';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function initialize(ExtensionManager $extensionManager): void
|
public function initialize(ExtensionManager $extensionManager): void
|
||||||
{
|
{
|
||||||
$this->registerSymfonyDriverFactory($extensionManager);
|
$this->registerSymfonyDriverFactory($extensionManager);
|
||||||
$this->initializeCrossContainerProcessor($extensionManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function configure(ArrayNodeDefinition $builder): void
|
public function configure(ArrayNodeDefinition $builder): void
|
||||||
{
|
{
|
||||||
$builder
|
$builder
|
||||||
@@ -124,8 +63,6 @@ final class SymfonyExtension implements Extension
|
|||||||
->arrayNode('kernel')
|
->arrayNode('kernel')
|
||||||
->addDefaultsIfNotSet()
|
->addDefaultsIfNotSet()
|
||||||
->children()
|
->children()
|
||||||
->scalarNode('bootstrap')->defaultFalse()->end()
|
|
||||||
->scalarNode('path')->end()
|
|
||||||
->scalarNode('class')->end()
|
->scalarNode('class')->end()
|
||||||
->scalarNode('env')->end()
|
->scalarNode('env')->end()
|
||||||
->booleanNode('debug')->end()
|
->booleanNode('debug')->end()
|
||||||
@@ -135,28 +72,18 @@ final class SymfonyExtension implements Extension
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function load(ContainerBuilder $container, array $config): void
|
public function load(ContainerBuilder $container, array $config): void
|
||||||
{
|
{
|
||||||
$config = $this->autoconfigure($container, $config);
|
$config = $this->autoconfigure($container, $config);
|
||||||
|
|
||||||
$this->loadKernel($container, $config['kernel']);
|
$this->loadKernel($container, $config['kernel']);
|
||||||
$this->loadKernelContainer($container);
|
|
||||||
|
|
||||||
$this->loadDriverKernel($container);
|
$this->loadDriverKernel($container);
|
||||||
|
|
||||||
$this->loadSharedKernel($container);
|
$this->loadEnvironmentHandler($container);
|
||||||
$this->loadSharedKernelContainer($container);
|
|
||||||
|
|
||||||
$this->loadKernelRebooter($container);
|
$this->loadKernelRebooter($container);
|
||||||
$this->declareSymfonyContainers($container);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function process(ContainerBuilder $container): void
|
public function process(ContainerBuilder $container): void
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -165,13 +92,6 @@ final class SymfonyExtension implements Extension
|
|||||||
{
|
{
|
||||||
$defaults = self::SYMFONY_DEFAULTS;
|
$defaults = self::SYMFONY_DEFAULTS;
|
||||||
|
|
||||||
$symfonyFourKernelPath = sprintf('%s/%s', $container->getParameter('paths.base'), self::SYMFONY_4_DEFAULTS['kernel']['path']);
|
|
||||||
if ($userConfig['kernel']['bootstrap'] === null || file_exists($symfonyFourKernelPath)) {
|
|
||||||
$defaults = self::SYMFONY_4_DEFAULTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
$userConfig['kernel']['bootstrap'] = $userConfig['kernel']['bootstrap'] === false ? null : $userConfig['kernel']['bootstrap'];
|
|
||||||
|
|
||||||
$config = array_replace_recursive($defaults, $userConfig);
|
$config = array_replace_recursive($defaults, $userConfig);
|
||||||
|
|
||||||
if (null !== $config['env_file']) {
|
if (null !== $config['env_file']) {
|
||||||
@@ -200,30 +120,12 @@ final class SymfonyExtension implements Extension
|
|||||||
{
|
{
|
||||||
$definition = new Definition($config['class'], [
|
$definition = new Definition($config['class'], [
|
||||||
$config['env'],
|
$config['env'],
|
||||||
$config['debug'],
|
(bool) $config['debug'],
|
||||||
]);
|
]);
|
||||||
$definition->addMethodCall('boot');
|
$definition->addMethodCall('boot');
|
||||||
$definition->setPublic(true);
|
$definition->setPublic(true);
|
||||||
|
|
||||||
$file = $this->getKernelFile($container->getParameter('paths.base'), $config['path']);
|
|
||||||
if (null !== $file) {
|
|
||||||
$definition->setFile($file);
|
|
||||||
}
|
|
||||||
|
|
||||||
$container->setDefinition(self::KERNEL_ID, $definition);
|
$container->setDefinition(self::KERNEL_ID, $definition);
|
||||||
|
|
||||||
$this->requireKernelBootstrapFile($container->getParameter('paths.base'), $config['bootstrap']);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function loadKernelContainer(ContainerBuilder $container): void
|
|
||||||
{
|
|
||||||
$containerDefinition = new Definition(Container::class);
|
|
||||||
$containerDefinition->setFactory([
|
|
||||||
new Reference(self::KERNEL_ID),
|
|
||||||
'getContainer',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$container->setDefinition(self::KERNEL_CONTAINER_ID, $containerDefinition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadDriverKernel(ContainerBuilder $container): void
|
private function loadDriverKernel(ContainerBuilder $container): void
|
||||||
@@ -231,71 +133,26 @@ final class SymfonyExtension implements Extension
|
|||||||
$container->setDefinition(self::DRIVER_KERNEL_ID, $container->findDefinition(self::KERNEL_ID));
|
$container->setDefinition(self::DRIVER_KERNEL_ID, $container->findDefinition(self::KERNEL_ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadSharedKernel(ContainerBuilder $container): void
|
|
||||||
{
|
|
||||||
$container->setDefinition(self::SHARED_KERNEL_ID, $container->findDefinition(self::KERNEL_ID));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function loadSharedKernelContainer(ContainerBuilder $container): void
|
|
||||||
{
|
|
||||||
$containerDefinition = new Definition(Container::class);
|
|
||||||
$containerDefinition->setFactory([
|
|
||||||
new Reference(self::SHARED_KERNEL_ID),
|
|
||||||
'getContainer',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$container->setDefinition(self::SHARED_KERNEL_CONTAINER_ID, $containerDefinition);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
private function loadKernelRebooter(ContainerBuilder $container): void
|
private function loadKernelRebooter(ContainerBuilder $container): void
|
||||||
{
|
{
|
||||||
$definition = new Definition(KernelRebooter::class, [new Reference(self::KERNEL_ID)]);
|
$definition = new Definition(KernelRebooter::class, [new Reference(self::KERNEL_ID), $container]);
|
||||||
$definition->addTag(EventDispatcherExtension::SUBSCRIBER_TAG);
|
$definition->addTag(EventDispatcherExtension::SUBSCRIBER_TAG);
|
||||||
|
|
||||||
$container->setDefinition(self::KERNEL_ID . '.rebooter', $definition);
|
$container->setDefinition(self::KERNEL_ID . '.rebooter', $definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function loadEnvironmentHandler(ContainerBuilder $container): void
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
private function declareSymfonyContainers(ContainerBuilder $container): void
|
|
||||||
{
|
{
|
||||||
if (null === $this->crossContainerProcessor) {
|
$definition = new Definition(ContextServiceEnvironmentHandler::class, [
|
||||||
return;
|
new Reference(self::KERNEL_ID),
|
||||||
|
]);
|
||||||
|
$definition->addTag(EnvironmentExtension::HANDLER_TAG, ['priority' => 128]);
|
||||||
|
|
||||||
|
foreach ($container->findTaggedServiceIds(ContextExtension::INITIALIZER_TAG) as $serviceId => $tags) {
|
||||||
|
$definition->addMethodCall('registerContextInitializer', [$container->getDefinition($serviceId)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$containerAccessors = [
|
$container->setDefinition('fob_symfony.environment_handler.context_service', $definition);
|
||||||
'symfony' => self::KERNEL_ID,
|
|
||||||
'symfony_driver' => self::DRIVER_KERNEL_ID,
|
|
||||||
'symfony_shared' => self::SHARED_KERNEL_ID,
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($containerAccessors as $containerName => $kernelIdentifier) {
|
|
||||||
$kernel = $container->get($kernelIdentifier);
|
|
||||||
|
|
||||||
if (!$kernel instanceof KernelInterface) {
|
|
||||||
throw new \RuntimeException(sprintf(
|
|
||||||
'Expected service "%s" to be an instance of "%s", got "%s" instead.',
|
|
||||||
$kernelIdentifier,
|
|
||||||
KernelInterface::class,
|
|
||||||
\is_object($kernel) ? \get_class($kernel) : \gettype($kernel)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->crossContainerProcessor->addContainerAccessor($containerName, new KernelBasedContainerAccessor($kernel));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function initializeCrossContainerProcessor(ExtensionManager $extensionManager): void
|
|
||||||
{
|
|
||||||
/** @var CrossContainerExtension $extension */
|
|
||||||
$extension = $extensionManager->getExtension('fob_cross_container');
|
|
||||||
if (null !== $extension) {
|
|
||||||
$this->crossContainerProcessor = $extension->getCrossContainerProcessor();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function registerSymfonyDriverFactory(ExtensionManager $extensionManager): void
|
private function registerSymfonyDriverFactory(ExtensionManager $extensionManager): void
|
||||||
@@ -306,50 +163,6 @@ final class SymfonyExtension implements Extension
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$minkExtension->registerDriverFactory(new SymfonyDriverFactory(
|
$minkExtension->registerDriverFactory(new SymfonyDriverFactory('symfony', new Reference(self::DRIVER_KERNEL_ID)));
|
||||||
'symfony',
|
|
||||||
new Reference(self::DRIVER_KERNEL_ID)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getKernelFile(string $basePath, string $kernelPath): ?string
|
|
||||||
{
|
|
||||||
$possibleFiles = [
|
|
||||||
sprintf('%s/%s', $basePath, $kernelPath),
|
|
||||||
$kernelPath,
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($possibleFiles as $possibleFile) {
|
|
||||||
if (file_exists($possibleFile)) {
|
|
||||||
return $possibleFile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws \DomainException
|
|
||||||
*/
|
|
||||||
private function requireKernelBootstrapFile(string $basePath, ?string $bootstrapPath): void
|
|
||||||
{
|
|
||||||
if (null === $bootstrapPath) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$possiblePaths = [
|
|
||||||
sprintf('%s/%s', $basePath, $bootstrapPath),
|
|
||||||
$bootstrapPath,
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($possiblePaths as $possiblePath) {
|
|
||||||
if (file_exists($possiblePath)) {
|
|
||||||
require_once $possiblePath;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new \DomainException('Could not load bootstrap file.');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user