Merge branch '4.1' into 4.2
* 4.1: Fix typos in doc blocks [Debug] ignore underscore vs backslash namespaces in DebugClassLoader [TwigBridge][Form] Prevent multiple rendering of form collection prototypes [FrameworkBundle] fix describing routes with no controllers [DI] move RegisterServiceSubscribersPass before DecoratorServicePass Update ValidationListener.php [Yaml] ensures that the mb_internal_encoding is reset to its initial value [WebLink] Fixed documentation link [Security] getTargetPath of TargetPathTrait must return string or null [Hackday][Serializer] Deserialization ignores argument type hint from phpdoc for array in constructor argument Optimize perf by replacing call_user_func with dynamic vars [Routing] fix dumping same-path routes with placeholders [Security] defer log message in guard authenticator [Validator] Added IBAN format for Vatican City State merge conflicts filter out invalid Intl values filter out invalid language values [Validator] Fixed grouped composite constraints [Form] Filter arrays out of scalar form types Fix HeaderBag::get phpdoc
This commit is contained in:
commit
b88728a13a
@ -213,7 +213,7 @@ abstract class DoctrineType extends AbstractType implements ResetInterface
|
|||||||
// for equal query builders
|
// for equal query builders
|
||||||
$queryBuilderNormalizer = function (Options $options, $queryBuilder) {
|
$queryBuilderNormalizer = function (Options $options, $queryBuilder) {
|
||||||
if (\is_callable($queryBuilder)) {
|
if (\is_callable($queryBuilder)) {
|
||||||
$queryBuilder = \call_user_func($queryBuilder, $options['em']->getRepository($options['class']));
|
$queryBuilder = $queryBuilder($options['em']->getRepository($options['class']));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $queryBuilder;
|
return $queryBuilder;
|
||||||
|
@ -29,7 +29,7 @@ class EntityType extends DoctrineType
|
|||||||
// for equal query builders
|
// for equal query builders
|
||||||
$queryBuilderNormalizer = function (Options $options, $queryBuilder) {
|
$queryBuilderNormalizer = function (Options $options, $queryBuilder) {
|
||||||
if (\is_callable($queryBuilder)) {
|
if (\is_callable($queryBuilder)) {
|
||||||
$queryBuilder = \call_user_func($queryBuilder, $options['em']->getRepository($options['class']));
|
$queryBuilder = $queryBuilder($options['em']->getRepository($options['class']));
|
||||||
|
|
||||||
if (null !== $queryBuilder && !$queryBuilder instanceof QueryBuilder) {
|
if (null !== $queryBuilder && !$queryBuilder instanceof QueryBuilder) {
|
||||||
throw new UnexpectedTypeException($queryBuilder, 'Doctrine\ORM\QueryBuilder');
|
throw new UnexpectedTypeException($queryBuilder, 'Doctrine\ORM\QueryBuilder');
|
||||||
|
@ -102,7 +102,7 @@ class ServerLogHandler extends AbstractHandler
|
|||||||
{
|
{
|
||||||
if ($this->processors) {
|
if ($this->processors) {
|
||||||
foreach ($this->processors as $processor) {
|
foreach ($this->processors as $processor) {
|
||||||
$record = \call_user_func($processor, $record);
|
$record = $processor($record);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class RuntimeInstantiator implements InstantiatorInterface
|
|||||||
return $this->factory->createProxy(
|
return $this->factory->createProxy(
|
||||||
$this->factory->getGenerator()->getProxifiedClass($definition),
|
$this->factory->getGenerator()->getProxifiedClass($definition),
|
||||||
function (&$wrappedInstance, LazyLoadingInterface $proxy) use ($realInstantiator) {
|
function (&$wrappedInstance, LazyLoadingInterface $proxy) use ($realInstantiator) {
|
||||||
$wrappedInstance = \call_user_func($realInstantiator);
|
$wrappedInstance = $realInstantiator();
|
||||||
|
|
||||||
$proxy->setProxyInitializer(null);
|
$proxy->setProxyInitializer(null);
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
{%- endblock form_widget_compound -%}
|
{%- endblock form_widget_compound -%}
|
||||||
|
|
||||||
{%- block collection_widget -%}
|
{%- block collection_widget -%}
|
||||||
{% if prototype is defined %}
|
{% if prototype is defined and not prototype.rendered %}
|
||||||
{%- set attr = attr|merge({'data-prototype': form_row(prototype) }) -%}
|
{%- set attr = attr|merge({'data-prototype': form_row(prototype) }) -%}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{- block('form_widget') -}}
|
{{- block('form_widget') -}}
|
||||||
|
@ -57,7 +57,7 @@ class TextDescriptor extends Descriptor
|
|||||||
|
|
||||||
if ($showControllers) {
|
if ($showControllers) {
|
||||||
$controller = $route->getDefault('_controller');
|
$controller = $route->getDefault('_controller');
|
||||||
$row[] = $this->formatCallable($controller);
|
$row[] = $controller ? $this->formatCallable($controller) : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$tableRows[] = $row;
|
$tableRows[] = $row;
|
||||||
|
@ -50,7 +50,7 @@ class RedirectController
|
|||||||
* @param string $route The route name to redirect to
|
* @param string $route The route name to redirect to
|
||||||
* @param bool $permanent Whether the redirection is permanent
|
* @param bool $permanent Whether the redirection is permanent
|
||||||
* @param bool|array $ignoreAttributes Whether to ignore attributes or an array of attributes to ignore
|
* @param bool|array $ignoreAttributes Whether to ignore attributes or an array of attributes to ignore
|
||||||
* @param bool $keepRequestMethod Wheter redirect action should keep HTTP request method
|
* @param bool $keepRequestMethod Whether redirect action should keep HTTP request method
|
||||||
*
|
*
|
||||||
* @throws HttpException In case the route name is empty
|
* @throws HttpException In case the route name is empty
|
||||||
*/
|
*/
|
||||||
@ -94,7 +94,7 @@ class RedirectController
|
|||||||
* @param string|null $scheme The URL scheme (null to keep the current one)
|
* @param string|null $scheme The URL scheme (null to keep the current one)
|
||||||
* @param int|null $httpPort The HTTP port (null to keep the current one for the same scheme or the default configured port)
|
* @param int|null $httpPort The HTTP port (null to keep the current one for the same scheme or the default configured port)
|
||||||
* @param int|null $httpsPort The HTTPS port (null to keep the current one for the same scheme or the default configured port)
|
* @param int|null $httpsPort The HTTPS port (null to keep the current one for the same scheme or the default configured port)
|
||||||
* @param bool $keepRequestMethod Wheter redirect action should keep HTTP request method
|
* @param bool $keepRequestMethod Whether redirect action should keep HTTP request method
|
||||||
*
|
*
|
||||||
* @throws HttpException In case the path is empty
|
* @throws HttpException In case the path is empty
|
||||||
*/
|
*/
|
||||||
|
@ -146,13 +146,13 @@ class PhpArrayAdapterWrapper extends PhpArrayAdapter
|
|||||||
|
|
||||||
public function save(CacheItemInterface $item)
|
public function save(CacheItemInterface $item)
|
||||||
{
|
{
|
||||||
\call_user_func(\Closure::bind(function () use ($item) {
|
(\Closure::bind(function () use ($item) {
|
||||||
$key = $item->getKey();
|
$key = $item->getKey();
|
||||||
$this->keys[$key] = $id = \count($this->values);
|
$this->keys[$key] = $id = \count($this->values);
|
||||||
$this->data[$key] = $this->values[$id] = $item->get();
|
$this->data[$key] = $this->values[$id] = $item->get();
|
||||||
$this->warmUp($this->data);
|
$this->warmUp($this->data);
|
||||||
list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
|
list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
|
||||||
}, $this, PhpArrayAdapter::class));
|
}, $this, PhpArrayAdapter::class))();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -62,9 +62,9 @@ class CacheItemTest extends TestCase
|
|||||||
$this->assertSame($item, $item->tag('foo'));
|
$this->assertSame($item, $item->tag('foo'));
|
||||||
$this->assertSame($item, $item->tag(array('bar', 'baz')));
|
$this->assertSame($item, $item->tag(array('bar', 'baz')));
|
||||||
|
|
||||||
\call_user_func(\Closure::bind(function () use ($item) {
|
(\Closure::bind(function () use ($item) {
|
||||||
$this->assertSame(array('foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz'), $item->newMetadata[CacheItem::METADATA_TAGS]);
|
$this->assertSame(array('foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz'), $item->newMetadata[CacheItem::METADATA_TAGS]);
|
||||||
}, $this, CacheItem::class));
|
}, $this, CacheItem::class))();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,11 +134,11 @@ class PhpArrayCacheWrapper extends PhpArrayCache
|
|||||||
|
|
||||||
public function set($key, $value, $ttl = null)
|
public function set($key, $value, $ttl = null)
|
||||||
{
|
{
|
||||||
\call_user_func(\Closure::bind(function () use ($key, $value) {
|
(\Closure::bind(function () use ($key, $value) {
|
||||||
$this->data[$key] = $value;
|
$this->data[$key] = $value;
|
||||||
$this->warmUp($this->data);
|
$this->warmUp($this->data);
|
||||||
list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
|
list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
|
||||||
}, $this, PhpArrayCache::class));
|
}, $this, PhpArrayCache::class))();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -148,13 +148,13 @@ class PhpArrayCacheWrapper extends PhpArrayCache
|
|||||||
if (!\is_array($values) && !$values instanceof \Traversable) {
|
if (!\is_array($values) && !$values instanceof \Traversable) {
|
||||||
return parent::setMultiple($values, $ttl);
|
return parent::setMultiple($values, $ttl);
|
||||||
}
|
}
|
||||||
\call_user_func(\Closure::bind(function () use ($values) {
|
(\Closure::bind(function () use ($values) {
|
||||||
foreach ($values as $key => $value) {
|
foreach ($values as $key => $value) {
|
||||||
$this->data[$key] = $value;
|
$this->data[$key] = $value;
|
||||||
}
|
}
|
||||||
$this->warmUp($this->data);
|
$this->warmUp($this->data);
|
||||||
list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
|
list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
|
||||||
}, $this, PhpArrayCache::class));
|
}, $this, PhpArrayCache::class))();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ class ConfigCacheFactory implements ConfigCacheFactoryInterface
|
|||||||
|
|
||||||
$cache = new ConfigCache($file, $this->debug);
|
$cache = new ConfigCache($file, $this->debug);
|
||||||
if (!$cache->isFresh()) {
|
if (!$cache->isFresh()) {
|
||||||
\call_user_func($callback, $cache);
|
$callback($cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $cache;
|
return $cache;
|
||||||
|
@ -155,15 +155,15 @@ class ReflectionClassResource implements SelfCheckingResourceInterface, \Seriali
|
|||||||
|
|
||||||
if (interface_exists(EventSubscriberInterface::class, false) && $class->isSubclassOf(EventSubscriberInterface::class)) {
|
if (interface_exists(EventSubscriberInterface::class, false) && $class->isSubclassOf(EventSubscriberInterface::class)) {
|
||||||
yield EventSubscriberInterface::class;
|
yield EventSubscriberInterface::class;
|
||||||
yield print_r(\call_user_func(array($class->name, 'getSubscribedEvents')), true);
|
yield print_r($class->name::getSubscribedEvents(), 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(\call_user_func(array($class->name, 'getSubscribedServices')), true);
|
yield print_r(array($class->name, 'getSubscribedServices')(), true);
|
||||||
} elseif (interface_exists(ServiceSubscriberInterface::class, false) && $class->isSubclassOf(ServiceSubscriberInterface::class)) {
|
} elseif (interface_exists(ServiceSubscriberInterface::class, false) && $class->isSubclassOf(ServiceSubscriberInterface::class)) {
|
||||||
yield ServiceSubscriberInterface::class;
|
yield ServiceSubscriberInterface::class;
|
||||||
yield print_r(\call_user_func(array($class->name, 'getSubscribedServices')), true);
|
yield print_r($class->name::getSubscribedServices(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ class ResourceCheckerConfigCacheFactory implements ConfigCacheFactoryInterface
|
|||||||
|
|
||||||
$cache = new ResourceCheckerConfigCache($file, $this->resourceCheckers);
|
$cache = new ResourceCheckerConfigCache($file, $this->resourceCheckers);
|
||||||
if (!$cache->isFresh()) {
|
if (!$cache->isFresh()) {
|
||||||
\call_user_func($callback, $cache);
|
$callback($cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $cache;
|
return $cache;
|
||||||
|
@ -80,7 +80,7 @@ class XmlUtils
|
|||||||
$e = null;
|
$e = null;
|
||||||
if (\is_callable($schemaOrCallable)) {
|
if (\is_callable($schemaOrCallable)) {
|
||||||
try {
|
try {
|
||||||
$valid = \call_user_func($schemaOrCallable, $dom, $internalErrors);
|
$valid = $schemaOrCallable($dom, $internalErrors);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$valid = false;
|
$valid = false;
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ class Command
|
|||||||
$input->validate();
|
$input->validate();
|
||||||
|
|
||||||
if ($this->code) {
|
if ($this->code) {
|
||||||
$statusCode = \call_user_func($this->code, $input, $output);
|
$statusCode = ($this->code)($input, $output);
|
||||||
} else {
|
} else {
|
||||||
$statusCode = $this->execute($input, $output);
|
$statusCode = $this->execute($input, $output);
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ class ProcessHelper extends Helper
|
|||||||
$output->write($formatter->progress(spl_object_hash($process), $this->escapeString($buffer), Process::ERR === $type));
|
$output->write($formatter->progress(spl_object_hash($process), $this->escapeString($buffer), Process::ERR === $type));
|
||||||
|
|
||||||
if (null !== $callback) {
|
if (null !== $callback) {
|
||||||
\call_user_func($callback, $type, $buffer);
|
$callback($type, $buffer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -496,7 +496,7 @@ final class ProgressBar
|
|||||||
$regex = "{%([a-z\-_]+)(?:\:([^%]+))?%}i";
|
$regex = "{%([a-z\-_]+)(?:\:([^%]+))?%}i";
|
||||||
$callback = function ($matches) {
|
$callback = function ($matches) {
|
||||||
if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) {
|
if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) {
|
||||||
$text = \call_user_func($formatter, $this, $this->output);
|
$text = $formatter($this, $this->output);
|
||||||
} elseif (isset($this->messages[$matches[1]])) {
|
} elseif (isset($this->messages[$matches[1]])) {
|
||||||
$text = $this->messages[$matches[1]];
|
$text = $this->messages[$matches[1]];
|
||||||
} else {
|
} else {
|
||||||
|
@ -196,7 +196,7 @@ class ProgressIndicator
|
|||||||
|
|
||||||
$this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self) {
|
$this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self) {
|
||||||
if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
|
if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
|
||||||
return \call_user_func($formatter, $self);
|
return $formatter($self);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $matches[0];
|
return $matches[0];
|
||||||
|
@ -381,7 +381,7 @@ class QuestionHelper extends Helper
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return \call_user_func($question->getValidator(), $interviewer());
|
return $question->getValidator()($interviewer());
|
||||||
} catch (RuntimeException $e) {
|
} catch (RuntimeException $e) {
|
||||||
throw $e;
|
throw $e;
|
||||||
} catch (\Exception $error) {
|
} catch (\Exception $error) {
|
||||||
|
@ -155,7 +155,7 @@ class Translator implements TranslatorInterface
|
|||||||
throw new ExpressionErrorException(sprintf('Node "%s" not supported.', $node->getNodeName()));
|
throw new ExpressionErrorException(sprintf('Node "%s" not supported.', $node->getNodeName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return \call_user_func($this->nodeTranslators[$node->getNodeName()], $node, $this);
|
return $this->nodeTranslators[$node->getNodeName()]($node, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,7 +167,7 @@ class Translator implements TranslatorInterface
|
|||||||
throw new ExpressionErrorException(sprintf('Combiner "%s" not supported.', $combiner));
|
throw new ExpressionErrorException(sprintf('Combiner "%s" not supported.', $combiner));
|
||||||
}
|
}
|
||||||
|
|
||||||
return \call_user_func($this->combinationTranslators[$combiner], $this->nodeToXPath($xpath), $this->nodeToXPath($combinedXpath));
|
return $this->combinationTranslators[$combiner]($this->nodeToXPath($xpath), $this->nodeToXPath($combinedXpath));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -179,7 +179,7 @@ class Translator implements TranslatorInterface
|
|||||||
throw new ExpressionErrorException(sprintf('Function "%s" not supported.', $function->getName()));
|
throw new ExpressionErrorException(sprintf('Function "%s" not supported.', $function->getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return \call_user_func($this->functionTranslators[$function->getName()], $xpath, $function);
|
return $this->functionTranslators[$function->getName()]($xpath, $function);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -191,7 +191,7 @@ class Translator implements TranslatorInterface
|
|||||||
throw new ExpressionErrorException(sprintf('Pseudo-class "%s" not supported.', $pseudoClass));
|
throw new ExpressionErrorException(sprintf('Pseudo-class "%s" not supported.', $pseudoClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
return \call_user_func($this->pseudoClassTranslators[$pseudoClass], $xpath);
|
return $this->pseudoClassTranslators[$pseudoClass]($xpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -203,7 +203,7 @@ class Translator implements TranslatorInterface
|
|||||||
throw new ExpressionErrorException(sprintf('Attribute matcher operator "%s" not supported.', $operator));
|
throw new ExpressionErrorException(sprintf('Attribute matcher operator "%s" not supported.', $operator));
|
||||||
}
|
}
|
||||||
|
|
||||||
return \call_user_func($this->attributeMatchingTranslators[$operator], $xpath, $attribute, $value);
|
return $this->attributeMatchingTranslators[$operator]($xpath, $attribute, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,7 +151,7 @@ class DebugClassLoader
|
|||||||
require $file;
|
require $file;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
\call_user_func($this->classLoader, $class);
|
($this->classLoader)($class);
|
||||||
$file = false;
|
$file = false;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@ -218,7 +218,7 @@ class DebugClassLoader
|
|||||||
$len = 0;
|
$len = 0;
|
||||||
$ns = '';
|
$ns = '';
|
||||||
} else {
|
} else {
|
||||||
$ns = \substr($class, 0, $len);
|
$ns = \str_replace('_', '\\', \substr($class, 0, $len));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect annotations on the class
|
// Detect annotations on the class
|
||||||
@ -249,13 +249,13 @@ class DebugClassLoader
|
|||||||
if (!isset(self::$checkedClasses[$use])) {
|
if (!isset(self::$checkedClasses[$use])) {
|
||||||
$this->checkClass($use);
|
$this->checkClass($use);
|
||||||
}
|
}
|
||||||
if (isset(self::$deprecated[$use]) && \strncmp($ns, $use, $len)) {
|
if (isset(self::$deprecated[$use]) && \strncmp($ns, \str_replace('_', '\\', $use), $len)) {
|
||||||
$type = class_exists($class, false) ? 'class' : (interface_exists($class, false) ? 'interface' : 'trait');
|
$type = class_exists($class, false) ? 'class' : (interface_exists($class, false) ? 'interface' : 'trait');
|
||||||
$verb = class_exists($use, false) || interface_exists($class, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses');
|
$verb = class_exists($use, false) || interface_exists($class, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses');
|
||||||
|
|
||||||
$deprecations[] = sprintf('The "%s" %s %s "%s" that is deprecated%s.', $class, $type, $verb, $use, self::$deprecated[$use]);
|
$deprecations[] = sprintf('The "%s" %s %s "%s" that is deprecated%s.', $class, $type, $verb, $use, self::$deprecated[$use]);
|
||||||
}
|
}
|
||||||
if (isset(self::$internal[$use]) && \strncmp($ns, $use, $len)) {
|
if (isset(self::$internal[$use]) && \strncmp($ns, \str_replace('_', '\\', $use), $len)) {
|
||||||
$deprecations[] = sprintf('The "%s" %s is considered internal%s. It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $class);
|
$deprecations[] = sprintf('The "%s" %s is considered internal%s. It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,7 +560,7 @@ class ErrorHandler
|
|||||||
$this->exceptionHandler = null;
|
$this->exceptionHandler = null;
|
||||||
try {
|
try {
|
||||||
if (null !== $exceptionHandler) {
|
if (null !== $exceptionHandler) {
|
||||||
return \call_user_func($exceptionHandler, $exception);
|
return $exceptionHandler($exception);
|
||||||
}
|
}
|
||||||
$handlerException = $handlerException ?: $exception;
|
$handlerException = $handlerException ?: $exception;
|
||||||
} catch (\Throwable $handlerException) {
|
} catch (\Throwable $handlerException) {
|
||||||
|
@ -142,7 +142,7 @@ class ExceptionHandler
|
|||||||
$this->caughtBuffer = null;
|
$this->caughtBuffer = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
\call_user_func($this->handler, $exception);
|
($this->handler)($exception);
|
||||||
$this->caughtLength = $caughtLength;
|
$this->caughtLength = $caughtLength;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
if (!$caughtLength) {
|
if (!$caughtLength) {
|
||||||
|
@ -52,11 +52,11 @@ class PassConfig
|
|||||||
new ValidateEnvPlaceholdersPass(),
|
new ValidateEnvPlaceholdersPass(),
|
||||||
new ResolveChildDefinitionsPass(),
|
new ResolveChildDefinitionsPass(),
|
||||||
new ServiceLocatorTagPass(),
|
new ServiceLocatorTagPass(),
|
||||||
|
new RegisterServiceSubscribersPass(),
|
||||||
new DecoratorServicePass(),
|
new DecoratorServicePass(),
|
||||||
new ResolveParameterPlaceHoldersPass(false),
|
new ResolveParameterPlaceHoldersPass(false),
|
||||||
new ResolveFactoryClassPass(),
|
new ResolveFactoryClassPass(),
|
||||||
new CheckDefinitionValidityPass(),
|
new CheckDefinitionValidityPass(),
|
||||||
new RegisterServiceSubscribersPass(),
|
|
||||||
new ResolveNamedArgumentsPass(),
|
new ResolveNamedArgumentsPass(),
|
||||||
new AutowireRequiredMethodsPass(),
|
new AutowireRequiredMethodsPass(),
|
||||||
new ResolveBindingsPass(),
|
new ResolveBindingsPass(),
|
||||||
|
@ -1162,7 +1162,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
throw new InvalidArgumentException(sprintf('The configure callable for class "%s" is not a callable.', \get_class($service)));
|
throw new InvalidArgumentException(sprintf('The configure callable for class "%s" is not a callable.', \get_class($service)));
|
||||||
}
|
}
|
||||||
|
|
||||||
\call_user_func($callable, $service);
|
$callable($service);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $service;
|
return $service;
|
||||||
|
@ -28,6 +28,6 @@ class RealServiceInstantiator implements InstantiatorInterface
|
|||||||
*/
|
*/
|
||||||
public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator)
|
public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator)
|
||||||
{
|
{
|
||||||
return \call_user_func($realInstantiator);
|
return $realInstantiator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ class ClosureLoader extends Loader
|
|||||||
*/
|
*/
|
||||||
public function load($resource, $type = null)
|
public function load($resource, $type = null)
|
||||||
{
|
{
|
||||||
\call_user_func($resource, $this->container);
|
$resource($this->container);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,39 +86,40 @@ class ServiceLocator implements PsrContainerInterface
|
|||||||
$class = isset($class[3]['object']) ? \get_class($class[3]['object']) : null;
|
$class = isset($class[3]['object']) ? \get_class($class[3]['object']) : null;
|
||||||
$externalId = $this->externalId ?: $class;
|
$externalId = $this->externalId ?: $class;
|
||||||
|
|
||||||
$msg = sprintf('Service "%s" not found: ', $id);
|
$msg = array();
|
||||||
|
$msg[] = sprintf('Service "%s" not found:', $id);
|
||||||
|
|
||||||
if (!$this->container) {
|
if (!$this->container) {
|
||||||
$class = null;
|
$class = null;
|
||||||
} elseif ($this->container->has($id) || isset($this->container->getRemovedIds()[$id])) {
|
} elseif ($this->container->has($id) || isset($this->container->getRemovedIds()[$id])) {
|
||||||
$msg .= 'even though it exists in the app\'s container, ';
|
$msg[] = 'even though it exists in the app\'s container,';
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
$this->container->get($id);
|
$this->container->get($id);
|
||||||
$class = null;
|
$class = null;
|
||||||
} catch (ServiceNotFoundException $e) {
|
} catch (ServiceNotFoundException $e) {
|
||||||
if ($e->getAlternatives()) {
|
if ($e->getAlternatives()) {
|
||||||
$msg .= sprintf(' did you mean %s? Anyway, ', $this->formatAlternatives($e->getAlternatives(), 'or'));
|
$msg[] = sprintf('did you mean %s? Anyway,', $this->formatAlternatives($e->getAlternatives(), 'or'));
|
||||||
} else {
|
} else {
|
||||||
$class = null;
|
$class = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($externalId) {
|
if ($externalId) {
|
||||||
$msg .= sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives());
|
$msg[] = sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives());
|
||||||
} else {
|
} else {
|
||||||
$msg .= sprintf('the current service locator %s', $this->formatAlternatives());
|
$msg[] = sprintf('the current service locator %s', $this->formatAlternatives());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$class) {
|
if (!$class) {
|
||||||
// no-op
|
// no-op
|
||||||
} elseif (is_subclass_of($class, ServiceSubscriberInterface::class)) {
|
} elseif (is_subclass_of($class, ServiceSubscriberInterface::class)) {
|
||||||
$msg .= sprintf(' Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', preg_replace('/([^\\\\]++\\\\)++/', '', $class));
|
$msg[] = sprintf('Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', preg_replace('/([^\\\\]++\\\\)++/', '', $class));
|
||||||
} else {
|
} else {
|
||||||
$msg .= 'Try using dependency injection instead.';
|
$msg[] = 'Try using dependency injection instead.';
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ServiceNotFoundException($id, end($this->loading) ?: null, null, array(), $msg);
|
return new ServiceNotFoundException($id, end($this->loading) ?: null, null, array(), implode(' ', $msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface
|
private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface
|
||||||
|
@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\Alias;
|
|||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
|
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class tests the integration of the different compiler passes.
|
* This class tests the integration of the different compiler passes.
|
||||||
@ -120,6 +121,21 @@ class IntegrationTest extends TestCase
|
|||||||
$this->assertFalse($container->hasDefinition('c'), 'Service C was not inlined.');
|
$this->assertFalse($container->hasDefinition('c'), 'Service C was not inlined.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCanDecorateServiceSubscriber()
|
||||||
|
{
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
$container->register(ServiceSubscriberStub::class)
|
||||||
|
->addTag('container.service_subscriber')
|
||||||
|
->setPublic(true);
|
||||||
|
|
||||||
|
$container->register(DecoratedServiceSubscriber::class)
|
||||||
|
->setDecoratedService(ServiceSubscriberStub::class);
|
||||||
|
|
||||||
|
$container->compile();
|
||||||
|
|
||||||
|
$this->assertInstanceOf(DecoratedServiceSubscriber::class, $container->get(ServiceSubscriberStub::class));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider getYamlCompileTests
|
* @dataProvider getYamlCompileTests
|
||||||
*/
|
*/
|
||||||
@ -220,6 +236,18 @@ class IntegrationTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ServiceSubscriberStub implements ServiceSubscriberInterface
|
||||||
|
{
|
||||||
|
public static function getSubscribedServices()
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DecoratedServiceSubscriber
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
class IntegrationTestStub extends IntegrationTestStubParent
|
class IntegrationTestStub extends IntegrationTestStubParent
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,20 @@ class ServiceLocatorTest extends BaseServiceLocatorTest
|
|||||||
$subscriber->getFoo();
|
$subscriber->getFoo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException
|
||||||
|
* @expectedExceptionMessage Service "foo" not found: even though it exists in the app's container, the container inside "foo" is a smaller service locator that is empty... Try using dependency injection instead.
|
||||||
|
*/
|
||||||
|
public function testGetThrowsServiceNotFoundException()
|
||||||
|
{
|
||||||
|
$container = new Container();
|
||||||
|
$container->set('foo', new \stdClass());
|
||||||
|
|
||||||
|
$locator = new ServiceLocator(array());
|
||||||
|
$locator = $locator->withContext('foo', $container);
|
||||||
|
$locator->get('foo');
|
||||||
|
}
|
||||||
|
|
||||||
public function testInvoke()
|
public function testInvoke()
|
||||||
{
|
{
|
||||||
$locator = $this->getServiceLocator(array(
|
$locator = $this->getServiceLocator(array(
|
||||||
|
@ -108,7 +108,7 @@ class WrappedListener
|
|||||||
|
|
||||||
$e = $this->stopwatch->start($this->name, 'event_listener');
|
$e = $this->stopwatch->start($this->name, 'event_listener');
|
||||||
|
|
||||||
\call_user_func($this->listener, $event, $eventName, $this->dispatcher ?: $dispatcher);
|
($this->listener)($event, $eventName, $this->dispatcher ?: $dispatcher);
|
||||||
|
|
||||||
if ($e->isStarted()) {
|
if ($e->isStarted()) {
|
||||||
$e->stop();
|
$e->stop();
|
||||||
|
@ -209,7 +209,7 @@ class EventDispatcher implements EventDispatcherInterface
|
|||||||
if ($event->isPropagationStopped()) {
|
if ($event->isPropagationStopped()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
\call_user_func($listener, $event, $eventName, $this);
|
$listener($event, $eventName, $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class CustomFilterIterator extends \FilterIterator
|
|||||||
$fileinfo = $this->current();
|
$fileinfo = $this->current();
|
||||||
|
|
||||||
foreach ($this->filters as $filter) {
|
foreach ($this->filters as $filter) {
|
||||||
if (false === \call_user_func($filter, $fileinfo)) {
|
if (false === $filter($fileinfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ class SortableIterator implements \IteratorAggregate
|
|||||||
} elseif (self::SORT_BY_NONE === $sort) {
|
} elseif (self::SORT_BY_NONE === $sort) {
|
||||||
$this->sort = $order;
|
$this->sort = $order;
|
||||||
} elseif (\is_callable($sort)) {
|
} elseif (\is_callable($sort)) {
|
||||||
$this->sort = $reverseOrder ? function ($a, $b) use ($sort) { return -\call_user_func($sort, $a, $b); } : $sort;
|
$this->sort = $reverseOrder ? function ($a, $b) use ($sort) { return -$sort($a, $b); } : $sort;
|
||||||
} else {
|
} else {
|
||||||
throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
|
throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ class CallbackTransformer implements DataTransformerInterface
|
|||||||
*/
|
*/
|
||||||
public function transform($data)
|
public function transform($data)
|
||||||
{
|
{
|
||||||
return \call_user_func($this->transform, $data);
|
return ($this->transform)($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,6 +57,6 @@ class CallbackTransformer implements DataTransformerInterface
|
|||||||
*/
|
*/
|
||||||
public function reverseTransform($data)
|
public function reverseTransform($data)
|
||||||
{
|
{
|
||||||
return \call_user_func($this->reverseTransform, $data);
|
return ($this->reverseTransform)($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ class ArrayChoiceList implements ChoiceListInterface
|
|||||||
$givenValues = array();
|
$givenValues = array();
|
||||||
|
|
||||||
foreach ($choices as $i => $givenChoice) {
|
foreach ($choices as $i => $givenChoice) {
|
||||||
$givenValues[$i] = (string) \call_user_func($this->valueCallback, $givenChoice);
|
$givenValues[$i] = (string) ($this->valueCallback)($givenChoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array_intersect($givenValues, array_keys($this->choices));
|
return array_intersect($givenValues, array_keys($this->choices));
|
||||||
@ -202,7 +202,7 @@ class ArrayChoiceList implements ChoiceListInterface
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$choiceValue = (string) \call_user_func($value, $choice);
|
$choiceValue = (string) $value($choice);
|
||||||
$choicesByValues[$choiceValue] = $choice;
|
$choicesByValues[$choiceValue] = $choice;
|
||||||
$keysByValues[$choiceValue] = $key;
|
$keysByValues[$choiceValue] = $key;
|
||||||
$structuredValues[$key] = $choiceValue;
|
$structuredValues[$key] = $choiceValue;
|
||||||
|
@ -118,7 +118,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
|
|||||||
// $value may be an integer or a string, since it's stored in the array
|
// $value may be an integer or a string, since it's stored in the array
|
||||||
// keys. We want to guarantee it's a string though.
|
// keys. We want to guarantee it's a string though.
|
||||||
$key = $keys[$value];
|
$key = $keys[$value];
|
||||||
$nextIndex = \is_int($index) ? $index++ : \call_user_func($index, $choice, $key, $value);
|
$nextIndex = \is_int($index) ? $index++ : $index($choice, $key, $value);
|
||||||
|
|
||||||
// BC normalize label to accept a false value
|
// BC normalize label to accept a false value
|
||||||
if (null === $label) {
|
if (null === $label) {
|
||||||
@ -127,7 +127,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
|
|||||||
} elseif (false !== $label) {
|
} elseif (false !== $label) {
|
||||||
// If "choice_label" is set to false and "expanded" is true, the value false
|
// If "choice_label" is set to false and "expanded" is true, the value false
|
||||||
// should be passed on to the "label" option of the checkboxes/radio buttons
|
// should be passed on to the "label" option of the checkboxes/radio buttons
|
||||||
$dynamicLabel = \call_user_func($label, $choice, $key, $value);
|
$dynamicLabel = $label($choice, $key, $value);
|
||||||
$label = false === $dynamicLabel ? false : (string) $dynamicLabel;
|
$label = false === $dynamicLabel ? false : (string) $dynamicLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,11 +137,11 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
|
|||||||
$label,
|
$label,
|
||||||
// The attributes may be a callable or a mapping from choice indices
|
// The attributes may be a callable or a mapping from choice indices
|
||||||
// to nested arrays
|
// to nested arrays
|
||||||
\is_callable($attr) ? \call_user_func($attr, $choice, $key, $value) : (isset($attr[$key]) ? $attr[$key] : array())
|
\is_callable($attr) ? $attr($choice, $key, $value) : (isset($attr[$key]) ? $attr[$key] : array())
|
||||||
);
|
);
|
||||||
|
|
||||||
// $isPreferred may be null if no choices are preferred
|
// $isPreferred may be null if no choices are preferred
|
||||||
if ($isPreferred && \call_user_func($isPreferred, $choice, $key, $value)) {
|
if ($isPreferred && $isPreferred($choice, $key, $value)) {
|
||||||
$preferredViews[$nextIndex] = $view;
|
$preferredViews[$nextIndex] = $view;
|
||||||
} else {
|
} else {
|
||||||
$otherViews[$nextIndex] = $view;
|
$otherViews[$nextIndex] = $view;
|
||||||
@ -200,7 +200,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
|
|||||||
|
|
||||||
private static function addChoiceViewGroupedBy($groupBy, $choice, $value, $label, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews)
|
private static function addChoiceViewGroupedBy($groupBy, $choice, $value, $label, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews)
|
||||||
{
|
{
|
||||||
$groupLabel = \call_user_func($groupBy, $choice, $keys[$value], $value);
|
$groupLabel = $groupBy($choice, $keys[$value], $value);
|
||||||
|
|
||||||
if (null === $groupLabel) {
|
if (null === $groupLabel) {
|
||||||
// If the callable returns null, don't group the choice
|
// If the callable returns null, don't group the choice
|
||||||
|
@ -46,7 +46,7 @@ class CallbackChoiceLoader implements ChoiceLoaderInterface
|
|||||||
return $this->choiceList;
|
return $this->choiceList;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->choiceList = new ArrayChoiceList(\call_user_func($this->callback), $value);
|
return $this->choiceList = new ArrayChoiceList(($this->callback)(), $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,11 +30,6 @@ class IntlCallbackChoiceLoader extends CallbackChoiceLoader
|
|||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no callable is set, values are the same as choices
|
|
||||||
if (null === $value) {
|
|
||||||
return $values;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->loadChoiceList($value)->getChoicesForValues($values);
|
return $this->loadChoiceList($value)->getChoicesForValues($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ class ResizeFormListener implements EventSubscriberInterface
|
|||||||
/** @var FormInterface $child */
|
/** @var FormInterface $child */
|
||||||
foreach ($form as $name => $child) {
|
foreach ($form as $name => $child) {
|
||||||
$isNew = !isset($previousData[$name]);
|
$isNew = !isset($previousData[$name]);
|
||||||
$isEmpty = \is_callable($this->deleteEmpty) ? \call_user_func($this->deleteEmpty, $child->getData()) : $child->isEmpty();
|
$isEmpty = \is_callable($this->deleteEmpty) ? ($this->deleteEmpty)($child->getData()) : $child->isEmpty();
|
||||||
|
|
||||||
// $isNew can only be true if allowAdd is true, so we don't
|
// $isNew can only be true if allowAdd is true, so we don't
|
||||||
// need to check allowAdd again
|
// need to check allowAdd again
|
||||||
|
@ -106,11 +106,6 @@ class CountryType extends AbstractType implements ChoiceLoaderInterface
|
|||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no callable is set, values are the same as choices
|
|
||||||
if (null === $value) {
|
|
||||||
return $values;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->loadChoiceList($value)->getChoicesForValues($values);
|
return $this->loadChoiceList($value)->getChoicesForValues($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,11 +106,6 @@ class CurrencyType extends AbstractType implements ChoiceLoaderInterface
|
|||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no callable is set, values are the same as choices
|
|
||||||
if (null === $value) {
|
|
||||||
return $values;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->loadChoiceList($value)->getChoicesForValues($values);
|
return $this->loadChoiceList($value)->getChoicesForValues($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,11 +106,6 @@ class LanguageType extends AbstractType implements ChoiceLoaderInterface
|
|||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no callable is set, values are the same as choices
|
|
||||||
if (null === $value) {
|
|
||||||
return $values;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->loadChoiceList($value)->getChoicesForValues($values);
|
return $this->loadChoiceList($value)->getChoicesForValues($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,11 +106,6 @@ class LocaleType extends AbstractType implements ChoiceLoaderInterface
|
|||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no callable is set, values are the same as choices
|
|
||||||
if (null === $value) {
|
|
||||||
return $values;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->loadChoiceList($value)->getChoicesForValues($values);
|
return $this->loadChoiceList($value)->getChoicesForValues($values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ class HttpFoundationRequestHandler implements RequestHandlerInterface
|
|||||||
$form->submit(null, false);
|
$form->submit(null, false);
|
||||||
|
|
||||||
$form->addError(new FormError(
|
$form->addError(new FormError(
|
||||||
\call_user_func($form->getConfig()->getOption('upload_max_size_message')),
|
$form->getConfig()->getOption('upload_max_size_message')(),
|
||||||
null,
|
null,
|
||||||
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize())
|
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize())
|
||||||
));
|
));
|
||||||
|
@ -180,7 +180,7 @@ class FormValidator extends ConstraintValidator
|
|||||||
private static function resolveValidationGroups($groups, FormInterface $form)
|
private static function resolveValidationGroups($groups, FormInterface $form)
|
||||||
{
|
{
|
||||||
if (!\is_string($groups) && \is_callable($groups)) {
|
if (!\is_string($groups) && \is_callable($groups)) {
|
||||||
$groups = \call_user_func($groups, $form);
|
$groups = $groups($form);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($groups instanceof GroupSequence) {
|
if ($groups instanceof GroupSequence) {
|
||||||
|
@ -51,7 +51,7 @@ class ValidationListener implements EventSubscriberInterface
|
|||||||
$form = $event->getForm();
|
$form = $event->getForm();
|
||||||
|
|
||||||
if ($form->isRoot()) {
|
if ($form->isRoot()) {
|
||||||
// Validate the form in group "Default"
|
// Form groups are validated internally (FormValidator). Here we don't set groups as they are retrieved into the validator.
|
||||||
foreach ($this->validator->validate($form) as $violation) {
|
foreach ($this->validator->validate($form) as $violation) {
|
||||||
// Allow the "invalid" constraint to be put onto
|
// Allow the "invalid" constraint to be put onto
|
||||||
// non-synchronized forms
|
// non-synchronized forms
|
||||||
|
@ -48,7 +48,7 @@ class UploadValidatorExtension extends AbstractTypeExtension
|
|||||||
$translationDomain = $this->translationDomain;
|
$translationDomain = $this->translationDomain;
|
||||||
$resolver->setNormalizer('upload_max_size_message', function (Options $options, $message) use ($translator, $translationDomain) {
|
$resolver->setNormalizer('upload_max_size_message', function (Options $options, $message) use ($translator, $translationDomain) {
|
||||||
return function () use ($translator, $translationDomain, $message) {
|
return function () use ($translator, $translationDomain, $message) {
|
||||||
return $translator->trans(\call_user_func($message), array(), $translationDomain);
|
return $translator->trans($message(), array(), $translationDomain);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -532,11 +532,12 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
|
|||||||
$submittedData = null;
|
$submittedData = null;
|
||||||
} elseif (is_scalar($submittedData)) {
|
} elseif (is_scalar($submittedData)) {
|
||||||
$submittedData = (string) $submittedData;
|
$submittedData = (string) $submittedData;
|
||||||
} elseif ($this->config->getOption('allow_file_upload')) {
|
} elseif (!$this->config->getOption('allow_file_upload') && $this->config->getRequestHandler()->isFileUpload($submittedData)) {
|
||||||
// no-op
|
|
||||||
} elseif ($this->config->getRequestHandler()->isFileUpload($submittedData)) {
|
|
||||||
$submittedData = null;
|
$submittedData = null;
|
||||||
$this->transformationFailure = new TransformationFailedException('Submitted data was expected to be text or number, file upload given.');
|
$this->transformationFailure = new TransformationFailedException('Submitted data was expected to be text or number, file upload given.');
|
||||||
|
} elseif (\is_array($submittedData) && !$this->config->getCompound() && !$this->config->hasOption('multiple')) {
|
||||||
|
$submittedData = null;
|
||||||
|
$this->transformationFailure = new TransformationFailedException('Submitted data was expected to be text or number, array given.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$dispatcher = $this->config->getEventDispatcher();
|
$dispatcher = $this->config->getEventDispatcher();
|
||||||
|
@ -78,7 +78,7 @@ class NativeRequestHandler implements RequestHandlerInterface
|
|||||||
$form->submit(null, false);
|
$form->submit(null, false);
|
||||||
|
|
||||||
$form->addError(new FormError(
|
$form->addError(new FormError(
|
||||||
\call_user_func($form->getConfig()->getOption('upload_max_size_message')),
|
$form->getConfig()->getOption('upload_max_size_message')(),
|
||||||
null,
|
null,
|
||||||
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize())
|
array('{{ max }}' => $this->serverParams->getNormalizedIniPostMaxSize())
|
||||||
));
|
));
|
||||||
|
@ -84,6 +84,11 @@ class IntlCallbackChoiceLoaderTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testLoadChoicesForValuesDropsNonExistentChoices()
|
||||||
|
{
|
||||||
|
$this->assertSame(array(), self::$loader->loadChoicesForValues(array('foo')));
|
||||||
|
}
|
||||||
|
|
||||||
public function testLoadValuesForChoicesLoadsChoiceListOnFirstCall()
|
public function testLoadValuesForChoicesLoadsChoiceListOnFirstCall()
|
||||||
{
|
{
|
||||||
$this->assertSame(
|
$this->assertSame(
|
||||||
|
@ -1081,6 +1081,22 @@ class CompoundFormTest extends AbstractFormTest
|
|||||||
$this->assertFalse($submit->isSubmitted());
|
$this->assertFalse($submit->isSubmitted());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testArrayTransformationFailureOnSubmit()
|
||||||
|
{
|
||||||
|
$this->form->add($this->getBuilder('foo')->setCompound(false)->getForm());
|
||||||
|
$this->form->add($this->getBuilder('bar', null, null, array('multiple' => false))->setCompound(false)->getForm());
|
||||||
|
|
||||||
|
$this->form->submit(array(
|
||||||
|
'foo' => array('foo'),
|
||||||
|
'bar' => array('bar'),
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertNull($this->form->get('foo')->getData());
|
||||||
|
$this->assertSame('Submitted data was expected to be text or number, array given.', $this->form->get('foo')->getTransformationFailure()->getMessage());
|
||||||
|
|
||||||
|
$this->assertSame(array('bar'), $this->form->get('bar')->getData());
|
||||||
|
}
|
||||||
|
|
||||||
public function testFileUpload()
|
public function testFileUpload()
|
||||||
{
|
{
|
||||||
$reqHandler = new HttpFoundationRequestHandler();
|
$reqHandler = new HttpFoundationRequestHandler();
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
||||||
|
|
||||||
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
|
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CountryType;
|
||||||
use Symfony\Component\Intl\Util\IntlTestHelper;
|
use Symfony\Component\Intl\Util\IntlTestHelper;
|
||||||
|
|
||||||
class CountryTypeTest extends BaseTypeTest
|
class CountryTypeTest extends BaseTypeTest
|
||||||
@ -80,4 +81,14 @@ class CountryTypeTest extends BaseTypeTest
|
|||||||
{
|
{
|
||||||
parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData);
|
parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
|
public function testInvalidChoiceValuesAreDropped()
|
||||||
|
{
|
||||||
|
$type = new CountryType();
|
||||||
|
|
||||||
|
$this->assertSame(array(), $type->loadChoicesForValues(array('foo')));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
||||||
|
|
||||||
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
|
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
|
||||||
use Symfony\Component\Intl\Util\IntlTestHelper;
|
use Symfony\Component\Intl\Util\IntlTestHelper;
|
||||||
|
|
||||||
class CurrencyTypeTest extends BaseTypeTest
|
class CurrencyTypeTest extends BaseTypeTest
|
||||||
@ -61,4 +62,14 @@ class CurrencyTypeTest extends BaseTypeTest
|
|||||||
{
|
{
|
||||||
parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData);
|
parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
|
public function testInvalidChoiceValuesAreDropped()
|
||||||
|
{
|
||||||
|
$type = new CurrencyType();
|
||||||
|
|
||||||
|
$this->assertSame(array(), $type->loadChoicesForValues(array('foo')));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
||||||
|
|
||||||
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
|
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\LanguageType;
|
||||||
use Symfony\Component\Intl\Util\IntlTestHelper;
|
use Symfony\Component\Intl\Util\IntlTestHelper;
|
||||||
|
|
||||||
class LanguageTypeTest extends BaseTypeTest
|
class LanguageTypeTest extends BaseTypeTest
|
||||||
@ -73,4 +74,14 @@ class LanguageTypeTest extends BaseTypeTest
|
|||||||
{
|
{
|
||||||
parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData);
|
parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
|
public function testInvalidChoiceValuesAreDropped()
|
||||||
|
{
|
||||||
|
$type = new LanguageType();
|
||||||
|
|
||||||
|
$this->assertSame(array(), $type->loadChoicesForValues(array('foo')));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
||||||
|
|
||||||
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
|
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\LocaleType;
|
||||||
use Symfony\Component\Intl\Util\IntlTestHelper;
|
use Symfony\Component\Intl\Util\IntlTestHelper;
|
||||||
|
|
||||||
class LocaleTypeTest extends BaseTypeTest
|
class LocaleTypeTest extends BaseTypeTest
|
||||||
@ -61,4 +62,14 @@ class LocaleTypeTest extends BaseTypeTest
|
|||||||
{
|
{
|
||||||
parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData);
|
parent::testSubmitNullUsesDefaultEmptyData($emptyData, $expectedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
|
public function testInvalidChoiceValuesAreDropped()
|
||||||
|
{
|
||||||
|
$type = new LocaleType();
|
||||||
|
|
||||||
|
$this->assertSame(array(), $type->loadChoicesForValues(array('foo')));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,14 +83,6 @@ class UrlTypeTest extends TextTypeTest
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSubmitWithNonStringDataDoesNotBreakTheFixUrlProtocolListener()
|
|
||||||
{
|
|
||||||
$form = $this->factory->create(static::TESTED_TYPE);
|
|
||||||
$form->submit(array('domain.com', 'www.domain.com'));
|
|
||||||
|
|
||||||
$this->assertSame(array('domain.com', 'www.domain.com'), $form->getData());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testSubmitNullUsesDefaultEmptyData($emptyData = 'empty', $expectedData = 'http://empty')
|
public function testSubmitNullUsesDefaultEmptyData($emptyData = 'empty', $expectedData = 'http://empty')
|
||||||
{
|
{
|
||||||
$form = $this->factory->create(static::TESTED_TYPE, null, array(
|
$form = $this->factory->create(static::TESTED_TYPE, null, array(
|
||||||
|
@ -220,7 +220,7 @@ class FormValidatorTest extends ConstraintValidatorTestCase
|
|||||||
->getForm();
|
->getForm();
|
||||||
|
|
||||||
// Launch transformer
|
// Launch transformer
|
||||||
$form->submit(array());
|
$form->submit('foo');
|
||||||
|
|
||||||
$this->expectNoValidate();
|
$this->expectNoValidate();
|
||||||
|
|
||||||
|
@ -41,6 +41,6 @@ class UploadValidatorExtensionTest extends TypeTestCase
|
|||||||
$extension->configureOptions($resolver);
|
$extension->configureOptions($resolver);
|
||||||
$options = $resolver->resolve();
|
$options = $resolver->resolve();
|
||||||
|
|
||||||
$this->assertEquals('translated max {{ max }}!', \call_user_func($options['upload_max_size_message']));
|
$this->assertEquals('translated max {{ max }}!', $options['upload_max_size_message']());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ class HeaderBag implements \IteratorAggregate, \Countable
|
|||||||
* Returns a header value by name.
|
* Returns a header value by name.
|
||||||
*
|
*
|
||||||
* @param string $key The header name
|
* @param string $key The header name
|
||||||
* @param string|string[]|null $default The default value
|
* @param string|null $default The default value
|
||||||
* @param bool $first Whether to return the first value or all header values
|
* @param bool $first Whether to return the first value or all header values
|
||||||
*
|
*
|
||||||
* @return string|string[]|null The first header value or default value if $first is true, an array of values otherwise
|
* @return string|string[]|null The first header value or default value if $first is true, an array of values otherwise
|
||||||
|
@ -1908,7 +1908,7 @@ class Request
|
|||||||
private static function createRequestFromFactory(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
|
private static function createRequestFromFactory(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
|
||||||
{
|
{
|
||||||
if (self::$requestFactory) {
|
if (self::$requestFactory) {
|
||||||
$request = \call_user_func(self::$requestFactory, $query, $request, $attributes, $cookies, $files, $server, $content);
|
$request = (self::$requestFactory)($query, $request, $attributes, $cookies, $files, $server, $content);
|
||||||
|
|
||||||
if (!$request instanceof self) {
|
if (!$request instanceof self) {
|
||||||
throw new \LogicException('The Request factory must return an instance of Symfony\Component\HttpFoundation\Request.');
|
throw new \LogicException('The Request factory must return an instance of Symfony\Component\HttpFoundation\Request.');
|
||||||
|
@ -111,7 +111,7 @@ class StreamedResponse extends Response
|
|||||||
throw new \LogicException('The Response callback must not be null.');
|
throw new \LogicException('The Response callback must not be null.');
|
||||||
}
|
}
|
||||||
|
|
||||||
\call_user_func($this->callback);
|
($this->callback)();
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -390,7 +390,7 @@ class MockPdo extends \PDO
|
|||||||
public function prepare($statement, $driverOptions = array())
|
public function prepare($statement, $driverOptions = array())
|
||||||
{
|
{
|
||||||
return \is_callable($this->prepareResult)
|
return \is_callable($this->prepareResult)
|
||||||
? \call_user_func($this->prepareResult, $statement, $driverOptions)
|
? ($this->prepareResult)($statement, $driverOptions)
|
||||||
: $this->prepareResult;
|
: $this->prepareResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ class FileLinkFormatter implements \Serializable
|
|||||||
if ($this->requestStack && $this->baseDir && $this->urlFormat) {
|
if ($this->requestStack && $this->baseDir && $this->urlFormat) {
|
||||||
$request = $this->requestStack->getMasterRequest();
|
$request = $this->requestStack->getMasterRequest();
|
||||||
if ($request instanceof Request) {
|
if ($request instanceof Request) {
|
||||||
if ($this->urlFormat instanceof \Closure && !$this->urlFormat = \call_user_func($this->urlFormat)) {
|
if ($this->urlFormat instanceof \Closure && !$this->urlFormat = ($this->urlFormat)()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ class OptionsResolverIntrospector
|
|||||||
*/
|
*/
|
||||||
public function getDefault(string $option)
|
public function getDefault(string $option)
|
||||||
{
|
{
|
||||||
return \call_user_func($this->get, 'defaults', $option, sprintf('No default value was set for the "%s" option.', $option));
|
return ($this->get)('defaults', $option, sprintf('No default value was set for the "%s" option.', $option));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,7 +57,7 @@ class OptionsResolverIntrospector
|
|||||||
*/
|
*/
|
||||||
public function getLazyClosures(string $option): array
|
public function getLazyClosures(string $option): array
|
||||||
{
|
{
|
||||||
return \call_user_func($this->get, 'lazy', $option, sprintf('No lazy closures were set for the "%s" option.', $option));
|
return ($this->get)('lazy', $option, sprintf('No lazy closures were set for the "%s" option.', $option));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,7 +67,7 @@ class OptionsResolverIntrospector
|
|||||||
*/
|
*/
|
||||||
public function getAllowedTypes(string $option): array
|
public function getAllowedTypes(string $option): array
|
||||||
{
|
{
|
||||||
return \call_user_func($this->get, 'allowedTypes', $option, sprintf('No allowed types were set for the "%s" option.', $option));
|
return ($this->get)('allowedTypes', $option, sprintf('No allowed types were set for the "%s" option.', $option));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,7 +77,7 @@ class OptionsResolverIntrospector
|
|||||||
*/
|
*/
|
||||||
public function getAllowedValues(string $option): array
|
public function getAllowedValues(string $option): array
|
||||||
{
|
{
|
||||||
return \call_user_func($this->get, 'allowedValues', $option, sprintf('No allowed values were set for the "%s" option.', $option));
|
return ($this->get)('allowedValues', $option, sprintf('No allowed values were set for the "%s" option.', $option));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,7 +85,7 @@ class OptionsResolverIntrospector
|
|||||||
*/
|
*/
|
||||||
public function getNormalizer(string $option): \Closure
|
public function getNormalizer(string $option): \Closure
|
||||||
{
|
{
|
||||||
return \call_user_func($this->get, 'normalizers', $option, sprintf('No normalizer was set for the "%s" option.', $option));
|
return ($this->get)('normalizers', $option, sprintf('No normalizer was set for the "%s" option.', $option));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,6 +95,6 @@ class OptionsResolverIntrospector
|
|||||||
*/
|
*/
|
||||||
public function getDeprecationMessage(string $option)
|
public function getDeprecationMessage(string $option)
|
||||||
{
|
{
|
||||||
return \call_user_func($this->get, 'deprecated', $option, sprintf('No deprecation was set for the "%s" option.', $option));
|
return ($this->get)('deprecated', $option, sprintf('No deprecation was set for the "%s" option.', $option));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1309,7 +1309,7 @@ class Process implements \IteratorAggregate
|
|||||||
if ($this->outputDisabled) {
|
if ($this->outputDisabled) {
|
||||||
return function ($type, $data) use ($callback) {
|
return function ($type, $data) use ($callback) {
|
||||||
if (null !== $callback) {
|
if (null !== $callback) {
|
||||||
return \call_user_func($callback, $type, $data);
|
return $callback($type, $data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1324,7 +1324,7 @@ class Process implements \IteratorAggregate
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $callback) {
|
if (null !== $callback) {
|
||||||
return \call_user_func($callback, $type, $data);
|
return $callback($type, $data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ abstract class ObjectRouteLoader extends Loader
|
|||||||
throw new \BadMethodCallException(sprintf('Method "%s" not found on "%s" when importing routing resource "%s"', $method, \get_class($loaderObject), $resource));
|
throw new \BadMethodCallException(sprintf('Method "%s" not found on "%s" when importing routing resource "%s"', $method, \get_class($loaderObject), $resource));
|
||||||
}
|
}
|
||||||
|
|
||||||
$routeCollection = \call_user_func(array($loaderObject, $method), $this);
|
$routeCollection = $loaderObject->$method($this);
|
||||||
|
|
||||||
if (!$routeCollection instanceof RouteCollection) {
|
if (!$routeCollection instanceof RouteCollection) {
|
||||||
$type = \is_object($routeCollection) ? \get_class($routeCollection) : \gettype($routeCollection);
|
$type = \is_object($routeCollection) ? \get_class($routeCollection) : \gettype($routeCollection);
|
||||||
|
@ -96,14 +96,22 @@ class GuardAuthenticationListener implements ListenerInterface
|
|||||||
$request = $event->getRequest();
|
$request = $event->getRequest();
|
||||||
try {
|
try {
|
||||||
if (null !== $this->logger) {
|
if (null !== $this->logger) {
|
||||||
$this->logger->debug('Calling getCredentials() on guard authenticator.', array('firewall_key' => $this->providerKey, 'authenticator' => \get_class($guardAuthenticator)));
|
$this->logger->debug('Checking support on guard authenticator.', array('firewall_key' => $this->providerKey, 'authenticator' => \get_class($guardAuthenticator)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// abort the execution of the authenticator if it doesn't support the request
|
// abort the execution of the authenticator if it doesn't support the request
|
||||||
if (!$guardAuthenticator->supports($request)) {
|
if (!$guardAuthenticator->supports($request)) {
|
||||||
|
if (null !== $this->logger) {
|
||||||
|
$this->logger->debug('Guard authenticator does not support the request.', array('firewall_key' => $this->providerKey, 'authenticator' => \get_class($guardAuthenticator)));
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null !== $this->logger) {
|
||||||
|
$this->logger->debug('Calling getCredentials() on guard authenticator.', array('firewall_key' => $this->providerKey, 'authenticator' => \get_class($guardAuthenticator)));
|
||||||
|
}
|
||||||
|
|
||||||
// allow the authenticator to fetch authentication info from the request
|
// allow the authenticator to fetch authentication info from the request
|
||||||
$credentials = $guardAuthenticator->getCredentials($request);
|
$credentials = $guardAuthenticator->getCredentials($request);
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ trait TargetPathTrait
|
|||||||
* @param SessionInterface $session
|
* @param SessionInterface $session
|
||||||
* @param string $providerKey The name of your firewall
|
* @param string $providerKey The name of your firewall
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
private function getTargetPath(SessionInterface $session, $providerKey)
|
private function getTargetPath(SessionInterface $session, $providerKey)
|
||||||
{
|
{
|
||||||
|
@ -413,25 +413,9 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
|
|||||||
unset($data[$key]);
|
unset($data[$key]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
if (null !== $constructorParameter->getClass()) {
|
|
||||||
if (!$this->serializer instanceof DenormalizerInterface) {
|
|
||||||
throw new LogicException(sprintf('Cannot create an instance of %s from serialized data because the serializer inject in "%s" is not a denormalizer', $constructorParameter->getClass(), self::class));
|
|
||||||
}
|
|
||||||
$parameterClass = $constructorParameter->getClass()->getName();
|
|
||||||
$parameterData = $this->serializer->denormalize($parameterData, $parameterClass, $format, $this->createChildContext($context, $paramName));
|
|
||||||
}
|
|
||||||
} catch (\ReflectionException $e) {
|
|
||||||
throw new RuntimeException(sprintf('Could not determine the class of the parameter "%s".', $key), 0, $e);
|
|
||||||
} catch (MissingConstructorArgumentsException $e) {
|
|
||||||
if (!$constructorParameter->getType()->allowsNull()) {
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
$parameterData = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't run set for a parameter passed to the constructor
|
// Don't run set for a parameter passed to the constructor
|
||||||
$params[] = $parameterData;
|
$params[] = $this->denormalizeParameter($reflectionClass, $constructorParameter, $paramName, $parameterData, $context, $format);
|
||||||
unset($data[$key]);
|
unset($data[$key]);
|
||||||
} elseif (array_key_exists($key, $context[static::DEFAULT_CONSTRUCTOR_ARGUMENTS][$class] ?? array())) {
|
} elseif (array_key_exists($key, $context[static::DEFAULT_CONSTRUCTOR_ARGUMENTS][$class] ?? array())) {
|
||||||
$params[] = $context[static::DEFAULT_CONSTRUCTOR_ARGUMENTS][$class][$key];
|
$params[] = $context[static::DEFAULT_CONSTRUCTOR_ARGUMENTS][$class][$key];
|
||||||
@ -454,6 +438,31 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
|
|||||||
return new $class();
|
return new $class();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
protected function denormalizeParameter(\ReflectionClass $class, \ReflectionParameter $parameter, $parameterName, $parameterData, array $context, $format = null)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (null !== $parameter->getClass()) {
|
||||||
|
if (!$this->serializer instanceof DenormalizerInterface) {
|
||||||
|
throw new LogicException(sprintf('Cannot create an instance of %s from serialized data because the serializer inject in "%s" is not a denormalizer', $parameter->getClass(), self::class));
|
||||||
|
}
|
||||||
|
$parameterClass = $parameter->getClass()->getName();
|
||||||
|
$parameterData = $this->serializer->denormalize($parameterData, $parameterClass, $format, $this->createChildContext($context, $parameterName));
|
||||||
|
}
|
||||||
|
} catch (\ReflectionException $e) {
|
||||||
|
throw new RuntimeException(sprintf('Could not determine the class of the parameter "%s".', $parameterName), 0, $e);
|
||||||
|
} catch (MissingConstructorArgumentsException $e) {
|
||||||
|
if (!$parameter->getType()->allowsNull()) {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
$parameterData = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $parameterData;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $parentContext
|
* @param array $parentContext
|
||||||
* @param string $attribute
|
* @param string $attribute
|
||||||
|
@ -94,7 +94,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
$data = array();
|
$data = array();
|
||||||
$stack = array();
|
$stack = array();
|
||||||
$attributes = $this->getAttributes($object, $format, $context);
|
$attributes = $this->getAttributes($object, $format, $context);
|
||||||
$class = $this->objectClassResolver ? \call_user_func($this->objectClassResolver, $object) : \get_class($object);
|
$class = $this->objectClassResolver ? ($this->objectClassResolver)($object) : \get_class($object);
|
||||||
$attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null;
|
$attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null;
|
||||||
$maxDepthHandler = $context[self::MAX_DEPTH_HANDLER] ?? $this->defaultContext[self::MAX_DEPTH_HANDLER] ?? $this->maxDepthHandler;
|
$maxDepthHandler = $context[self::MAX_DEPTH_HANDLER] ?? $this->defaultContext[self::MAX_DEPTH_HANDLER] ?? $this->maxDepthHandler;
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
|
|
||||||
$attributeValue = $this->getAttributeValue($object, $attribute, $format, $context);
|
$attributeValue = $this->getAttributeValue($object, $attribute, $format, $context);
|
||||||
if ($maxDepthReached) {
|
if ($maxDepthReached) {
|
||||||
$attributeValue = \call_user_func($maxDepthHandler, $attributeValue, $object, $attribute, $format, $context);
|
$attributeValue = $maxDepthHandler($attributeValue, $object, $attribute, $format, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,7 +168,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
*/
|
*/
|
||||||
protected function getAttributes($object, $format = null, array $context)
|
protected function getAttributes($object, $format = null, array $context)
|
||||||
{
|
{
|
||||||
$class = $this->objectClassResolver ? \call_user_func($this->objectClassResolver, $object) : \get_class($object);
|
$class = $this->objectClassResolver ? ($this->objectClassResolver)($object) : \get_class($object);
|
||||||
$key = $class.'-'.$context['cache_key'];
|
$key = $class.'-'.$context['cache_key'];
|
||||||
|
|
||||||
if (isset($this->attributesCache[$key])) {
|
if (isset($this->attributesCache[$key])) {
|
||||||
@ -363,7 +363,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
return (float) $data;
|
return (float) $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (\call_user_func('is_'.$builtinType, $data)) {
|
if (('is_'.$builtinType)($data)) {
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -375,6 +375,18 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
throw new NotNormalizableValueException(sprintf('The type of the "%s" attribute for class "%s" must be one of "%s" ("%s" given).', $attribute, $currentClass, implode('", "', array_keys($expectedTypes)), \gettype($data)));
|
throw new NotNormalizableValueException(sprintf('The type of the "%s" attribute for class "%s" must be one of "%s" ("%s" given).', $attribute, $currentClass, implode('", "', array_keys($expectedTypes)), \gettype($data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
protected function denormalizeParameter(\ReflectionClass $class, \ReflectionParameter $parameter, $parameterName, $parameterData, array $context, $format = null)
|
||||||
|
{
|
||||||
|
if (null === $this->propertyTypeExtractor || null === $types = $this->propertyTypeExtractor->getTypes($class->getName(), $parameterName)) {
|
||||||
|
return parent::denormalizeParameter($class, $parameter, $parameterName, $parameterData, $context, $format);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->validateAndDenormalize($class->getName(), $parameterName, $parameterData, $format, $context);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Type[]|null
|
* @return Type[]|null
|
||||||
*/
|
*/
|
||||||
|
@ -53,7 +53,7 @@ class ArrayDenormalizer implements ContextAwareDenormalizerInterface, Serializer
|
|||||||
|
|
||||||
$builtinType = isset($context['key_type']) ? $context['key_type']->getBuiltinType() : null;
|
$builtinType = isset($context['key_type']) ? $context['key_type']->getBuiltinType() : null;
|
||||||
foreach ($data as $key => $value) {
|
foreach ($data as $key => $value) {
|
||||||
if (null !== $builtinType && !\call_user_func('is_'.$builtinType, $key)) {
|
if (null !== $builtinType && !('is_'.$builtinType)($key)) {
|
||||||
throw new NotNormalizableValueException(sprintf('The type of the key "%s" must be "%s" ("%s" given).', $key, $builtinType, \gettype($key)));
|
throw new NotNormalizableValueException(sprintf('The type of the key "%s" must be "%s" ("%s" given).', $key, $builtinType, \gettype($key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,128 @@
|
|||||||
|
<?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;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
|
||||||
|
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
||||||
|
use Symfony\Component\Serializer\Serializer;
|
||||||
|
|
||||||
|
class DeserializeNestedArrayOfObjectsTest extends TestCase
|
||||||
|
{
|
||||||
|
public function provider()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
//from property PhpDoc
|
||||||
|
array(Zoo::class),
|
||||||
|
//from argument constructor PhpDoc
|
||||||
|
array(ZooImmutable::class),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provider
|
||||||
|
*/
|
||||||
|
public function testPropertyPhpDoc($class)
|
||||||
|
{
|
||||||
|
//GIVEN
|
||||||
|
$json = <<<EOF
|
||||||
|
{
|
||||||
|
"animals": [
|
||||||
|
{"name": "Bug"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
EOF;
|
||||||
|
$serializer = new Serializer(array(
|
||||||
|
new ObjectNormalizer(null, null, null, new PhpDocExtractor()),
|
||||||
|
new ArrayDenormalizer(),
|
||||||
|
), array('json' => new JsonEncoder()));
|
||||||
|
//WHEN
|
||||||
|
/** @var Zoo $zoo */
|
||||||
|
$zoo = $serializer->deserialize($json, $class, 'json');
|
||||||
|
//THEN
|
||||||
|
self::assertCount(1, $zoo->getAnimals());
|
||||||
|
self::assertInstanceOf(Animal::class, $zoo->getAnimals()[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Zoo
|
||||||
|
{
|
||||||
|
/** @var Animal[] */
|
||||||
|
private $animals = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Animal[]
|
||||||
|
*/
|
||||||
|
public function getAnimals()
|
||||||
|
{
|
||||||
|
return $this->animals;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Animal[] $animals
|
||||||
|
*/
|
||||||
|
public function setAnimals(array $animals)
|
||||||
|
{
|
||||||
|
$this->animals = $animals;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ZooImmutable
|
||||||
|
{
|
||||||
|
/** @var Animal[] */
|
||||||
|
private $animals = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Animal[] $animals
|
||||||
|
*/
|
||||||
|
public function __construct(array $animals = array())
|
||||||
|
{
|
||||||
|
$this->animals = $animals;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Animal[]
|
||||||
|
*/
|
||||||
|
public function getAnimals()
|
||||||
|
{
|
||||||
|
return $this->animals;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Animal
|
||||||
|
{
|
||||||
|
/** @var string */
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
echo '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|null $name
|
||||||
|
*/
|
||||||
|
public function setName($name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
}
|
@ -313,13 +313,13 @@ class PhpEngine implements EngineInterface, \ArrayAccess
|
|||||||
// the performance when the same value is escaped multiple times (e.g. loops)
|
// the performance when the same value is escaped multiple times (e.g. loops)
|
||||||
if (is_scalar($value)) {
|
if (is_scalar($value)) {
|
||||||
if (!isset(self::$escaperCache[$context][$value])) {
|
if (!isset(self::$escaperCache[$context][$value])) {
|
||||||
self::$escaperCache[$context][$value] = \call_user_func($this->getEscaper($context), $value);
|
self::$escaperCache[$context][$value] = $this->getEscaper($context)($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$escaperCache[$context][$value];
|
return self::$escaperCache[$context][$value];
|
||||||
}
|
}
|
||||||
|
|
||||||
return \call_user_func($this->getEscaper($context), $value);
|
return $this->getEscaper($context)($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -242,7 +242,7 @@ EOF
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (null !== $this->directoryIteratorProvider) {
|
if (null !== $this->directoryIteratorProvider) {
|
||||||
return \call_user_func($this->directoryIteratorProvider, $directory, $default);
|
return ($this->directoryIteratorProvider)($directory, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $default($directory);
|
return $default($directory);
|
||||||
@ -255,7 +255,7 @@ EOF
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (null !== $this->isReadableProvider) {
|
if (null !== $this->isReadableProvider) {
|
||||||
return \call_user_func($this->isReadableProvider, $fileOrDirectory, $default);
|
return ($this->isReadableProvider)($fileOrDirectory, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $default($fileOrDirectory);
|
return $default($fileOrDirectory);
|
||||||
|
@ -46,7 +46,7 @@ class PluralizationRules
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset(self::$rules[$locale])) {
|
if (isset(self::$rules[$locale])) {
|
||||||
$return = \call_user_func(self::$rules[$locale], $number);
|
$return = self::$rules[$locale]($number);
|
||||||
|
|
||||||
if (!\is_int($return) || $return < 0) {
|
if (!\is_int($return) || $return < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -43,7 +43,7 @@ class CallbackValidator extends ConstraintValidator
|
|||||||
throw new ConstraintDefinitionException(sprintf('%s targeted by Callback constraint is not a valid callable', json_encode($method)));
|
throw new ConstraintDefinitionException(sprintf('%s targeted by Callback constraint is not a valid callable', json_encode($method)));
|
||||||
}
|
}
|
||||||
|
|
||||||
\call_user_func($method, $object, $this->context, $constraint->payload);
|
$method($object, $this->context, $constraint->payload);
|
||||||
} elseif (null !== $object) {
|
} elseif (null !== $object) {
|
||||||
if (!method_exists($object, $method)) {
|
if (!method_exists($object, $method)) {
|
||||||
throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist in class %s', $method, \get_class($object)));
|
throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist in class %s', $method, \get_class($object)));
|
||||||
|
@ -54,7 +54,7 @@ class ChoiceValidator extends ConstraintValidator
|
|||||||
) {
|
) {
|
||||||
throw new ConstraintDefinitionException('The Choice constraint expects a valid callback');
|
throw new ConstraintDefinitionException('The Choice constraint expects a valid callback');
|
||||||
}
|
}
|
||||||
$choices = \call_user_func($choices);
|
$choices = $choices();
|
||||||
} else {
|
} else {
|
||||||
$choices = $constraint->choices;
|
$choices = $constraint->choices;
|
||||||
}
|
}
|
||||||
|
@ -130,6 +130,7 @@ class IbanValidator extends ConstraintValidator
|
|||||||
'TN' => 'TN59\d{2}\d{3}\d{13}\d{2}', // Tunisia
|
'TN' => 'TN59\d{2}\d{3}\d{13}\d{2}', // Tunisia
|
||||||
'TR' => 'TR\d{2}\d{5}[\dA-Z]{1}[\dA-Z]{16}', // Turkey
|
'TR' => 'TR\d{2}\d{5}[\dA-Z]{1}[\dA-Z]{16}', // Turkey
|
||||||
'UA' => 'UA\d{2}\d{6}[\dA-Z]{19}', // Ukraine
|
'UA' => 'UA\d{2}\d{6}[\dA-Z]{19}', // Ukraine
|
||||||
|
'VA' => 'VA\d{2}\d{3}\d{15}', // Vatican City State
|
||||||
'VG' => 'VG\d{2}[A-Z]{4}\d{16}', // Virgin Islands, British
|
'VG' => 'VG\d{2}[A-Z]{4}\d{16}', // Virgin Islands, British
|
||||||
'WF' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // Wallis and Futuna Islands
|
'WF' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // Wallis and Futuna Islands
|
||||||
'XK' => 'XK\d{2}\d{4}\d{10}\d{2}', // Republic of Kosovo
|
'XK' => 'XK\d{2}\d{4}\d{10}\d{2}', // Republic of Kosovo
|
||||||
|
@ -156,6 +156,7 @@ class IbanValidatorTest extends ConstraintValidatorTestCase
|
|||||||
array('TR330006100519786457841326'), //Turkey
|
array('TR330006100519786457841326'), //Turkey
|
||||||
array('UA213223130000026007233566001'), //Ukraine
|
array('UA213223130000026007233566001'), //Ukraine
|
||||||
array('AE260211000000230064016'), //United Arab Emirates
|
array('AE260211000000230064016'), //United Arab Emirates
|
||||||
|
array('VA59001123000012345678'), //Vatican City State
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,6 +275,7 @@ class IbanValidatorTest extends ConstraintValidatorTestCase
|
|||||||
array('TR3300061005197864578413261'), //Turkey
|
array('TR3300061005197864578413261'), //Turkey
|
||||||
array('UA21AAAA1300000260072335660012'), //Ukraine
|
array('UA21AAAA1300000260072335660012'), //Ukraine
|
||||||
array('AE2602110000002300640161'), //United Arab Emirates
|
array('AE2602110000002300640161'), //United Arab Emirates
|
||||||
|
array('VA590011230000123456781'), //Vatican City State
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,6 +387,7 @@ class IbanValidatorTest extends ConstraintValidatorTestCase
|
|||||||
array('TR330006100519786457841327'), //Turkey
|
array('TR330006100519786457841327'), //Turkey
|
||||||
array('UA213223130000026007233566002'), //Ukraine
|
array('UA213223130000026007233566002'), //Ukraine
|
||||||
array('AE260211000000230064017'), //United Arab Emirates
|
array('AE260211000000230064017'), //United Arab Emirates
|
||||||
|
array('VA59001123000012345671'), //Vatican City State
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,10 @@
|
|||||||
namespace Symfony\Component\Validator\Tests\Validator;
|
namespace Symfony\Component\Validator\Tests\Validator;
|
||||||
|
|
||||||
use Symfony\Component\Translation\IdentityTranslator;
|
use Symfony\Component\Translation\IdentityTranslator;
|
||||||
|
use Symfony\Component\Validator\Constraints\All;
|
||||||
|
use Symfony\Component\Validator\Constraints\Collection;
|
||||||
|
use Symfony\Component\Validator\Constraints\Length;
|
||||||
|
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||||
use Symfony\Component\Validator\ConstraintValidatorFactory;
|
use Symfony\Component\Validator\ConstraintValidatorFactory;
|
||||||
use Symfony\Component\Validator\Context\ExecutionContextFactory;
|
use Symfony\Component\Validator\Context\ExecutionContextFactory;
|
||||||
use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface;
|
use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface;
|
||||||
@ -95,4 +99,38 @@ class RecursiveValidatorTest extends AbstractTest
|
|||||||
|
|
||||||
$validator->validate($entity, null, array());
|
$validator->validate($entity, null, array());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCollectionConstraintValidateAllGroupsForNestedConstraints()
|
||||||
|
{
|
||||||
|
$this->metadata->addPropertyConstraint('data', new Collection(array('fields' => array(
|
||||||
|
'one' => array(new NotBlank(array('groups' => 'one')), new Length(array('min' => 2, 'groups' => 'two'))),
|
||||||
|
'two' => array(new NotBlank(array('groups' => 'two'))),
|
||||||
|
))));
|
||||||
|
|
||||||
|
$entity = new Entity();
|
||||||
|
$entity->data = array('one' => 't', 'two' => '');
|
||||||
|
|
||||||
|
$violations = $this->validator->validate($entity, null, array('one', 'two'));
|
||||||
|
|
||||||
|
$this->assertCount(2, $violations);
|
||||||
|
$this->assertInstanceOf(Length::class, $violations->get(0)->getConstraint());
|
||||||
|
$this->assertInstanceOf(NotBlank::class, $violations->get(1)->getConstraint());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAllConstraintValidateAllGroupsForNestedConstraints()
|
||||||
|
{
|
||||||
|
$this->metadata->addPropertyConstraint('data', new All(array('constraints' => array(
|
||||||
|
new NotBlank(array('groups' => 'one')),
|
||||||
|
new Length(array('min' => 2, 'groups' => 'two')),
|
||||||
|
))));
|
||||||
|
|
||||||
|
$entity = new Entity();
|
||||||
|
$entity->data = array('one' => 't', 'two' => '');
|
||||||
|
|
||||||
|
$violations = $this->validator->validate($entity, null, array('one', 'two'));
|
||||||
|
|
||||||
|
$this->assertCount(2, $violations);
|
||||||
|
$this->assertInstanceOf(NotBlank::class, $violations->get(0)->getConstraint());
|
||||||
|
$this->assertInstanceOf(Length::class, $violations->get(1)->getConstraint());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\Validator\Validator;
|
namespace Symfony\Component\Validator\Validator;
|
||||||
|
|
||||||
use Symfony\Component\Validator\Constraint;
|
use Symfony\Component\Validator\Constraint;
|
||||||
|
use Symfony\Component\Validator\Constraints\Composite;
|
||||||
use Symfony\Component\Validator\Constraints\GroupSequence;
|
use Symfony\Component\Validator\Constraints\GroupSequence;
|
||||||
use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
|
use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
|
||||||
use Symfony\Component\Validator\Context\ExecutionContext;
|
use Symfony\Component\Validator\Context\ExecutionContext;
|
||||||
@ -788,6 +789,10 @@ class RecursiveContextualValidator implements ContextualValidatorInterface
|
|||||||
if (null !== $cacheKey) {
|
if (null !== $cacheKey) {
|
||||||
$constraintHash = spl_object_hash($constraint);
|
$constraintHash = spl_object_hash($constraint);
|
||||||
|
|
||||||
|
if ($constraint instanceof Composite) {
|
||||||
|
$constraintHash .= $group;
|
||||||
|
}
|
||||||
|
|
||||||
if ($context->isConstraintValidated($cacheKey, $constraintHash)) {
|
if ($context->isConstraintValidated($cacheKey, $constraintHash)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ abstract class AbstractCloner implements ClonerInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($this->prevErrorHandler) {
|
if ($this->prevErrorHandler) {
|
||||||
return \call_user_func($this->prevErrorHandler, $type, $msg, $file, $line, $context);
|
return ($this->prevErrorHandler)($type, $msg, $file, $line, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -164,7 +164,7 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
|
|||||||
*/
|
*/
|
||||||
protected function dumpLine($depth)
|
protected function dumpLine($depth)
|
||||||
{
|
{
|
||||||
\call_user_func($this->lineDumper, $this->line, $depth, $this->indentPad);
|
($this->lineDumper)($this->line, $depth, $this->indentPad);
|
||||||
$this->line = '';
|
$this->line = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ class VarDumper
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return \call_user_func(self::$handler, $var);
|
return (self::$handler)($var);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function setHandler(callable $callable = null)
|
public static function setHandler(callable $callable = null)
|
||||||
|
@ -11,7 +11,7 @@ It can also be used with extensions defined in the [HTML5 link type extensions w
|
|||||||
Resources
|
Resources
|
||||||
---------
|
---------
|
||||||
|
|
||||||
* [Documentation](https://symfony.com/doc/current/components/weblink/introduction.html)
|
* [Documentation](https://symfony.com/doc/current/components/web_link.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)
|
||||||
|
@ -232,7 +232,7 @@ EOF
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (null !== $this->directoryIteratorProvider) {
|
if (null !== $this->directoryIteratorProvider) {
|
||||||
return \call_user_func($this->directoryIteratorProvider, $directory, $default);
|
return ($this->directoryIteratorProvider)($directory, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $default($directory);
|
return $default($directory);
|
||||||
@ -245,7 +245,7 @@ EOF
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (null !== $this->isReadableProvider) {
|
if (null !== $this->isReadableProvider) {
|
||||||
return \call_user_func($this->isReadableProvider, $fileOrDirectory, $default);
|
return ($this->isReadableProvider)($fileOrDirectory, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $default($fileOrDirectory);
|
return $default($fileOrDirectory);
|
||||||
|
@ -78,6 +78,7 @@ class Inline
|
|||||||
mb_internal_encoding('ASCII');
|
mb_internal_encoding('ASCII');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$tag = self::parseTag($value, $i, $flags);
|
$tag = self::parseTag($value, $i, $flags);
|
||||||
switch ($value[$i]) {
|
switch ($value[$i]) {
|
||||||
@ -102,11 +103,12 @@ class Inline
|
|||||||
throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
|
throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
} finally {
|
||||||
if (isset($mbEncoding)) {
|
if (isset($mbEncoding)) {
|
||||||
mb_internal_encoding($mbEncoding);
|
mb_internal_encoding($mbEncoding);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user