Merge branch '4.1'

* 4.1:
  Move commands-specifics to a compiler pass in FWB
  bumped Symfony version to 4.1.5
  updated VERSION for 4.1.4
  updated CHANGELOG for 4.1.4
  [travis] disable symfony/flex during phpunit install
This commit is contained in:
Samuel ROZE 2018-09-01 18:54:47 +01:00
commit 3833f8816d
7 changed files with 179 additions and 61 deletions

View File

@ -7,6 +7,30 @@ in 4.1 minor versions.
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.1.0...v4.1.1
* 4.1.4 (2018-08-28)
* bug #28278 [HttpFoundation] Fix unprepared BinaryFileResponse sends empty file (wackymole)
* bug #28284 [PhpUnitBridge] keep compat with composer 1.0 (nicolas-grekas)
* bug #28251 [HttpFoundation] Allow RedisCluster class for RedisSessionHandler (michaelperrin)
* bug #28241 [HttpKernel] fix forwarding trusted headers as server parameters (nicolas-grekas)
* bug #28220 [PropertyAccess] fix type error handling when writing values (xabbuh)
* bug #28249 [Cache] enable Memcached::OPT_TCP_NODELAY to fix perf of misses (nicolas-grekas)
* bug #28252 [DoctrineBridge] support __toString as documented for UniqueEntityValidator (dmaicher)
* bug #28216 [FrameworkBundle] `message_bus` alias public (sroze)
* bug #28113 [Form] Add help texts for checkboxes in horizontal bootstrap 4 forms (apfelbox)
* bug #28100 [Security] Call AccessListener after LogoutListener (chalasr)
* bug #28174 Remove the HTML5 validation from the profiler URL search form (Soullivaneuh)
* bug #28159 [DI] Fix autowire inner service (hason)
* bug #28060 [DI] Fix false-positive circular ref leading to wrong exceptions or infinite loops at runtime (nicolas-grekas)
* bug #28144 [HttpFoundation] fix false-positive ConflictingHeadersException (nicolas-grekas)
* bug #28152 [Translation] fix perf of lint:xliff command (nicolas-grekas)
* bug #28115 [Form] Remove extra .form-group wrapper around file widget in bootstrap 4 (MrMitch)
* bug #28120 [Routing] Fixed scheme redirecting for root path (twoleds)
* bug #28112 Fix CSS property typo (AhmedAbdulrahman)
* bug #28012 [PropertyInfo] Allow nested collections (jderusse)
* bug #28055 [PropertyInfo] Allow nested collections (jderusse)
* bug #28083 Remove the Expires header when calling Response::expire() (javiereguiluz)
* 4.1.3 (2018-08-01)
* security #cve-2018-14774 [HttpKernel] fix trusted headers management in HttpCache and InlineFragmentRenderer (nicolas-grekas)

View File

@ -0,0 +1,53 @@
<?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\Bundle\FrameworkBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Messenger\DependencyInjection\MessengerPass;
/**
* @author Samuel Roze <samuel.roze@gmail.com>
*/
class MessengerCommandsPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('console.command.messenger_consume_messages')) {
return;
}
$buses = array();
foreach ($container->findTaggedServiceIds('messenger.bus') as $busId => $tags) {
$buses[$busId] = new Reference($busId);
}
$container
->getDefinition('console.command.messenger_consume_messages')
->replaceArgument(3, $this->findReceiverNames($container))
;
}
private function findReceiverNames(ContainerBuilder $container)
{
$receiverNames = array();
foreach (MessengerPass::findReceivers($container, 'messenger.receiver') as $name => $reference) {
$receiverNames[(string) $reference] = $name;
}
return array_values($receiverNames);
}
}

View File

@ -21,6 +21,7 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolPrunerP
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilderDebugDumpPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\DataCollectorTranslatorPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\LoggingTranslatorPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\MessengerCommandsPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TemplatingPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerRealRefPass;
@ -119,6 +120,7 @@ class FrameworkBundle extends Bundle
$container->addCompilerPass(new TestServiceContainerWeakRefPass(), PassConfig::TYPE_BEFORE_REMOVING, -32);
$container->addCompilerPass(new TestServiceContainerRealRefPass(), PassConfig::TYPE_AFTER_REMOVING);
$this->addCompilerPassIfExists($container, MessengerPass::class);
$container->addCompilerPass(new MessengerCommandsPass());
if ($container->getParameter('kernel.debug')) {
$container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -32);

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\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\MessengerCommandsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Messenger\Command\ConsumeMessagesCommand;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Tests\Fixtures\DummyReceiver;
use Symfony\Component\Messenger\Transport\AmqpExt\AmqpReceiver;
class MessengerCommandsPassTest extends TestCase
{
public function testItRegistersMultipleReceiversAndSetsTheReceiverNamesOnTheCommand()
{
$container = new ContainerBuilder();
$container->register('my_bus_name', MessageBusInterface::class)->addTag('messenger.bus')->setArgument(0, array());
$container->register('console.command.messenger_consume_messages', ConsumeMessagesCommand::class)->setArguments(array(
null,
new Reference('messenger.receiver_locator'),
null,
null,
null,
));
$container->register(AmqpReceiver::class, AmqpReceiver::class)->addTag('messenger.receiver', array('alias' => 'amqp'));
$container->register(DummyReceiver::class, DummyReceiver::class)->addTag('messenger.receiver', array('alias' => 'dummy'));
(new MessengerCommandsPass())->process($container);
$this->assertSame(array('amqp', 'dummy'), $container->getDefinition('console.command.messenger_consume_messages')->getArgument(3));
}
}

View File

@ -245,30 +245,7 @@ class MessengerPass implements CompilerPassInterface
private function registerReceivers(ContainerBuilder $container)
{
$receiverMapping = array();
foreach ($container->findTaggedServiceIds($this->receiverTag) as $id => $tags) {
$receiverClass = $container->findDefinition($id)->getClass();
if (!is_subclass_of($receiverClass, ReceiverInterface::class)) {
throw new RuntimeException(sprintf('Invalid receiver "%s": class "%s" must implement interface "%s".', $id, $receiverClass, ReceiverInterface::class));
}
$receiverMapping[$id] = new Reference($id);
foreach ($tags as $tag) {
if (isset($tag['alias'])) {
$receiverMapping[$tag['alias']] = $receiverMapping[$id];
}
}
}
if ($container->hasDefinition('console.command.messenger_consume_messages')) {
$receiverNames = array();
foreach ($receiverMapping as $name => $reference) {
$receiverNames[(string) $reference] = $name;
}
$container->getDefinition('console.command.messenger_consume_messages')->replaceArgument(3, array_values($receiverNames));
}
$receiverMapping = self::findReceivers($container, $this->receiverTag);
$container->getDefinition('messenger.receiver_locator')->replaceArgument(0, $receiverMapping);
}
@ -337,4 +314,29 @@ class MessengerPass implements CompilerPassInterface
$container->getDefinition($busId)->replaceArgument(0, $middlewareReferences);
}
/**
* @internal
*/
public static function findReceivers(ContainerBuilder $container, string $receiverTag)
{
$receiverMapping = array();
foreach ($container->findTaggedServiceIds($receiverTag) as $id => $tags) {
$receiverClass = $container->findDefinition($id)->getClass();
if (!is_subclass_of($receiverClass, ReceiverInterface::class)) {
throw new RuntimeException(sprintf('Invalid receiver "%s": class "%s" must implement interface "%s".', $id, $receiverClass, ReceiverInterface::class));
}
$receiverMapping[$id] = new Reference($id);
foreach ($tags as $tag) {
if (isset($tag['alias'])) {
$receiverMapping[$tag['alias']] = $receiverMapping[$id];
}
}
}
return $receiverMapping;
}
}

View File

@ -18,11 +18,9 @@ use Symfony\Component\DependencyInjection\Compiler\ResolveClassPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\Messenger\Command\ConsumeMessagesCommand;
use Symfony\Component\Messenger\Command\DebugCommand;
use Symfony\Component\Messenger\DataCollector\MessengerDataCollector;
use Symfony\Component\Messenger\DependencyInjection\MessengerPass;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Handler\ChainHandler;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
@ -35,12 +33,12 @@ use Symfony\Component\Messenger\Tests\Fixtures\DummyCommandHandler;
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
use Symfony\Component\Messenger\Tests\Fixtures\DummyQuery;
use Symfony\Component\Messenger\Tests\Fixtures\DummyQueryHandler;
use Symfony\Component\Messenger\Tests\Fixtures\DummyReceiver;
use Symfony\Component\Messenger\Tests\Fixtures\MultipleBusesMessage;
use Symfony\Component\Messenger\Tests\Fixtures\MultipleBusesMessageHandler;
use Symfony\Component\Messenger\Tests\Fixtures\SecondMessage;
use Symfony\Component\Messenger\Transport\AmqpExt\AmqpReceiver;
use Symfony\Component\Messenger\Transport\AmqpExt\AmqpSender;
use Symfony\Component\Messenger\Transport\ReceiverInterface;
class MessengerPassTest extends TestCase
{
@ -237,26 +235,6 @@ class MessengerPassTest extends TestCase
$this->assertEquals(array(AmqpReceiver::class => new Reference(AmqpReceiver::class)), $container->getDefinition('messenger.receiver_locator')->getArgument(0));
}
public function testItRegistersMultipleReceiversAndSetsTheReceiverNamesOnTheCommand()
{
$container = $this->getContainerBuilder();
$container->register('console.command.messenger_consume_messages', ConsumeMessagesCommand::class)->setArguments(array(
null,
new Reference('messenger.receiver_locator'),
null,
null,
null,
));
$container->register(AmqpReceiver::class, AmqpReceiver::class)->addTag('messenger.receiver', array('alias' => 'amqp'));
$container->register(DummyReceiver::class, DummyReceiver::class)->addTag('messenger.receiver', array('alias' => 'dummy'));
(new MessengerPass())->process($container);
$this->assertSame(array('amqp', 'dummy'), $container->getDefinition('console.command.messenger_consume_messages')->getArgument(3));
$this->assertSame(array('message_bus'), $container->getDefinition('console.command.messenger_consume_messages')->getArgument(4));
}
public function testItRegistersSenders()
{
$container = $this->getContainerBuilder();
@ -631,20 +609,6 @@ class DummyHandler
}
}
class DummyReceiver implements ReceiverInterface
{
public function receive(callable $handler): void
{
for ($i = 0; $i < 3; ++$i) {
$handler(Envelope::wrap(new DummyMessage("Dummy $i")));
}
}
public function stop(): void
{
}
}
class InvalidReceiver
{
}

View File

@ -0,0 +1,29 @@
<?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\Messenger\Tests\Fixtures;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Transport\ReceiverInterface;
class DummyReceiver implements ReceiverInterface
{
public function receive(callable $handler): void
{
for ($i = 0; $i < 3; ++$i) {
$handler(Envelope::wrap(new DummyMessage("Dummy $i")));
}
}
public function stop(): void
{
}
}