Merge branch '4.3'
* 4.3: (23 commits) minor: add some test in the ldap component [Workflow] Update MethodMarkingStore [Bridge\ProxyManager] isProxyCandidate() does not take into account interfaces adding experimental note [HttpClient] add missing argument check [Messenger] Fix undefined index on read timeout [Workflow] use method marking store [Routing][AnnotationClassLoader] fix utf-8 encoding in default route name fixed a phpdoc [Debug] Wrap call to require_once in a try/catch [EventDispatcher] Removed "callable" type hint from WrappedListener constructor prevent deprecation when filesize matches error code [PropertyInfo] Add missing documentation link in Readme Use the current working dir as default first arg in 'link' binary Respect parent class contract in ContainerAwareDoctrineEventManager [WebProfilerBundle][Form] The form data collector return serialized object when profiler bundle attends object [Validator] Add the missing translations for the Danish ("da") locale [PropertyAccess] Add missing property to PropertyAccessor [Cache] fix saving unrelated keys in recursive callback calls [Serializer] Fix denormalization of object with variadic constructor typed argument ...
This commit is contained in:
commit
beb603694d
16
link
16
link
@ -23,14 +23,12 @@ use Symfony\Component\Filesystem\Filesystem;
|
|||||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (2 !== $argc) {
|
$pathToProject = $argv[1] ?? getcwd();
|
||||||
echo 'Link dependencies to components to a local clone of the main symfony/symfony GitHub repository.'.PHP_EOL.PHP_EOL;
|
|
||||||
echo "Usage: $argv[0] /path/to/the/project".PHP_EOL;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_dir("$argv[1]/vendor/symfony")) {
|
if (!is_dir("$pathToProject/vendor/symfony")) {
|
||||||
echo "The directory \"$argv[1]\" does not exist or the dependencies are not installed, did you forget to run \"composer install\" in your project?".PHP_EOL;
|
echo 'Link dependencies to components to a local clone of the main symfony/symfony GitHub repository.'.PHP_EOL.PHP_EOL;
|
||||||
|
echo "Usage: $argv[0] /path/to/the/project".PHP_EOL.PHP_EOL;
|
||||||
|
echo "The directory \"$pathToProject\" does not exist or the dependencies are not installed, did you forget to run \"composer install\" in your project?".PHP_EOL;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +48,7 @@ foreach ($directories as $dir) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (glob("$argv[1]/vendor/symfony/*", GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
|
foreach (glob("$pathToProject/vendor/symfony/*", GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
|
||||||
$package = 'symfony/'.basename($dir);
|
$package = 'symfony/'.basename($dir);
|
||||||
if (is_link($dir)) {
|
if (is_link($dir)) {
|
||||||
echo "\"$package\" is already a symlink, skipping.".PHP_EOL;
|
echo "\"$package\" is already a symlink, skipping.".PHP_EOL;
|
||||||
@ -68,6 +66,6 @@ foreach (glob("$argv[1]/vendor/symfony/*", GLOB_ONLYDIR | GLOB_NOSORT) as $dir)
|
|||||||
echo "\"$package\" has been linked to \"$sfPackages[$package]\".".PHP_EOL;
|
echo "\"$package\" has been linked to \"$sfPackages[$package]\".".PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (glob("$argv[1]/var/cache/*") as $cacheDir) {
|
foreach (glob("$pathToProject/var/cache/*") as $cacheDir) {
|
||||||
$filesystem->remove($cacheDir);
|
$filesystem->remove($cacheDir);
|
||||||
}
|
}
|
||||||
|
@ -37,51 +37,49 @@ class ContainerAwareEventManager extends EventManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatches an event to all registered listeners.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param string $eventName The name of the event to dispatch. The name of the event is
|
|
||||||
* the name of the method that is invoked on listeners.
|
|
||||||
* @param EventArgs $eventArgs The event arguments to pass to the event handlers/listeners.
|
|
||||||
* If not supplied, the single empty EventArgs instance is used.
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function dispatchEvent($eventName, EventArgs $eventArgs = null)
|
public function dispatchEvent($eventName, EventArgs $eventArgs = null)
|
||||||
{
|
{
|
||||||
if (isset($this->listeners[$eventName])) {
|
if (!isset($this->listeners[$eventName])) {
|
||||||
$eventArgs = null === $eventArgs ? EventArgs::getEmptyInstance() : $eventArgs;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$initialized = isset($this->initialized[$eventName]);
|
$eventArgs = null === $eventArgs ? EventArgs::getEmptyInstance() : $eventArgs;
|
||||||
|
|
||||||
foreach ($this->listeners[$eventName] as $hash => $listener) {
|
if (!isset($this->initialized[$eventName])) {
|
||||||
if (!$initialized && \is_string($listener)) {
|
$this->initializeListeners($eventName);
|
||||||
$this->listeners[$eventName][$hash] = $listener = $this->container->get($listener);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$listener->$eventName($eventArgs);
|
foreach ($this->listeners[$eventName] as $hash => $listener) {
|
||||||
}
|
$listener->$eventName($eventArgs);
|
||||||
$this->initialized[$eventName] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the listeners of a specific event or all listeners.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param string $event The name of the event
|
|
||||||
*
|
|
||||||
* @return array The event listeners for the specified event, or all event listeners
|
|
||||||
*/
|
*/
|
||||||
public function getListeners($event = null)
|
public function getListeners($event = null)
|
||||||
{
|
{
|
||||||
return $event ? $this->listeners[$event] : $this->listeners;
|
if (null !== $event) {
|
||||||
|
if (!isset($this->initialized[$event])) {
|
||||||
|
$this->initializeListeners($event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->listeners[$event];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->listeners as $event => $listeners) {
|
||||||
|
if (!isset($this->initialized[$event])) {
|
||||||
|
$this->initializeListeners($event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->listeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether an event has any registered listeners.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param string $event
|
|
||||||
*
|
|
||||||
* @return bool TRUE if the specified event has any listeners, FALSE otherwise
|
|
||||||
*/
|
*/
|
||||||
public function hasListeners($event)
|
public function hasListeners($event)
|
||||||
{
|
{
|
||||||
@ -89,20 +87,11 @@ class ContainerAwareEventManager extends EventManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an event listener that listens on the specified events.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param string|array $events The event(s) to listen on
|
|
||||||
* @param object|string $listener The listener object
|
|
||||||
*
|
|
||||||
* @throws \RuntimeException
|
|
||||||
*/
|
*/
|
||||||
public function addEventListener($events, $listener)
|
public function addEventListener($events, $listener)
|
||||||
{
|
{
|
||||||
if (\is_string($listener)) {
|
if (\is_string($listener)) {
|
||||||
if ($this->initialized) {
|
|
||||||
throw new \RuntimeException('Adding lazy-loading listeners after construction is not supported.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$hash = '_service_'.$listener;
|
$hash = '_service_'.$listener;
|
||||||
} else {
|
} else {
|
||||||
// Picks the hash code related to that listener
|
// Picks the hash code related to that listener
|
||||||
@ -113,14 +102,15 @@ class ContainerAwareEventManager extends EventManager
|
|||||||
// Overrides listener if a previous one was associated already
|
// Overrides listener if a previous one was associated already
|
||||||
// Prevents duplicate listeners on same event (same instance only)
|
// Prevents duplicate listeners on same event (same instance only)
|
||||||
$this->listeners[$event][$hash] = $listener;
|
$this->listeners[$event][$hash] = $listener;
|
||||||
|
|
||||||
|
if (\is_string($listener)) {
|
||||||
|
unset($this->initialized[$event]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes an event listener from the specified events.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param string|array $events
|
|
||||||
* @param object|string $listener
|
|
||||||
*/
|
*/
|
||||||
public function removeEventListener($events, $listener)
|
public function removeEventListener($events, $listener)
|
||||||
{
|
{
|
||||||
@ -138,4 +128,17 @@ class ContainerAwareEventManager extends EventManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $eventName
|
||||||
|
*/
|
||||||
|
private function initializeListeners($eventName)
|
||||||
|
{
|
||||||
|
foreach ($this->listeners[$eventName] as $hash => $listener) {
|
||||||
|
if (\is_string($listener)) {
|
||||||
|
$this->listeners[$eventName][$hash] = $this->container->get($listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->initialized[$eventName] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ class ContainerAwareEventManagerTest extends TestCase
|
|||||||
|
|
||||||
public function testDispatchEvent()
|
public function testDispatchEvent()
|
||||||
{
|
{
|
||||||
$this->container->set('foobar', $listener1 = new MyListener());
|
$this->container->set('lazy', $listener1 = new MyListener());
|
||||||
$this->evm->addEventListener('foo', 'foobar');
|
$this->evm->addEventListener('foo', 'lazy');
|
||||||
$this->evm->addEventListener('foo', $listener2 = new MyListener());
|
$this->evm->addEventListener('foo', $listener2 = new MyListener());
|
||||||
|
|
||||||
$this->evm->dispatchEvent('foo');
|
$this->evm->dispatchEvent('foo');
|
||||||
@ -38,19 +38,69 @@ class ContainerAwareEventManagerTest extends TestCase
|
|||||||
$this->assertTrue($listener2->called);
|
$this->assertTrue($listener2->called);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAddEventListenerAfterDispatchEvent()
|
||||||
|
{
|
||||||
|
$this->container->set('lazy1', $listener1 = new MyListener());
|
||||||
|
$this->evm->addEventListener('foo', 'lazy1');
|
||||||
|
$this->evm->addEventListener('foo', $listener2 = new MyListener());
|
||||||
|
|
||||||
|
$this->evm->dispatchEvent('foo');
|
||||||
|
|
||||||
|
$this->container->set('lazy2', $listener3 = new MyListener());
|
||||||
|
$this->evm->addEventListener('foo', 'lazy2');
|
||||||
|
$this->evm->addEventListener('foo', $listener4 = new MyListener());
|
||||||
|
|
||||||
|
$this->evm->dispatchEvent('foo');
|
||||||
|
|
||||||
|
$this->assertTrue($listener1->called);
|
||||||
|
$this->assertTrue($listener2->called);
|
||||||
|
$this->assertTrue($listener3->called);
|
||||||
|
$this->assertTrue($listener4->called);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetListenersForEvent()
|
||||||
|
{
|
||||||
|
$this->container->set('lazy', $listener1 = new MyListener());
|
||||||
|
$this->evm->addEventListener('foo', 'lazy');
|
||||||
|
$this->evm->addEventListener('foo', $listener2 = new MyListener());
|
||||||
|
|
||||||
|
$this->assertSame([$listener1, $listener2], array_values($this->evm->getListeners('foo')));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetListeners()
|
||||||
|
{
|
||||||
|
$this->container->set('lazy', $listener1 = new MyListener());
|
||||||
|
$this->evm->addEventListener('foo', 'lazy');
|
||||||
|
$this->evm->addEventListener('foo', $listener2 = new MyListener());
|
||||||
|
|
||||||
|
$this->assertSame([$listener1, $listener2], array_values($this->evm->getListeners()['foo']));
|
||||||
|
}
|
||||||
|
|
||||||
public function testRemoveEventListener()
|
public function testRemoveEventListener()
|
||||||
{
|
{
|
||||||
$this->evm->addEventListener('foo', 'bar');
|
$this->container->set('lazy', $listener1 = new MyListener());
|
||||||
$this->evm->addEventListener('foo', $listener = new MyListener());
|
$this->evm->addEventListener('foo', 'lazy');
|
||||||
|
$this->evm->addEventListener('foo', $listener2 = new MyListener());
|
||||||
|
|
||||||
$listeners = ['foo' => ['_service_bar' => 'bar', spl_object_hash($listener) => $listener]];
|
$this->evm->removeEventListener('foo', $listener2);
|
||||||
$this->assertSame($listeners, $this->evm->getListeners());
|
$this->assertSame([$listener1], array_values($this->evm->getListeners('foo')));
|
||||||
$this->assertSame($listeners['foo'], $this->evm->getListeners('foo'));
|
|
||||||
|
|
||||||
$this->evm->removeEventListener('foo', $listener);
|
$this->evm->removeEventListener('foo', 'lazy');
|
||||||
$this->assertSame(['_service_bar' => 'bar'], $this->evm->getListeners('foo'));
|
$this->assertSame([], $this->evm->getListeners('foo'));
|
||||||
|
}
|
||||||
|
|
||||||
$this->evm->removeEventListener('foo', 'bar');
|
public function testRemoveEventListenerAfterDispatchEvent()
|
||||||
|
{
|
||||||
|
$this->container->set('lazy', $listener1 = new MyListener());
|
||||||
|
$this->evm->addEventListener('foo', 'lazy');
|
||||||
|
$this->evm->addEventListener('foo', $listener2 = new MyListener());
|
||||||
|
|
||||||
|
$this->evm->dispatchEvent('foo');
|
||||||
|
|
||||||
|
$this->evm->removeEventListener('foo', $listener2);
|
||||||
|
$this->assertSame([$listener1], array_values($this->evm->getListeners('foo')));
|
||||||
|
|
||||||
|
$this->evm->removeEventListener('foo', 'lazy');
|
||||||
$this->assertSame([], $this->evm->getListeners('foo'));
|
$this->assertSame([], $this->evm->getListeners('foo'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ namespace Symfony\Bridge\ProxyManager\Tests\LazyProxy\PhpDumper;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
|
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
|
||||||
use Symfony\Component\DependencyInjection\Definition;
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
|
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@see \Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper}.
|
* Tests for {@see \Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper}.
|
||||||
@ -182,6 +183,7 @@ EOPHP;
|
|||||||
$definitions = [
|
$definitions = [
|
||||||
[new Definition(__CLASS__), true],
|
[new Definition(__CLASS__), true],
|
||||||
[new Definition('stdClass'), true],
|
[new Definition('stdClass'), true],
|
||||||
|
[new Definition(DumperInterface::class), true],
|
||||||
[new Definition(uniqid('foo', true)), false],
|
[new Definition(uniqid('foo', true)), false],
|
||||||
[new Definition(), false],
|
[new Definition(), false],
|
||||||
];
|
];
|
||||||
|
@ -32,7 +32,8 @@
|
|||||||
"conflict": {
|
"conflict": {
|
||||||
"symfony/dependency-injection": "<3.4",
|
"symfony/dependency-injection": "<3.4",
|
||||||
"symfony/messenger": "<4.2",
|
"symfony/messenger": "<4.2",
|
||||||
"symfony/var-dumper": "<3.4"
|
"symfony/var-dumper": "<3.4",
|
||||||
|
"symfony/form": "<4.3"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": { "Symfony\\Bundle\\WebProfilerBundle\\": "" },
|
"psr-4": { "Symfony\\Bundle\\WebProfilerBundle\\": "" },
|
||||||
|
@ -59,6 +59,26 @@ abstract class AdapterTestCase extends CachePoolTest
|
|||||||
$this->assertFalse($isHit);
|
$this->assertFalse($isHit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRecursiveGet()
|
||||||
|
{
|
||||||
|
if (isset($this->skippedTests[__FUNCTION__])) {
|
||||||
|
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$cache = $this->createCachePool(0, __FUNCTION__);
|
||||||
|
|
||||||
|
$v = $cache->get('k1', function () use (&$counter, $cache) {
|
||||||
|
$v = $cache->get('k2', function () use (&$counter) { return ++$counter; });
|
||||||
|
$v = $cache->get('k2', function () use (&$counter) { return ++$counter; });
|
||||||
|
|
||||||
|
return $v;
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->assertSame(1, $counter);
|
||||||
|
$this->assertSame(1, $v);
|
||||||
|
$this->assertSame(1, $cache->get('k2', function () { return 2; }));
|
||||||
|
}
|
||||||
|
|
||||||
public function testGetMetadata()
|
public function testGetMetadata()
|
||||||
{
|
{
|
||||||
if (isset($this->skippedTests[__FUNCTION__])) {
|
if (isset($this->skippedTests[__FUNCTION__])) {
|
||||||
|
@ -23,6 +23,7 @@ class PhpArrayAdapterTest extends AdapterTestCase
|
|||||||
{
|
{
|
||||||
protected $skippedTests = [
|
protected $skippedTests = [
|
||||||
'testGet' => 'PhpArrayAdapter is read-only.',
|
'testGet' => 'PhpArrayAdapter is read-only.',
|
||||||
|
'testRecursiveGet' => 'PhpArrayAdapter is read-only.',
|
||||||
'testBasicUsage' => 'PhpArrayAdapter is read-only.',
|
'testBasicUsage' => 'PhpArrayAdapter is read-only.',
|
||||||
'testBasicUsageWithLongKey' => 'PhpArrayAdapter is read-only.',
|
'testBasicUsageWithLongKey' => 'PhpArrayAdapter is read-only.',
|
||||||
'testClear' => 'PhpArrayAdapter is read-only.',
|
'testClear' => 'PhpArrayAdapter is read-only.',
|
||||||
|
@ -32,6 +32,7 @@ trait ContractsTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
private $callbackWrapper = [LockRegistry::class, 'compute'];
|
private $callbackWrapper = [LockRegistry::class, 'compute'];
|
||||||
|
private $computing = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps the callback passed to ->get() in a callable.
|
* Wraps the callback passed to ->get() in a callable.
|
||||||
@ -69,26 +70,27 @@ trait ContractsTrait
|
|||||||
CacheItem::class
|
CacheItem::class
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata) {
|
return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata, $key) {
|
||||||
// don't wrap nor save recursive calls
|
// don't wrap nor save recursive calls
|
||||||
if (null === $callbackWrapper = $this->callbackWrapper) {
|
if (isset($this->computing[$key])) {
|
||||||
$value = $callback($item, $save);
|
$value = $callback($item, $save);
|
||||||
$save = false;
|
$save = false;
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
$this->callbackWrapper = null;
|
|
||||||
|
$this->computing[$key] = $key;
|
||||||
$startTime = microtime(true);
|
$startTime = microtime(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$value = $callbackWrapper($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) {
|
$value = ($this->callbackWrapper)($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) {
|
||||||
$setMetadata($item, $startTime, $metadata);
|
$setMetadata($item, $startTime, $metadata);
|
||||||
}, $this->logger ?? null);
|
}, $this->logger ?? null);
|
||||||
$setMetadata($item, $startTime, $metadata);
|
$setMetadata($item, $startTime, $metadata);
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
} finally {
|
} finally {
|
||||||
$this->callbackWrapper = $callbackWrapper;
|
unset($this->computing[$key]);
|
||||||
}
|
}
|
||||||
}, $beta, $metadata, $this->logger ?? null);
|
}, $beta, $metadata, $this->logger ?? null);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Config\Resource;
|
|||||||
|
|
||||||
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface as LegacyServiceSubscriberInterface;
|
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface as LegacyServiceSubscriberInterface;
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
|
||||||
use Symfony\Contracts\Service\ServiceSubscriberInterface;
|
use Symfony\Contracts\Service\ServiceSubscriberInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -158,6 +159,13 @@ class ReflectionClassResource implements SelfCheckingResourceInterface
|
|||||||
yield print_r($class->name::getSubscribedEvents(), true);
|
yield print_r($class->name::getSubscribedEvents(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (interface_exists(MessageSubscriberInterface::class, false) && $class->isSubclassOf(MessageSubscriberInterface::class)) {
|
||||||
|
yield MessageSubscriberInterface::class;
|
||||||
|
foreach ($class->name::getHandledMessages() as $key => $value) {
|
||||||
|
yield $key.print_r($value, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (interface_exists(LegacyServiceSubscriberInterface::class, false) && $class->isSubclassOf(LegacyServiceSubscriberInterface::class)) {
|
if (interface_exists(LegacyServiceSubscriberInterface::class, false) && $class->isSubclassOf(LegacyServiceSubscriberInterface::class)) {
|
||||||
yield LegacyServiceSubscriberInterface::class;
|
yield LegacyServiceSubscriberInterface::class;
|
||||||
yield print_r([$class->name, 'getSubscribedServices'](), true);
|
yield print_r([$class->name, 'getSubscribedServices'](), true);
|
||||||
|
@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
use Symfony\Component\Config\Resource\ReflectionClassResource;
|
use Symfony\Component\Config\Resource\ReflectionClassResource;
|
||||||
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
|
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
|
||||||
|
|
||||||
class ReflectionClassResourceTest extends TestCase
|
class ReflectionClassResourceTest extends TestCase
|
||||||
{
|
{
|
||||||
@ -147,6 +148,24 @@ EOPHP;
|
|||||||
$this->assertTrue($res->isFresh(0));
|
$this->assertTrue($res->isFresh(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMessageSubscriber()
|
||||||
|
{
|
||||||
|
$res = new ReflectionClassResource(new \ReflectionClass(TestMessageSubscriber::class));
|
||||||
|
$this->assertTrue($res->isFresh(0));
|
||||||
|
|
||||||
|
TestMessageSubscriberConfigHolder::$handledMessages = ['SomeMessageClass' => []];
|
||||||
|
$this->assertFalse($res->isFresh(0));
|
||||||
|
|
||||||
|
$res = new ReflectionClassResource(new \ReflectionClass(TestMessageSubscriber::class));
|
||||||
|
$this->assertTrue($res->isFresh(0));
|
||||||
|
|
||||||
|
TestMessageSubscriberConfigHolder::$handledMessages = ['OtherMessageClass' => []];
|
||||||
|
$this->assertFalse($res->isFresh(0));
|
||||||
|
|
||||||
|
$res = new ReflectionClassResource(new \ReflectionClass(TestMessageSubscriber::class));
|
||||||
|
$this->assertTrue($res->isFresh(0));
|
||||||
|
}
|
||||||
|
|
||||||
public function testServiceSubscriber()
|
public function testServiceSubscriber()
|
||||||
{
|
{
|
||||||
$res = new ReflectionClassResource(new \ReflectionClass(TestServiceSubscriber::class));
|
$res = new ReflectionClassResource(new \ReflectionClass(TestServiceSubscriber::class));
|
||||||
@ -174,6 +193,20 @@ class TestEventSubscriber implements EventSubscriberInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestMessageSubscriber implements MessageSubscriberInterface
|
||||||
|
{
|
||||||
|
public static function getHandledMessages(): iterable
|
||||||
|
{
|
||||||
|
foreach (TestMessageSubscriberConfigHolder::$handledMessages as $key => $subscribedMessage) {
|
||||||
|
yield $key => $subscribedMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class TestMessageSubscriberConfigHolder
|
||||||
|
{
|
||||||
|
public static $handledMessages = [];
|
||||||
|
}
|
||||||
|
|
||||||
class TestServiceSubscriber implements ServiceSubscriberInterface
|
class TestServiceSubscriber implements ServiceSubscriberInterface
|
||||||
{
|
{
|
||||||
public static $subscribedServices = [];
|
public static $subscribedServices = [];
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
"symfony/dependency-injection": "~3.4|~4.0",
|
"symfony/dependency-injection": "~3.4|~4.0",
|
||||||
"symfony/event-dispatcher": "~3.4|~4.0",
|
"symfony/event-dispatcher": "~3.4|~4.0",
|
||||||
"symfony/finder": "~3.4|~4.0",
|
"symfony/finder": "~3.4|~4.0",
|
||||||
|
"symfony/messenger": "~4.1",
|
||||||
"symfony/yaml": "~3.4|~4.0"
|
"symfony/yaml": "~3.4|~4.0"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
|
@ -171,7 +171,11 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once $file;
|
try {
|
||||||
|
require_once $file;
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($candidates as $candidate) {
|
foreach ($candidates as $candidate) {
|
||||||
if ($this->classExists($candidate)) {
|
if ($this->classExists($candidate)) {
|
||||||
|
@ -38,7 +38,7 @@ class WrappedListener
|
|||||||
private $priority;
|
private $priority;
|
||||||
private static $hasClassStub;
|
private static $hasClassStub;
|
||||||
|
|
||||||
public function __construct(callable $listener, ?string $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null)
|
public function __construct($listener, ?string $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null)
|
||||||
{
|
{
|
||||||
$this->listener = $listener;
|
$this->listener = $listener;
|
||||||
$this->optimizedListener = $listener instanceof \Closure ? $listener : \Closure::fromCallable($listener);
|
$this->optimizedListener = $listener instanceof \Closure ? $listener : \Closure::fromCallable($listener);
|
||||||
|
@ -14,6 +14,122 @@
|
|||||||
<source>The CSRF token is invalid. Please try to resubmit the form.</source>
|
<source>The CSRF token is invalid. Please try to resubmit the form.</source>
|
||||||
<target>CSRF-token er ugyldig.</target>
|
<target>CSRF-token er ugyldig.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="64">
|
||||||
|
<source>This value is not a valid currency.</source>
|
||||||
|
<target>Denne værdi er ikke en gyldig valuta.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="65">
|
||||||
|
<source>This value should be equal to {{ compared_value }}.</source>
|
||||||
|
<target>Denne værdi skal være lig med {{ compared_value }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="66">
|
||||||
|
<source>This value should be greater than {{ compared_value }}.</source>
|
||||||
|
<target>Denne værdi skal være større end {{ compared_value }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="67">
|
||||||
|
<source>This value should be greater than or equal to {{ compared_value }}.</source>
|
||||||
|
<target>Denne værdi skal være større end eller lig med {{ compared_value }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="68">
|
||||||
|
<source>This value should be identical to {{ compared_value_type }} {{ compared_value }}.</source>
|
||||||
|
<target>Denne værdi skal være identisk med {{ compared_value_type }} {{ compared_value }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="69">
|
||||||
|
<source>This value should be less than {{ compared_value }}.</source>
|
||||||
|
<target>Denne værdi skal være mindre end {{ compared_value }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="70">
|
||||||
|
<source>This value should be less than or equal to {{ compared_value }}.</source>
|
||||||
|
<target>Denne værdi skal være mindre end eller lig med {{ compared_value }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="71">
|
||||||
|
<source>This value should not be equal to {{ compared_value }}.</source>
|
||||||
|
<target>Denne værdi bør ikke være lig med {{ compared_value }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="72">
|
||||||
|
<source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
|
||||||
|
<target>Denne værdi bør ikke være identisk med {{ compared_value_type }} {{ compared_value }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="73">
|
||||||
|
<source>The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.</source>
|
||||||
|
<target>Billedforholdet er for stort ({{ratio}}). Tilladt maksimumsforhold er {{ max_ratio }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="74">
|
||||||
|
<source>The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.</source>
|
||||||
|
<target>Billedforholdet er for lille ({{ ratio }}). Minimumsforventet forventet er {{ min_ratio }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="75">
|
||||||
|
<source>The image is square ({{ width }}x{{ height }}px). Square images are not allowed.</source>
|
||||||
|
<target>Billedet er firkantet ({{ width }} x {{ height }} px). Firkantede billeder er ikke tilladt.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="76">
|
||||||
|
<source>The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.</source>
|
||||||
|
<target>Billedet er landskabsorienteret ({{width}} x {{height}} px). Landskabsorienterede billeder er ikke tilladt</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="77">
|
||||||
|
<source>The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.</source>
|
||||||
|
<target>Billedet er portrætorienteret ({{ width }}x{{ height }}px). Portrætorienterede billeder er ikke tilladt.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="78">
|
||||||
|
<source>An empty file is not allowed.</source>
|
||||||
|
<target>En tom fil er ikke tilladt.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="79">
|
||||||
|
<source>The host could not be resolved.</source>
|
||||||
|
<target>Værten kunne ikke løses.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="80">
|
||||||
|
<source>This value does not match the expected {{ charset }} charset.</source>
|
||||||
|
<target>Denne værdi stemmer ikke overens med den forventede {{ charset }} charset.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="81">
|
||||||
|
<source>This is not a valid Business Identifier Code (BIC).</source>
|
||||||
|
<target>Dette er ikke en gyldig Business Identifier Code (BIC).a</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="83">
|
||||||
|
<source>This is not a valid UUID.</source>
|
||||||
|
<target>Dette er ikke en gyldig UUID.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="84">
|
||||||
|
<source>This value should be a multiple of {{ compared_value }}.</source>
|
||||||
|
<target>Denne værdi skal være et flertal af {{ compared_value }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="85">
|
||||||
|
<source>This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.</source>
|
||||||
|
<target>Denne Business Identifier Code (BIC) er ikke forbundet med IBAN {{ iban }}.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="86">
|
||||||
|
<source>This value should be valid JSON.</source>
|
||||||
|
<target>Denne værdi skal være gyldig JSON.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="87">
|
||||||
|
<source>This collection should contain only unique elements.</source>
|
||||||
|
<target>Denne samling bør kun indeholde unikke elementer.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="88">
|
||||||
|
<source>This value should be positive.</source>
|
||||||
|
<target>Denne værdi skal være positiv.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="89">
|
||||||
|
<source>This value should be either positive or zero.</source>
|
||||||
|
<target>Denne værdi skal være enten positiv eller nul.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="90">
|
||||||
|
<source>This value should be negative.</source>
|
||||||
|
<target>Denne værdi skal være negativ.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="91">
|
||||||
|
<source>This value should be either negative or zero.</source>
|
||||||
|
<target>Denne værdi skal være enten negativ eller nul.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="92">
|
||||||
|
<source>This value is not a valid timezone.</source>
|
||||||
|
<target>Denne værdi er ikke en gyldig tidszone.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="93">
|
||||||
|
<source>This password has been leaked in a data breach, it must not be used. Please use another password.</source>
|
||||||
|
<target>Denne adgangskode er blevet lækket i et databrud, det må ikke bruges. Brug venligst en anden adgangskode.</target>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
@ -36,6 +36,10 @@ class ScopingHttpClient implements HttpClientInterface
|
|||||||
$this->client = $client;
|
$this->client = $client;
|
||||||
$this->defaultOptionsByRegexp = $defaultOptionsByRegexp;
|
$this->defaultOptionsByRegexp = $defaultOptionsByRegexp;
|
||||||
$this->defaultRegexp = $defaultRegexp;
|
$this->defaultRegexp = $defaultRegexp;
|
||||||
|
|
||||||
|
if (null !== $defaultRegexp && !isset($defaultOptionsByRegexp[$defaultRegexp])) {
|
||||||
|
throw new InvalidArgumentException(sprintf('No options are mapped to the provided "%s" default regexp.', $defaultRegexp));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function forBaseUri(HttpClientInterface $client, string $baseUri, array $defaultOptions = [], $regexp = null): self
|
public static function forBaseUri(HttpClientInterface $client, string $baseUri, array $defaultOptions = [], $regexp = null): self
|
||||||
|
@ -29,6 +29,7 @@ class Cookie
|
|||||||
private $sameSite;
|
private $sameSite;
|
||||||
private $secureDefault = false;
|
private $secureDefault = false;
|
||||||
|
|
||||||
|
const SAMESITE_NONE = 'none';
|
||||||
const SAMESITE_LAX = 'lax';
|
const SAMESITE_LAX = 'lax';
|
||||||
const SAMESITE_STRICT = 'strict';
|
const SAMESITE_STRICT = 'strict';
|
||||||
|
|
||||||
@ -126,7 +127,7 @@ class Cookie
|
|||||||
$sameSite = strtolower($sameSite);
|
$sameSite = strtolower($sameSite);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!\in_array($sameSite, [self::SAMESITE_LAX, self::SAMESITE_STRICT, null], true)) {
|
if (!\in_array($sameSite, [self::SAMESITE_LAX, self::SAMESITE_STRICT, self::SAMESITE_NONE, null], true)) {
|
||||||
throw new \InvalidArgumentException('The "sameSite" parameter value is not valid.');
|
throw new \InvalidArgumentException('The "sameSite" parameter value is not valid.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ class FileBag extends ParameterBag
|
|||||||
if (UPLOAD_ERR_NO_FILE == $file['error']) {
|
if (UPLOAD_ERR_NO_FILE == $file['error']) {
|
||||||
$file = null;
|
$file = null;
|
||||||
} else {
|
} else {
|
||||||
$file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['error']);
|
$file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['error'], false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$file = array_map([$this, 'convertFileInformation'], $file);
|
$file = array_map([$this, 'convertFileInformation'], $file);
|
||||||
|
@ -21,7 +21,7 @@ use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
|||||||
interface FlashBagInterface extends SessionBagInterface
|
interface FlashBagInterface extends SessionBagInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Adds a flash message for type.
|
* Adds a flash message for the given type.
|
||||||
*
|
*
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @param mixed $message
|
* @param mixed $message
|
||||||
@ -29,12 +29,12 @@ interface FlashBagInterface extends SessionBagInterface
|
|||||||
public function add($type, $message);
|
public function add($type, $message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a message for a given type.
|
* Registers one or more messages for a given type.
|
||||||
*
|
*
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @param string|array $message
|
* @param string|array $messages
|
||||||
*/
|
*/
|
||||||
public function set($type, $message);
|
public function set($type, $messages);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets flash messages for a given type.
|
* Gets flash messages for a given type.
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
<?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\Ldap\Tests\Adapter\ExtLdap;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Ldap\Adapter\ExtLdap\Connection;
|
||||||
|
use Symfony\Component\Ldap\Adapter\ExtLdap\EntryManager;
|
||||||
|
use Symfony\Component\Ldap\Entry;
|
||||||
|
|
||||||
|
class EntryManagerTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Ldap\Exception\NotBoundException
|
||||||
|
* @expectedExceptionMessage Query execution is not possible without binding the connection first.
|
||||||
|
*/
|
||||||
|
public function testGetResources()
|
||||||
|
{
|
||||||
|
$connection = $this->getMockBuilder(Connection::class)->getMock();
|
||||||
|
$connection
|
||||||
|
->expects($this->once())
|
||||||
|
->method('isBound')->willReturn(false);
|
||||||
|
|
||||||
|
$entry = new Entry('$$$$$$');
|
||||||
|
$entryManager = new EntryManager($connection);
|
||||||
|
$entryManager->update($entry);
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,11 @@ Mailer Component
|
|||||||
|
|
||||||
The Mailer component helps sending emails.
|
The Mailer component helps sending emails.
|
||||||
|
|
||||||
|
**This Component is experimental**.
|
||||||
|
[Experimental features](https://symfony.com/doc/current/contributing/code/experimental.html)
|
||||||
|
are not covered by Symfony's
|
||||||
|
[Backward Compatibility Promise](https://symfony.com/doc/current/contributing/code/bc.html).
|
||||||
|
|
||||||
Resources
|
Resources
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
@ -115,7 +115,8 @@ class ConnectionTest extends TestCase
|
|||||||
|
|
||||||
public function testGetAfterReject()
|
public function testGetAfterReject()
|
||||||
{
|
{
|
||||||
$connection = Connection::fromDsn('redis://localhost/messenger-rejectthenget');
|
$redis = new \Redis();
|
||||||
|
$connection = Connection::fromDsn('redis://localhost/messenger-rejectthenget', [], $redis);
|
||||||
try {
|
try {
|
||||||
$connection->setup();
|
$connection->setup();
|
||||||
} catch (TransportException $e) {
|
} catch (TransportException $e) {
|
||||||
@ -129,5 +130,20 @@ class ConnectionTest extends TestCase
|
|||||||
|
|
||||||
$connection = Connection::fromDsn('redis://localhost/messenger-rejectthenget');
|
$connection = Connection::fromDsn('redis://localhost/messenger-rejectthenget');
|
||||||
$this->assertNotNull($connection->get());
|
$this->assertNotNull($connection->get());
|
||||||
|
|
||||||
|
$redis->del('messenger-rejectthenget');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBlockingTimeout()
|
||||||
|
{
|
||||||
|
$redis = new \Redis();
|
||||||
|
$connection = Connection::fromDsn('redis://localhost/messenger-blockingtimeout', ['blocking_timeout' => 1], $redis);
|
||||||
|
try {
|
||||||
|
$connection->setup();
|
||||||
|
} catch (TransportException $e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertNull($connection->get());
|
||||||
|
$redis->del('messenger-blockingtimeout');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ class Connection
|
|||||||
return $this->get();
|
return $this->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($messages[$this->stream] as $key => $message) {
|
foreach ($messages[$this->stream] ?? [] as $key => $message) {
|
||||||
$redisEnvelope = \json_decode($message['message'], true);
|
$redisEnvelope = \json_decode($message['message'], true);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
@ -63,6 +63,7 @@ class PropertyAccessor implements PropertyAccessorInterface
|
|||||||
*/
|
*/
|
||||||
private $cacheItemPool;
|
private $cacheItemPool;
|
||||||
|
|
||||||
|
private $propertyPathCache = [];
|
||||||
private $readPropertyCache = [];
|
private $readPropertyCache = [];
|
||||||
private $writePropertyCache = [];
|
private $writePropertyCache = [];
|
||||||
private static $resultProto = [self::VALUE => null];
|
private static $resultProto = [self::VALUE => null];
|
||||||
@ -823,7 +824,7 @@ class PropertyAccessor implements PropertyAccessorInterface
|
|||||||
*
|
*
|
||||||
* @return AdapterInterface
|
* @return AdapterInterface
|
||||||
*
|
*
|
||||||
* @throws RuntimeException When the Cache Component isn't available
|
* @throws \LogicException When the Cache Component isn't available
|
||||||
*/
|
*/
|
||||||
public static function createCache($namespace, $defaultLifetime, $version, LoggerInterface $logger = null)
|
public static function createCache($namespace, $defaultLifetime, $version, LoggerInterface $logger = null)
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@ of popular sources.
|
|||||||
Resources
|
Resources
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
* [Documentation](https://symfony.com/doc/current/components/property_info.html)
|
||||||
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
|
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
|
||||||
* [Report issues](https://github.com/symfony/symfony/issues) and
|
* [Report issues](https://github.com/symfony/symfony/issues) and
|
||||||
[send Pull Requests](https://github.com/symfony/symfony/pulls)
|
[send Pull Requests](https://github.com/symfony/symfony/pulls)
|
||||||
|
@ -248,7 +248,8 @@ abstract class AnnotationClassLoader implements LoaderInterface
|
|||||||
*/
|
*/
|
||||||
protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method)
|
protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method)
|
||||||
{
|
{
|
||||||
$name = strtolower(str_replace('\\', '_', $class->name).'_'.$method->name);
|
$name = str_replace('\\', '_', $class->name).'_'.$method->name;
|
||||||
|
$name = \function_exists('mb_strtolower') && preg_match('//u', $name) ? mb_strtolower($name, 'UTF-8') : strtolower($name);
|
||||||
if ($this->defaultRouteIndex > 0) {
|
if ($this->defaultRouteIndex > 0) {
|
||||||
$name .= '_'.$this->defaultRouteIndex;
|
$name .= '_'.$this->defaultRouteIndex;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses;
|
||||||
|
|
||||||
|
class EncodingClass
|
||||||
|
{
|
||||||
|
public function routeÀction()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -306,6 +306,34 @@ class AnnotationClassLoaderTest extends AbstractAnnotationLoaderTest
|
|||||||
$this->assertEquals('/nl/suffix', $routes->get('action.nl')->getPath());
|
$this->assertEquals('/nl/suffix', $routes->get('action.nl')->getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires function mb_strtolower
|
||||||
|
*/
|
||||||
|
public function testDefaultRouteName()
|
||||||
|
{
|
||||||
|
$methodRouteData = [
|
||||||
|
'name' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
$reader = $this->getReader();
|
||||||
|
$reader
|
||||||
|
->expects($this->once())
|
||||||
|
->method('getMethodAnnotations')
|
||||||
|
->will($this->returnValue([new RouteAnnotation($methodRouteData)]))
|
||||||
|
;
|
||||||
|
|
||||||
|
$loader = new class($reader) extends AnnotationClassLoader {
|
||||||
|
protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$routeCollection = $loader->load('Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\EncodingClass');
|
||||||
|
|
||||||
|
$defaultName = array_keys($routeCollection->all())[0];
|
||||||
|
|
||||||
|
$this->assertSame($defaultName, 'symfony_component_routing_tests_fixtures_annotatedclasses_encodingclass_routeàction');
|
||||||
|
}
|
||||||
|
|
||||||
public function testLoadingRouteWithPrefix()
|
public function testLoadingRouteWithPrefix()
|
||||||
{
|
{
|
||||||
$routes = $this->loader->load(RouteWithPrefixController::class);
|
$routes = $this->loader->load(RouteWithPrefixController::class);
|
||||||
|
@ -29,7 +29,7 @@ class AnnotationDirectoryLoaderTest extends AbstractAnnotationLoaderTest
|
|||||||
|
|
||||||
public function testLoad()
|
public function testLoad()
|
||||||
{
|
{
|
||||||
$this->reader->expects($this->exactly(3))->method('getClassAnnotation');
|
$this->reader->expects($this->exactly(4))->method('getClassAnnotation');
|
||||||
|
|
||||||
$this->reader
|
$this->reader
|
||||||
->expects($this->any())
|
->expects($this->any())
|
||||||
@ -52,6 +52,7 @@ class AnnotationDirectoryLoaderTest extends AbstractAnnotationLoaderTest
|
|||||||
'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
|
'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BarClass',
|
||||||
'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass',
|
'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\BazClass',
|
||||||
'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\FooClass',
|
'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\FooClass',
|
||||||
|
'Symfony\Component\Routing\Tests\Fixtures\AnnotatedClasses\EncodingClass',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->reader
|
$this->reader
|
||||||
|
@ -486,7 +486,13 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
|
|||||||
throw new RuntimeException(sprintf('Cannot create an instance of %s from serialized data because the variadic parameter %s can only accept an array.', $class, $constructorParameter->name));
|
throw new RuntimeException(sprintf('Cannot create an instance of %s from serialized data because the variadic parameter %s can only accept an array.', $class, $constructorParameter->name));
|
||||||
}
|
}
|
||||||
|
|
||||||
$params = array_merge($params, $data[$paramName]);
|
$variadicParameters = [];
|
||||||
|
foreach ($data[$paramName] as $parameterData) {
|
||||||
|
$variadicParameters[] = $this->denormalizeParameter($reflectionClass, $constructorParameter, $paramName, $parameterData, $context, $format);
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = array_merge($params, $variadicParameters);
|
||||||
|
unset($data[$key]);
|
||||||
}
|
}
|
||||||
} elseif ($allowed && !$ignored && (isset($data[$key]) || \array_key_exists($key, $data))) {
|
} elseif ($allowed && !$ignored && (isset($data[$key]) || \array_key_exists($key, $data))) {
|
||||||
$parameterData = $data[$key];
|
$parameterData = $data[$key];
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
<?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\Serializer\Tests\Fixtures;
|
||||||
|
|
||||||
|
class VariadicConstructorTypedArgsDummy
|
||||||
|
{
|
||||||
|
private $foo;
|
||||||
|
|
||||||
|
public function __construct(Dummy ...$foo)
|
||||||
|
{
|
||||||
|
$this->foo = $foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFoo()
|
||||||
|
{
|
||||||
|
return $this->foo;
|
||||||
|
}
|
||||||
|
}
|
@ -8,10 +8,14 @@ use Symfony\Component\Serializer\Mapping\ClassMetadata;
|
|||||||
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
|
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||||
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
|
||||||
|
use Symfony\Component\Serializer\Serializer;
|
||||||
use Symfony\Component\Serializer\Tests\Fixtures\AbstractNormalizerDummy;
|
use Symfony\Component\Serializer\Tests\Fixtures\AbstractNormalizerDummy;
|
||||||
|
use Symfony\Component\Serializer\Tests\Fixtures\Dummy;
|
||||||
use Symfony\Component\Serializer\Tests\Fixtures\NullableConstructorArgumentDummy;
|
use Symfony\Component\Serializer\Tests\Fixtures\NullableConstructorArgumentDummy;
|
||||||
use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorDummy;
|
use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorDummy;
|
||||||
use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorNormalizer;
|
use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorNormalizer;
|
||||||
|
use Symfony\Component\Serializer\Tests\Fixtures\VariadicConstructorTypedArgsDummy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a dummy Normalizer which extends the AbstractNormalizer.
|
* Provides a dummy Normalizer which extends the AbstractNormalizer.
|
||||||
@ -108,9 +112,6 @@ class AbstractNormalizerTest extends TestCase
|
|||||||
$this->assertNull($dummy->foo);
|
$this->assertNull($dummy->foo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @requires PHP 7.1
|
|
||||||
*/
|
|
||||||
public function testObjectWithNullableConstructorArgument()
|
public function testObjectWithNullableConstructorArgument()
|
||||||
{
|
{
|
||||||
$normalizer = new ObjectNormalizer();
|
$normalizer = new ObjectNormalizer();
|
||||||
@ -118,4 +119,18 @@ class AbstractNormalizerTest extends TestCase
|
|||||||
|
|
||||||
$this->assertNull($dummy->getFoo());
|
$this->assertNull($dummy->getFoo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testObjectWithVariadicConstructorTypedArguments()
|
||||||
|
{
|
||||||
|
$normalizer = new PropertyNormalizer();
|
||||||
|
$normalizer->setSerializer(new Serializer([$normalizer]));
|
||||||
|
$data = ['foo' => [['foo' => 'Foo', 'bar' => 'Bar', 'baz' => 'Baz', 'qux' => 'Qux'], ['foo' => 'FOO', 'bar' => 'BAR', 'baz' => 'BAZ', 'qux' => 'QUX']]];
|
||||||
|
$dummy = $normalizer->denormalize($data, VariadicConstructorTypedArgsDummy::class);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(VariadicConstructorTypedArgsDummy::class, $dummy);
|
||||||
|
$this->assertCount(2, $dummy->getFoo());
|
||||||
|
foreach ($dummy->getFoo() as $foo) {
|
||||||
|
$this->assertInstanceOf(Dummy::class, $foo);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ class AddValidatorInitializersPass implements CompilerPassInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (!($class = $translator->getClass()) && $translator instanceof ChildDefinition) {
|
while (!($class = $translator->getClass()) && $translator instanceof ChildDefinition) {
|
||||||
$translator = $translator->getParent();
|
$translator = $container->findDefinition($translator->getParent());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_subclass_of($class, LegacyTranslatorInterface::class)) {
|
if (!is_subclass_of($class, LegacyTranslatorInterface::class)) {
|
||||||
|
@ -20,7 +20,7 @@ use Symfony\Component\Workflow\Marking;
|
|||||||
* This store deals with a "single state" or "multiple state" Marking.
|
* This store deals with a "single state" or "multiple state" Marking.
|
||||||
*
|
*
|
||||||
* "single state" Marking means a subject can be in one and only one state at
|
* "single state" Marking means a subject can be in one and only one state at
|
||||||
* the same time. Use it with state machine or specific workflow.
|
* the same time. Use it with state machine.
|
||||||
*
|
*
|
||||||
* "multiple state" Marking means a subject can be in many states at the same
|
* "multiple state" Marking means a subject can be in many states at the same
|
||||||
* time. Use it with workflow.
|
* time. Use it with workflow.
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
namespace Symfony\Component\Workflow;
|
namespace Symfony\Component\Workflow;
|
||||||
|
|
||||||
use Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface;
|
use Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface;
|
||||||
use Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore;
|
use Symfony\Component\Workflow\MarkingStore\MethodMarkingStore;
|
||||||
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,6 +22,6 @@ class StateMachine extends Workflow
|
|||||||
{
|
{
|
||||||
public function __construct(Definition $definition, MarkingStoreInterface $markingStore = null, EventDispatcherInterface $dispatcher = null, string $name = 'unnamed')
|
public function __construct(Definition $definition, MarkingStoreInterface $markingStore = null, EventDispatcherInterface $dispatcher = null, string $name = 'unnamed')
|
||||||
{
|
{
|
||||||
parent::__construct($definition, $markingStore ?: new SingleStateMarkingStore(), $dispatcher, $name);
|
parent::__construct($definition, $markingStore ?: new MethodMarkingStore(true, 'marking'), $dispatcher, $name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user