Merge branch '4.3' into 4.4

* 4.3:
  Fixes windows error
  [Messenger] Added more test for MessageBus
  fixed typo
  [Filesystem] added missing deprecations to UPGRADE-4.3.md
  Fix authentication for redis transport
  only decorate when an event dispatcher was passed
  [FrmaeworkBundle] More simplifications in the DI configuration
  Fixing validation for messenger transports retry_strategy service key
  Removed unused field.
  Remove @internal annotations for the serilize methods
  [Lock] Stores must implement `putOffExpiration`
  Annotated correct return type for getInEdges()/getOutEdges().
  deprecate the framework.templating option
This commit is contained in:
Fabien Potencier 2019-07-03 19:15:45 +02:00
commit b79a1bf229
17 changed files with 88 additions and 27 deletions

View File

@ -57,6 +57,12 @@ EventDispatcher
* The signature of the `EventDispatcherInterface::dispatch()` method should be updated to `dispatch($event, string $eventName = null)`, not doing so is deprecated * The signature of the `EventDispatcherInterface::dispatch()` method should be updated to `dispatch($event, string $eventName = null)`, not doing so is deprecated
* The `Event` class has been deprecated, use `Symfony\Contracts\EventDispatcher\Event` instead * The `Event` class has been deprecated, use `Symfony\Contracts\EventDispatcher\Event` instead
Filesystem
----------
* Support for passing arrays to `Filesystem::dumpFile()` is deprecated.
* Support for passing arrays to `Filesystem::appendToFile()` is deprecated.
Form Form
---- ----
@ -71,6 +77,7 @@ Form
FrameworkBundle FrameworkBundle
--------------- ---------------
* Deprecated the `framework.templating` option, use Twig instead.
* Not passing the project directory to the constructor of the `AssetsInstallCommand` is deprecated. This argument will * Not passing the project directory to the constructor of the `AssetsInstallCommand` is deprecated. This argument will
be mandatory in 5.0. be mandatory in 5.0.
* Deprecated the "Psr\SimpleCache\CacheInterface" / "cache.app.simple" service, use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead. * Deprecated the "Psr\SimpleCache\CacheInterface" / "cache.app.simple" service, use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead.

View File

@ -207,8 +207,8 @@ Form
FrameworkBundle FrameworkBundle
--------------- ---------------
* Removed the `framework.templating` option, use Twig instead.
* The project dir argument of the constructor of `AssetsInstallCommand` is required. * The project dir argument of the constructor of `AssetsInstallCommand` is required.
* Removed support for `bundle:controller:action` syntax to reference controllers. Use `serviceOrFqcn::method` * Removed support for `bundle:controller:action` syntax to reference controllers. Use `serviceOrFqcn::method`
instead where `serviceOrFqcn` is either the service ID when using controllers as services or the FQCN of the controller. instead where `serviceOrFqcn` is either the service ID when using controllers as services or the FQCN of the controller.

View File

@ -131,7 +131,7 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__
$prevRoot = getenv('COMPOSER_ROOT_VERSION'); $prevRoot = getenv('COMPOSER_ROOT_VERSION');
putenv("COMPOSER_ROOT_VERSION=$PHPUNIT_VERSION.99"); putenv("COMPOSER_ROOT_VERSION=$PHPUNIT_VERSION.99");
// --no-suggest is not in the list to keep compat with composer 1.0, which is shipped with Ubuntu 16.04LTS // --no-suggest is not in the list to keep compat with composer 1.0, which is shipped with Ubuntu 16.04LTS
$exit = proc_close(proc_open("$COMPOSER install --no-dev --prefer-dist --no-progress --ansi", array(), $p, getcwd(), null, array('bypass_shell' => true))); $exit = proc_close(proc_open("$COMPOSER install --no-dev --prefer-dist --no-progress --ansi", array(), $p));
putenv('COMPOSER_ROOT_VERSION'.(false !== $prevRoot ? '='.$prevRoot : '')); putenv('COMPOSER_ROOT_VERSION'.(false !== $prevRoot ? '='.$prevRoot : ''));
if ($exit) { if ($exit) {
exit($exit); exit($exit);

View File

@ -12,6 +12,7 @@ CHANGELOG
4.3.0 4.3.0
----- -----
* Deprecated the `framework.templating` option, use Twig instead.
* Added `WebTestAssertionsTrait` (included by default in `WebTestCase`) * Added `WebTestAssertionsTrait` (included by default in `WebTestCase`)
* Renamed `Client` to `KernelBrowser` * Renamed `Client` to `KernelBrowser`
* Not passing the project directory to the constructor of the `AssetsInstallCommand` is deprecated. This argument will * Not passing the project directory to the constructor of the `AssetsInstallCommand` is deprecated. This argument will

View File

@ -339,10 +339,7 @@ class Configuration implements ConfigurationInterface
->defaultNull() ->defaultNull()
->end() ->end()
->arrayNode('initial_marking') ->arrayNode('initial_marking')
->beforeNormalization() ->beforeNormalization()->castToArray()->end()
->ifTrue(function ($v) { return !\is_array($v); })
->then(function ($v) { return [$v]; })
->end()
->defaultValue([]) ->defaultValue([])
->prototype('scalar')->end() ->prototype('scalar')->end()
->end() ->end()
@ -602,6 +599,7 @@ class Configuration implements ConfigurationInterface
->arrayNode('templating') ->arrayNode('templating')
->info('templating configuration') ->info('templating configuration')
->canBeEnabled() ->canBeEnabled()
->setDeprecated('The "%path%.%node%" configuration is deprecated since Symfony 4.3. Use the "twig" service directly instead.')
->beforeNormalization() ->beforeNormalization()
->ifTrue(function ($v) { return false === $v || \is_array($v) && false === $v['enabled']; }) ->ifTrue(function ($v) { return false === $v || \is_array($v) && false === $v['enabled']; })
->then(function () { return ['enabled' => false, 'engines' => false]; }) ->then(function () { return ['enabled' => false, 'engines' => false]; })
@ -1180,9 +1178,14 @@ class Configuration implements ConfigurationInterface
->end() ->end()
->arrayNode('retry_strategy') ->arrayNode('retry_strategy')
->addDefaultsIfNotSet() ->addDefaultsIfNotSet()
->validate() ->beforeNormalization()
->ifTrue(function ($v) { return null !== $v['service'] && (isset($v['max_retries']) || isset($v['delay']) || isset($v['multiplier']) || isset($v['max_delay'])); }) ->always(function ($v) {
->thenInvalid('"service" cannot be used along with the other retry_strategy options.') if (isset($v['service']) && (isset($v['max_retries']) || isset($v['delay']) || isset($v['multiplier']) || isset($v['max_delay']))) {
throw new \InvalidArgumentException('The "service" cannot be used along with the other "retry_strategy" options.');
}
return $v;
})
->end() ->end()
->children() ->children()
->scalarNode('service')->defaultNull()->info('Service id to override the retry strategy entirely')->end() ->scalarNode('service')->defaultNull()->info('Service id to override the retry strategy entirely')->end()

View File

@ -35,6 +35,9 @@ class ConfigurationTest extends TestCase
); );
} }
/**
* @group legacy
*/
public function testDoNoDuplicateDefaultFormResources() public function testDoNoDuplicateDefaultFormResources()
{ {
$input = ['templating' => [ $input = ['templating' => [

View File

@ -602,6 +602,9 @@ abstract class FrameworkExtensionTest extends TestCase
$this->assertEquals('global_hinclude_template', $container->getParameter('fragment.renderer.hinclude.global_template'), '->registerTemplatingConfiguration() registers the global hinclude.js template'); $this->assertEquals('global_hinclude_template', $container->getParameter('fragment.renderer.hinclude.global_template'), '->registerTemplatingConfiguration() registers the global hinclude.js template');
} }
/**
* @group legacy
*/
public function testTemplatingCanBeDisabled() public function testTemplatingCanBeDisabled()
{ {
$container = $this->createContainerFromFile('templating_disabled'); $container = $this->createContainerFromFile('templating_disabled');
@ -872,6 +875,7 @@ abstract class FrameworkExtensionTest extends TestCase
} }
/** /**
* @group legacy
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
*/ */
public function testTemplatingRequiresAtLeastOneEngine() public function testTemplatingRequiresAtLeastOneEngine()

View File

@ -34,7 +34,6 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe
private $onlyConstructorArguments; private $onlyConstructorArguments;
private $hasProxyDumper; private $hasProxyDumper;
private $lazy; private $lazy;
private $expressionLanguage;
private $byConstructor; private $byConstructor;
private $definitions; private $definitions;
private $aliases; private $aliases;

View File

@ -81,7 +81,7 @@ class ServiceReferenceGraphNode
/** /**
* Returns the in edges. * Returns the in edges.
* *
* @return array The in ServiceReferenceGraphEdge array * @return ServiceReferenceGraphEdge[]
*/ */
public function getInEdges() public function getInEdges()
{ {
@ -91,7 +91,7 @@ class ServiceReferenceGraphNode
/** /**
* Returns the out edges. * Returns the out edges.
* *
* @return array The out ServiceReferenceGraphEdge array * @return ServiceReferenceGraphEdge[]
*/ */
public function getOutEdges() public function getOutEdges()
{ {

View File

@ -95,7 +95,7 @@ class ZookeeperStore implements StoreInterface
*/ */
public function putOffExpiration(Key $key, $ttl) public function putOffExpiration(Key $key, $ttl)
{ {
throw new NotSupportedException(); // do nothing, zookeeper locks forever.
} }
/** /**

View File

@ -49,7 +49,6 @@ interface StoreInterface
* @param float $ttl amount of seconds to keep the lock in the store * @param float $ttl amount of seconds to keep the lock in the store
* *
* @throws LockConflictedException * @throws LockConflictedException
* @throws NotSupportedException
*/ */
public function putOffExpiration(Key $key, $ttl); public function putOffExpiration(Key $key, $ttl);

View File

@ -16,6 +16,7 @@ use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBus; use Symfony\Component\Messenger\MessageBus;
use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Middleware\MiddlewareInterface; use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
use Symfony\Component\Messenger\Middleware\StackInterface;
use Symfony\Component\Messenger\Stamp\BusNameStamp; use Symfony\Component\Messenger\Stamp\BusNameStamp;
use Symfony\Component\Messenger\Stamp\DelayStamp; use Symfony\Component\Messenger\Stamp\DelayStamp;
use Symfony\Component\Messenger\Stamp\ReceivedStamp; use Symfony\Component\Messenger\Stamp\ReceivedStamp;
@ -148,4 +149,44 @@ class MessageBusTest extends TestCase
$finalEnvelope = (new MessageBus())->dispatch(new Envelope(new \stdClass()), [new DelayStamp(5), new BusNameStamp('bar')]); $finalEnvelope = (new MessageBus())->dispatch(new Envelope(new \stdClass()), [new DelayStamp(5), new BusNameStamp('bar')]);
$this->assertCount(2, $finalEnvelope->all()); $this->assertCount(2, $finalEnvelope->all());
} }
public function provideConstructorDataStucture()
{
yield 'iterator' => [new \ArrayObject([
new SimpleMiddleware(),
new SimpleMiddleware(),
])];
yield 'array' => [[
new SimpleMiddleware(),
new SimpleMiddleware(),
]];
yield 'generator' => [(function (): \Generator {
yield new SimpleMiddleware();
yield new SimpleMiddleware();
})()];
}
/** @dataProvider provideConstructorDataStucture */
public function testConstructDataStructure($dataStructure)
{
$bus = new MessageBus($dataStructure);
$envelope = new Envelope(new DummyMessage('Hello'));
$newEnvelope = $bus->dispatch($envelope);
$this->assertSame($envelope->getMessage(), $newEnvelope->getMessage());
// Test rewindable capacity
$envelope = new Envelope(new DummyMessage('Hello'));
$newEnvelope = $bus->dispatch($envelope);
$this->assertSame($envelope->getMessage(), $newEnvelope->getMessage());
}
}
class SimpleMiddleware implements MiddlewareInterface
{
public function handle(Envelope $envelope, StackInterface $stack): Envelope
{
return $envelope;
}
} }

View File

@ -79,6 +79,16 @@ class ConnectionTest extends TestCase
$this->assertNotNull($connection->get()); $this->assertNotNull($connection->get());
} }
public function testAuth()
{
$redis = $this->getMockBuilder(\Redis::class)->disableOriginalConstructor()->getMock();
$redis->expects($this->exactly(1))->method('auth')
->with('password');
Connection::fromDsn('redis://password@localhost/queue', [], $redis);
}
public function testFirstGetPendingMessagesThenNewMessages() public function testFirstGetPendingMessagesThenNewMessages()
{ {
$redis = $this->getMockBuilder(\Redis::class)->disableOriginalConstructor()->getMock(); $redis = $this->getMockBuilder(\Redis::class)->disableOriginalConstructor()->getMock();

View File

@ -51,6 +51,11 @@ class Connection
$this->connection = $redis ?: new \Redis(); $this->connection = $redis ?: new \Redis();
$this->connection->connect($connectionCredentials['host'] ?? '127.0.0.1', $connectionCredentials['port'] ?? 6379); $this->connection->connect($connectionCredentials['host'] ?? '127.0.0.1', $connectionCredentials['port'] ?? 6379);
$this->connection->setOption(\Redis::OPT_SERIALIZER, $redisOptions['serializer'] ?? \Redis::SERIALIZER_PHP); $this->connection->setOption(\Redis::OPT_SERIALIZER, $redisOptions['serializer'] ?? \Redis::SERIALIZER_PHP);
if (isset($connectionCredentials['auth'])) {
$this->connection->auth($connectionCredentials['auth']);
}
$this->stream = $configuration['stream'] ?? self::DEFAULT_OPTIONS['stream']; $this->stream = $configuration['stream'] ?? self::DEFAULT_OPTIONS['stream'];
$this->group = $configuration['group'] ?? self::DEFAULT_OPTIONS['group']; $this->group = $configuration['group'] ?? self::DEFAULT_OPTIONS['group'];
$this->consumer = $configuration['consumer'] ?? self::DEFAULT_OPTIONS['consumer']; $this->consumer = $configuration['consumer'] ?? self::DEFAULT_OPTIONS['consumer'];
@ -73,6 +78,7 @@ class Connection
$connectionCredentials = [ $connectionCredentials = [
'host' => $parsedUrl['host'] ?? '127.0.0.1', 'host' => $parsedUrl['host'] ?? '127.0.0.1',
'port' => $parsedUrl['port'] ?? 6379, 'port' => $parsedUrl['port'] ?? 6379,
'auth' => $parsedUrl['pass'] ?? $parsedUrl['user'] ?? null,
]; ];
if (isset($parsedUrl['query'])) { if (isset($parsedUrl['query'])) {

View File

@ -128,17 +128,11 @@ class Message extends RawMessage
return bin2hex(random_bytes(16)).strstr($email, '@'); return bin2hex(random_bytes(16)).strstr($email, '@');
} }
/**
* @internal
*/
public function __serialize(): array public function __serialize(): array
{ {
return [$this->headers, $this->body]; return [$this->headers, $this->body];
} }
/**
* @internal
*/
public function __unserialize(array $data): void public function __unserialize(array $data): void
{ {
[$this->headers, $this->body] = $data; [$this->headers, $this->body] = $data;

View File

@ -67,17 +67,11 @@ class RawMessage implements \Serializable
$this->__unserialize(unserialize($serialized)); $this->__unserialize(unserialize($serialized));
} }
/**
* @internal
*/
public function __serialize(): array public function __serialize(): array
{ {
return [$this->message]; return [$this->message];
} }
/**
* @internal
*/
public function __unserialize(array $data): void public function __unserialize(array $data): void
{ {
[$this->message] = $data; [$this->message] = $data;

View File

@ -43,7 +43,7 @@ class Workflow implements WorkflowInterface
{ {
$this->definition = $definition; $this->definition = $definition;
$this->markingStore = $markingStore ?: new MultipleStateMarkingStore(); $this->markingStore = $markingStore ?: new MultipleStateMarkingStore();
$this->dispatcher = LegacyEventDispatcherProxy::decorate($dispatcher); $this->dispatcher = null !== $dispatcher ? LegacyEventDispatcherProxy::decorate($dispatcher) : null;
$this->name = $name; $this->name = $name;
} }