Commit 5379041f authored by alexpott's avatar alexpott

Issue #2343677 by damiankloip, znerol, Fabianx, pounard: Fixed Stack...

Issue #2343677 by damiankloip, znerol, Fabianx, pounard: Fixed Stack middleware suffers from incomplete service construction.

This reverts commit 39eb84fc.
parent 39eb84fc
......@@ -393,12 +393,7 @@ services:
class: Drupal\Core\Controller\TitleResolver
arguments: ['@controller_resolver', '@string_translation']
http_kernel:
class: Symfony\Component\HttpKernel\HttpKernel
factory_method: resolve
factory_service: http_kernel_factory
arguments: ['@http_kernel.basic']
http_kernel_factory:
class: Stack\Builder
class: Stack\StackedHttpKernel
http_kernel.basic:
class: Symfony\Component\HttpKernel\HttpKernel
arguments: ['@event_dispatcher', '@controller_resolver', '@request_stack']
......
......@@ -9,6 +9,7 @@
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Provides a compiler pass for stacked HTTP kernels.
......@@ -21,25 +22,44 @@ class StackedKernelPass implements CompilerPassInterface {
* {@inheritdoc}
*/
public function process(ContainerBuilder $container) {
if (!$container->hasDefinition('http_kernel_factory')) {
if (!$container->hasDefinition('http_kernel')) {
return;
}
$stacked_kernel = $container->getDefinition('http_kernel');
// Return now if this is not a stacked kernel.
if ($stacked_kernel->getClass() !== 'Stack\StackedHttpKernel') {
return;
}
$http_kernel_factory = $container->getDefinition('http_kernel_factory');
$middleware_priorities = array();
$middleware_arguments = array();
$middlewares = [];
$priorities = [];
foreach ($container->findTaggedServiceIds('http_middleware') as $id => $attributes) {
$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
$middleware_priorities[$id] = $priority;
$definition = $container->getDefinition($id);
$middleware_arguments[$id] = $definition->getArguments();
array_unshift($middleware_arguments[$id], $definition->getClass());
$priorities[$id] = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
$middlewares[$id] = $container->getDefinition($id);
}
array_multisort($middleware_priorities, SORT_DESC, $middleware_arguments, SORT_DESC);
foreach ($middleware_arguments as $id => $push_arguments) {
$http_kernel_factory->addMethodCall('push', $push_arguments);
array_multisort($priorities, SORT_ASC, $middlewares);
$decorated_id = 'http_kernel.basic';
$middlewares_param = [new Reference($decorated_id)];
foreach ($middlewares as $id => $decorator) {
// Prepend a reference to the middlewares container parameter.
array_unshift($middlewares_param, new Reference($id));
// Prepend the inner kernel as first constructor argument.
$arguments = $decorator->getArguments();
array_unshift($arguments, new Reference($decorated_id));
$decorator->setArguments($arguments);
$decorated_id = $id;
}
$arguments = [$middlewares_param[0], $middlewares_param];
$stacked_kernel->setArguments($arguments);
}
}
<?php
/**
* @file
* Contains \Drupal\Tests\Core\DependencyInjection\Compiler\StackedKernelPassTest.
*/
namespace Drupal\Tests\Core\DependencyInjection\Compiler;
use Drupal\Core\DependencyInjection\Compiler\StackedKernelPass;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\DependencyInjection\Definition;
/**
* @coversDefaultClass \Drupal\Core\DependencyInjection\Compiler\StackedKernelPass
* @group DependencyInjection
*/
class StackedKernelPassTest extends UnitTestCase {
/**
* The stacked kernel pass.
*
* @var \Drupal\Core\DependencyInjection\Compiler\StackedKernelPass
*/
protected $stackedKernelPass;
/**
* @var \Drupal\Core\DependencyInjection\Container
*/
protected $containerBuilder;
/**
* {@inheritdoc}
*/
public function setUp() {
$this->stackedKernelPass = new StackedKernelPass();
$this->containerBuilder = new ContainerBuilder();
}
/**
* @covers ::process
*/
public function testProcessWithStackedKernel() {
$stacked_kernel = new Definition('Stack\StackedHttpKernel');
$this->containerBuilder->setDefinition('http_kernel', $stacked_kernel);
$this->containerBuilder->setDefinition('http_kernel.basic', $this->createMiddlewareServiceDefinition(FALSE, 0));
$this->containerBuilder->setDefinition('http_kernel.three', $this->createMiddlewareServiceDefinition());
$this->containerBuilder->setDefinition('http_kernel.one', $this->createMiddlewareServiceDefinition(TRUE, 10));
$this->containerBuilder->setDefinition('http_kernel.two', $this->createMiddlewareServiceDefinition(TRUE, 5));
$this->stackedKernelPass->process($this->containerBuilder);
$stacked_kernel_args = $this->containerBuilder->getDefinition('http_kernel')->getArguments();
// Check the stacked kernel args.
$this->assertSame((string) $stacked_kernel_args[0], 'http_kernel.one');
$this->assertCount(4, $stacked_kernel_args[1]);
$this->assertSame((string) $stacked_kernel_args[1][0], 'http_kernel.one');
$this->assertSame((string) $stacked_kernel_args[1][1], 'http_kernel.two');
$this->assertSame((string) $stacked_kernel_args[1][2], 'http_kernel.three');
$this->assertSame((string) $stacked_kernel_args[1][3], 'http_kernel.basic');
// Check the modified definitions.
$definition = $this->containerBuilder->getDefinition('http_kernel.one');
$args = $definition->getArguments();
$this->assertSame('http_kernel.two', (string) $args[0]);
$this->assertSame('test', $args[1]);
$definition = $this->containerBuilder->getDefinition('http_kernel.two');
$args = $definition->getArguments();
$this->assertSame('http_kernel.three', (string) $args[0]);
$this->assertSame('test', $args[1]);
$definition = $this->containerBuilder->getDefinition('http_kernel.three');
$args = $definition->getArguments();
$this->assertSame('http_kernel.basic', (string) $args[0]);
$this->assertSame('test', $args[1]);
}
/**
* @covers ::process
*/
public function testProcessWithHttpKernel() {
$kernel = new Definition('Symfony\Component\HttpKernel\HttpKernelInterface');
$this->containerBuilder->setDefinition('http_kernel', $kernel);
$this->stackedKernelPass->process($this->containerBuilder);
$unprocessed_kernel = $this->containerBuilder->getDefinition('http_kernel');
$this->assertSame($kernel, $unprocessed_kernel);
$this->assertSame($kernel->getArguments(), $unprocessed_kernel->getArguments());
}
/**
* Creates a middleware definition.
*
* @param bool $tag
* Whether ot not to set the http_middleware tag.
* @param int $priority
* The priority to be used for the tag.
*
* @return \Symfony\Component\DependencyInjection\Definition
*/
protected function createMiddlewareServiceDefinition($tag = TRUE, $priority = 0) {
$definition = new Definition('Symfony\Component\HttpKernel\HttpKernelInterface', ['test']);
if ($tag) {
$definition->addTag('http_middleware', ['priority' => $priority]);
}
return $definition;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment