Merge branch '4.3'
* 4.3: (22 commits) [Messenger] Fix incorrect error when symfony/serializer is missing Allow WrappedListener to describe uncallable listeners. [HttpClient] fix handling exceptions thrown before first mock chunk [Filesystem] fix wrong method call casing [HttpClient] fix test [Translation] Fixed issue with new vs old TranslatorInterface in TranslationDataCollector Don't reference symfony/security [HttpClient] display proper error message on TransportException when curl is used [FrameworkBundle] fix named autowiring aliases for TagAwareCacheInterface [Cache] improve logged messages [FrameworkBundle] improve cs [Mime][HttpFoundation] Added mime type audio/x-hx-aac-adts bumped Symfony version to 4.3.0 updated VERSION for 4.3.0-BETA2 updated CHANGELOG for 4.3.0-BETA2 [HttpClient] Only use CURLMOPT_MAX_HOST_CONNECTIONS & CURL_VERSION_HTTP2 if defined [Security] fixed a fatal error when upgrading from 4.2 [HttpClient] Allow arrays as query parameters Throws UnrecoverableMessageHandlingException when passed invalid entity manager name for Doctrine middlewares [Messenger] Make redis Connection::get() non blocking by default ...
This commit is contained in:
commit
5dba412d30
@ -7,6 +7,51 @@ in 4.3 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.3.0...v4.3.1
|
||||
|
||||
* 4.3.0-BETA2 (2019-05-22)
|
||||
|
||||
* bug #31569 [HttpClient] Only use CURLMOPT_MAX_HOST_CONNECTIONS & CURL_VERSION_HTTP2 if defined (GawainLynch)
|
||||
* bug #31566 [Security] fixed a fatal error when upgrading from 4.2 (fabpot)
|
||||
* bug #31219 [HttpClient] Allow arrays as query parameters (sleepyboy)
|
||||
* bug #31482 [Messenger][DoctrineBridge] Throws UnrecoverableMessageHandlingException when passed invalid entity manager name (Koc)
|
||||
* feature #31471 [Messenger] Add "non sendable" stamps (weaverryan)
|
||||
* bug #31545 [Messenger] Fix redis Connection::get() should be non blocking by default (chalasr)
|
||||
* bug #31537 [Workflow] use method marking store (noniagriconomie)
|
||||
* bug #31551 [ProxyManager] isProxyCandidate() does not take into account interfaces (andrerom)
|
||||
* bug #31542 [HttpClient] add missing argument check (nicolas-grekas)
|
||||
* bug #31544 [Messenger] Fix undefined index on read timeout (chalasr)
|
||||
* bug #31335 [Doctrine] Respect parent class contract in ContainerAwareEventManager (Koc)
|
||||
* bug #31421 [Routing][AnnotationClassLoader] fix utf-8 encoding in default route name (przemyslaw-bogusz)
|
||||
* bug #31493 [EventDispatcher] Removed "callable" type hint from WrappedListener constructor (wskorodecki)
|
||||
* bug #31502 [WebProfilerBundle][Form] The form data collector return serialized data (Simperfit)
|
||||
* bug #31510 Use the current working dir as default first arg in 'link' binary (lyrixx)
|
||||
* bug #31524 [HttpFoundation] prevent deprecation when filesize matches error code (xabbuh)
|
||||
* bug #31535 [Debug] Wrap call to require_once in a try/catch (lyrixx)
|
||||
* feature #31030 [Serializer] Deprecate calling createChildContext without the format parameter (dbu)
|
||||
* bug #31459 Fix the interface incompatibility of EventDispatchers (keulinho)
|
||||
* bug #31463 [DI] default to service id - *not* FQCN - when building tagged locators (nicolas-grekas)
|
||||
* feature #31294 [Form] Add intl/choice_translation_locale option to TimezoneType (ro0NL)
|
||||
* feature #31452 [FrameworkBundle] Add cache configuration for PropertyInfo (alanpoulain)
|
||||
* feature #31486 [Doctrine][PropertyInfo] Detect if the ID is writeable (dunglas)
|
||||
* bug #31481 [Validator] Autovalidation: skip readonly props (dunglas)
|
||||
* bug #31480 Update dependencies in the main component (DavidPrevot)
|
||||
* bug #31477 [PropertyAccess] Add missing property to PropertyAccessor (vudaltsov)
|
||||
* bug #31479 [Cache] fix saving unrelated keys in recursive callback calls (nicolas-grekas)
|
||||
* bug #30930 [FrameworkBundle] Fixed issue when a parameter contains a '' (lyrixx)
|
||||
* bug #31438 [Serializer] Fix denormalization of object with variadic constructor typed argument (ajgarlag)
|
||||
* bug #31445 [Messenger] Making cache rebuild correctly when message subscribers change (weaverryan)
|
||||
* bug #31442 [Validator] Fix finding translator parent definition in compiler pass (deguif)
|
||||
* bug #31475 [HttpFoundation] Allow set 'None' on samesite cookie flag (markitosgv)
|
||||
* feature #31454 [Messenger] remove send_and_handle which can be achieved with SyncTransport (Tobion)
|
||||
* bug #31425 [Messenger] On failure retry, make message appear received from original sender (weaverryan)
|
||||
* bug #31472 [Messenger] Fix routable message bus default bus (weaverryan)
|
||||
* bug #31465 [Serializer] Fix BC break: DEPTH_KEY_PATTERN must be public (dunglas)
|
||||
* bug #31458 [TwigBundle] Fix Mailer integration in Twig (fabpot)
|
||||
* bug #31456 Remove deprecated usage of some Twig features (fabpot)
|
||||
* bug #31207 [Routing] Fixed unexpected 404 NoConfigurationException (yceruto)
|
||||
* bug #31261 [Console] Commands with an alias should not be recognized as ambiguous when using register (Simperfit)
|
||||
* bug #31371 [DI] Removes number of elements information in debug mode (jschaedl)
|
||||
* bug #31418 [FrameworkBundle] clarify the possible class/interface of the cache (xabbuh)
|
||||
|
||||
* 4.3.0-BETA1 (2019-05-09)
|
||||
|
||||
* feature #31249 [Translator] Set sources when extracting strings from php files (Stadly)
|
||||
|
@ -12,8 +12,8 @@
|
||||
namespace Symfony\Bridge\Doctrine\Messenger;
|
||||
|
||||
use Doctrine\Common\Persistence\ManagerRegistry;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
|
||||
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
|
||||
use Symfony\Component\Messenger\Middleware\StackInterface;
|
||||
|
||||
@ -40,10 +40,10 @@ class DoctrineCloseConnectionMiddleware implements MiddlewareInterface
|
||||
*/
|
||||
public function handle(Envelope $envelope, StackInterface $stack): Envelope
|
||||
{
|
||||
$entityManager = $this->managerRegistry->getManager($this->entityManagerName);
|
||||
|
||||
if (!$entityManager instanceof EntityManagerInterface) {
|
||||
throw new \InvalidArgumentException(sprintf('The ObjectManager with name "%s" must be an instance of EntityManagerInterface', $this->entityManagerName));
|
||||
try {
|
||||
$entityManager = $this->managerRegistry->getManager($this->entityManagerName);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
throw new UnrecoverableMessageHandlingException($e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -12,8 +12,8 @@
|
||||
namespace Symfony\Bridge\Doctrine\Messenger;
|
||||
|
||||
use Doctrine\Common\Persistence\ManagerRegistry;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
|
||||
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
|
||||
use Symfony\Component\Messenger\Middleware\StackInterface;
|
||||
|
||||
@ -40,10 +40,10 @@ class DoctrinePingConnectionMiddleware implements MiddlewareInterface
|
||||
*/
|
||||
public function handle(Envelope $envelope, StackInterface $stack): Envelope
|
||||
{
|
||||
$entityManager = $this->managerRegistry->getManager($this->entityManagerName);
|
||||
|
||||
if (!$entityManager instanceof EntityManagerInterface) {
|
||||
throw new \InvalidArgumentException(sprintf('The ObjectManager with name "%s" must be an instance of EntityManagerInterface', $this->entityManagerName));
|
||||
try {
|
||||
$entityManager = $this->managerRegistry->getManager($this->entityManagerName);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
throw new UnrecoverableMessageHandlingException($e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
$connection = $entityManager->getConnection();
|
||||
|
@ -12,8 +12,8 @@
|
||||
namespace Symfony\Bridge\Doctrine\Messenger;
|
||||
|
||||
use Doctrine\Common\Persistence\ManagerRegistry;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
|
||||
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
|
||||
use Symfony\Component\Messenger\Middleware\StackInterface;
|
||||
|
||||
@ -40,10 +40,10 @@ class DoctrineTransactionMiddleware implements MiddlewareInterface
|
||||
*/
|
||||
public function handle(Envelope $envelope, StackInterface $stack): Envelope
|
||||
{
|
||||
$entityManager = $this->managerRegistry->getManager($this->entityManagerName);
|
||||
|
||||
if (!$entityManager instanceof EntityManagerInterface) {
|
||||
throw new \InvalidArgumentException(sprintf('The ObjectManager with name "%s" must be an instance of EntityManagerInterface', $this->entityManagerName));
|
||||
try {
|
||||
$entityManager = $this->managerRegistry->getManager($this->entityManagerName);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
throw new UnrecoverableMessageHandlingException($e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
$entityManager->getConnection()->beginTransaction();
|
||||
|
@ -16,6 +16,7 @@ use Doctrine\DBAL\Connection;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bridge\Doctrine\Messenger\DoctrineCloseConnectionMiddleware;
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
|
||||
use Symfony\Component\Messenger\Test\Middleware\MiddlewareTestCase;
|
||||
|
||||
class DoctrineCloseConnectionMiddlewareTest extends MiddlewareTestCase
|
||||
@ -50,4 +51,19 @@ class DoctrineCloseConnectionMiddlewareTest extends MiddlewareTestCase
|
||||
|
||||
$this->middleware->handle(new Envelope(new \stdClass()), $this->getStackMock());
|
||||
}
|
||||
|
||||
public function testInvalidEntityManagerThrowsException()
|
||||
{
|
||||
$managerRegistry = $this->createMock(ManagerRegistry::class);
|
||||
$managerRegistry
|
||||
->method('getManager')
|
||||
->with('unknown_manager')
|
||||
->will($this->throwException(new \InvalidArgumentException()));
|
||||
|
||||
$middleware = new DoctrineCloseConnectionMiddleware($managerRegistry, 'unknown_manager');
|
||||
|
||||
$this->expectException(UnrecoverableMessageHandlingException::class);
|
||||
|
||||
$middleware->handle(new Envelope(new \stdClass()), $this->getStackMock(false));
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use Doctrine\DBAL\Connection;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bridge\Doctrine\Messenger\DoctrinePingConnectionMiddleware;
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
|
||||
use Symfony\Component\Messenger\Test\Middleware\MiddlewareTestCase;
|
||||
|
||||
class DoctrinePingConnectionMiddlewareTest extends MiddlewareTestCase
|
||||
@ -71,4 +72,19 @@ class DoctrinePingConnectionMiddlewareTest extends MiddlewareTestCase
|
||||
|
||||
$this->middleware->handle(new Envelope(new \stdClass()), $this->getStackMock());
|
||||
}
|
||||
|
||||
public function testInvalidEntityManagerThrowsException()
|
||||
{
|
||||
$managerRegistry = $this->createMock(ManagerRegistry::class);
|
||||
$managerRegistry
|
||||
->method('getManager')
|
||||
->with('unknown_manager')
|
||||
->will($this->throwException(new \InvalidArgumentException()));
|
||||
|
||||
$middleware = new DoctrinePingConnectionMiddleware($managerRegistry, 'unknown_manager');
|
||||
|
||||
$this->expectException(UnrecoverableMessageHandlingException::class);
|
||||
|
||||
$middleware->handle(new Envelope(new \stdClass()), $this->getStackMock(false));
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use Doctrine\DBAL\Connection;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bridge\Doctrine\Messenger\DoctrineTransactionMiddleware;
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
|
||||
use Symfony\Component\Messenger\Test\Middleware\MiddlewareTestCase;
|
||||
|
||||
class DoctrineTransactionMiddlewareTest extends MiddlewareTestCase
|
||||
@ -67,4 +68,19 @@ class DoctrineTransactionMiddlewareTest extends MiddlewareTestCase
|
||||
|
||||
$this->middleware->handle(new Envelope(new \stdClass()), $this->getThrowingStackMock());
|
||||
}
|
||||
|
||||
public function testInvalidEntityManagerThrowsException()
|
||||
{
|
||||
$managerRegistry = $this->createMock(ManagerRegistry::class);
|
||||
$managerRegistry
|
||||
->method('getManager')
|
||||
->with('unknown_manager')
|
||||
->will($this->throwException(new \InvalidArgumentException()));
|
||||
|
||||
$middleware = new DoctrineTransactionMiddleware($managerRegistry, 'unknown_manager');
|
||||
|
||||
$this->expectException(UnrecoverableMessageHandlingException::class);
|
||||
|
||||
$middleware->handle(new Envelope(new \stdClass()), $this->getStackMock(false));
|
||||
}
|
||||
}
|
||||
|
@ -29,11 +29,11 @@
|
||||
"symfony/dependency-injection": "~3.4|~4.0",
|
||||
"symfony/form": "~4.3",
|
||||
"symfony/http-kernel": "~3.4|~4.0",
|
||||
"symfony/messenger": "~4.2",
|
||||
"symfony/messenger": "~4.3",
|
||||
"symfony/property-access": "~3.4|~4.0",
|
||||
"symfony/property-info": "~3.4|~4.0",
|
||||
"symfony/proxy-manager-bridge": "~3.4|~4.0",
|
||||
"symfony/security": "~3.4|~4.0",
|
||||
"symfony/security-core": "~3.4|~4.0",
|
||||
"symfony/expression-language": "~3.4|~4.0",
|
||||
"symfony/validator": "~3.4|~4.0",
|
||||
"symfony/translation": "~3.4|~4.0",
|
||||
@ -49,7 +49,7 @@
|
||||
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
|
||||
"symfony/dependency-injection": "<3.4",
|
||||
"symfony/form": "<4.3",
|
||||
"symfony/messenger": "<4.2"
|
||||
"symfony/messenger": "<4.3"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/form": "",
|
||||
|
@ -34,8 +34,9 @@
|
||||
"symfony/templating": "~3.4|~4.0",
|
||||
"symfony/translation": "~4.2",
|
||||
"symfony/yaml": "~3.4|~4.0",
|
||||
"symfony/security": "~3.4|~4.0",
|
||||
"symfony/security-acl": "~2.8|~3.0",
|
||||
"symfony/security-csrf": "~3.4|~4.0",
|
||||
"symfony/security-http": "~3.4|~4.0",
|
||||
"symfony/stopwatch": "~3.4|~4.0",
|
||||
"symfony/console": "~3.4|~4.0",
|
||||
"symfony/var-dumper": "~3.4|~4.0",
|
||||
@ -59,7 +60,9 @@
|
||||
"symfony/templating": "For using the TwigEngine",
|
||||
"symfony/translation": "For using the TranslationExtension",
|
||||
"symfony/yaml": "For using the YamlExtension",
|
||||
"symfony/security": "For using the SecurityExtension",
|
||||
"symfony/security-core": "For using the SecurityExtension",
|
||||
"symfony/security-csrf": "For using the CsrfExtension",
|
||||
"symfony/security-http": "For using the LogoutUrlExtension",
|
||||
"symfony/stopwatch": "For using the StopwatchExtension",
|
||||
"symfony/var-dumper": "For using the DumpExtension",
|
||||
"symfony/expression-language": "For using the ExpressionExtension",
|
||||
|
@ -117,6 +117,7 @@ use Symfony\Component\Workflow\WorkflowInterface;
|
||||
use Symfony\Component\Yaml\Command\LintCommand as BaseYamlLintCommand;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
use Symfony\Contracts\Service\ResetInterface;
|
||||
use Symfony\Contracts\Service\ServiceSubscriberInterface;
|
||||
@ -737,7 +738,7 @@ class FrameworkExtension extends Extension
|
||||
}
|
||||
|
||||
if (!class_exists(Security::class)) {
|
||||
throw new LogicException('Cannot guard workflows as the Security component is not installed. Try running "composer require symfony/security".');
|
||||
throw new LogicException('Cannot guard workflows as the Security component is not installed. Try running "composer require symfony/security-core".');
|
||||
}
|
||||
|
||||
$guard = new Definition(Workflow\EventListener\GuardListener::class);
|
||||
@ -1819,13 +1820,9 @@ class FrameworkExtension extends Extension
|
||||
$pool['adapter'] = '.'.$pool['adapter'].'.inner';
|
||||
}
|
||||
$definition = new ChildDefinition($pool['adapter']);
|
||||
if (!\in_array($name, ['cache.app', 'cache.system'], true)) {
|
||||
$container->registerAliasForArgument($name, CacheInterface::class);
|
||||
$container->registerAliasForArgument($name, CacheItemPoolInterface::class);
|
||||
}
|
||||
|
||||
if ($pool['tags']) {
|
||||
if ($config['pools'][$pool['tags']]['tags'] ?? false) {
|
||||
if (true !== $pool['tags'] && ($config['pools'][$pool['tags']]['tags'] ?? false)) {
|
||||
$pool['tags'] = '.'.$pool['tags'].'.inner';
|
||||
}
|
||||
$container->register($name, TagAwareAdapter::class)
|
||||
@ -1837,7 +1834,21 @@ class FrameworkExtension extends Extension
|
||||
$pool['name'] = $name;
|
||||
$pool['public'] = false;
|
||||
$name = '.'.$name.'.inner';
|
||||
|
||||
if (!\in_array($pool['name'], ['cache.app', 'cache.system'], true)) {
|
||||
$container->registerAliasForArgument($pool['name'], TagAwareCacheInterface::class);
|
||||
$container->registerAliasForArgument($name, CacheInterface::class, $pool['name']);
|
||||
$container->registerAliasForArgument($name, CacheItemPoolInterface::class, $pool['name']);
|
||||
}
|
||||
} elseif (!\in_array($name, ['cache.app', 'cache.system'], true)) {
|
||||
$container->register('.'.$name.'.taggable', TagAwareAdapter::class)
|
||||
->addArgument(new Reference($name))
|
||||
;
|
||||
$container->registerAliasForArgument('.'.$name.'.taggable', TagAwareCacheInterface::class, $name);
|
||||
$container->registerAliasForArgument($name, CacheInterface::class);
|
||||
$container->registerAliasForArgument($name, CacheItemPoolInterface::class);
|
||||
}
|
||||
|
||||
$definition->setPublic($pool['public']);
|
||||
unset($pool['adapter'], $pool['public'], $pool['tags']);
|
||||
|
||||
|
@ -38,7 +38,6 @@
|
||||
"symfony/css-selector": "~3.4|~4.0",
|
||||
"symfony/dom-crawler": "^4.3",
|
||||
"symfony/polyfill-intl-icu": "~1.0",
|
||||
"symfony/security": "~3.4|~4.0",
|
||||
"symfony/form": "^4.3",
|
||||
"symfony/expression-language": "~3.4|~4.0",
|
||||
"symfony/http-client": "^4.3",
|
||||
@ -46,8 +45,8 @@
|
||||
"symfony/messenger": "^4.3",
|
||||
"symfony/mime": "^4.3",
|
||||
"symfony/process": "~3.4|~4.0",
|
||||
"symfony/security-core": "~3.4|~4.0",
|
||||
"symfony/security-csrf": "~3.4|~4.0",
|
||||
"symfony/security-http": "~3.4|~4.0",
|
||||
"symfony/serializer": "^4.3",
|
||||
"symfony/stopwatch": "~3.4|~4.0",
|
||||
"symfony/translation": "~4.2",
|
||||
|
@ -253,7 +253,8 @@ abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagA
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
CacheItem::log($this->logger, 'Failed to delete key "{key}"', ['key' => $key, 'exception' => $e]);
|
||||
$message = 'Failed to delete key "{key}"'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
|
||||
CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e]);
|
||||
$ok = false;
|
||||
}
|
||||
|
||||
|
@ -198,7 +198,7 @@ class RedisTagAwareAdapter extends AbstractTagAwareAdapter
|
||||
$info = $host->info('Server');
|
||||
$info = isset($info['Server']) ? $info['Server'] : $info;
|
||||
if (version_compare($info['redis_version'], '3.2', '<')) {
|
||||
CacheItem::log($this->logger, 'Redis server needs to be version 3.2 or higher, your Redis server was detected as {version}', ['version' => $info['redis_version']]);
|
||||
CacheItem::log($this->logger, 'Redis server needs to be version 3.2 or higher, your Redis server was detected as '.$info['redis_version']);
|
||||
|
||||
return $this->redisServerSupportSPOP = false;
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterfac
|
||||
return $value;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch key "{key}"', ['key' => $key, 'exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to fetch key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
|
||||
}
|
||||
|
||||
return $default;
|
||||
@ -90,7 +90,7 @@ abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterfac
|
||||
try {
|
||||
$values = $this->doFetch($ids);
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch requested values', ['keys' => $keys, 'exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to fetch values: '.$e->getMessage(), ['keys' => $keys, 'exception' => $e]);
|
||||
$values = [];
|
||||
}
|
||||
$ids = array_combine($ids, $keys);
|
||||
@ -129,7 +129,8 @@ abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterfac
|
||||
foreach (\is_array($e) ? $e : array_keys($valuesById) as $id) {
|
||||
$keys[] = substr($id, \strlen($this->namespace));
|
||||
}
|
||||
CacheItem::log($this->logger, 'Failed to save values', ['keys' => $keys, 'exception' => $e instanceof \Exception ? $e : null]);
|
||||
$message = 'Failed to save values'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
|
||||
CacheItem::log($this->logger, $message, ['keys' => $keys, 'exception' => $e instanceof \Exception ? $e : null]);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -175,7 +176,7 @@ abstract class AbstractCache implements Psr16CacheInterface, LoggerAwareInterfac
|
||||
yield $key => $value;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch requested values', ['keys' => array_values($keys), 'exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to fetch values: '.$e->getMessage(), ['keys' => array_values($keys), 'exception' => $e]);
|
||||
}
|
||||
|
||||
foreach ($keys as $key) {
|
||||
|
@ -52,7 +52,7 @@ trait AbstractAdapterTrait
|
||||
$isHit = true;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch key "{key}"', ['key' => $key, 'exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to fetch key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
|
||||
}
|
||||
|
||||
return $f($key, $value, $isHit);
|
||||
@ -74,7 +74,7 @@ trait AbstractAdapterTrait
|
||||
try {
|
||||
$items = $this->doFetch($ids);
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch requested items', ['keys' => $keys, 'exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to fetch items: '.$e->getMessage(), ['keys' => $keys, 'exception' => $e]);
|
||||
$items = [];
|
||||
}
|
||||
$ids = array_combine($ids, $keys);
|
||||
@ -129,7 +129,7 @@ trait AbstractAdapterTrait
|
||||
yield $key => $f($key, $value, true);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to fetch requested items', ['keys' => array_values($keys), 'exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to fetch items: '.$e->getMessage(), ['keys' => array_values($keys), 'exception' => $e]);
|
||||
}
|
||||
|
||||
foreach ($keys as $key) {
|
||||
|
@ -94,7 +94,7 @@ trait AbstractTrait
|
||||
try {
|
||||
return $this->doHave($id);
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to check if key "{key}" is cached', ['key' => $key, 'exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to check if key "{key}" is cached: '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -122,7 +122,7 @@ trait AbstractTrait
|
||||
try {
|
||||
return $this->doClear($this->namespace) || $cleared;
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to clear the cache', ['exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to clear the cache: '.$e->getMessage(), ['exception' => $e]);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -166,7 +166,8 @@ trait AbstractTrait
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
CacheItem::log($this->logger, 'Failed to delete key "{key}"', ['key' => $key, 'exception' => $e]);
|
||||
$message = 'Failed to delete key "{key}"'.($e instanceof \Exception ? ': '.$e->getMessage() : '.');
|
||||
CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e]);
|
||||
$ok = false;
|
||||
}
|
||||
|
||||
|
@ -128,8 +128,8 @@ trait ArrayTrait
|
||||
$serialized = serialize($value);
|
||||
} catch (\Exception $e) {
|
||||
$type = \is_object($value) ? \get_class($value) : \gettype($value);
|
||||
$message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
|
||||
CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null]);
|
||||
$message = sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage());
|
||||
CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e]);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -151,7 +151,7 @@ trait ArrayTrait
|
||||
try {
|
||||
$value = unserialize($value);
|
||||
} catch (\Exception $e) {
|
||||
CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', ['key' => $key, 'exception' => $e]);
|
||||
CacheItem::log($this->logger, 'Failed to unserialize key "{key}": '.$e->getMessage(), ['key' => $key, 'exception' => $e]);
|
||||
$value = false;
|
||||
}
|
||||
if (false === $value) {
|
||||
|
@ -41,7 +41,7 @@ class WrappedListener
|
||||
public function __construct($listener, ?string $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null)
|
||||
{
|
||||
$this->listener = $listener;
|
||||
$this->optimizedListener = $listener instanceof \Closure ? $listener : \Closure::fromCallable($listener);
|
||||
$this->optimizedListener = $listener instanceof \Closure ? $listener : (\is_callable($listener) ? \Closure::fromCallable($listener) : null);
|
||||
$this->stopwatch = $stopwatch;
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->called = false;
|
||||
@ -123,7 +123,7 @@ class WrappedListener
|
||||
|
||||
$e = $this->stopwatch->start($this->name, 'event_listener');
|
||||
|
||||
($this->optimizedListener)($event, $eventName, $dispatcher);
|
||||
($this->optimizedListener ?? $this->listener)($event, $eventName, $dispatcher);
|
||||
|
||||
if ($e->isStarted()) {
|
||||
$e->stop();
|
||||
|
@ -21,7 +21,7 @@ class WrappedListenerTest extends TestCase
|
||||
/**
|
||||
* @dataProvider provideListenersToDescribe
|
||||
*/
|
||||
public function testListenerDescription(callable $listener, $expected)
|
||||
public function testListenerDescription($listener, $expected)
|
||||
{
|
||||
$wrappedListener = new WrappedListener($listener, null, $this->getMockBuilder(Stopwatch::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock());
|
||||
|
||||
@ -34,6 +34,7 @@ class WrappedListenerTest extends TestCase
|
||||
[new FooListener(), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::__invoke'],
|
||||
[[new FooListener(), 'listen'], 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listen'],
|
||||
[['Symfony\Component\EventDispatcher\Tests\Debug\FooListener', 'listenStatic'], 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listenStatic'],
|
||||
[['Symfony\Component\EventDispatcher\Tests\Debug\FooListener', 'invalidMethod'], 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::invalidMethod'],
|
||||
['var_dump', 'var_dump'],
|
||||
[function () {}, 'closure'],
|
||||
[\Closure::fromCallable([new FooListener(), 'listen']), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listen'],
|
||||
|
@ -572,7 +572,7 @@ class Filesystem
|
||||
$targetDirInfo = new \SplFileInfo($targetDir);
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
if ($file->getPathName() === $targetDir || $file->getRealPath() === $targetDir || 0 === strpos($file->getRealPath(), $targetDirInfo->getRealPath())) {
|
||||
if ($file->getPathname() === $targetDir || $file->getRealPath() === $targetDir || 0 === strpos($file->getRealPath(), $targetDirInfo->getRealPath())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,9 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface
|
||||
if (\defined('CURLPIPE_MULTIPLEX')) {
|
||||
curl_multi_setopt($this->multi->handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
}
|
||||
curl_multi_setopt($this->multi->handle, CURLMOPT_MAX_HOST_CONNECTIONS, 0 < $maxHostConnections ? $maxHostConnections : PHP_INT_MAX);
|
||||
if (\defined('CURLMOPT_MAX_HOST_CONNECTIONS')) {
|
||||
curl_multi_setopt($this->multi->handle, CURLMOPT_MAX_HOST_CONNECTIONS, 0 < $maxHostConnections ? $maxHostConnections : PHP_INT_MAX);
|
||||
}
|
||||
|
||||
// Skip configuring HTTP/2 push when it's unsupported or buggy, see https://bugs.php.net/bug.php?id=77535
|
||||
if (0 >= $maxPendingPushes || \PHP_VERSION_ID < 70217 || (\PHP_VERSION_ID >= 70300 && \PHP_VERSION_ID < 70304)) {
|
||||
@ -188,7 +190,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface
|
||||
$curlopts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0;
|
||||
} elseif (1.1 === (float) $options['http_version'] || 'https:' !== $scheme) {
|
||||
$curlopts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1;
|
||||
} elseif (CURL_VERSION_HTTP2 & curl_version()['features']) {
|
||||
} elseif (\defined('CURL_VERSION_HTTP2') && CURL_VERSION_HTTP2 & curl_version()['features']) {
|
||||
$curlopts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ trait HttpExceptionTrait
|
||||
$this->response = $response;
|
||||
$code = $response->getInfo('http_code');
|
||||
$url = $response->getInfo('url');
|
||||
$message = sprintf('HTTP %d returned for URL "%s".', $code, $url);
|
||||
$message = sprintf('HTTP %d returned for "%s".', $code, $url);
|
||||
|
||||
$httpCodeFound = false;
|
||||
$isJson = false;
|
||||
@ -37,7 +37,7 @@ trait HttpExceptionTrait
|
||||
break;
|
||||
}
|
||||
|
||||
$message = sprintf('%s returned for URL "%s".', $h, $url);
|
||||
$message = sprintf('%s returned for "%s".', $h, $url);
|
||||
$httpCodeFound = true;
|
||||
}
|
||||
|
||||
|
@ -481,17 +481,20 @@ trait HttpClientTrait
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($queryArray as $k => $v) {
|
||||
if (is_scalar($v)) {
|
||||
$queryArray[$k] = rawurlencode($k).'='.rawurlencode($v);
|
||||
} elseif (null === $v) {
|
||||
unset($queryArray[$k]);
|
||||
|
||||
if ($replace) {
|
||||
if ($replace) {
|
||||
foreach ($queryArray as $k => $v) {
|
||||
if (null === $v) {
|
||||
unset($query[$k]);
|
||||
}
|
||||
} else {
|
||||
throw new InvalidArgumentException(sprintf('Unsupported value for query parameter "%s": scalar or null expected, %s given.', $k, \gettype($v)));
|
||||
}
|
||||
}
|
||||
|
||||
$queryString = http_build_query($queryArray, '', '&', PHP_QUERY_RFC3986);
|
||||
$queryArray = [];
|
||||
|
||||
if ($queryString) {
|
||||
foreach (explode('&', $queryString) as $v) {
|
||||
$queryArray[rawurldecode(explode('=', $v, 2)[0])] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,7 @@ final class CurlResponse implements ResponseInterface
|
||||
|
||||
while ($info = curl_multi_info_read($multi->handle)) {
|
||||
$multi->handlesActivity[(int) $info['handle']][] = null;
|
||||
$multi->handlesActivity[(int) $info['handle']][] = \in_array($info['result'], [\CURLE_OK, \CURLE_TOO_MANY_REDIRECTS], true) || (\CURLE_WRITE_ERROR === $info['result'] && 'destruct' === @curl_getinfo($info['handle'], CURLINFO_PRIVATE)) ? null : new TransportException(curl_error($info['handle']));
|
||||
$multi->handlesActivity[(int) $info['handle']][] = \in_array($info['result'], [\CURLE_OK, \CURLE_TOO_MANY_REDIRECTS], true) || (\CURLE_WRITE_ERROR === $info['result'] && 'destruct' === @curl_getinfo($info['handle'], CURLINFO_PRIVATE)) ? null : new TransportException(sprintf('%s for"%s".', curl_strerror($info['result']), curl_getinfo($info['handle'], CURLINFO_EFFECTIVE_URL)));
|
||||
}
|
||||
} finally {
|
||||
self::$performing = false;
|
||||
|
@ -25,7 +25,9 @@ use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||
*/
|
||||
class MockResponse implements ResponseInterface
|
||||
{
|
||||
use ResponseTrait;
|
||||
use ResponseTrait {
|
||||
doDestruct as public __destruct;
|
||||
}
|
||||
|
||||
private $body;
|
||||
private $requestOptions = [];
|
||||
@ -162,8 +164,8 @@ class MockResponse implements ResponseInterface
|
||||
$offset = 0;
|
||||
$chunk[1]->getStatusCode();
|
||||
$response->headers = $chunk[1]->getHeaders(false);
|
||||
$multi->handlesActivity[$id][] = new FirstChunk();
|
||||
self::readResponse($response, $chunk[0], $chunk[1], $offset);
|
||||
$multi->handlesActivity[$id][] = new FirstChunk();
|
||||
} catch (\Throwable $e) {
|
||||
$multi->handlesActivity[$id][] = null;
|
||||
$multi->handlesActivity[$id][] = $e;
|
||||
|
@ -61,14 +61,14 @@ class CurlHttpClientTest extends HttpClientTestCase
|
||||
$js->getHeaders();
|
||||
|
||||
$expected = [
|
||||
'Request: GET https://http2-push.io/',
|
||||
'Queueing pushed response: https://http2-push.io/css/style.css',
|
||||
'Queueing pushed response: https://http2-push.io/js/http2-push.js',
|
||||
'Response: 200 https://http2-push.io/',
|
||||
'Connecting request to pushed response: GET https://http2-push.io/css/style.css',
|
||||
'Connecting request to pushed response: GET https://http2-push.io/js/http2-push.js',
|
||||
'Response: 200 https://http2-push.io/css/style.css',
|
||||
'Response: 200 https://http2-push.io/js/http2-push.js',
|
||||
'Request: "GET https://http2-push.io/"',
|
||||
'Queueing pushed response: "https://http2-push.io/css/style.css"',
|
||||
'Queueing pushed response: "https://http2-push.io/js/http2-push.js"',
|
||||
'Response: "200 https://http2-push.io/"',
|
||||
'Connecting request to pushed response: "GET https://http2-push.io/css/style.css"',
|
||||
'Connecting request to pushed response: "GET https://http2-push.io/js/http2-push.js"',
|
||||
'Response: "200 https://http2-push.io/css/style.css"',
|
||||
'Response: "200 https://http2-push.io/js/http2-push.js"',
|
||||
];
|
||||
$this->assertSame($expected, $logger->logs);
|
||||
}
|
||||
|
@ -141,6 +141,10 @@ class HttpClientTraitTest extends TestCase
|
||||
yield [[null, null, 'bar', '?a=1&c=c', null], 'bar?a=a&b=b', ['b' => null, 'c' => 'c', 'a' => 1]];
|
||||
yield [[null, null, 'bar', '?a=b+c&b=b', null], 'bar?a=b+c', ['b' => 'b']];
|
||||
yield [[null, null, 'bar', '?a=b%2B%20c', null], 'bar?a=b+c', ['a' => 'b+ c']];
|
||||
yield [[null, null, 'bar', '?a%5Bb%5D=c', null], 'bar', ['a' => ['b' => 'c']]];
|
||||
yield [[null, null, 'bar', '?a%5Bb%5Bc%5D=d', null], 'bar?a[b[c]=d', []];
|
||||
yield [[null, null, 'bar', '?a%5Bb%5D%5Bc%5D=dd', null], 'bar?a[b][c]=d&e[f]=g', ['a' => ['b' => ['c' => 'dd']], 'e[f]' => null]];
|
||||
yield [[null, null, 'bar', '?a=b&a%5Bb%20c%5D=d&e%3Df=%E2%9C%93', null], 'bar?a=b', ['a' => ['b c' => 'd'], 'e=f' => '✓']];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,7 +115,7 @@ class MockHttpClientTest extends HttpClientTestCase
|
||||
case 'testResolve':
|
||||
$responses[] = new MockResponse($body, ['response_headers' => $headers]);
|
||||
$responses[] = new MockResponse($body, ['response_headers' => $headers]);
|
||||
$responses[] = $client->request('GET', 'http://symfony.com:8057/');
|
||||
$responses[] = new MockResponse((function () { throw new \Exception('Fake connection timeout'); yield ''; })(), ['response_headers' => $headers]);
|
||||
break;
|
||||
|
||||
case 'testTimeoutOnStream':
|
||||
|
@ -645,6 +645,7 @@ class MimeTypeExtensionGuesser implements ExtensionGuesserInterface
|
||||
'audio/x-aiff' => 'aif',
|
||||
'audio/x-caf' => 'caf',
|
||||
'audio/x-flac' => 'flac',
|
||||
'audio/x-hx-aac-adts' => 'aac',
|
||||
'audio/x-matroska' => 'mka',
|
||||
'audio/x-mpegurl' => 'm3u',
|
||||
'audio/x-ms-wax' => 'wax',
|
||||
|
@ -17,6 +17,22 @@ use Symfony\Component\Ldap\Entry;
|
||||
|
||||
class EntryManagerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Ldap\Exception\LdapException
|
||||
* @expectedExceptionMessage Entry "$$$$$$" malformed, could not parse RDN.
|
||||
*/
|
||||
public function testMove()
|
||||
{
|
||||
$connection = $this->createMock(Connection::class);
|
||||
$connection
|
||||
->expects($this->once())
|
||||
->method('isBound')->willReturn(true);
|
||||
|
||||
$entry = new Entry('$$$$$$');
|
||||
$entryManager = new EntryManager($connection);
|
||||
$entryManager->move($entry, 'a');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Ldap\Exception\NotBoundException
|
||||
* @expectedExceptionMessage Query execution is not possible without binding the connection first.
|
||||
|
@ -4,6 +4,9 @@ CHANGELOG
|
||||
4.3.0
|
||||
-----
|
||||
|
||||
* Added `NonSendableStampInterface` that a stamp can implement if
|
||||
it should not be sent to a transport. Transport serializers
|
||||
must now check for these stamps and not encode them.
|
||||
* [BC BREAK] `SendersLocatorInterface` has an additional method:
|
||||
`getSenderByAlias()`.
|
||||
* Removed argument `?bool &$handle = false` from `SendersLocatorInterface::getSenders`
|
||||
|
@ -80,6 +80,22 @@ final class Envelope
|
||||
return $cloned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all stamps that implement the given type.
|
||||
*/
|
||||
public function withoutStampsOfType(string $type): self
|
||||
{
|
||||
$cloned = clone $this;
|
||||
|
||||
foreach ($cloned->stamps as $class => $stamps) {
|
||||
if ($class === $type || \is_subclass_of($class, $type)) {
|
||||
unset($cloned->stamps[$class]);
|
||||
}
|
||||
}
|
||||
|
||||
return $cloned;
|
||||
}
|
||||
|
||||
public function last(string $stampFqcn): ?StampInterface
|
||||
{
|
||||
return isset($this->stamps[$stampFqcn]) ? end($this->stamps[$stampFqcn]) : null;
|
||||
|
@ -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\Messenger\Stamp;
|
||||
|
||||
/**
|
||||
* A stamp that should not be included with the Envelope if sent to a transport.
|
||||
*
|
||||
* @author Ryan Weaver <ryan@symfonycasts.com>
|
||||
*
|
||||
* @experimental in 4.3
|
||||
*/
|
||||
interface NonSendableStampInterface extends StampInterface
|
||||
{
|
||||
}
|
@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Stamp\DelayStamp;
|
||||
use Symfony\Component\Messenger\Stamp\ReceivedStamp;
|
||||
use Symfony\Component\Messenger\Stamp\StampInterface;
|
||||
use Symfony\Component\Messenger\Stamp\ValidationStamp;
|
||||
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
|
||||
|
||||
@ -50,6 +51,30 @@ class EnvelopeTest extends TestCase
|
||||
$this->assertCount(1, $envelope->all(DelayStamp::class));
|
||||
}
|
||||
|
||||
public function testWithoutStampsOfType()
|
||||
{
|
||||
$envelope = new Envelope(new DummyMessage('dummy'), [
|
||||
new ReceivedStamp('transport1'),
|
||||
new DelayStamp(5000),
|
||||
new DummyExtendsDelayStamp(5000),
|
||||
new DummyImplementsFooBarStampInterface(),
|
||||
]);
|
||||
|
||||
$envelope2 = $envelope->withoutStampsOfType(DummyNothingImplementsMeStampInterface::class);
|
||||
$this->assertEquals($envelope, $envelope2);
|
||||
|
||||
$envelope3 = $envelope2->withoutStampsOfType(ReceivedStamp::class);
|
||||
$this->assertEmpty($envelope3->all(ReceivedStamp::class));
|
||||
|
||||
$envelope4 = $envelope3->withoutStampsOfType(DelayStamp::class);
|
||||
$this->assertEmpty($envelope4->all(DelayStamp::class));
|
||||
$this->assertEmpty($envelope4->all(DummyExtendsDelayStamp::class));
|
||||
|
||||
$envelope5 = $envelope4->withoutStampsOfType(DummyFooBarStampInterface::class);
|
||||
$this->assertEmpty($envelope5->all(DummyImplementsFooBarStampInterface::class));
|
||||
$this->assertEmpty($envelope5->all());
|
||||
}
|
||||
|
||||
public function testLast()
|
||||
{
|
||||
$receivedStamp = new ReceivedStamp('transport');
|
||||
@ -92,3 +117,16 @@ class EnvelopeTest extends TestCase
|
||||
$this->assertCount(1, $envelope->all(ReceivedStamp::class));
|
||||
}
|
||||
}
|
||||
|
||||
class DummyExtendsDelayStamp extends DelayStamp
|
||||
{
|
||||
}
|
||||
interface DummyFooBarStampInterface extends StampInterface
|
||||
{
|
||||
}
|
||||
interface DummyNothingImplementsMeStampInterface extends StampInterface
|
||||
{
|
||||
}
|
||||
class DummyImplementsFooBarStampInterface implements DummyFooBarStampInterface
|
||||
{
|
||||
}
|
||||
|
@ -46,9 +46,9 @@ class ConnectionTest extends TestCase
|
||||
'host' => 'localhost',
|
||||
'port' => 6379,
|
||||
], [
|
||||
'blocking_timeout' => 30,
|
||||
'serializer' => 2,
|
||||
]),
|
||||
Connection::fromDsn('redis://localhost/queue/group1/consumer1', ['blocking_timeout' => 30])
|
||||
Connection::fromDsn('redis://localhost/queue/group1/consumer1', ['serializer' => 2])
|
||||
);
|
||||
}
|
||||
|
||||
@ -59,9 +59,9 @@ class ConnectionTest extends TestCase
|
||||
'host' => 'localhost',
|
||||
'port' => 6379,
|
||||
], [
|
||||
'blocking_timeout' => 30,
|
||||
'serializer' => 2,
|
||||
]),
|
||||
Connection::fromDsn('redis://localhost/queue/group1/consumer1?blocking_timeout=30')
|
||||
Connection::fromDsn('redis://localhost/queue/group1/consumer1?serializer=2')
|
||||
);
|
||||
}
|
||||
|
||||
@ -134,16 +134,20 @@ class ConnectionTest extends TestCase
|
||||
$redis->del('messenger-rejectthenget');
|
||||
}
|
||||
|
||||
public function testBlockingTimeout()
|
||||
public function testGetNonBlocking()
|
||||
{
|
||||
$redis = new \Redis();
|
||||
$connection = Connection::fromDsn('redis://localhost/messenger-blockingtimeout', ['blocking_timeout' => 1], $redis);
|
||||
|
||||
$connection = Connection::fromDsn('redis://localhost/messenger-getnonblocking', [], $redis);
|
||||
try {
|
||||
$connection->setup();
|
||||
} catch (TransportException $e) {
|
||||
}
|
||||
|
||||
$this->assertNull($connection->get());
|
||||
$redis->del('messenger-blockingtimeout');
|
||||
$this->assertNull($connection->get()); // no message, should return null immediately
|
||||
$connection->add('1', []);
|
||||
$this->assertNotEmpty($message = $connection->get());
|
||||
$connection->reject($message['id']);
|
||||
$redis->del('messenger-getnonblocking');
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\Messenger\Tests\Transport\Serialization;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Exception\MessageDecodingFailedException;
|
||||
use Symfony\Component\Messenger\Stamp\NonSendableStampInterface;
|
||||
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
|
||||
use Symfony\Component\Messenger\Transport\Serialization\PhpSerializer;
|
||||
|
||||
@ -63,4 +64,20 @@ class PhpSerializerTest extends TestCase
|
||||
'body' => 'O:13:"ReceivedSt0mp":0:{}',
|
||||
]);
|
||||
}
|
||||
|
||||
public function testEncodedSkipsNonEncodeableStamps()
|
||||
{
|
||||
$serializer = new PhpSerializer();
|
||||
|
||||
$envelope = new Envelope(new DummyMessage('Hello'), [
|
||||
new DummyPhpSerializerNonSendableStamp(),
|
||||
]);
|
||||
|
||||
$encoded = $serializer->encode($envelope);
|
||||
$this->assertNotContains('DummyPhpSerializerNonSendableStamp', $encoded['body']);
|
||||
}
|
||||
}
|
||||
|
||||
class DummyPhpSerializerNonSendableStamp implements NonSendableStampInterface
|
||||
{
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\Messenger\Tests\Transport\Serialization;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Exception\MessageDecodingFailedException;
|
||||
use Symfony\Component\Messenger\Stamp\NonSendableStampInterface;
|
||||
use Symfony\Component\Messenger\Stamp\SerializerStamp;
|
||||
use Symfony\Component\Messenger\Stamp\ValidationStamp;
|
||||
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
|
||||
@ -193,4 +194,19 @@ class SerializerTest extends TestCase
|
||||
'headers' => ['type' => 'NonExistentClass'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testEncodedSkipsNonEncodeableStamps()
|
||||
{
|
||||
$serializer = new Serializer();
|
||||
|
||||
$envelope = new Envelope(new DummyMessage('Hello'), [
|
||||
new DummySymfonySerializerNonSendableStamp(),
|
||||
]);
|
||||
|
||||
$encoded = $serializer->encode($envelope);
|
||||
$this->assertNotContains('DummySymfonySerializerNonSendableStamp', print_r($encoded['headers'], true));
|
||||
}
|
||||
}
|
||||
class DummySymfonySerializerNonSendableStamp implements NonSendableStampInterface
|
||||
{
|
||||
}
|
||||
|
@ -11,14 +11,14 @@
|
||||
|
||||
namespace Symfony\Component\Messenger\Transport\AmqpExt;
|
||||
|
||||
use Symfony\Component\Messenger\Stamp\StampInterface;
|
||||
use Symfony\Component\Messenger\Stamp\NonSendableStampInterface;
|
||||
|
||||
/**
|
||||
* Stamp applied when a message is received from Amqp.
|
||||
*
|
||||
* @experimental in 4.3
|
||||
*/
|
||||
class AmqpReceivedStamp implements StampInterface
|
||||
class AmqpReceivedStamp implements NonSendableStampInterface
|
||||
{
|
||||
private $amqpEnvelope;
|
||||
private $queueName;
|
||||
|
@ -11,14 +11,14 @@
|
||||
|
||||
namespace Symfony\Component\Messenger\Transport\Doctrine;
|
||||
|
||||
use Symfony\Component\Messenger\Stamp\StampInterface;
|
||||
use Symfony\Component\Messenger\Stamp\NonSendableStampInterface;
|
||||
|
||||
/**
|
||||
* @author Vincent Touzet <vincent.touzet@gmail.com>
|
||||
*
|
||||
* @experimental in 4.3
|
||||
*/
|
||||
class DoctrineReceivedStamp implements StampInterface
|
||||
class DoctrineReceivedStamp implements NonSendableStampInterface
|
||||
{
|
||||
private $id;
|
||||
|
||||
|
@ -31,7 +31,6 @@ class Connection
|
||||
private $stream;
|
||||
private $group;
|
||||
private $consumer;
|
||||
private $blockingTimeout;
|
||||
private $couldHavePendingMessages = true;
|
||||
|
||||
public function __construct(array $configuration, array $connectionCredentials = [], array $redisOptions = [], \Redis $redis = null)
|
||||
@ -42,7 +41,6 @@ class Connection
|
||||
$this->stream = $configuration['stream'] ?? '' ?: 'messages';
|
||||
$this->group = $configuration['group'] ?? '' ?: 'symfony';
|
||||
$this->consumer = $configuration['consumer'] ?? '' ?: 'consumer';
|
||||
$this->blockingTimeout = $redisOptions['blocking_timeout'] ?? null;
|
||||
}
|
||||
|
||||
public static function fromDsn(string $dsn, array $redisOptions = [], \Redis $redis = null): self
|
||||
@ -83,8 +81,7 @@ class Connection
|
||||
$this->group,
|
||||
$this->consumer,
|
||||
[$this->stream => $messageId],
|
||||
1,
|
||||
$this->blockingTimeout
|
||||
1
|
||||
);
|
||||
} catch (\RedisException $e) {
|
||||
}
|
||||
@ -142,7 +139,7 @@ class Connection
|
||||
}
|
||||
}
|
||||
|
||||
public function add(string $body, array $headers)
|
||||
public function add(string $body, array $headers): void
|
||||
{
|
||||
$e = null;
|
||||
try {
|
||||
|
@ -11,14 +11,14 @@
|
||||
|
||||
namespace Symfony\Component\Messenger\Transport\RedisExt;
|
||||
|
||||
use Symfony\Component\Messenger\Stamp\StampInterface;
|
||||
use Symfony\Component\Messenger\Stamp\NonSendableStampInterface;
|
||||
|
||||
/**
|
||||
* @author Alexander Schranz <alexander@sulu.io>
|
||||
*
|
||||
* @experimental in 4.3
|
||||
*/
|
||||
class RedisReceivedStamp implements StampInterface
|
||||
class RedisReceivedStamp implements NonSendableStampInterface
|
||||
{
|
||||
private $id;
|
||||
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Messenger\Transport\Serialization;
|
||||
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Exception\MessageDecodingFailedException;
|
||||
use Symfony\Component\Messenger\Stamp\NonSendableStampInterface;
|
||||
|
||||
/**
|
||||
* @author Ryan Weaver<ryan@symfonycasts.com>
|
||||
@ -40,6 +41,8 @@ class PhpSerializer implements SerializerInterface
|
||||
*/
|
||||
public function encode(Envelope $envelope): array
|
||||
{
|
||||
$envelope = $envelope->withoutStampsOfType(NonSendableStampInterface::class);
|
||||
|
||||
$body = addslashes(serialize($envelope));
|
||||
|
||||
return [
|
||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\Messenger\Transport\Serialization;
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Exception\LogicException;
|
||||
use Symfony\Component\Messenger\Exception\MessageDecodingFailedException;
|
||||
use Symfony\Component\Messenger\Stamp\NonSendableStampInterface;
|
||||
use Symfony\Component\Messenger\Stamp\SerializerStamp;
|
||||
use Symfony\Component\Messenger\Stamp\StampInterface;
|
||||
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||
@ -47,7 +48,7 @@ class Serializer implements SerializerInterface
|
||||
public static function create(): self
|
||||
{
|
||||
if (!class_exists(SymfonySerializer::class)) {
|
||||
throw new LogicException(sprintf('The default Messenger Serializer requires Symfony\'s Serializer component. Try running "composer require symfony/serializer".'));
|
||||
throw new LogicException(sprintf('The "%s" class requires Symfony\'s Serializer component. Try running "composer require symfony/serializer" or use "%s" instead.', __CLASS__, PhpSerializer::class));
|
||||
}
|
||||
|
||||
$encoders = [new XmlEncoder(), new JsonEncoder()];
|
||||
@ -98,6 +99,8 @@ class Serializer implements SerializerInterface
|
||||
$context = $serializerStamp->getContext() + $context;
|
||||
}
|
||||
|
||||
$envelope = $envelope->withoutStampsOfType(NonSendableStampInterface::class);
|
||||
|
||||
$headers = ['type' => \get_class($envelope->getMessage())] + $this->encodeStamps($envelope);
|
||||
|
||||
return [
|
||||
|
@ -39,6 +39,9 @@ interface SerializerInterface
|
||||
* Encodes an envelope content (message & stamps) to a common format understandable by transports.
|
||||
* The encoded array should only contain scalars and arrays.
|
||||
*
|
||||
* Stamps that implement NonSendableStampInterface should
|
||||
* not be encoded.
|
||||
*
|
||||
* The most common keys of the encoded array are:
|
||||
* - `body` (string) - the message body
|
||||
* - `headers` (string<string>) - a key/value pair of headers
|
||||
|
@ -1157,6 +1157,7 @@ final class MimeTypes implements MimeTypesInterface
|
||||
'audio/x-flac' => ['flac'],
|
||||
'audio/x-flac+ogg' => ['oga', 'ogg'],
|
||||
'audio/x-gsm' => ['gsm'],
|
||||
'audio/x-hx-aac-adts' => ['aac', 'adts', 'ass'],
|
||||
'audio/x-imelody' => ['imy', 'ime'],
|
||||
'audio/x-iriver-pla' => ['pla'],
|
||||
'audio/x-it' => ['it'],
|
||||
@ -1631,7 +1632,7 @@ final class MimeTypes implements MimeTypesInterface
|
||||
'a78' => ['application/x-atari-7800-rom'],
|
||||
'aa' => ['audio/vnd.audible', 'audio/vnd.audible.aax', 'audio/x-pn-audibleaudio'],
|
||||
'aab' => ['application/x-authorware-bin'],
|
||||
'aac' => ['audio/aac', 'audio/x-aac'],
|
||||
'aac' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts'],
|
||||
'aam' => ['application/x-authorware-map'],
|
||||
'aas' => ['application/x-authorware-seg'],
|
||||
'aax' => ['audio/vnd.audible', 'audio/vnd.audible.aax', 'audio/x-pn-audibleaudio'],
|
||||
@ -1648,7 +1649,7 @@ final class MimeTypes implements MimeTypesInterface
|
||||
'adf' => ['application/x-amiga-disk-format'],
|
||||
'adp' => ['audio/adpcm'],
|
||||
'ads' => ['text/x-adasrc'],
|
||||
'adts' => ['audio/aac', 'audio/x-aac'],
|
||||
'adts' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts'],
|
||||
'aep' => ['application/vnd.audiograph'],
|
||||
'afm' => ['application/x-font-afm', 'application/x-font-type1'],
|
||||
'afp' => ['application/vnd.ibm.modcap'],
|
||||
@ -1687,7 +1688,7 @@ final class MimeTypes implements MimeTypesInterface
|
||||
'asm' => ['text/x-asm'],
|
||||
'aso' => ['application/vnd.accpac.simply.aso'],
|
||||
'asp' => ['application/x-asp'],
|
||||
'ass' => ['audio/aac', 'audio/x-aac', 'text/x-ssa'],
|
||||
'ass' => ['audio/aac', 'audio/x-aac', 'audio/x-hx-aac-adts', 'text/x-ssa'],
|
||||
'asx' => ['application/x-ms-asx', 'audio/x-ms-asx', 'video/x-ms-asf', 'video/x-ms-wax', 'video/x-ms-wmx', 'video/x-ms-wvx'],
|
||||
'atc' => ['application/vnd.acucorp'],
|
||||
'atom' => ['application/atom+xml'],
|
||||
|
@ -199,7 +199,15 @@ abstract class AbstractToken implements TokenInterface
|
||||
*/
|
||||
public function __unserialize(array $data): void
|
||||
{
|
||||
[$this->user, $this->authenticated, $this->roles, $this->attributes, $this->roleNames] = $data;
|
||||
[$this->user, $this->authenticated, $this->roles, $this->attributes] = $data;
|
||||
|
||||
// migration path to 4.3+
|
||||
if (null === $this->roleNames = $data[4] ?? null) {
|
||||
$this->roleNames = [];
|
||||
foreach ($this->roles as $role) {
|
||||
$this->roleNames[] = (string) $role;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,10 +68,10 @@ class DataCollectorTranslator implements LegacyTranslatorInterface, TranslatorIn
|
||||
{
|
||||
if ($this->translator instanceof TranslatorInterface) {
|
||||
$trans = $this->translator->trans($id, ['%count%' => $number] + $parameters, $domain, $locale);
|
||||
} else {
|
||||
$trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
|
||||
}
|
||||
|
||||
$trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
|
||||
|
||||
$this->collectMessage($locale, $domain, $id, $trans, ['%count%' => $number] + $parameters);
|
||||
|
||||
return $trans;
|
||||
|
Reference in New Issue
Block a user