+ * @author Nicolas Grekas
*/
class ResolveDefinitionTemplatesPass implements CompilerPassInterface
{
- private $container;
private $compiler;
private $formatter;
+ private $currentId;
/**
* Process the ContainerBuilder to replace DefinitionDecorator instances with their real Definition instances.
@@ -35,44 +36,80 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
*/
public function process(ContainerBuilder $container)
{
- $this->container = $container;
$this->compiler = $container->getCompiler();
$this->formatter = $this->compiler->getLoggingFormatter();
- foreach ($container->getDefinitions() as $id => $definition) {
- // yes, we are specifically fetching the definition from the
- // container to ensure we are not operating on stale data
- $definition = $container->getDefinition($id);
- if (!$definition instanceof DefinitionDecorator || $definition->isAbstract()) {
- continue;
- }
+ $container->setDefinitions($this->resolveArguments($container, $container->getDefinitions(), true));
+ }
- $this->resolveDefinition($id, $definition);
+ /**
+ * Resolves definition decorator arguments.
+ *
+ * @param ContainerBuilder $container The ContainerBuilder
+ * @param array $arguments An array of arguments
+ * @param bool $isRoot If we are processing the root definitions or not
+ *
+ * @return array
+ */
+ private function resolveArguments(ContainerBuilder $container, array $arguments, $isRoot = false)
+ {
+ foreach ($arguments as $k => $argument) {
+ if ($isRoot) {
+ // yes, we are specifically fetching the definition from the
+ // container to ensure we are not operating on stale data
+ $arguments[$k] = $argument = $container->getDefinition($k);
+ $this->currentId = $k;
+ }
+ if (is_array($argument)) {
+ $arguments[$k] = $this->resolveArguments($container, $argument);
+ } elseif ($argument instanceof Definition) {
+ if ($argument instanceof DefinitionDecorator) {
+ $arguments[$k] = $argument = $this->resolveDefinition($container, $argument);
+ if ($isRoot) {
+ $container->setDefinition($k, $argument);
+ }
+ }
+ $argument->setArguments($this->resolveArguments($container, $argument->getArguments()));
+ $argument->setMethodCalls($this->resolveArguments($container, $argument->getMethodCalls()));
+ $argument->setProperties($this->resolveArguments($container, $argument->getProperties()));
+
+ $configurator = $this->resolveArguments($container, array($argument->getConfigurator()));
+ $argument->setConfigurator($configurator[0]);
+
+ $factory = $this->resolveArguments($container, array($argument->getFactory()));
+ $argument->setFactory($factory[0]);
+ }
}
+
+ return $arguments;
}
/**
* Resolves the definition.
*
- * @param string $id The definition identifier
+ * @param ContainerBuilder $container The ContainerBuilder
* @param DefinitionDecorator $definition
*
* @return Definition
*
* @throws \RuntimeException When the definition is invalid
*/
- private function resolveDefinition($id, DefinitionDecorator $definition)
+ private function resolveDefinition(ContainerBuilder $container, DefinitionDecorator $definition)
{
- if (!$this->container->hasDefinition($parent = $definition->getParent())) {
- throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $id));
+ if (!$container->hasDefinition($parent = $definition->getParent())) {
+ throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $this->currentId));
}
- $parentDef = $this->container->getDefinition($parent);
+ $parentDef = $container->getDefinition($parent);
if ($parentDef instanceof DefinitionDecorator) {
- $parentDef = $this->resolveDefinition($parent, $parentDef);
+ $id = $this->currentId;
+ $this->currentId = $parent;
+ $parentDef = $this->resolveDefinition($container, $parentDef);
+ $container->setDefinition($parent, $parentDef);
+ $this->currentId = $id;
}
- $this->compiler->addLogMessage($this->formatter->formatResolveInheritance($this, $id, $parent));
+ $this->compiler->addLogMessage($this->formatter->formatResolveInheritance($this, $this->currentId, $parent));
$def = new Definition();
// merge in parent definition
@@ -107,6 +144,14 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
if (isset($changes['lazy'])) {
$def->setLazy($definition->isLazy());
}
+ if (isset($changes['decorated_service'])) {
+ $decoratedService = $definition->getDecoratedService();
+ if (null === $decoratedService) {
+ $def->setDecoratedService($decoratedService);
+ } else {
+ $def->setDecoratedService($decoratedService[0], $decoratedService[1]);
+ }
+ }
// merge arguments
foreach ($definition->getArguments() as $k => $v) {
@@ -135,12 +180,9 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
// these attributes are always taken from the child
$def->setAbstract($definition->isAbstract());
- $def->setScope($definition->getScope());
+ $def->setScope($definition->getScope(false), false);
$def->setTags($definition->getTags());
- // set new definition on container
- $this->container->setDefinition($id, $def);
-
return $def;
}
}
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php
index c90d76f48a..3111d7f091 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php
@@ -68,7 +68,7 @@ class ResolveReferencesToAliasesPass implements CompilerPassInterface
$defId = $this->getDefinitionId($id = (string) $argument);
if ($defId !== $id) {
- $arguments[$k] = new Reference($defId, $argument->getInvalidBehavior(), $argument->isStrict());
+ $arguments[$k] = new Reference($defId, $argument->getInvalidBehavior(), $argument->isStrict(false));
}
}
}
diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php
index 34e47bc883..3818ed719b 100644
--- a/src/Symfony/Component/DependencyInjection/Container.php
+++ b/src/Symfony/Component/DependencyInjection/Container.php
@@ -180,6 +180,8 @@ class Container implements IntrospectableContainerInterface
* Setting a service to null resets the service: has() returns false and get()
* behaves in the same way as if the service was never created.
*
+ * Note: The $scope parameter is deprecated since version 2.8 and will be removed in 3.0.
+ *
* @param string $id The service identifier
* @param object $service The service instance
* @param string $scope The scope of the service
@@ -191,6 +193,10 @@ class Container implements IntrospectableContainerInterface
*/
public function set($id, $service, $scope = self::SCOPE_CONTAINER)
{
+ if (!in_array($scope, array('container', 'request')) || ('request' === $scope && 'request' !== $id)) {
+ @trigger_error('The concept of container scopes is deprecated since version 2.8 and will be removed in 3.0. Omit the third parameter.', E_USER_DEPRECATED);
+ }
+
if (self::SCOPE_PROTOTYPE === $scope) {
throw new InvalidArgumentException(sprintf('You cannot set service "%s" of scope "prototype".', $id));
}
@@ -389,9 +395,15 @@ class Container implements IntrospectableContainerInterface
* @throws InvalidArgumentException When the scope does not exist
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function enterScope($name)
{
+ if ('request' !== $name) {
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
+ }
+
if (!isset($this->scopes[$name])) {
throw new InvalidArgumentException(sprintf('The scope "%s" does not exist.', $name));
}
@@ -437,9 +449,15 @@ class Container implements IntrospectableContainerInterface
* @throws InvalidArgumentException if the scope is not active
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function leaveScope($name)
{
+ if ('request' !== $name) {
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
+ }
+
if (!isset($this->scopedServices[$name])) {
throw new InvalidArgumentException(sprintf('The scope "%s" is not active.', $name));
}
@@ -484,12 +502,17 @@ class Container implements IntrospectableContainerInterface
* @throws InvalidArgumentException
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function addScope(ScopeInterface $scope)
{
$name = $scope->getName();
$parentScope = $scope->getParentName();
+ if ('request' !== $name) {
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
+ }
if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) {
throw new InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name));
}
@@ -518,9 +541,15 @@ class Container implements IntrospectableContainerInterface
* @return bool
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function hasScope($name)
{
+ if ('request' !== $name) {
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
+ }
+
return isset($this->scopes[$name]);
}
@@ -534,9 +563,13 @@ class Container implements IntrospectableContainerInterface
* @return bool
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function isScopeActive($name)
{
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
+
return isset($this->scopedServices[$name]);
}
diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
index 70fd2cdaec..c3013a3c02 100644
--- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
@@ -358,9 +358,15 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
* @return array An array of scopes
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
- public function getScopes()
+ public function getScopes($triggerDeprecationError = true)
{
+ if ($triggerDeprecationError) {
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
+ }
+
return $this->scopes;
}
@@ -370,15 +376,23 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
* @return array An array of scope children.
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
- public function getScopeChildren()
+ public function getScopeChildren($triggerDeprecationError = true)
{
+ if ($triggerDeprecationError) {
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
+ }
+
return $this->scopeChildren;
}
/**
* Sets a service.
*
+ * Note: The $scope parameter is deprecated since version 2.8 and will be removed in 3.0.
+ *
* @param string $id The service identifier
* @param object $service The service instance
* @param string $scope The scope
@@ -1126,7 +1140,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
*/
private function shareService(Definition $definition, $service, $id)
{
- if (self::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) {
+ if ($definition->isShared() && self::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) {
if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) {
throw new InactiveScopeException($id, $scope);
}
diff --git a/src/Symfony/Component/DependencyInjection/ContainerInterface.php b/src/Symfony/Component/DependencyInjection/ContainerInterface.php
index 19e800b314..39683a6d66 100644
--- a/src/Symfony/Component/DependencyInjection/ContainerInterface.php
+++ b/src/Symfony/Component/DependencyInjection/ContainerInterface.php
@@ -34,6 +34,8 @@ interface ContainerInterface
/**
* Sets a service.
*
+ * Note: The $scope parameter is deprecated since version 2.8 and will be removed in 3.0.
+ *
* @param string $id The service identifier
* @param object $service The service instance
* @param string $scope The scope of the service
@@ -110,6 +112,8 @@ interface ContainerInterface
* @param string $name
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function enterScope($name);
@@ -119,6 +123,8 @@ interface ContainerInterface
* @param string $name
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function leaveScope($name);
@@ -128,6 +134,8 @@ interface ContainerInterface
* @param ScopeInterface $scope
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function addScope(ScopeInterface $scope);
@@ -139,6 +147,8 @@ interface ContainerInterface
* @return bool
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function hasScope($name);
@@ -152,6 +162,8 @@ interface ContainerInterface
* @return bool
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
public function isScopeActive($name);
}
diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php
index fc289e467c..18c97e06e1 100644
--- a/src/Symfony/Component/DependencyInjection/Definition.php
+++ b/src/Symfony/Component/DependencyInjection/Definition.php
@@ -26,6 +26,7 @@ class Definition
private $class;
private $file;
private $factory;
+ private $shared = true;
private $scope = ContainerInterface::SCOPE_CONTAINER;
private $properties = array();
private $calls = array();
@@ -484,6 +485,34 @@ class Definition
return $this->file;
}
+ /**
+ * Sets if the service must be shared or not.
+ *
+ * @param bool $shared Whether the service must be shared or not
+ *
+ * @return Definition The current instance
+ *
+ * @api
+ */
+ public function setShared($shared)
+ {
+ $this->shared = (bool) $shared;
+
+ return $this;
+ }
+
+ /**
+ * Whether this service is shared.
+ *
+ * @return bool
+ *
+ * @api
+ */
+ public function isShared()
+ {
+ return $this->shared;
+ }
+
/**
* Sets the scope of the service.
*
@@ -492,9 +521,19 @@ class Definition
* @return Definition The current instance
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
- public function setScope($scope)
+ public function setScope($scope, $triggerDeprecationError = true)
{
+ if ($triggerDeprecationError) {
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
+ }
+
+ if (ContainerInterface::SCOPE_PROTOTYPE === $scope) {
+ $this->setShared(false);
+ }
+
$this->scope = $scope;
return $this;
@@ -506,9 +545,15 @@ class Definition
* @return string
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
- public function getScope()
+ public function getScope($triggerDeprecationError = true)
{
+ if ($triggerDeprecationError) {
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
+ }
+
return $this->scope;
}
diff --git a/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php b/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php
index 939190d231..74ac2c3bb6 100644
--- a/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php
+++ b/src/Symfony/Component/DependencyInjection/DefinitionDecorator.php
@@ -134,6 +134,16 @@ class DefinitionDecorator extends Definition
return parent::setLazy($boolean);
}
+ /**
+ * {@inheritdoc}
+ */
+ public function setDecoratedService($id, $renamedId = null)
+ {
+ $this->changes['decorated_service'] = true;
+
+ return parent::setDecoratedService($id, $renamedId);
+ }
+
/**
* Gets an argument to pass to the service constructor/factory method.
*
diff --git a/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php
index 5f35a1e5bb..70e19af52f 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php
@@ -173,7 +173,7 @@ class GraphvizDumper extends Dumper
} catch (ParameterNotFoundException $e) {
}
- $nodes[$id] = array('class' => str_replace('\\', '\\\\', $className), 'attributes' => array_merge($this->options['node.definition'], array('style' => ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope() ? 'filled' : 'dotted')));
+ $nodes[$id] = array('class' => str_replace('\\', '\\\\', $className), 'attributes' => array_merge($this->options['node.definition'], array('style' => $definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope(false) ? 'filled' : 'dotted')));
$container->setDefinition($id, new Definition('stdClass'));
}
@@ -201,7 +201,7 @@ class GraphvizDumper extends Dumper
$container->setDefinitions($this->container->getDefinitions());
$container->setAliases($this->container->getAliases());
$container->setResources($this->container->getResources());
- foreach ($this->container->getScopes() as $scope => $parentScope) {
+ foreach ($this->container->getScopes(false) as $scope => $parentScope) {
$container->addScope(new Scope($scope, $parentScope));
}
foreach ($this->container->getExtensions() as $extension) {
diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
index af6b24d7d2..6ae16ab09b 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
@@ -377,9 +377,9 @@ class PhpDumper extends Dumper
$isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition);
$instantiation = '';
- if (!$isProxyCandidate && ContainerInterface::SCOPE_CONTAINER === $definition->getScope()) {
+ if (!$isProxyCandidate && $definition->isShared() && ContainerInterface::SCOPE_CONTAINER === $definition->getScope(false)) {
$instantiation = "\$this->services['$id'] = ".($simple ? '' : '$instance');
- } elseif (!$isProxyCandidate && ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) {
+ } elseif (!$isProxyCandidate && $definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) {
$instantiation = "\$this->services['$id'] = \$this->scopedServices['$scope']['$id'] = ".($simple ? '' : '$instance');
} elseif (!$simple) {
$instantiation = '$instance';
@@ -569,7 +569,7 @@ class PhpDumper extends Dumper
}
}
- $scope = $definition->getScope();
+ $scope = $definition->getScope(false);
if (!in_array($scope, array(ContainerInterface::SCOPE_CONTAINER, ContainerInterface::SCOPE_PROTOTYPE))) {
if ($return && 0 === strpos($return[count($return) - 1], '@return')) {
$return[] = '';
@@ -580,7 +580,7 @@ class PhpDumper extends Dumper
$return = implode("\n * ", $return);
$doc = '';
- if (ContainerInterface::SCOPE_PROTOTYPE !== $scope) {
+ if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $scope) {
$doc .= <<container->getScopes()) > 0) {
+ if (count($scopes = $this->container->getScopes(false)) > 0) {
$code .= "\n";
$code .= " \$this->scopes = ".$this->dumpValue($scopes).";\n";
- $code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren()).";\n";
+ $code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren(false)).";\n";
}
$code .= $this->addMethodMap();
@@ -879,9 +879,9 @@ EOF;
EOF;
$code .= "\n";
- if (count($scopes = $this->container->getScopes()) > 0) {
+ if (count($scopes = $this->container->getScopes(false)) > 0) {
$code .= " \$this->scopes = ".$this->dumpValue($scopes).";\n";
- $code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren()).";\n";
+ $code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren(false)).";\n";
} else {
$code .= " \$this->scopes = array();\n";
$code .= " \$this->scopeChildren = array();\n";
@@ -1273,11 +1273,6 @@ EOF;
foreach ($value->getArguments() as $argument) {
$arguments[] = $this->dumpValue($argument);
}
- $class = $this->dumpValue($value->getClass());
-
- if (false !== strpos($class, '$')) {
- throw new RuntimeException('Cannot dump definitions which have a variable class name.');
- }
if (null !== $value->getFactory()) {
$factory = $value->getFactory();
@@ -1303,7 +1298,16 @@ EOF;
throw new RuntimeException('Cannot dump definition because of invalid factory');
}
- return sprintf("new \\%s(%s)", substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments));
+ $class = $value->getClass();
+ if (null === $class) {
+ throw new RuntimeException('Cannot dump definitions which have no class nor factory.');
+ }
+ $class = $this->dumpValue($class);
+ if (false !== strpos($class, '$')) {
+ throw new RuntimeException('Cannot dump definitions which have a variable class name.');
+ }
+
+ return sprintf('new \\%s(%s)', substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments));
} elseif ($value instanceof Variable) {
return '$'.$value;
} elseif ($value instanceof Reference) {
diff --git a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
index 2911e069e3..89abcc695b 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
@@ -117,7 +117,10 @@ class XmlDumper extends Dumper
if ($definition->getClass()) {
$service->setAttribute('class', $definition->getClass());
}
- if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope()) {
+ if (!$definition->isShared()) {
+ $service->setAttribute('shared', 'false');
+ }
+ if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope(false)) {
$service->setAttribute('scope', $scope);
}
if (!$definition->isPublic()) {
@@ -271,7 +274,7 @@ class XmlDumper extends Dumper
} elseif ($behaviour == ContainerInterface::IGNORE_ON_INVALID_REFERENCE) {
$element->setAttribute('on-invalid', 'ignore');
}
- if (!$value->isStrict()) {
+ if (!$value->isStrict(false)) {
$element->setAttribute('strict', 'false');
}
} elseif ($value instanceof Definition) {
diff --git a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php
index db0b32ff75..1b414f842a 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php
@@ -112,7 +112,11 @@ class YamlDumper extends Dumper
$code .= sprintf(" calls:\n%s\n", $this->dumper->dump($this->dumpValue($definition->getMethodCalls()), 1, 12));
}
- if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope()) {
+ if (!$definition->isShared()) {
+ $code .= " shared: false\n";
+ }
+
+ if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope(false)) {
$code .= sprintf(" scope: %s\n", $scope);
}
@@ -196,7 +200,7 @@ class YamlDumper extends Dumper
}
/**
- * Dumps callable to YAML format
+ * Dumps callable to YAML format.
*
* @param callable $callable
*
diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
index 6085762610..78790be98b 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
@@ -148,11 +148,8 @@ class XmlFileLoader extends FileLoader
$definition = new Definition();
}
- foreach (array('class', 'scope', 'public', 'synthetic', 'lazy', 'abstract') as $key) {
+ foreach (array('class', 'shared', 'public', 'synthetic', 'lazy', 'abstract') as $key) {
if ($value = $service->getAttribute($key)) {
- if (in_array($key, array('factory-class', 'factory-method', 'factory-service'))) {
- @trigger_error(sprintf('The "%s" attribute in file "%s" is deprecated since version 2.6 and will be removed in 3.0. Use the "factory" element instead.', $key, $file), E_USER_DEPRECATED);
- }
$method = 'set'.str_replace('-', '', $key);
$definition->$method(XmlUtils::phpize($value));
}
diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
index d54c969131..8f800190ce 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
@@ -163,8 +163,15 @@ class YamlFileLoader extends FileLoader
$definition->setClass($service['class']);
}
+ if (isset($service['shared'])) {
+ $definition->setShared($service['shared']);
+ }
+
if (isset($service['scope'])) {
- $definition->setScope($service['scope']);
+ if ('request' !== $id) {
+ @trigger_error(sprintf('The "scope" key of service "%s" in file "%s" is deprecated since version 2.8 and will be removed in 3.0.', $id, $file), E_USER_DEPRECATED);
+ }
+ $definition->setScope($service['scope'], false);
}
if (isset($service['synthetic'])) {
diff --git a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
index 97b38af463..45e6f9ac50 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
+++ b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
@@ -87,6 +87,7 @@
+
diff --git a/src/Symfony/Component/DependencyInjection/Reference.php b/src/Symfony/Component/DependencyInjection/Reference.php
index 88084880f8..6bb117abb6 100644
--- a/src/Symfony/Component/DependencyInjection/Reference.php
+++ b/src/Symfony/Component/DependencyInjection/Reference.php
@@ -27,6 +27,8 @@ class Reference
/**
* Constructor.
*
+ * Note: The $strict parameter is deprecated since version 2.8 and will be removed in 3.0.
+ *
* @param string $id The service identifier
* @param int $invalidBehavior The behavior when the service does not exist
* @param bool $strict Sets how this reference is validated
@@ -64,9 +66,15 @@ class Reference
* Returns true when this Reference is strict.
*
* @return bool
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
- public function isStrict()
+ public function isStrict($triggerDeprecationError = true)
{
+ if ($triggerDeprecationError) {
+ @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
+ }
+
return $this->strict;
}
}
diff --git a/src/Symfony/Component/DependencyInjection/Scope.php b/src/Symfony/Component/DependencyInjection/Scope.php
index 161229e44b..c97c887584 100644
--- a/src/Symfony/Component/DependencyInjection/Scope.php
+++ b/src/Symfony/Component/DependencyInjection/Scope.php
@@ -17,6 +17,8 @@ namespace Symfony\Component\DependencyInjection;
* @author Johannes M. Schmitt
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
class Scope implements ScopeInterface
{
diff --git a/src/Symfony/Component/DependencyInjection/ScopeInterface.php b/src/Symfony/Component/DependencyInjection/ScopeInterface.php
index 81ac67cc4d..69d57685a2 100644
--- a/src/Symfony/Component/DependencyInjection/ScopeInterface.php
+++ b/src/Symfony/Component/DependencyInjection/ScopeInterface.php
@@ -17,6 +17,8 @@ namespace Symfony\Component\DependencyInjection;
* @author Johannes M. Schmitt
*
* @api
+ *
+ * @deprecated since version 2.8, to be removed in 3.0.
*/
interface ScopeInterface
{
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckDefinitionValidityPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckDefinitionValidityPassTest.php
index b5e49842e7..1dfed9c757 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckDefinitionValidityPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckDefinitionValidityPassTest.php
@@ -30,6 +30,7 @@ class CheckDefinitionValidityPassTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
+ * @group legacy
*/
public function testProcessDetectsSyntheticPrototypeDefinitions()
{
@@ -39,6 +40,18 @@ class CheckDefinitionValidityPassTest extends \PHPUnit_Framework_TestCase
$this->process($container);
}
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
+ * @group legacy
+ */
+ public function testProcessDetectsSharedPrototypeDefinitions()
+ {
+ $container = new ContainerBuilder();
+ $container->register('a')->setShared(true)->setScope(ContainerInterface::SCOPE_PROTOTYPE);
+
+ $this->process($container);
+ }
+
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
*/
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckReferenceValidityPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckReferenceValidityPassTest.php
index cd4448a96a..45cf279e37 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckReferenceValidityPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckReferenceValidityPassTest.php
@@ -19,6 +19,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
{
+ /**
+ * @group legacy
+ */
public function testProcessIgnoresScopeWideningIfNonStrictReference()
{
$container = new ContainerBuilder();
@@ -30,6 +33,7 @@ class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \RuntimeException
+ * @group legacy
*/
public function testProcessDetectsScopeWidening()
{
@@ -40,6 +44,9 @@ class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
$this->process($container);
}
+ /**
+ * @group legacy
+ */
public function testProcessIgnoresCrossScopeHierarchyReferenceIfNotStrict()
{
$container = new ContainerBuilder();
@@ -54,6 +61,7 @@ class CheckReferenceValidityPassTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \RuntimeException
+ * @group legacy
*/
public function testProcessDetectsCrossScopeHierarchyReference()
{
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php
index 590ca4cfae..0388434163 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php
@@ -41,6 +41,29 @@ class InlineServiceDefinitionsPassTest extends \PHPUnit_Framework_TestCase
$this->assertSame($container->getDefinition('inlinable.service'), $arguments[0]);
}
+ public function testProcessDoesNotInlinesWhenAliasedServiceIsShared()
+ {
+ $container = new ContainerBuilder();
+ $container
+ ->register('foo')
+ ->setPublic(false)
+ ;
+ $container->setAlias('moo', 'foo');
+
+ $container
+ ->register('service')
+ ->setArguments(array($ref = new Reference('foo')))
+ ;
+
+ $this->process($container);
+
+ $arguments = $container->getDefinition('service')->getArguments();
+ $this->assertSame($ref, $arguments[0]);
+ }
+
+ /**
+ * @group legacy
+ */
public function testProcessDoesNotInlineWhenAliasedServiceIsNotOfPrototypeScope()
{
$container = new ContainerBuilder();
@@ -61,6 +84,38 @@ class InlineServiceDefinitionsPassTest extends \PHPUnit_Framework_TestCase
$this->assertSame($ref, $arguments[0]);
}
+ public function testProcessDoesInlineNonSharedService()
+ {
+ $container = new ContainerBuilder();
+ $container
+ ->register('foo')
+ ->setShared(false)
+ ;
+ $container
+ ->register('bar')
+ ->setPublic(false)
+ ->setShared(false)
+ ;
+ $container->setAlias('moo', 'bar');
+
+ $container
+ ->register('service')
+ ->setArguments(array(new Reference('foo'), $ref = new Reference('moo'), new Reference('bar')))
+ ;
+
+ $this->process($container);
+
+ $arguments = $container->getDefinition('service')->getArguments();
+ $this->assertEquals($container->getDefinition('foo'), $arguments[0]);
+ $this->assertNotSame($container->getDefinition('foo'), $arguments[0]);
+ $this->assertSame($ref, $arguments[1]);
+ $this->assertEquals($container->getDefinition('bar'), $arguments[2]);
+ $this->assertNotSame($container->getDefinition('bar'), $arguments[2]);
+ }
+
+ /**
+ * @group legacy
+ */
public function testProcessDoesInlineServiceOfPrototypeScope()
{
$container = new ContainerBuilder();
@@ -188,6 +243,9 @@ class InlineServiceDefinitionsPassTest extends \PHPUnit_Framework_TestCase
$this->assertSame($ref, $args[0]);
}
+ /**
+ * @group legacy
+ */
public function testProcessInlinesOnlyIfSameScope()
{
$container = new ContainerBuilder();
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
index fb2bb5fca3..9f1cc87b1d 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
@@ -79,6 +79,9 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($def->isAbstract());
}
+ /**
+ * @group legacy
+ */
public function testProcessDoesNotCopyScope()
{
$container = new ContainerBuilder();
@@ -117,6 +120,25 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array(), $def->getTags());
}
+ public function testProcessDoesNotCopyDecoratedService()
+ {
+ $container = new ContainerBuilder();
+
+ $container
+ ->register('parent')
+ ->setDecoratedService('foo')
+ ;
+
+ $container
+ ->setDefinition('child', new DefinitionDecorator('parent'))
+ ;
+
+ $this->process($container);
+
+ $def = $container->getDefinition('child');
+ $this->assertNull($def->getDecoratedService());
+ }
+
public function testProcessHandlesMultipleInheritance()
{
$container = new ContainerBuilder();
@@ -173,6 +195,55 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($container->getDefinition('child1')->isLazy());
}
+ public function testDeepDefinitionsResolving()
+ {
+ $container = new ContainerBuilder();
+
+ $container->register('parent', 'parentClass');
+ $container->register('sibling', 'siblingClass')
+ ->setConfigurator(new DefinitionDecorator('parent'), 'foo')
+ ->setFactory(array(new DefinitionDecorator('parent'), 'foo'))
+ ->addArgument(new DefinitionDecorator('parent'))
+ ->setProperty('prop', new DefinitionDecorator('parent'))
+ ->addMethodCall('meth', array(new DefinitionDecorator('parent')))
+ ;
+
+ $this->process($container);
+
+ $configurator = $container->getDefinition('sibling')->getConfigurator();
+ $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($configurator));
+ $this->assertSame('parentClass', $configurator->getClass());
+
+ $factory = $container->getDefinition('sibling')->getFactory();
+ $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($factory[0]));
+ $this->assertSame('parentClass', $factory[0]->getClass());
+
+ $argument = $container->getDefinition('sibling')->getArgument(0);
+ $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($argument));
+ $this->assertSame('parentClass', $argument->getClass());
+
+ $properties = $container->getDefinition('sibling')->getProperties();
+ $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($properties['prop']));
+ $this->assertSame('parentClass', $properties['prop']->getClass());
+
+ $methodCalls = $container->getDefinition('sibling')->getMethodCalls();
+ $this->assertSame('Symfony\Component\DependencyInjection\Definition', get_class($methodCalls[0][1][0]));
+ $this->assertSame('parentClass', $methodCalls[0][1][0]->getClass());
+ }
+
+ public function testSetDecoratedServiceOnServiceHasParent()
+ {
+ $container = new ContainerBuilder();
+
+ $container->register('parent', 'stdClass');
+
+ $container->setDefinition('child1', new DefinitionDecorator('parent'))
+ ->setDecoratedService('foo', 'foo_inner')
+ ;
+
+ $this->assertEquals(array('foo', 'foo_inner'), $container->getDefinition('child1')->getDecoratedService());
+ }
+
protected function process(ContainerBuilder $container)
{
$pass = new ResolveDefinitionTemplatesPass();
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php
index 72058868d4..498baf82fc 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInvalidReferencesPassTest.php
@@ -61,6 +61,9 @@ class ResolveInvalidReferencesPassTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array(), $def->getProperties());
}
+ /**
+ * @group legacy
+ */
public function testStrictFlagIsPreserved()
{
$container = new ContainerBuilder();
diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
index eed6dd1761..abe748924d 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
@@ -117,10 +117,21 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('Circular reference detected for service "baz", path: "baz".', $e->getMessage(), '->get() throws a LogicException if the service has a circular reference to itself');
}
- $builder->register('foobar', 'stdClass')->setScope('container');
$this->assertTrue($builder->get('bar') === $builder->get('bar'), '->get() always returns the same instance if the service is shared');
}
+ /**
+ * @covers Symfony\Component\DependencyInjection\ContainerBuilder::get
+ * @covers Symfony\Component\DependencyInjection\ContainerBuilder::setShared
+ */
+ public function testNonSharedServicesReturnsDifferentInstances()
+ {
+ $builder = new ContainerBuilder();
+ $builder->register('bar', 'stdClass')->setShared(false);
+
+ $this->assertNotSame($builder->get('bar'), $builder->get('bar'));
+ }
+
/**
* @covers \Symfony\Component\DependencyInjection\ContainerBuilder::get
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
@@ -143,6 +154,7 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
/**
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::get
+ * @group legacy
*/
public function testGetReturnsNullOnInactiveScope()
{
@@ -154,6 +166,7 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
/**
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::get
+ * @group legacy
*/
public function testGetReturnsNullOnInactiveScopeWhenServiceIsCreatedByAMethod()
{
diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php
index d970e5f56f..999dd5a0c1 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerTest.php
@@ -171,6 +171,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \InvalidArgumentException
+ * @group legacy
*/
public function testSetDoesNotAllowPrototypeScope()
{
@@ -180,6 +181,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \RuntimeException
+ * @group legacy
*/
public function testSetDoesNotAllowInactiveScope()
{
@@ -188,6 +190,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
$c->set('foo', new \stdClass(), 'foo');
}
+ /**
+ * @group legacy
+ */
public function testSetAlsoSetsScopedService()
{
$c = new Container();
@@ -264,6 +269,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
/**
* @covers Symfony\Component\DependencyInjection\Container::get
+ * @group legacy
*/
public function testGetReturnsNullOnInactiveScope()
{
@@ -302,6 +308,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($sc->initialized('alias'), '->initialized() returns true for alias if aliased service is initialized');
}
+ /**
+ * @group legacy
+ */
public function testEnterLeaveCurrentScope()
{
$container = new ProjectServiceContainer();
@@ -327,6 +336,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
$this->assertSame($scopedFoo1, $scopedFoo3);
}
+ /**
+ * @group legacy
+ */
public function testEnterLeaveScopeWithChildScopes()
{
$container = new Container();
@@ -357,6 +369,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($container->has('a'));
}
+ /**
+ * @group legacy
+ */
public function testEnterScopeRecursivelyWithInactiveChildScopes()
{
$container = new Container();
@@ -398,6 +413,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($container->has('a'));
}
+ /**
+ * @group legacy
+ */
public function testEnterChildScopeRecursively()
{
$container = new Container();
@@ -435,6 +453,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \InvalidArgumentException
+ * @group legacy
*/
public function testEnterScopeNotAdded()
{
@@ -444,6 +463,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \RuntimeException
+ * @group legacy
*/
public function testEnterScopeDoesNotAllowInactiveParentScope()
{
@@ -453,6 +473,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
$container->enterScope('bar');
}
+ /**
+ * @group legacy
+ */
public function testLeaveScopeNotActive()
{
$container = new Container();
@@ -477,7 +500,8 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \InvalidArgumentException
- * @dataProvider getBuiltInScopes
+ * @dataProvider getLegacyBuiltInScopes
+ * @group legacy
*/
public function testAddScopeDoesNotAllowBuiltInScopes($scope)
{
@@ -487,6 +511,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \InvalidArgumentException
+ * @group legacy
*/
public function testAddScopeDoesNotAllowExistingScope()
{
@@ -497,7 +522,8 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \InvalidArgumentException
- * @dataProvider getInvalidParentScopes
+ * @dataProvider getLegacyInvalidParentScopes
+ * @group legacy
*/
public function testAddScopeDoesNotAllowInvalidParentScope($scope)
{
@@ -505,6 +531,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
$c->addScope(new Scope('foo', $scope));
}
+ /**
+ * @group legacy
+ */
public function testAddScope()
{
$c = new Container();
@@ -520,6 +549,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
$this->assertSame(array('foo' => array('bar', 'baz'), 'bar' => array('baz'), 'baz' => array()), $this->getField($c, 'scopeChildren'));
}
+ /**
+ * @group legacy
+ */
public function testHasScope()
{
$c = new Container();
@@ -568,6 +600,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($c->initialized('throws_exception_on_service_configuration'));
}
+ /**
+ * @group legacy
+ */
public function testIsScopeActive()
{
$c = new Container();
@@ -584,7 +619,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($c->isScopeActive('foo'));
}
- public function getInvalidParentScopes()
+ public function getLegacyInvalidParentScopes()
{
return array(
array(ContainerInterface::SCOPE_PROTOTYPE),
@@ -592,7 +627,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
);
}
- public function getBuiltInScopes()
+ public function getLegacyBuiltInScopes()
{
return array(
array(ContainerInterface::SCOPE_CONTAINER),
diff --git a/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php b/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php
index 625d56d97c..90a6f1580e 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\DependencyInjection\Tests;
use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\ContainerInterface;
class DefinitionTest extends \PHPUnit_Framework_TestCase
{
@@ -127,9 +128,34 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('foo', $def->getFile(), '->getFile() returns the file to include');
}
+ /**
+ * @covers Symfony\Component\DependencyInjection\Definition::setShared
+ * @covers Symfony\Component\DependencyInjection\Definition::isShared
+ */
+ public function testSetIsShared()
+ {
+ $def = new Definition('stdClass');
+ $this->assertTrue($def->isShared(), '->isShared() returns true by default');
+ $this->assertSame($def, $def->setShared(false), '->setShared() implements a fluent interface');
+ $this->assertFalse($def->isShared(), '->isShared() returns false if the instance must not be shared');
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testPrototypeScopedDefinitionAreNotShared()
+ {
+ $def = new Definition('stdClass');
+ $def->setScope(ContainerInterface::SCOPE_PROTOTYPE);
+
+ $this->assertFalse($def->isShared());
+ $this->assertEquals(ContainerInterface::SCOPE_PROTOTYPE, $def->getScope());
+ }
+
/**
* @covers Symfony\Component\DependencyInjection\Definition::setScope
* @covers Symfony\Component\DependencyInjection\Definition::getScope
+ * @group legacy
*/
public function testSetGetScope()
{
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php
index 79689d78dc..8f0b998c0f 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/GraphvizDumperTest.php
@@ -71,9 +71,12 @@ class GraphvizDumperTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services17.dot')), $dumper->dump(), '->dump() dumps services');
}
+ /**
+ * @group legacy
+ */
public function testDumpWithScopes()
{
- $container = include self::$fixturesPath.'/containers/container18.php';
+ $container = include self::$fixturesPath.'/containers/legacy-container18.php';
$dumper = new GraphvizDumper($container);
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services18.dot')), $dumper->dump(), '->dump() dumps services');
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php
index e97a2dda69..d9b65a43fe 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php
@@ -28,12 +28,11 @@ $container
$container
->register('bar', 'Bar\FooClass')
->setArguments(array('foo', new Reference('foo.baz'), new Parameter('foo_bar')))
- ->setScope('container')
->setConfigurator(array(new Reference('foo.baz'), 'configure'))
;
$container
->register('foo_bar', '%foo_class%')
- ->setScope('prototype')
+ ->setShared(false)
;
$container->getParameterBag()->clear();
$container->getParameterBag()->add(array(
@@ -93,7 +92,6 @@ $container
$container
->register('new_factory', 'FactoryClass')
->setProperty('foo', 'bar')
- ->setScope('container')
->setPublic(false)
;
$container
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container18.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/legacy-container18.php
similarity index 100%
rename from src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container18.php
rename to src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/legacy-container18.php
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectWithXsdExtensionInPhar.phar b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectWithXsdExtensionInPhar.phar
index 402e17b2f2..040e136a34 100644
Binary files a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectWithXsdExtensionInPhar.phar and b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectWithXsdExtensionInPhar.phar differ
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/createphar.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/createphar.php
index cfe9425c50..5fa06a0eb5 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/createphar.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/createphar.php
@@ -44,4 +44,4 @@ $phar->addFromString('schema/project-1.0.xsd', <<
EOT
);
-$phar->setStub('');
+$phar->setStub('');
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml
index 80e3dd60b2..da746abf63 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services6.xml
@@ -6,9 +6,7 @@
-
-
-
+
%path%/foo.php
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml
index c4ddc416b4..f1e6e98efa 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml
@@ -40,7 +40,7 @@
%foo_bar%
-
+
%path%foo.php
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml
index f4c5e32c6f..87dc11f673 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services6.yml
@@ -1,9 +1,7 @@
services:
foo: { class: FooClass }
baz: { class: BazClass }
- scope.container: { class: FooClass, scope: container }
- scope.custom: { class: FooClass, scope: custom }
- scope.prototype: { class: FooClass, scope: prototype }
+ not_shared: { class: FooClass, shared: false }
file: { class: FooClass, file: %path%/foo.php }
arguments: { class: FooClass, arguments: [foo, @foo, [true, false]] }
configurator1: { class: FooClass, configurator: sc_configure }
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml
index fdab85fc7e..ddb5d3a96a 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml
@@ -27,7 +27,7 @@ services:
configurator: ['@foo.baz', configure]
foo_bar:
class: %foo_class%
- scope: prototype
+ shared: false
method_call1:
class: Bar\FooClass
file: %path%foo.php
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
index 575c82af5b..f893ab111e 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
@@ -197,11 +197,9 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
$loader->load('services6.xml');
$services = $container->getDefinitions();
$this->assertTrue(isset($services['foo']), '->load() parses elements');
+ $this->assertFalse($services['not_shared']->isShared(), '->load() parses shared flag');
$this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Definition', $services['foo'], '->load() converts element to Definition instances');
$this->assertEquals('FooClass', $services['foo']->getClass(), '->load() parses the class attribute');
- $this->assertEquals('container', $services['scope.container']->getScope());
- $this->assertEquals('custom', $services['scope.custom']->getScope());
- $this->assertEquals('prototype', $services['scope.prototype']->getScope());
$this->assertEquals('%path%/foo.php', $services['file']->getFile(), '->load() parses the file tag');
$this->assertEquals(array('foo', new Reference('foo'), array(true, false)), $services['arguments']->getArguments(), '->load() parses the argument tags');
$this->assertEquals('sc_configure', $services['configurator1']->getConfigurator(), '->load() parses the configurator tag');
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
index 518914a4c8..67d569611c 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
@@ -126,11 +126,9 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
$loader->load('services6.yml');
$services = $container->getDefinitions();
$this->assertTrue(isset($services['foo']), '->load() parses service elements');
+ $this->assertFalse($services['not_shared']->isShared(), '->load() parses the shared flag');
$this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Definition', $services['foo'], '->load() converts service element to Definition instances');
$this->assertEquals('FooClass', $services['foo']->getClass(), '->load() parses the class attribute');
- $this->assertEquals('container', $services['scope.container']->getScope());
- $this->assertEquals('custom', $services['scope.custom']->getScope());
- $this->assertEquals('prototype', $services['scope.prototype']->getScope());
$this->assertEquals('%path%/foo.php', $services['file']->getFile(), '->load() parses the file tag');
$this->assertEquals(array('foo', new Reference('foo'), array(true, false)), $services['arguments']->getArguments(), '->load() parses the argument tags');
$this->assertEquals('sc_configure', $services['configurator1']->getConfigurator(), '->load() parses the configurator tag');
diff --git a/src/Symfony/Component/EventDispatcher/Tests/ContainerAwareEventDispatcherTest.php b/src/Symfony/Component/EventDispatcher/Tests/ContainerAwareEventDispatcherTest.php
index 24a04d9862..145d228f3e 100644
--- a/src/Symfony/Component/EventDispatcher/Tests/ContainerAwareEventDispatcherTest.php
+++ b/src/Symfony/Component/EventDispatcher/Tests/ContainerAwareEventDispatcherTest.php
@@ -92,6 +92,7 @@ class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
/**
* @expectedException \InvalidArgumentException
+ * @group legacy
*/
public function testTriggerAListenerServiceOutOfScope()
{
@@ -111,6 +112,9 @@ class ContainerAwareEventDispatcherTest extends AbstractEventDispatcherTest
$dispatcher->dispatch('onEvent');
}
+ /**
+ * @group legacy
+ */
public function testReEnteringAScope()
{
$event = new Event();
diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php
index 1c79f19dcb..feda6b7a9f 100644
--- a/src/Symfony/Component/Filesystem/Filesystem.php
+++ b/src/Symfony/Component/Filesystem/Filesystem.php
@@ -244,7 +244,7 @@ class Filesystem
$this->chgrp(new \FilesystemIterator($file), $group, true);
}
if (is_link($file) && function_exists('lchgrp')) {
- if (true !== @lchgrp($file, $group)) {
+ if (true !== @lchgrp($file, $group) || (defined('HHVM_VERSION') && !posix_getgrnam($group))) {
throw new IOException(sprintf('Failed to chgrp file "%s".', $file), 0, null, $file);
}
} else {
diff --git a/src/Symfony/Component/Finder/Tests/GlobTest.php b/src/Symfony/Component/Finder/Tests/GlobTest.php
index 24cad96e05..60884a7a2e 100755
--- a/src/Symfony/Component/Finder/Tests/GlobTest.php
+++ b/src/Symfony/Component/Finder/Tests/GlobTest.php
@@ -15,11 +15,10 @@ use Symfony\Component\Finder\Glob;
class GlobTest extends \PHPUnit_Framework_TestCase
{
-
public function testGlobToRegexDelimiters()
{
- $this->assertEquals(Glob::toRegex('.*'), '#^\.[^/]*$#');
- $this->assertEquals(Glob::toRegex('.*', true, true, ''), '^\.[^/]*$');
- $this->assertEquals(Glob::toRegex('.*', true, true, '/'), '/^\.[^/]*$/');
+ $this->assertEquals('#^\.[^/]*$#', Glob::toRegex('.*'));
+ $this->assertEquals('^\.[^/]*$', Glob::toRegex('.*', true, true, ''));
+ $this->assertEquals('/^\.[^/]*$/', Glob::toRegex('.*', true, true, '/'));
}
}
diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md
index b23805d1dc..09f3aeaf48 100644
--- a/src/Symfony/Component/Form/CHANGELOG.md
+++ b/src/Symfony/Component/Form/CHANGELOG.md
@@ -18,6 +18,7 @@ CHANGELOG
* added the html5 "range" FormType
* deprecated the "cascade_validation" option in favor of setting "constraints"
with the Valid constraint
+ * moved data trimming logic of TrimListener into StringUtil
2.7.0
-----
diff --git a/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php b/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php
index f55154b085..9996966f19 100644
--- a/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php
+++ b/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php
@@ -30,14 +30,21 @@ class ArrayChoiceList implements ChoiceListInterface
*
* @var array
*/
- protected $choices = array();
+ protected $choices;
/**
- * The values of the choices.
+ * The values indexed by the original keys.
*
- * @var string[]
+ * @var array
*/
- protected $values = array();
+ protected $structuredValues;
+
+ /**
+ * The original keys of the choices array.
+ *
+ * @var int[]|string[]
+ */
+ protected $originalKeys;
/**
* The callback for creating the value for a choice.
@@ -51,31 +58,41 @@ class ArrayChoiceList implements ChoiceListInterface
*
* The given choice array must have the same array keys as the value array.
*
- * @param array $choices The selectable choices
- * @param callable|null $value The callable for creating the value for a
- * choice. If `null` is passed, incrementing
- * integers are used as values
+ * @param array|\Traversable $choices The selectable choices
+ * @param callable|null $value The callable for creating the value
+ * for a choice. If `null` is passed,
+ * incrementing integers are used as
+ * values
*/
- public function __construct(array $choices, $value = null)
+ public function __construct($choices, $value = null)
{
if (null !== $value && !is_callable($value)) {
throw new UnexpectedTypeException($value, 'null or callable');
}
- $this->choices = $choices;
- $this->values = array();
- $this->valueCallback = $value;
-
- if (null === $value) {
- $i = 0;
- foreach ($this->choices as $key => $choice) {
- $this->values[$key] = (string) $i++;
- }
- } else {
- foreach ($choices as $key => $choice) {
- $this->values[$key] = (string) call_user_func($value, $choice);
- }
+ if ($choices instanceof \Traversable) {
+ $choices = iterator_to_array($choices);
}
+
+ if (null !== $value) {
+ // If a deterministic value generator was passed, use it later
+ $this->valueCallback = $value;
+ } else {
+ // Otherwise simply generate incrementing integers as values
+ $i = 0;
+ $value = function () use (&$i) {
+ return $i++;
+ };
+ }
+
+ // If the choices are given as recursive array (i.e. with explicit
+ // choice groups), flatten the array. The grouping information is needed
+ // in the view only.
+ $this->flatten($choices, $value, $choicesByValues, $keysByValues, $structuredValues);
+
+ $this->choices = $choicesByValues;
+ $this->originalKeys = $keysByValues;
+ $this->structuredValues = $structuredValues;
}
/**
@@ -91,7 +108,23 @@ class ArrayChoiceList implements ChoiceListInterface
*/
public function getValues()
{
- return $this->values;
+ return array_map('strval', array_keys($this->choices));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getStructuredValues()
+ {
+ return $this->structuredValues;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOriginalKeys()
+ {
+ return $this->originalKeys;
}
/**
@@ -102,17 +135,8 @@ class ArrayChoiceList implements ChoiceListInterface
$choices = array();
foreach ($values as $i => $givenValue) {
- foreach ($this->values as $j => $value) {
- if ($value !== (string) $givenValue) {
- continue;
- }
-
- $choices[$i] = $this->choices[$j];
- unset($values[$i]);
-
- if (0 === count($values)) {
- break 2;
- }
+ if (isset($this->choices[$givenValue])) {
+ $choices[$i] = $this->choices[$givenValue];
}
}
@@ -131,28 +155,56 @@ class ArrayChoiceList implements ChoiceListInterface
$givenValues = array();
foreach ($choices as $i => $givenChoice) {
- $givenValues[$i] = (string) call_user_func($this->valueCallback, $givenChoice);
+ $givenValues[$i] = call_user_func($this->valueCallback, $givenChoice);
}
- return array_intersect($givenValues, $this->values);
+ return array_intersect($givenValues, array_keys($this->choices));
}
// Otherwise compare choices by identity
foreach ($choices as $i => $givenChoice) {
- foreach ($this->choices as $j => $choice) {
- if ($choice !== $givenChoice) {
- continue;
- }
-
- $values[$i] = $this->values[$j];
- unset($choices[$i]);
-
- if (0 === count($choices)) {
- break 2;
+ foreach ($this->choices as $value => $choice) {
+ if ($choice === $givenChoice) {
+ $values[$i] = (string) $value;
+ break;
}
}
}
return $values;
}
+
+ /**
+ * Flattens an array into the given output variables.
+ *
+ * @param array $choices The array to flatten
+ * @param callable $value The callable for generating choice values
+ * @param array $choicesByValues The flattened choices indexed by the
+ * corresponding values
+ * @param array $keysByValues The original keys indexed by the
+ * corresponding values
+ *
+ * @internal Must not be used by user-land code
+ */
+ protected function flatten(array $choices, $value, &$choicesByValues, &$keysByValues, &$structuredValues)
+ {
+ if (null === $choicesByValues) {
+ $choicesByValues = array();
+ $keysByValues = array();
+ $structuredValues = array();
+ }
+
+ foreach ($choices as $key => $choice) {
+ if (is_array($choice)) {
+ $this->flatten($choice, $value, $choicesByValues, $keysByValues, $structuredValues[$key]);
+
+ continue;
+ }
+
+ $choiceValue = (string) call_user_func($value, $choice);
+ $choicesByValues[$choiceValue] = $choice;
+ $keysByValues[$choiceValue] = $key;
+ $structuredValues[$key] = $choiceValue;
+ }
+ }
}
diff --git a/src/Symfony/Component/Form/ChoiceList/ArrayKeyChoiceList.php b/src/Symfony/Component/Form/ChoiceList/ArrayKeyChoiceList.php
index 30709108e8..7c3c107d0f 100644
--- a/src/Symfony/Component/Form/ChoiceList/ArrayKeyChoiceList.php
+++ b/src/Symfony/Component/Form/ChoiceList/ArrayKeyChoiceList.php
@@ -62,6 +62,8 @@ class ArrayKeyChoiceList extends ArrayChoiceList
* @return int|string The choice as PHP array key
*
* @throws InvalidArgumentException If the choice is not scalar
+ *
+ * @internal Must not be used outside this class
*/
public static function toArrayKey($choice)
{
@@ -89,23 +91,27 @@ class ArrayKeyChoiceList extends ArrayChoiceList
* If no values are given, the choices are cast to strings and used as
* values.
*
- * @param array $choices The selectable choices
- * @param callable $value The callable for creating the value for a
- * choice. If `null` is passed, the choices are
- * cast to strings and used as values
+ * @param array|\Traversable $choices The selectable choices
+ * @param callable $value The callable for creating the value
+ * for a choice. If `null` is passed, the
+ * choices are cast to strings and used
+ * as values
*
* @throws InvalidArgumentException If the keys of the choices don't match
* the keys of the values or if any of the
* choices is not scalar
*/
- public function __construct(array $choices, $value = null)
+ public function __construct($choices, $value = null)
{
- $choices = array_map(array(__CLASS__, 'toArrayKey'), $choices);
-
+ // If no values are given, use the choices as values
+ // Since the choices are stored in the collection keys, i.e. they are
+ // strings or integers, we are guaranteed to be able to convert them
+ // to strings
if (null === $value) {
$value = function ($choice) {
return (string) $choice;
};
+
$this->useChoicesAsValues = true;
}
@@ -122,7 +128,7 @@ class ArrayKeyChoiceList extends ArrayChoiceList
// If the values are identical to the choices, so we can just return
// them to improve performance a little bit
- return array_map(array(__CLASS__, 'toArrayKey'), array_intersect($values, $this->values));
+ return array_map(array(__CLASS__, 'toArrayKey'), array_intersect($values, array_keys($this->choices)));
}
return parent::getChoicesForValues($values);
@@ -143,4 +149,38 @@ class ArrayKeyChoiceList extends ArrayChoiceList
return parent::getValuesForChoices($choices);
}
+
+ /**
+ * Flattens and flips an array into the given output variable.
+ *
+ * @param array $choices The array to flatten
+ * @param callable $value The callable for generating choice values
+ * @param array $choicesByValues The flattened choices indexed by the
+ * corresponding values
+ * @param array $keysByValues The original keys indexed by the
+ * corresponding values
+ *
+ * @internal Must not be used by user-land code
+ */
+ protected function flatten(array $choices, $value, &$choicesByValues, &$keysByValues, &$structuredValues)
+ {
+ if (null === $choicesByValues) {
+ $choicesByValues = array();
+ $keysByValues = array();
+ $structuredValues = array();
+ }
+
+ foreach ($choices as $choice => $key) {
+ if (is_array($key)) {
+ $this->flatten($key, $value, $choicesByValues, $keysByValues, $structuredValues[$choice]);
+
+ continue;
+ }
+
+ $choiceValue = (string) call_user_func($value, $choice);
+ $choicesByValues[$choiceValue] = $choice;
+ $keysByValues[$choiceValue] = $key;
+ $structuredValues[$key] = $choiceValue;
+ }
+ }
}
diff --git a/src/Symfony/Component/Form/ChoiceList/ChoiceListInterface.php b/src/Symfony/Component/Form/ChoiceList/ChoiceListInterface.php
index 62f3158646..b59e77bf79 100644
--- a/src/Symfony/Component/Form/ChoiceList/ChoiceListInterface.php
+++ b/src/Symfony/Component/Form/ChoiceList/ChoiceListInterface.php
@@ -14,16 +14,13 @@ namespace Symfony\Component\Form\ChoiceList;
/**
* A list of choices that can be selected in a choice field.
*
- * A choice list assigns string values to each of a list of choices. These
- * string values are displayed in the "value" attributes in HTML and submitted
- * back to the server.
+ * A choice list assigns unique string values to each of a list of choices.
+ * These string values are displayed in the "value" attributes in HTML and
+ * submitted back to the server.
*
* The acceptable data types for the choices depend on the implementation.
* Values must always be strings and (within the list) free of duplicates.
*
- * The choices returned by {@link getChoices()} and the values returned by
- * {@link getValues()} must have the same array indices.
- *
* @author Bernhard Schussek
*/
interface ChoiceListInterface
@@ -31,23 +28,66 @@ interface ChoiceListInterface
/**
* Returns all selectable choices.
*
- * The keys of the choices correspond to the keys of the values returned by
- * {@link getValues()}.
- *
- * @return array The selectable choices
+ * @return array The selectable choices indexed by the corresponding values
*/
public function getChoices();
/**
* Returns the values for the choices.
*
- * The keys of the values correspond to the keys of the choices returned by
- * {@link getChoices()}.
+ * The values are strings that do not contain duplicates.
*
* @return string[] The choice values
*/
public function getValues();
+ /**
+ * Returns the values in the structure originally passed to the list.
+ *
+ * Contrary to {@link getValues()}, the result is indexed by the original
+ * keys of the choices. If the original array contained nested arrays, these
+ * nested arrays are represented here as well:
+ *
+ * $form->add('field', 'choice', array(
+ * 'choices' => array(
+ * 'Decided' => array('Yes' => true, 'No' => false),
+ * 'Undecided' => array('Maybe' => null),
+ * ),
+ * ));
+ *
+ * In this example, the result of this method is:
+ *
+ * array(
+ * 'Decided' => array('Yes' => '0', 'No' => '1'),
+ * 'Undecided' => array('Maybe' => '2'),
+ * )
+ *
+ * @return string[] The choice values
+ */
+ public function getStructuredValues();
+
+ /**
+ * Returns the original keys of the choices.
+ *
+ * The original keys are the keys of the choice array that was passed in the
+ * "choice" option of the choice type. Note that this array may contain
+ * duplicates if the "choice" option contained choice groups:
+ *
+ * $form->add('field', 'choice', array(
+ * 'choices' => array(
+ * 'Decided' => array(true, false),
+ * 'Undecided' => array(null),
+ * ),
+ * ));
+ *
+ * In this example, the original key 0 appears twice, once for `true` and
+ * once for `null`.
+ *
+ * @return int[]|string[] The original choice keys indexed by the
+ * corresponding choice values
+ */
+ public function getOriginalKeys();
+
/**
* Returns the choices corresponding to the given values.
*
diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php
index f9848c2d0e..8796acfc4d 100644
--- a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php
+++ b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php
@@ -65,6 +65,30 @@ class CachingFactoryDecorator implements ChoiceListFactoryInterface
return hash('sha256', $namespace.':'.json_encode($value));
}
+ /**
+ * Flattens an array into the given output variable.
+ *
+ * @param array $array The array to flatten
+ * @param array $output The flattened output
+ *
+ * @internal Should not be used by user-land code
+ */
+ private static function flatten(array $array, &$output)
+ {
+ if (null === $output) {
+ $output = array();
+ }
+
+ foreach ($array as $key => $value) {
+ if (is_array($value)) {
+ self::flatten($value, $output);
+ continue;
+ }
+
+ $output[$key] = $value;
+ }
+ }
+
/**
* Decorates the given factory.
*
@@ -100,7 +124,7 @@ class CachingFactoryDecorator implements ChoiceListFactoryInterface
// We ignore the choice groups for caching. If two choice lists are
// requested with the same choices, but a different grouping, the same
// choice list is returned.
- DefaultChoiceListFactory::flatten($choices, $flatChoices);
+ self::flatten($choices, $flatChoices);
$hash = self::generateHash(array($flatChoices, $value), 'fromChoices');
@@ -129,7 +153,7 @@ class CachingFactoryDecorator implements ChoiceListFactoryInterface
// We ignore the choice groups for caching. If two choice lists are
// requested with the same choices, but a different grouping, the same
// choice list is returned.
- DefaultChoiceListFactory::flattenFlipped($choices, $flatChoices);
+ self::flatten($choices, $flatChoices);
$hash = self::generateHash(array($flatChoices, $value), 'fromFlippedChoices');
@@ -161,7 +185,6 @@ class CachingFactoryDecorator implements ChoiceListFactoryInterface
{
// The input is not validated on purpose. This way, the decorated
// factory may decide which input to accept and which not.
-
$hash = self::generateHash(array($list, $preferredChoices, $label, $index, $groupBy, $attr));
if (!isset($this->views[$hash])) {
diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/ChoiceListFactoryInterface.php b/src/Symfony/Component/Form/ChoiceList/Factory/ChoiceListFactoryInterface.php
index 60239423f3..7933dd91d4 100644
--- a/src/Symfony/Component/Form/ChoiceList/Factory/ChoiceListFactoryInterface.php
+++ b/src/Symfony/Component/Form/ChoiceList/Factory/ChoiceListFactoryInterface.php
@@ -69,7 +69,7 @@ interface ChoiceListFactoryInterface
* argument.
*
* @param ChoiceLoaderInterface $loader The choice loader
- * @param null|callable $value The callable generating the choice
+ * @param null|callable $value The callable generating the choice
* values
*
* @return ChoiceListInterface The choice list
@@ -98,25 +98,20 @@ interface ChoiceListFactoryInterface
* The preferred choices can also be passed as array. Each choice that is
* contained in that array will be marked as preferred.
*
- * The groups can be passed as a multi-dimensional array. In that case, a
- * group will be created for each array entry containing a nested array.
- * For all other entries, the choice for the corresponding key will be
- * inserted at that position.
- *
* The attributes can be passed as multi-dimensional array. The keys should
* match the keys of the choices. The values should be arrays of HTML
* attributes that should be added to the respective choice.
*
- * @param ChoiceListInterface $list The choice list
- * @param null|array|callable $preferredChoices The preferred choices
- * @param null|callable $label The callable generating
- * the choice labels
- * @param null|callable $index The callable generating
- * the view indices
- * @param null|array|\Traversable|callable $groupBy The callable generating
- * the group names
- * @param null|array|callable $attr The callable generating
- * the HTML attributes
+ * @param ChoiceListInterface $list The choice list
+ * @param null|array|callable $preferredChoices The preferred choices
+ * @param null|callable $label The callable generating the
+ * choice labels
+ * @param null|callable $index The callable generating the
+ * view indices
+ * @param null|callable $groupBy The callable generating the
+ * group names
+ * @param null|array|callable $attr The callable generating the
+ * HTML attributes
*
* @return ChoiceListView The choice list view
*/
diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php
index b7f37137d8..1433da2e87 100644
--- a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php
+++ b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php
@@ -15,11 +15,11 @@ use Symfony\Component\Form\ChoiceList\ArrayKeyChoiceList;
use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
use Symfony\Component\Form\ChoiceList\LazyChoiceList;
+use Symfony\Component\Form\ChoiceList\LegacyChoiceListAdapter;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView;
use Symfony\Component\Form\ChoiceList\View\ChoiceListView;
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
-use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface as LegacyChoiceListInterface;
use Symfony\Component\Form\Extension\Core\View\ChoiceView as LegacyChoiceView;
/**
@@ -29,72 +29,12 @@ use Symfony\Component\Form\Extension\Core\View\ChoiceView as LegacyChoiceView;
*/
class DefaultChoiceListFactory implements ChoiceListFactoryInterface
{
- /**
- * Flattens an array into the given output variable.
- *
- * @param array $array The array to flatten
- * @param array $output The flattened output
- *
- * @internal Should not be used by user-land code
- */
- public static function flatten(array $array, &$output)
- {
- if (null === $output) {
- $output = array();
- }
-
- foreach ($array as $key => $value) {
- if (is_array($value)) {
- self::flatten($value, $output);
- continue;
- }
-
- $output[$key] = $value;
- }
- }
-
- /**
- * Flattens and flips an array into the given output variable.
- *
- * During the flattening, the keys and values of the input array are
- * flipped.
- *
- * @param array $array The array to flatten
- * @param array $output The flattened output
- *
- * @internal Should not be used by user-land code
- */
- public static function flattenFlipped(array $array, &$output)
- {
- if (null === $output) {
- $output = array();
- }
-
- foreach ($array as $key => $value) {
- if (is_array($value)) {
- self::flattenFlipped($value, $output);
- continue;
- }
-
- $output[$value] = $key;
- }
- }
-
/**
* {@inheritdoc}
*/
public function createListFromChoices($choices, $value = null)
{
- if ($choices instanceof \Traversable) {
- $choices = iterator_to_array($choices);
- }
-
- // If the choices are given as recursive array (i.e. with explicit
- // choice groups), flatten the array. The grouping information is needed
- // in the view only.
- self::flatten($choices, $flatChoices);
-
- return new ArrayChoiceList($flatChoices, $value);
+ return new ArrayChoiceList($choices, $value);
}
/**
@@ -105,26 +45,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
*/
public function createListFromFlippedChoices($choices, $value = null)
{
- if ($choices instanceof \Traversable) {
- $choices = iterator_to_array($choices);
- }
-
- // If the choices are given as recursive array (i.e. with explicit
- // choice groups), flatten the array. The grouping information is needed
- // in the view only.
- self::flattenFlipped($choices, $flatChoices);
-
- // If no values are given, use the choices as values
- // Since the choices are stored in the collection keys, i.e. they are
- // strings or integers, we are guaranteed to be able to convert them
- // to strings
- if (null === $value) {
- $value = function ($choice) {
- return (string) $choice;
- };
- }
-
- return new ArrayKeyChoiceList($flatChoices, $value);
+ return new ArrayKeyChoiceList($choices, $value);
}
/**
@@ -141,22 +62,24 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null)
{
// Backwards compatibility
- if ($list instanceof LegacyChoiceListInterface && empty($preferredChoices)
+ if ($list instanceof LegacyChoiceListAdapter && empty($preferredChoices)
&& null === $label && null === $index && null === $groupBy && null === $attr) {
$mapToNonLegacyChoiceView = function (LegacyChoiceView $choiceView) {
return new ChoiceView($choiceView->data, $choiceView->value, $choiceView->label);
};
+ $adaptedList = $list->getAdaptedList();
+
return new ChoiceListView(
- array_map($mapToNonLegacyChoiceView, $list->getRemainingViews()),
- array_map($mapToNonLegacyChoiceView, $list->getPreferredViews())
+ array_map($mapToNonLegacyChoiceView, $adaptedList->getRemainingViews()),
+ array_map($mapToNonLegacyChoiceView, $adaptedList->getPreferredViews())
);
}
$preferredViews = array();
$otherViews = array();
$choices = $list->getChoices();
- $values = $list->getValues();
+ $keys = $list->getOriginalKeys();
if (!is_callable($preferredChoices) && !empty($preferredChoices)) {
$preferredChoices = function ($choice) use ($preferredChoices) {
@@ -169,36 +92,17 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$index = 0;
}
- // If $groupBy is not given, no grouping is done
- if (empty($groupBy)) {
- foreach ($choices as $key => $choice) {
- self::addChoiceView(
- $choice,
- $key,
- $label,
- $values,
- $index,
- $attr,
- $preferredChoices,
- $preferredViews,
- $otherViews
- );
- }
-
- return new ChoiceListView($otherViews, $preferredViews);
- }
-
// If $groupBy is a callable, choices are added to the group with the
// name returned by the callable. If the callable returns null, the
// choice is not added to any group
if (is_callable($groupBy)) {
- foreach ($choices as $key => $choice) {
+ foreach ($choices as $value => $choice) {
self::addChoiceViewGroupedBy(
$groupBy,
$choice,
- $key,
+ (string) $value,
$label,
- $values,
+ $keys,
$index,
$attr,
$preferredChoices,
@@ -207,13 +111,12 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
);
}
} else {
- // If $groupBy is passed as array, use that array as template for
- // constructing the groups
+ // Otherwise use the original structure of the choices
self::addChoiceViewsGroupedBy(
- $groupBy,
+ $list->getStructuredValues(),
$label,
$choices,
- $values,
+ $keys,
$index,
$attr,
$preferredChoices,
@@ -239,15 +142,17 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
return new ChoiceListView($otherViews, $preferredViews);
}
- private static function addChoiceView($choice, $key, $label, $values, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews)
+ private static function addChoiceView($choice, $value, $label, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews)
{
- $value = $values[$key];
+ // $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.
+ $key = $keys[$value];
$nextIndex = is_int($index) ? $index++ : call_user_func($index, $choice, $key, $value);
$view = new ChoiceView(
$choice,
$value,
- // If the labels are null, use the choice key by default
+ // If the labels are null, use the original choice key by default
null === $label ? (string) $key : (string) call_user_func($label, $choice, $key, $value),
// The attributes may be a callable or a mapping from choice indices
// to nested arrays
@@ -262,19 +167,19 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
}
}
- private static function addChoiceViewsGroupedBy($groupBy, $label, $choices, $values, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews)
+ private static function addChoiceViewsGroupedBy($groupBy, $label, $choices, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$otherViews)
{
- foreach ($groupBy as $key => $content) {
+ foreach ($groupBy as $key => $value) {
// Add the contents of groups to new ChoiceGroupView instances
- if (is_array($content)) {
+ if (is_array($value)) {
$preferredViewsForGroup = array();
$otherViewsForGroup = array();
self::addChoiceViewsGroupedBy(
- $content,
+ $value,
$label,
$choices,
- $values,
+ $keys,
$index,
$attr,
$isPreferred,
@@ -295,10 +200,10 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
// Add ungrouped items directly
self::addChoiceView(
- $choices[$key],
- $key,
+ $choices[$value],
+ $value,
$label,
- $values,
+ $keys,
$index,
$attr,
$isPreferred,
@@ -308,17 +213,17 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
}
}
- private static function addChoiceViewGroupedBy($groupBy, $choice, $key, $label, $values, &$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, $key, $values[$key]);
+ $groupLabel = call_user_func($groupBy, $choice, $keys[$value], $value);
if (null === $groupLabel) {
// If the callable returns null, don't group the choice
self::addChoiceView(
$choice,
- $key,
+ $value,
$label,
- $values,
+ $keys,
$index,
$attr,
$isPreferred,
@@ -329,6 +234,8 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
return;
}
+ $groupLabel = (string) $groupLabel;
+
// Initialize the group views if necessary. Unnnecessarily built group
// views will be cleaned up at the end of createView()
if (!isset($preferredViews[$groupLabel])) {
@@ -338,9 +245,9 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
self::addChoiceView(
$choice,
- $key,
+ $value,
$label,
- $values,
+ $keys,
$index,
$attr,
$isPreferred,
diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php
index 0f4bcaa14e..e86772fddc 100644
--- a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php
+++ b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php
@@ -54,8 +54,8 @@ class PropertyAccessDecorator implements ChoiceListFactoryInterface
/**
* Decorates the given factory.
*
- * @param ChoiceListFactoryInterface $decoratedFactory The decorated factory
- * @param null|PropertyAccessorInterface $propertyAccessor The used property accessor
+ * @param ChoiceListFactoryInterface $decoratedFactory The decorated factory
+ * @param null|PropertyAccessorInterface $propertyAccessor The used property accessor
*/
public function __construct(ChoiceListFactoryInterface $decoratedFactory, PropertyAccessorInterface $propertyAccessor = null)
{
@@ -98,8 +98,6 @@ class PropertyAccessDecorator implements ChoiceListFactoryInterface
if (is_object($choice) || is_array($choice)) {
return $accessor->getValue($choice, $value);
}
-
- return;
};
}
@@ -128,9 +126,9 @@ class PropertyAccessDecorator implements ChoiceListFactoryInterface
/**
* {@inheritdoc}
*
- * @param ChoiceLoaderInterface $loader The choice loader
- * @param null|callable|string|PropertyPath $value The callable or path for
- * generating the choice values
+ * @param ChoiceLoaderInterface $loader The choice loader
+ * @param null|callable|string|PropertyPath $value The callable or path for
+ * generating the choice values
*
* @return ChoiceListInterface The choice list
*/
diff --git a/src/Symfony/Component/Form/ChoiceList/LazyChoiceList.php b/src/Symfony/Component/Form/ChoiceList/LazyChoiceList.php
index 092e2c4644..f691d71330 100644
--- a/src/Symfony/Component/Form/ChoiceList/LazyChoiceList.php
+++ b/src/Symfony/Component/Form/ChoiceList/LazyChoiceList.php
@@ -43,13 +43,6 @@ class LazyChoiceList implements ChoiceListInterface
*/
private $value;
- /**
- * Whether to use the value callback to compare choices.
- *
- * @var bool
- */
- private $compareByValue;
-
/**
* @var ChoiceListInterface|null
*/
@@ -66,11 +59,10 @@ class LazyChoiceList implements ChoiceListInterface
* @param null|callable $value The callable generating the choice
* values
*/
- public function __construct(ChoiceLoaderInterface $loader, $value = null, $compareByValue = false)
+ public function __construct(ChoiceLoaderInterface $loader, $value = null)
{
$this->loader = $loader;
$this->value = $value;
- $this->compareByValue = $compareByValue;
}
/**
@@ -97,6 +89,30 @@ class LazyChoiceList implements ChoiceListInterface
return $this->loadedList->getValues();
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getStructuredValues()
+ {
+ if (!$this->loadedList) {
+ $this->loadedList = $this->loader->loadChoiceList($this->value);
+ }
+
+ return $this->loadedList->getStructuredValues();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOriginalKeys()
+ {
+ if (!$this->loadedList) {
+ $this->loadedList = $this->loader->loadChoiceList($this->value);
+ }
+
+ return $this->loadedList->getOriginalKeys();
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Symfony/Component/Form/ChoiceList/LegacyChoiceListAdapter.php b/src/Symfony/Component/Form/ChoiceList/LegacyChoiceListAdapter.php
new file mode 100644
index 0000000000..929ef8c290
--- /dev/null
+++ b/src/Symfony/Component/Form/ChoiceList/LegacyChoiceListAdapter.php
@@ -0,0 +1,144 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\ChoiceList;
+
+use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface as LegacyChoiceListInterface;
+
+/**
+ * Adapts a legacy choice list implementation to {@link ChoiceListInterface}.
+ *
+ * @author Bernhard Schussek
+ *
+ * @deprecated Added for backwards compatibility in Symfony 2.7, to be
+ * removed in Symfony 3.0.
+ */
+class LegacyChoiceListAdapter implements ChoiceListInterface
+{
+ /**
+ * @var LegacyChoiceListInterface
+ */
+ private $adaptedList;
+
+ /**
+ * @var array|null
+ */
+ private $choices;
+
+ /**
+ * @var array|null
+ */
+ private $values;
+
+ /**
+ * @var array|null
+ */
+ private $structuredValues;
+
+ /**
+ * Adapts a legacy choice list to {@link ChoiceListInterface}.
+ *
+ * @param LegacyChoiceListInterface $adaptedList The adapted list
+ */
+ public function __construct(LegacyChoiceListInterface $adaptedList)
+ {
+ $this->adaptedList = $adaptedList;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getChoices()
+ {
+ if (!$this->choices) {
+ $this->initialize();
+ }
+
+ return $this->choices;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getValues()
+ {
+ if (!$this->values) {
+ $this->initialize();
+ }
+
+ return $this->values;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getStructuredValues()
+ {
+ if (!$this->structuredValues) {
+ $this->initialize();
+ }
+
+ return $this->structuredValues;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOriginalKeys()
+ {
+ if (!$this->structuredValues) {
+ $this->initialize();
+ }
+
+ return array_flip($this->structuredValues);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getChoicesForValues(array $values)
+ {
+ return $this->adaptedList->getChoicesForValues($values);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getValuesForChoices(array $choices)
+ {
+ return $this->adaptedList->getValuesForChoices($choices);
+ }
+
+ /**
+ * Returns the adapted choice list.
+ *
+ * @return LegacyChoiceListInterface The adapted list
+ */
+ public function getAdaptedList()
+ {
+ return $this->adaptedList;
+ }
+
+ private function initialize()
+ {
+ $this->choices = array();
+ $this->values = array();
+ $this->structuredValues = $this->adaptedList->getValues();
+
+ $innerChoices = $this->adaptedList->getChoices();
+
+ foreach ($innerChoices as $index => $choice) {
+ $value = $this->structuredValues[$index];
+ $this->values[] = $value;
+ $this->choices[$value] = $choice;
+ }
+ }
+}
diff --git a/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceListInterface.php b/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceListInterface.php
index ac5847ed32..f7f8acdfea 100644
--- a/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceListInterface.php
+++ b/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceListInterface.php
@@ -11,9 +11,6 @@
namespace Symfony\Component\Form\Extension\Core\ChoiceList;
-use Symfony\Component\Form\ChoiceList\ChoiceListInterface as BaseChoiceListInterface;
-use Symfony\Component\Form\FormConfigBuilder;
-
/**
* Contains choices that can be selected in a form field.
*
@@ -30,10 +27,24 @@ use Symfony\Component\Form\FormConfigBuilder;
* @author Bernhard Schussek
*
* @deprecated since version 2.7, to be removed in 3.0.
- * Use {@link BaseChoiceListInterface} instead.
+ * Use {@link \Symfony\Component\Form\ChoiceList\ChoiceListInterface} instead.
*/
-interface ChoiceListInterface extends BaseChoiceListInterface
+interface ChoiceListInterface
{
+ /**
+ * Returns the list of choices.
+ *
+ * @return array The choices with their indices as keys
+ */
+ public function getChoices();
+
+ /**
+ * Returns the values for the choices.
+ *
+ * @return array The values with the corresponding choice indices as keys
+ */
+ public function getValues();
+
/**
* Returns the choice views of the preferred choices as nested array with
* the choice groups as top-level keys.
@@ -84,6 +95,37 @@ interface ChoiceListInterface extends BaseChoiceListInterface
*/
public function getRemainingViews();
+ /**
+ * Returns the choices corresponding to the given values.
+ *
+ * The choices can have any data type.
+ *
+ * The choices must be returned with the same keys and in the same order
+ * as the corresponding values in the given array.
+ *
+ * @param array $values An array of choice values. Not existing values in
+ * this array are ignored
+ *
+ * @return array An array of choices with ascending, 0-based numeric keys
+ */
+ public function getChoicesForValues(array $values);
+
+ /**
+ * Returns the values corresponding to the given choices.
+ *
+ * The values must be strings.
+ *
+ * The values must be returned with the same keys and in the same order
+ * as the corresponding choices in the given array.
+ *
+ * @param array $choices An array of choices. Not existing choices in this
+ * array are ignored
+ *
+ * @return array An array of choice values with ascending, 0-based numeric
+ * keys
+ */
+ public function getValuesForChoices(array $choices);
+
/**
* Returns the indices corresponding to the given choices.
*
diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php
index afbfc1041e..07070952f5 100644
--- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php
+++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php
@@ -179,15 +179,16 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
try {
$dateTime = new \DateTime(sprintf(
- '%s-%s-%s %s:%s:%s %s',
+ '%s-%s-%s %s:%s:%s',
empty($value['year']) ? '1970' : $value['year'],
empty($value['month']) ? '1' : $value['month'],
empty($value['day']) ? '1' : $value['day'],
empty($value['hour']) ? '0' : $value['hour'],
empty($value['minute']) ? '0' : $value['minute'],
- empty($value['second']) ? '0' : $value['second'],
- $this->outputTimezone
- ));
+ empty($value['second']) ? '0' : $value['second']
+ ),
+ new \DateTimeZone($this->outputTimezone)
+ );
if ($this->inputTimezone !== $this->outputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/TrimListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/TrimListener.php
index db291e0e5b..260e2699f5 100644
--- a/src/Symfony/Component/Form/Extension/Core/EventListener/TrimListener.php
+++ b/src/Symfony/Component/Form/Extension/Core/EventListener/TrimListener.php
@@ -14,6 +14,7 @@ namespace Symfony\Component\Form\Extension\Core\EventListener;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\Form\Util\StringUtil;
/**
* Trims string data.
@@ -30,11 +31,7 @@ class TrimListener implements EventSubscriberInterface
return;
}
- if (null !== $result = @preg_replace('/^[\pZ\p{Cc}]+|[\pZ\p{Cc}]+$/u', '', $data)) {
- $event->setData($result);
- } else {
- $event->setData(trim($data));
- }
+ $event->setData(StringUtil::trim($data));
}
/**
diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php
index d9791b4739..386f27dbc9 100644
--- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php
+++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php
@@ -13,6 +13,7 @@ namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\ChoiceList\Factory\PropertyAccessDecorator;
+use Symfony\Component\Form\ChoiceList\LegacyChoiceListAdapter;
use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView;
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
use Symfony\Component\Form\ChoiceList\Factory\DefaultChoiceListFactory;
@@ -27,6 +28,7 @@ use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
+use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface as LegacyChoiceListInterface;
use Symfony\Component\Form\Extension\Core\EventListener\MergeCollectionListener;
use Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToValueTransformer;
use Symfony\Component\Form\Extension\Core\DataTransformer\ChoicesToValuesTransformer;
@@ -259,6 +261,10 @@ class ChoiceType extends AbstractType
if ($choiceList) {
@trigger_error('The "choice_list" option is deprecated since version 2.7 and will be removed in 3.0. Use "choice_loader" instead.', E_USER_DEPRECATED);
+ if ($choiceList instanceof LegacyChoiceListInterface) {
+ return new LegacyChoiceListAdapter($choiceList);
+ }
+
return $choiceList;
}
@@ -338,7 +344,7 @@ class ChoiceType extends AbstractType
$resolver->setNormalizer('placeholder', $placeholderNormalizer);
$resolver->setNormalizer('choice_translation_domain', $choiceTranslationDomainNormalizer);
- $resolver->setAllowedTypes('choice_list', array('null', 'Symfony\Component\Form\ChoiceList\ChoiceListInterface'));
+ $resolver->setAllowedTypes('choice_list', array('null', 'Symfony\Component\Form\ChoiceList\ChoiceListInterface', 'Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface'));
$resolver->setAllowedTypes('choices', array('null', 'array', '\Traversable'));
$resolver->setAllowedTypes('choice_translation_domain', array('null', 'bool', 'string'));
$resolver->setAllowedTypes('choices_as_values', 'bool');
diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php
index d67bcf3094..9c567d76e2 100644
--- a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php
+++ b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php
@@ -146,6 +146,10 @@ class DateType extends AbstractType
// remove special characters unless the format was explicitly specified
if (!is_string($options['format'])) {
+ // remove quoted strings first
+ $pattern = preg_replace('/\'[^\']+\'/', '', $pattern);
+
+ // remove remaining special chars
$pattern = preg_replace('/[^yMd]+/', '', $pattern);
}
diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php
index e69a7b9394..1a0a57f933 100644
--- a/src/Symfony/Component/Form/Form.php
+++ b/src/Symfony/Component/Form/Form.php
@@ -931,7 +931,7 @@ class Form implements \IteratorAggregate, FormInterface
$child->setParent($this);
if (!$this->lockSetData && $this->defaultDataSet && !$this->config->getInheritData()) {
- $iterator = new InheritDataAwareIterator(new \ArrayIterator(array($child)));
+ $iterator = new InheritDataAwareIterator(new \ArrayIterator(array($child->getName() => $child)));
$iterator = new \RecursiveIteratorIterator($iterator);
$this->config->getDataMapper()->mapDataToForms($viewData, $iterator);
}
diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php
index fc42c5c8df..f2cb23d0f1 100644
--- a/src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php
+++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php
@@ -231,6 +231,29 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
);
}
+ public function testSingleChoiceWithoutTranslation()
+ {
+ $form = $this->factory->createNamed('name', 'choice', '&a', array(
+ 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'),
+ 'multiple' => false,
+ 'expanded' => false,
+ 'choice_translation_domain' => false,
+ ));
+
+ $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class')),
+'/select
+ [@name="name"]
+ [@class="my&class form-control"]
+ [not(@required)]
+ [
+ ./option[@value="&a"][@selected="selected"][.="Choice&A"]
+ /following-sibling::option[@value="&b"][not(@selected)][.="Choice&B"]
+ ]
+ [count(./option)=2]
+'
+ );
+ }
+
public function testSingleChoiceAttributes()
{
$form = $this->factory->createNamed('name', 'choice', '&a', array(
@@ -357,7 +380,7 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
[@class="my&class form-control"]
[not(@required)]
[
- ./option[@value=""][.="[trans][/trans]"]
+ ./option[@value=""][.=""]
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
/following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
]
@@ -381,7 +404,7 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
[@class="my&class form-control"]
[not(@required)]
[
- ./option[@value=""][.="[trans][/trans]"]
+ ./option[@value=""][.=""]
/following-sibling::option[@value="&a"][not(@selected)][.="[trans]Choice&A[/trans]"]
/following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
]
@@ -455,7 +478,7 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
[@class="my&class form-control"]
[@required="required"]
[
- ./option[@value=""][not(@selected)][not(@disabled)][.="[trans][/trans]"]
+ ./option[@value=""][not(@selected)][not(@disabled)][.=""]
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
/following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
]
@@ -625,6 +648,42 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
);
}
+ public function testSingleChoiceExpandedWithoutTranslation()
+ {
+ $form = $this->factory->createNamed('name', 'choice', '&a', array(
+ 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'),
+ 'multiple' => false,
+ 'expanded' => true,
+ 'choice_translation_domain' => false,
+ ));
+
+ $this->assertWidgetMatchesXpath($form->createView(), array(),
+'/div
+ [
+ ./div
+ [@class="radio"]
+ [
+ ./label
+ [.="Choice&A"]
+ [
+ ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
+ ]
+ ]
+ /following-sibling::div
+ [@class="radio"]
+ [
+ ./label
+ [.="Choice&B"]
+ [
+ ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
+ ]
+ ]
+ /following-sibling::input[@type="hidden"][@id="name__token"][@class="form-control"]
+ ]
+'
+ );
+ }
+
public function testSingleChoiceExpandedAttributes()
{
$form = $this->factory->createNamed('name', 'choice', '&a', array(
@@ -786,6 +845,52 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
);
}
+ public function testMultipleChoiceExpandedWithoutTranslation()
+ {
+ $form = $this->factory->createNamed('name', 'choice', array('&a', '&c'), array(
+ 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B', '&c' => 'Choice&C'),
+ 'multiple' => true,
+ 'expanded' => true,
+ 'required' => true,
+ 'choice_translation_domain' => false,
+ ));
+
+ $this->assertWidgetMatchesXpath($form->createView(), array(),
+'/div
+ [
+ ./div
+ [@class="checkbox"]
+ [
+ ./label
+ [.="Choice&A"]
+ [
+ ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
+ ]
+ ]
+ /following-sibling::div
+ [@class="checkbox"]
+ [
+ ./label
+ [.="Choice&B"]
+ [
+ ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)]
+ ]
+ ]
+ /following-sibling::div
+ [@class="checkbox"]
+ [
+ ./label
+ [.="Choice&C"]
+ [
+ ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
+ ]
+ ]
+ /following-sibling::input[@type="hidden"][@id="name__token"][@class="form-control"]
+ ]
+'
+ );
+ }
+
public function testMultipleChoiceExpandedAttributes()
{
$form = $this->factory->createNamed('name', 'choice', array('&a', '&c'), array(
@@ -1270,17 +1375,17 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
./select
[@id="name_month"]
[@class="form-control"]
- [./option[@value=""][not(@selected)][not(@disabled)][.="[trans][/trans]"]]
+ [./option[@value=""][not(@selected)][not(@disabled)][.=""]]
[./option[@value="1"][@selected="selected"]]
/following-sibling::select
[@id="name_day"]
[@class="form-control"]
- [./option[@value=""][not(@selected)][not(@disabled)][.="[trans][/trans]"]]
+ [./option[@value=""][not(@selected)][not(@disabled)][.=""]]
[./option[@value="1"][@selected="selected"]]
/following-sibling::select
[@id="name_year"]
[@class="form-control"]
- [./option[@value=""][not(@selected)][not(@disabled)][.="[trans][/trans]"]]
+ [./option[@value=""][not(@selected)][not(@disabled)][.=""]]
[./option[@value="1950"][@selected="selected"]]
]
[count(./select)=3]
diff --git a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
index 3de10bbb76..e9769d222f 100644
--- a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
+++ b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
@@ -139,6 +139,20 @@ abstract class AbstractLayoutTest extends \Symfony\Component\Form\Test\FormInteg
);
}
+ public function testLabelWithoutTranslation()
+ {
+ $form = $this->factory->createNamed('name', 'text', null, array(
+ 'translation_domain' => false,
+ ));
+
+ $this->assertMatchesXpath($this->renderLabel($form->createView()),
+'/label
+ [@for="name"]
+ [.="Name"]
+'
+ );
+ }
+
public function testLabelOnForm()
{
$form = $this->factory->createNamed('name', 'date');
@@ -484,6 +498,28 @@ abstract class AbstractLayoutTest extends \Symfony\Component\Form\Test\FormInteg
);
}
+ public function testSingleChoiceWithoutTranslation()
+ {
+ $form = $this->factory->createNamed('name', 'choice', '&a', array(
+ 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'),
+ 'multiple' => false,
+ 'expanded' => false,
+ 'choice_translation_domain' => false,
+ ));
+
+ $this->assertWidgetMatchesXpath($form->createView(), array(),
+'/select
+ [@name="name"]
+ [not(@required)]
+ [
+ ./option[@value="&a"][@selected="selected"][.="Choice&A"]
+ /following-sibling::option[@value="&b"][not(@selected)][.="Choice&B"]
+ ]
+ [count(./option)=2]
+'
+ );
+ }
+
public function testSingleChoiceAttributes()
{
$form = $this->factory->createNamed('name', 'choice', '&a', array(
@@ -604,7 +640,7 @@ abstract class AbstractLayoutTest extends \Symfony\Component\Form\Test\FormInteg
[@name="name"]
[not(@required)]
[
- ./option[@value=""][.="[trans][/trans]"]
+ ./option[@value=""][.=""]
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
/following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
]
@@ -627,7 +663,7 @@ abstract class AbstractLayoutTest extends \Symfony\Component\Form\Test\FormInteg
[@name="name"]
[not(@required)]
[
- ./option[@value=""][.="[trans][/trans]"]
+ ./option[@value=""][.=""]
/following-sibling::option[@value="&a"][not(@selected)][.="[trans]Choice&A[/trans]"]
/following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
]
@@ -704,7 +740,7 @@ abstract class AbstractLayoutTest extends \Symfony\Component\Form\Test\FormInteg
[@name="name"]
[@required="required"]
[
- ./option[@value=""][not(@selected)][not(@disabled)][.="[trans][/trans]"]
+ ./option[@value=""][not(@selected)][not(@disabled)][.=""]
/following-sibling::option[@value="&a"][@selected="selected"][.="[trans]Choice&A[/trans]"]
/following-sibling::option[@value="&b"][not(@selected)][.="[trans]Choice&B[/trans]"]
]
@@ -856,6 +892,29 @@ abstract class AbstractLayoutTest extends \Symfony\Component\Form\Test\FormInteg
);
}
+ public function testSingleChoiceExpandedWithoutTranslation()
+ {
+ $form = $this->factory->createNamed('name', 'choice', '&a', array(
+ 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'),
+ 'multiple' => false,
+ 'expanded' => true,
+ 'choice_translation_domain' => false,
+ ));
+
+ $this->assertWidgetMatchesXpath($form->createView(), array(),
+'/div
+ [
+ ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked]
+ /following-sibling::label[@for="name_0"][.="Choice&A"]
+ /following-sibling::input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)]
+ /following-sibling::label[@for="name_1"][.="Choice&B"]
+ /following-sibling::input[@type="hidden"][@id="name__token"]
+ ]
+ [count(./input)=3]
+'
+ );
+ }
+
public function testSingleChoiceExpandedAttributes()
{
$form = $this->factory->createNamed('name', 'choice', '&a', array(
@@ -951,6 +1010,32 @@ abstract class AbstractLayoutTest extends \Symfony\Component\Form\Test\FormInteg
);
}
+ public function testMultipleChoiceExpandedWithoutTranslation()
+ {
+ $form = $this->factory->createNamed('name', 'choice', array('&a', '&c'), array(
+ 'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B', '&c' => 'Choice&C'),
+ 'multiple' => true,
+ 'expanded' => true,
+ 'required' => true,
+ 'choice_translation_domain' => false,
+ ));
+
+ $this->assertWidgetMatchesXpath($form->createView(), array(),
+'/div
+ [
+ ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)]
+ /following-sibling::label[@for="name_0"][.="Choice&A"]
+ /following-sibling::input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)]
+ /following-sibling::label[@for="name_1"][.="Choice&B"]
+ /following-sibling::input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)]
+ /following-sibling::label[@for="name_2"][.="Choice&C"]
+ /following-sibling::input[@type="hidden"][@id="name__token"]
+ ]
+ [count(./input)=4]
+'
+ );
+ }
+
public function testMultipleChoiceExpandedAttributes()
{
$form = $this->factory->createNamed('name', 'choice', array('&a', '&c'), array(
@@ -1405,15 +1490,15 @@ abstract class AbstractLayoutTest extends \Symfony\Component\Form\Test\FormInteg
[
./select
[@id="name_month"]
- [./option[@value=""][not(@selected)][not(@disabled)][.="[trans][/trans]"]]
+ [./option[@value=""][not(@selected)][not(@disabled)][.=""]]
[./option[@value="1"][@selected="selected"]]
/following-sibling::select
[@id="name_day"]
- [./option[@value=""][not(@selected)][not(@disabled)][.="[trans][/trans]"]]
+ [./option[@value=""][not(@selected)][not(@disabled)][.=""]]
[./option[@value="1"][@selected="selected"]]
/following-sibling::select
[@id="name_year"]
- [./option[@value=""][not(@selected)][not(@disabled)][.="[trans][/trans]"]]
+ [./option[@value=""][not(@selected)][not(@disabled)][.=""]]
[./option[@value="1950"][@selected="selected"]]
]
[count(./select)=3]
diff --git a/src/Symfony/Component/Form/Tests/ChoiceList/AbstractChoiceListTest.php b/src/Symfony/Component/Form/Tests/ChoiceList/AbstractChoiceListTest.php
index 0805238f7f..ca244ebd69 100644
--- a/src/Symfony/Component/Form/Tests/ChoiceList/AbstractChoiceListTest.php
+++ b/src/Symfony/Component/Form/Tests/ChoiceList/AbstractChoiceListTest.php
@@ -31,6 +31,16 @@ abstract class AbstractChoiceListTest extends \PHPUnit_Framework_TestCase
*/
protected $values;
+ /**
+ * @var array
+ */
+ protected $structuredValues;
+
+ /**
+ * @var array
+ */
+ protected $keys;
+
/**
* @var mixed
*/
@@ -71,25 +81,52 @@ abstract class AbstractChoiceListTest extends \PHPUnit_Framework_TestCase
*/
protected $value4;
+ /**
+ * @var string
+ */
+ protected $key1;
+
+ /**
+ * @var string
+ */
+ protected $key2;
+
+ /**
+ * @var string
+ */
+ protected $key3;
+
+ /**
+ * @var string
+ */
+ protected $key4;
+
protected function setUp()
{
parent::setUp();
$this->list = $this->createChoiceList();
- $this->choices = $this->getChoices();
+ $choices = $this->getChoices();
+
$this->values = $this->getValues();
+ $this->structuredValues = array_combine(array_keys($choices), $this->values);
+ $this->choices = array_combine($this->values, $choices);
+ $this->keys = array_combine($this->values, array_keys($choices));
// allow access to the individual entries without relying on their indices
reset($this->choices);
reset($this->values);
+ reset($this->keys);
for ($i = 1; $i <= 4; ++$i) {
$this->{'choice'.$i} = current($this->choices);
$this->{'value'.$i} = current($this->values);
+ $this->{'key'.$i} = current($this->keys);
next($this->choices);
next($this->values);
+ next($this->keys);
}
}
@@ -103,6 +140,16 @@ abstract class AbstractChoiceListTest extends \PHPUnit_Framework_TestCase
$this->assertSame($this->values, $this->list->getValues());
}
+ public function testGetStructuredValues()
+ {
+ $this->assertSame($this->values, $this->list->getStructuredValues());
+ }
+
+ public function testGetOriginalKeys()
+ {
+ $this->assertSame($this->keys, $this->list->getOriginalKeys());
+ }
+
public function testGetChoicesForValues()
{
$values = array($this->value1, $this->value2);
diff --git a/src/Symfony/Component/Form/Tests/ChoiceList/ArrayChoiceListTest.php b/src/Symfony/Component/Form/Tests/ChoiceList/ArrayChoiceListTest.php
index 129a093b89..50d4df8a9b 100644
--- a/src/Symfony/Component/Form/Tests/ChoiceList/ArrayChoiceListTest.php
+++ b/src/Symfony/Component/Form/Tests/ChoiceList/ArrayChoiceListTest.php
@@ -29,8 +29,6 @@ class ArrayChoiceListTest extends AbstractChoiceListTest
protected function createChoiceList()
{
- $i = 0;
-
return new ArrayChoiceList($this->getChoices());
}
@@ -60,11 +58,31 @@ class ArrayChoiceListTest extends AbstractChoiceListTest
$choiceList = new ArrayChoiceList(array(2 => 'foo', 7 => 'bar', 10 => 'baz'), $callback);
- $this->assertSame(array(2 => ':foo', 7 => ':bar', 10 => ':baz'), $choiceList->getValues());
+ $this->assertSame(array(':foo', ':bar', ':baz'), $choiceList->getValues());
+ $this->assertSame(array(':foo' => 'foo', ':bar' => 'bar', ':baz' => 'baz'), $choiceList->getChoices());
+ $this->assertSame(array(':foo' => 2, ':bar' => 7, ':baz' => 10), $choiceList->getOriginalKeys());
$this->assertSame(array(1 => 'foo', 2 => 'baz'), $choiceList->getChoicesForValues(array(1 => ':foo', 2 => ':baz')));
$this->assertSame(array(1 => ':foo', 2 => ':baz'), $choiceList->getValuesForChoices(array(1 => 'foo', 2 => 'baz')));
}
+ public function testCreateChoiceListWithGroupedChoices()
+ {
+ $choiceList = new ArrayChoiceList(array(
+ 'Group 1' => array('A' => 'a', 'B' => 'b'),
+ 'Group 2' => array('C' => 'c', 'D' => 'd'),
+ ));
+
+ $this->assertSame(array('0', '1', '2', '3'), $choiceList->getValues());
+ $this->assertSame(array(
+ 'Group 1' => array('A' => '0', 'B' => '1'),
+ 'Group 2' => array('C' => '2', 'D' => '3'),
+ ), $choiceList->getStructuredValues());
+ $this->assertSame(array(0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd'), $choiceList->getChoices());
+ $this->assertSame(array(0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D'), $choiceList->getOriginalKeys());
+ $this->assertSame(array(1 => 'a', 2 => 'b'), $choiceList->getChoicesForValues(array(1 => '0', 2 => '1')));
+ $this->assertSame(array(1 => '0', 2 => '1'), $choiceList->getValuesForChoices(array(1 => 'a', 2 => 'b')));
+ }
+
public function testCompareChoicesByIdentityByDefault()
{
$callback = function ($choice) {
diff --git a/src/Symfony/Component/Form/Tests/ChoiceList/ArrayKeyChoiceListTest.php b/src/Symfony/Component/Form/Tests/ChoiceList/ArrayKeyChoiceListTest.php
index 5024a60db7..5cbadf6e0f 100644
--- a/src/Symfony/Component/Form/Tests/ChoiceList/ArrayKeyChoiceListTest.php
+++ b/src/Symfony/Component/Form/Tests/ChoiceList/ArrayKeyChoiceListTest.php
@@ -29,7 +29,7 @@ class ArrayKeyChoiceListTest extends AbstractChoiceListTest
protected function createChoiceList()
{
- return new ArrayKeyChoiceList($this->getChoices());
+ return new ArrayKeyChoiceList(array_flip($this->getChoices()));
}
protected function getChoices()
@@ -44,9 +44,11 @@ class ArrayKeyChoiceListTest extends AbstractChoiceListTest
public function testUseChoicesAsValuesByDefault()
{
- $list = new ArrayKeyChoiceList(array(1 => '', 3 => 0, 7 => '1', 10 => 1.23));
+ $list = new ArrayKeyChoiceList(array('' => 'Empty', 0 => 'Zero', 1 => 'One', '1.23' => 'Float'));
- $this->assertSame(array(1 => '', 3 => '0', 7 => '1', 10 => '1.23'), $list->getValues());
+ $this->assertSame(array('', '0', '1', '1.23'), $list->getValues());
+ $this->assertSame(array('' => '', 0 => 0, 1 => 1, '1.23' => '1.23'), $list->getChoices());
+ $this->assertSame(array('' => 'Empty', 0 => 'Zero', 1 => 'One', '1.23' => 'Float'), $list->getOriginalKeys());
}
public function testNoChoices()
@@ -102,33 +104,22 @@ class ArrayKeyChoiceListTest extends AbstractChoiceListTest
public function provideConvertibleChoices()
{
return array(
- array(array(0), array(0)),
- array(array(1), array(1)),
- array(array('0'), array(0)),
- array(array('1'), array(1)),
- array(array('1.23'), array('1.23')),
- array(array('foobar'), array('foobar')),
+ array(array(0 => 'Label'), array(0 => 0)),
+ array(array(1 => 'Label'), array(1 => 1)),
+ array(array('1.23' => 'Label'), array('1.23' => '1.23')),
+ array(array('foobar' => 'Label'), array('foobar' => 'foobar')),
// The default value of choice fields is NULL. It should be treated
// like the empty value for this choice list type
- array(array(null), array('')),
- array(array(1.23), array('1.23')),
+ array(array(null => 'Label'), array('' => '')),
+ array(array('1.23' => 'Label'), array('1.23' => '1.23')),
// Always cast booleans to 0 and 1, because:
// array(true => 'Yes', false => 'No') === array(1 => 'Yes', 0 => 'No')
// see ChoiceTypeTest::testSetDataSingleNonExpandedAcceptsBoolean
- array(array(true), array(1)),
- array(array(false), array(0)),
+ array(array(true => 'Label'), array(1 => 1)),
+ array(array(false => 'Label'), array(0 => 0)),
);
}
- /**
- * @dataProvider provideInvalidChoices
- * @expectedException \Symfony\Component\Form\Exception\InvalidArgumentException
- */
- public function testFailIfInvalidChoices(array $choices)
- {
- new ArrayKeyChoiceList($choices);
- }
-
/**
* @dataProvider provideInvalidChoices
* @expectedException \Symfony\Component\Form\Exception\InvalidArgumentException
@@ -155,7 +146,7 @@ class ArrayKeyChoiceListTest extends AbstractChoiceListTest
return $value;
};
- $list = new ArrayKeyChoiceList(array('choice'), $callback);
+ $list = new ArrayKeyChoiceList(array('choice' => 'Label'), $callback);
$this->assertSame(array($converted), $list->getValues());
}
@@ -169,15 +160,7 @@ class ArrayKeyChoiceListTest extends AbstractChoiceListTest
array('1', '1'),
array('1.23', '1.23'),
array('foobar', 'foobar'),
- // The default value of choice fields is NULL. It should be treated
- // like the empty value for this choice list type
- array(null, ''),
- array(1.23, '1.23'),
- // Always cast booleans to 0 and 1, because:
- // array(true => 'Yes', false => 'No') === array(1 => 'Yes', 0 => 'No')
- // see ChoiceTypeTest::testSetDataSingleNonExpandedAcceptsBoolean
- array(true, '1'),
- array(false, ''),
+ array('', ''),
);
}
@@ -187,9 +170,11 @@ class ArrayKeyChoiceListTest extends AbstractChoiceListTest
return ':'.$choice;
};
- $choiceList = new ArrayKeyChoiceList(array(2 => 'foo', 7 => 'bar', 10 => 'baz'), $callback);
+ $choiceList = new ArrayKeyChoiceList(array('foo' => 'Foo', 'bar' => 'Bar', 'baz' => 'Baz'), $callback);
- $this->assertSame(array(2 => ':foo', 7 => ':bar', 10 => ':baz'), $choiceList->getValues());
+ $this->assertSame(array(':foo', ':bar', ':baz'), $choiceList->getValues());
+ $this->assertSame(array(':foo' => 'foo', ':bar' => 'bar', ':baz' => 'baz'), $choiceList->getChoices());
+ $this->assertSame(array(':foo' => 'Foo', ':bar' => 'Bar', ':baz' => 'Baz'), $choiceList->getOriginalKeys());
$this->assertSame(array(1 => 'foo', 2 => 'baz'), $choiceList->getChoicesForValues(array(1 => ':foo', 2 => ':baz')));
$this->assertSame(array(1 => ':foo', 2 => ':baz'), $choiceList->getValuesForChoices(array(1 => 'foo', 2 => 'baz')));
}
diff --git a/src/Symfony/Component/Form/Tests/ChoiceList/Factory/CachingFactoryDecoratorTest.php b/src/Symfony/Component/Form/Tests/ChoiceList/Factory/CachingFactoryDecoratorTest.php
index 716468276a..9855c4a708 100644
--- a/src/Symfony/Component/Form/Tests/ChoiceList/Factory/CachingFactoryDecoratorTest.php
+++ b/src/Symfony/Component/Form/Tests/ChoiceList/Factory/CachingFactoryDecoratorTest.php
@@ -204,8 +204,8 @@ class CachingFactoryDecoratorTest extends \PHPUnit_Framework_TestCase
*/
public function testCreateFromFlippedChoicesSameChoices($choice1, $choice2)
{
- $choices1 = array($choice1);
- $choices2 = array($choice2);
+ $choices1 = array($choice1 => 'A');
+ $choices2 = array($choice2 => 'A');
$list = new \stdClass();
$this->decoratedFactory->expects($this->once())
@@ -222,8 +222,8 @@ class CachingFactoryDecoratorTest extends \PHPUnit_Framework_TestCase
*/
public function testCreateFromFlippedChoicesDifferentChoices($choice1, $choice2)
{
- $choices1 = array($choice1);
- $choices2 = array($choice2);
+ $choices1 = array($choice1 => 'A');
+ $choices2 = array($choice2 => 'A');
$list1 = new \stdClass();
$list2 = new \stdClass();
diff --git a/src/Symfony/Component/Form/Tests/ChoiceList/Factory/DefaultChoiceListFactoryTest.php b/src/Symfony/Component/Form/Tests/ChoiceList/Factory/DefaultChoiceListFactoryTest.php
index e5112bf38f..e8508ab06f 100644
--- a/src/Symfony/Component/Form/Tests/ChoiceList/Factory/DefaultChoiceListFactoryTest.php
+++ b/src/Symfony/Component/Form/Tests/ChoiceList/Factory/DefaultChoiceListFactoryTest.php
@@ -15,6 +15,7 @@ use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
use Symfony\Component\Form\ChoiceList\Factory\DefaultChoiceListFactory;
use Symfony\Component\Form\ChoiceList\LazyChoiceList;
+use Symfony\Component\Form\ChoiceList\LegacyChoiceListAdapter;
use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView;
use Symfony\Component\Form\ChoiceList\View\ChoiceListView;
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
@@ -77,6 +78,13 @@ class DefaultChoiceListFactoryTest extends \PHPUnit_Framework_TestCase
return $this->obj1 === $object || $this->obj2 === $object ? 'Group 1' : 'Group 2';
}
+ public function getGroupAsObject($object)
+ {
+ return $this->obj1 === $object || $this->obj2 === $object
+ ? new DefaultChoiceListFactoryTest_Castable('Group 1')
+ : new DefaultChoiceListFactoryTest_Castable('Group 2');
+ }
+
protected function setUp()
{
$this->obj1 = (object) array('label' => 'A', 'index' => 'w', 'value' => 'a', 'preferred' => false, 'group' => 'Group 1', 'attr' => array());
@@ -199,7 +207,7 @@ class DefaultChoiceListFactoryTest extends \PHPUnit_Framework_TestCase
array('a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D')
);
- $this->assertScalarListWithGeneratedValues($list);
+ $this->assertScalarListWithChoiceValues($list);
}
public function testCreateFromFlippedChoicesFlatTraversable()
@@ -208,7 +216,7 @@ class DefaultChoiceListFactoryTest extends \PHPUnit_Framework_TestCase
new \ArrayIterator(array('a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D'))
);
- $this->assertScalarListWithGeneratedValues($list);
+ $this->assertScalarListWithChoiceValues($list);
}
public function testCreateFromFlippedChoicesFlatValuesAsCallable()
@@ -247,7 +255,7 @@ class DefaultChoiceListFactoryTest extends \PHPUnit_Framework_TestCase
)
);
- $this->assertScalarListWithGeneratedValues($list);
+ $this->assertScalarListWithChoiceValues($list);
}
public function testCreateFromFlippedChoicesGroupedTraversable()
@@ -259,7 +267,7 @@ class DefaultChoiceListFactoryTest extends \PHPUnit_Framework_TestCase
))
);
- $this->assertScalarListWithGeneratedValues($list);
+ $this->assertScalarListWithChoiceValues($list);
}
public function testCreateFromFlippedChoicesGroupedValuesAsCallable()
@@ -523,33 +531,16 @@ class DefaultChoiceListFactoryTest extends \PHPUnit_Framework_TestCase
$this->assertFlatViewWithCustomIndices($view);
}
- public function testCreateViewFlatGroupByAsArray()
+ public function testCreateViewFlatGroupByOriginalStructure()
{
- $view = $this->factory->createView(
- $this->list,
- array($this->obj2, $this->obj3),
- null, // label
- null, // index
- array(
- 'Group 1' => array('A' => true, 'B' => true),
- 'Group 2' => array('C' => true, 'D' => true),
- )
- );
+ $list = new ArrayChoiceList(array(
+ 'Group 1' => array('A' => $this->obj1, 'B' => $this->obj2),
+ 'Group 2' => array('C' => $this->obj3, 'D' => $this->obj4),
+ ));
- $this->assertGroupedView($view);
- }
-
- public function testCreateViewFlatGroupByAsTraversable()
- {
$view = $this->factory->createView(
- $this->list,
- array($this->obj2, $this->obj3),
- null, // label
- null, // index
- new \ArrayIterator(array(
- 'Group 1' => array('A' => true, 'B' => true),
- 'Group 2' => array('C' => true, 'D' => true),
- ))
+ $list,
+ array($this->obj2, $this->obj3)
);
$this->assertGroupedView($view);
@@ -581,6 +572,19 @@ class DefaultChoiceListFactoryTest extends \PHPUnit_Framework_TestCase
$this->assertGroupedView($view);
}
+ public function testCreateViewFlatGroupByObjectThatCanBeCastToString()
+ {
+ $view = $this->factory->createView(
+ $this->list,
+ array($this->obj2, $this->obj3),
+ null, // label
+ null, // index
+ array($this, 'getGroupAsObject')
+ );
+
+ $this->assertGroupedView($view);
+ }
+
public function testCreateViewFlatGroupByAsClosure()
{
$obj1 = $this->obj1;
@@ -592,8 +596,7 @@ class DefaultChoiceListFactoryTest extends \PHPUnit_Framework_TestCase
null, // label
null, // index
function ($object) use ($obj1, $obj2) {
- return $obj1 === $object || $obj2 === $object ? 'Group 1'
- : 'Group 2';
+ return $obj1 === $object || $obj2 === $object ? 'Group 1' : 'Group 2';
}
);
@@ -749,78 +752,86 @@ class DefaultChoiceListFactoryTest extends \PHPUnit_Framework_TestCase
->method('getRemainingViews')
->will($this->returnValue($other));
- $view = $this->factory->createView($list);
+ $view = $this->factory->createView(new LegacyChoiceListAdapter($list));
$this->assertEquals(array(new ChoiceView('y', 'y', 'Other')), $view->choices);
$this->assertEquals(array(new ChoiceView('x', 'x', 'Preferred')), $view->preferredChoices);
}
- private function assertScalarListWithGeneratedValues(ChoiceListInterface $list)
+ private function assertScalarListWithChoiceValues(ChoiceListInterface $list)
{
+ $this->assertSame(array('a', 'b', 'c', 'd'), $list->getValues());
+
$this->assertSame(array(
- 'A' => 'a',
- 'B' => 'b',
- 'C' => 'c',
- 'D' => 'd',
+ 'a' => 'a',
+ 'b' => 'b',
+ 'c' => 'c',
+ 'd' => 'd',
), $list->getChoices());
$this->assertSame(array(
- 'A' => 'a',
- 'B' => 'b',
- 'C' => 'c',
- 'D' => 'd',
- ), $list->getValues());
+ 'a' => 'A',
+ 'b' => 'B',
+ 'c' => 'C',
+ 'd' => 'D',
+ ), $list->getOriginalKeys());
}
private function assertObjectListWithGeneratedValues(ChoiceListInterface $list)
{
+ $this->assertSame(array('0', '1', '2', '3'), $list->getValues());
+
$this->assertSame(array(
- 'A' => $this->obj1,
- 'B' => $this->obj2,
- 'C' => $this->obj3,
- 'D' => $this->obj4,
+ 0 => $this->obj1,
+ 1 => $this->obj2,
+ 2 => $this->obj3,
+ 3 => $this->obj4,
), $list->getChoices());
$this->assertSame(array(
- 'A' => '0',
- 'B' => '1',
- 'C' => '2',
- 'D' => '3',
- ), $list->getValues());
+ 0 => 'A',
+ 1 => 'B',
+ 2 => 'C',
+ 3 => 'D',
+ ), $list->getOriginalKeys());
}
private function assertScalarListWithCustomValues(ChoiceListInterface $list)
{
+ $this->assertSame(array('a', 'b', '1', '2'), $list->getValues());
+
$this->assertSame(array(
- 'A' => 'a',
- 'B' => 'b',
- 'C' => 'c',
- 'D' => 'd',
+ 'a' => 'a',
+ 'b' => 'b',
+ 1 => 'c',
+ 2 => 'd',
), $list->getChoices());
$this->assertSame(array(
- 'A' => 'a',
- 'B' => 'b',
- 'C' => '1',
- 'D' => '2',
- ), $list->getValues());
+ 'a' => 'A',
+ 'b' => 'B',
+ 1 => 'C',
+ 2 => 'D',
+ ), $list->getOriginalKeys());
}
private function assertObjectListWithCustomValues(ChoiceListInterface $list)
{
+ $this->assertSame(array('a', 'b', '1', '2'), $list->getValues());
+
$this->assertSame(array(
- 'A' => $this->obj1,
- 'B' => $this->obj2,
- 'C' => $this->obj3,
- 'D' => $this->obj4,
+ 'a' => $this->obj1,
+ 'b' => $this->obj2,
+ 1 => $this->obj3,
+ 2 => $this->obj4,
), $list->getChoices());
$this->assertSame(array(
- 'A' => 'a',
- 'B' => 'b',
- 'C' => '1',
- 'D' => '2',
- ), $list->getValues());
+ 'a' => 'A',
+ 'b' => 'B',
+ 1 => 'C',
+ 2 => 'D',
+ ), $list->getOriginalKeys());
}
private function assertFlatView($view)
@@ -897,3 +908,18 @@ class DefaultChoiceListFactoryTest extends \PHPUnit_Framework_TestCase
), $view);
}
}
+
+class DefaultChoiceListFactoryTest_Castable
+{
+ private $property;
+
+ public function __construct($property)
+ {
+ $this->property = $property;
+ }
+
+ public function __toString()
+ {
+ return $this->property;
+ }
+}
diff --git a/src/Symfony/Component/Form/Tests/ChoiceList/LazyChoiceListTest.php b/src/Symfony/Component/Form/Tests/ChoiceList/LazyChoiceListTest.php
index 2993721c82..5db96e6a7d 100644
--- a/src/Symfony/Component/Form/Tests/ChoiceList/LazyChoiceListTest.php
+++ b/src/Symfony/Component/Form/Tests/ChoiceList/LazyChoiceListTest.php
@@ -73,6 +73,36 @@ class LazyChoiceListTest extends \PHPUnit_Framework_TestCase
$this->assertSame('RESULT', $this->list->getValues());
}
+ public function testGetStructuredValuesLoadsInnerListOnFirstCall()
+ {
+ $this->loader->expects($this->once())
+ ->method('loadChoiceList')
+ ->with($this->value)
+ ->will($this->returnValue($this->innerList));
+
+ $this->innerList->expects($this->exactly(2))
+ ->method('getStructuredValues')
+ ->will($this->returnValue('RESULT'));
+
+ $this->assertSame('RESULT', $this->list->getStructuredValues());
+ $this->assertSame('RESULT', $this->list->getStructuredValues());
+ }
+
+ public function testGetOriginalKeysLoadsInnerListOnFirstCall()
+ {
+ $this->loader->expects($this->once())
+ ->method('loadChoiceList')
+ ->with($this->value)
+ ->will($this->returnValue($this->innerList));
+
+ $this->innerList->expects($this->exactly(2))
+ ->method('getOriginalKeys')
+ ->will($this->returnValue('RESULT'));
+
+ $this->assertSame('RESULT', $this->list->getOriginalKeys());
+ $this->assertSame('RESULT', $this->list->getOriginalKeys());
+ }
+
public function testGetChoicesForValuesForwardsCallIfListNotLoaded()
{
$this->loader->expects($this->exactly(2))
diff --git a/src/Symfony/Component/Form/Tests/ChoiceList/LegacyChoiceListAdapterTest.php b/src/Symfony/Component/Form/Tests/ChoiceList/LegacyChoiceListAdapterTest.php
new file mode 100644
index 0000000000..521c950331
--- /dev/null
+++ b/src/Symfony/Component/Form/Tests/ChoiceList/LegacyChoiceListAdapterTest.php
@@ -0,0 +1,110 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\Tests\ChoiceList;
+
+use Symfony\Component\Form\ChoiceList\LegacyChoiceListAdapter;
+use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface;
+
+/**
+ * @author Bernhard Schussek
+ */
+class LegacyChoiceListAdapterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var LegacyChoiceListAdapter
+ */
+ private $list;
+
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject|ChoiceListInterface
+ */
+ private $adaptedList;
+
+ protected function setUp()
+ {
+ $this->adaptedList = $this->getMock('Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface');
+ $this->list = new LegacyChoiceListAdapter($this->adaptedList);
+ }
+
+ public function testGetChoices()
+ {
+ $this->adaptedList->expects($this->once())
+ ->method('getChoices')
+ ->willReturn(array(1 => 'a', 4 => 'b', 7 => 'c'));
+ $this->adaptedList->expects($this->once())
+ ->method('getValues')
+ ->willReturn(array(1 => ':a', 4 => ':b', 7 => ':c'));
+
+ $this->assertSame(array(':a' => 'a', ':b' => 'b', ':c' => 'c'), $this->list->getChoices());
+ }
+
+ public function testGetValues()
+ {
+ $this->adaptedList->expects($this->once())
+ ->method('getChoices')
+ ->willReturn(array(1 => 'a', 4 => 'b', 7 => 'c'));
+ $this->adaptedList->expects($this->once())
+ ->method('getValues')
+ ->willReturn(array(1 => ':a', 4 => ':b', 7 => ':c'));
+
+ $this->assertSame(array(':a', ':b', ':c'), $this->list->getValues());
+ }
+
+ public function testGetStructuredValues()
+ {
+ $this->adaptedList->expects($this->once())
+ ->method('getChoices')
+ ->willReturn(array(1 => 'a', 4 => 'b', 7 => 'c'));
+ $this->adaptedList->expects($this->once())
+ ->method('getValues')
+ ->willReturn(array(1 => ':a', 4 => ':b', 7 => ':c'));
+
+ $this->assertSame(array(1 => ':a', 4 => ':b', 7 => ':c'), $this->list->getStructuredValues());
+ }
+
+ public function testGetOriginalKeys()
+ {
+ $this->adaptedList->expects($this->once())
+ ->method('getChoices')
+ ->willReturn(array(1 => 'a', 4 => 'b', 7 => 'c'));
+ $this->adaptedList->expects($this->once())
+ ->method('getValues')
+ ->willReturn(array(1 => ':a', 4 => ':b', 7 => ':c'));
+
+ $this->assertSame(array(':a' => 1, ':b' => 4, ':c' => 7), $this->list->getOriginalKeys());
+ }
+
+ public function testGetChoicesForValues()
+ {
+ $this->adaptedList->expects($this->once())
+ ->method('getChoicesForValues')
+ ->with(array(1 => ':a', 4 => ':b', 7 => ':c'))
+ ->willReturn(array(1 => 'a', 4 => 'b', 7 => 'c'));
+
+ $this->assertSame(array(1 => 'a', 4 => 'b', 7 => 'c'), $this->list->getChoicesForValues(array(1 => ':a', 4 => ':b', 7 => ':c')));
+ }
+
+ public function testGetValuesForChoices()
+ {
+ $this->adaptedList->expects($this->once())
+ ->method('getValuesForChoices')
+ ->with(array(1 => 'a', 4 => 'b', 7 => 'c'))
+ ->willReturn(array(1 => ':a', 4 => ':b', 7 => ':c'));
+
+ $this->assertSame(array(1 => ':a', 4 => ':b', 7 => ':c'), $this->list->getValuesForChoices(array(1 => 'a', 4 => 'b', 7 => 'c')));
+ }
+
+ public function testGetAdaptedList()
+ {
+ $this->assertSame($this->adaptedList, $this->list->getAdaptedList());
+ }
+}
diff --git a/src/Symfony/Component/Form/Tests/CompoundFormTest.php b/src/Symfony/Component/Form/Tests/CompoundFormTest.php
index efacc58bda..27c6b0de1c 100644
--- a/src/Symfony/Component/Form/Tests/CompoundFormTest.php
+++ b/src/Symfony/Component/Form/Tests/CompoundFormTest.php
@@ -349,7 +349,7 @@ class CompoundFormTest extends AbstractFormTest
->with('bar', $this->isInstanceOf('\RecursiveIteratorIterator'))
->will($this->returnCallback(function ($data, \RecursiveIteratorIterator $iterator) use ($child) {
$this->assertInstanceOf('Symfony\Component\Form\Util\InheritDataAwareIterator', $iterator->getInnerIterator());
- $this->assertSame(array($child), iterator_to_array($iterator));
+ $this->assertSame(array($child->getName() => $child), iterator_to_array($iterator));
}));
$form->initialize();
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeTestCase.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeTestCase.php
index f7722c496e..200cbc3282 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeTestCase.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeTestCase.php
@@ -15,6 +15,6 @@ abstract class DateTimeTestCase extends \PHPUnit_Framework_TestCase
{
public static function assertDateTimeEquals(\DateTime $expected, \DateTime $actual)
{
- self::assertEquals($expected->format('c'), $actual->format('c'));
+ self::assertEquals($expected->format('U'), $actual->format('U'));
}
}
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixRadioInputListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixRadioInputListenerTest.php
index cb0b34b41f..b936ea35cc 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixRadioInputListenerTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixRadioInputListenerTest.php
@@ -11,9 +11,9 @@
namespace Symfony\Component\Form\Tests\Extension\Core\EventListener;
+use Symfony\Component\Form\ChoiceList\ArrayKeyChoiceList;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\Extension\Core\EventListener\FixRadioInputListener;
-use Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList;
/**
* @group legacy
@@ -26,7 +26,7 @@ class FixRadioInputListenerTest extends \PHPUnit_Framework_TestCase
{
parent::setUp();
- $this->choiceList = new SimpleChoiceList(array('' => 'Empty', 0 => 'A', 1 => 'B'));
+ $this->choiceList = new ArrayKeyChoiceList(array('' => 'Empty', 0 => 'A', 1 => 'B'));
}
protected function tearDown()
@@ -45,7 +45,6 @@ class FixRadioInputListenerTest extends \PHPUnit_Framework_TestCase
$listener = new FixRadioInputListener($this->choiceList, true);
$listener->preSubmit($event);
- // Indices in SimpleChoiceList are zero-based generated integers
$this->assertEquals(array(2 => '1'), $event->getData());
}
@@ -58,7 +57,6 @@ class FixRadioInputListenerTest extends \PHPUnit_Framework_TestCase
$listener = new FixRadioInputListener($this->choiceList, true);
$listener->preSubmit($event);
- // Indices in SimpleChoiceList are zero-based generated integers
$this->assertEquals(array(1 => '0'), $event->getData());
}
@@ -71,13 +69,12 @@ class FixRadioInputListenerTest extends \PHPUnit_Framework_TestCase
$listener = new FixRadioInputListener($this->choiceList, true);
$listener->preSubmit($event);
- // Indices in SimpleChoiceList are zero-based generated integers
$this->assertEquals(array(0 => ''), $event->getData());
}
public function testConvertEmptyStringToPlaceholderIfNotFound()
{
- $list = new SimpleChoiceList(array(0 => 'A', 1 => 'B'));
+ $list = new ArrayKeyChoiceList(array(0 => 'A', 1 => 'B'));
$data = '';
$form = $this->getMock('Symfony\Component\Form\Test\FormInterface');
@@ -91,7 +88,7 @@ class FixRadioInputListenerTest extends \PHPUnit_Framework_TestCase
public function testDontConvertEmptyStringToPlaceholderIfNoPlaceholderUsed()
{
- $list = new SimpleChoiceList(array(0 => 'A', 1 => 'B'));
+ $list = new ArrayKeyChoiceList(array(0 => 'A', 1 => 'B'));
$data = '';
$form = $this->getMock('Symfony\Component\Form\Test\FormInterface');
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php
index 3818c7861f..959eb928d2 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php
@@ -39,67 +39,4 @@ class TrimListenerTest extends \PHPUnit_Framework_TestCase
$this->assertSame(1234, $event->getData());
}
-
- /**
- * @dataProvider spaceProvider
- */
- public function testTrimUtf8Separators($hex)
- {
- if (!function_exists('mb_convert_encoding')) {
- $this->markTestSkipped('The "mb_convert_encoding" function is not available');
- }
-
- // Convert hexadecimal representation into binary
- // H: hex string, high nibble first (UCS-2BE)
- // *: repeat until end of string
- $binary = pack('H*', $hex);
-
- // Convert UCS-2BE to UTF-8
- $symbol = mb_convert_encoding($binary, 'UTF-8', 'UCS-2BE');
- $symbol = $symbol."ab\ncd".$symbol;
-
- $form = $this->getMock('Symfony\Component\Form\Test\FormInterface');
- $event = new FormEvent($form, $symbol);
-
- $filter = new TrimListener();
- $filter->preSubmit($event);
-
- $this->assertSame("ab\ncd", $event->getData());
- }
-
- public function spaceProvider()
- {
- return array(
- // separators
- array('0020'),
- array('00A0'),
- array('1680'),
-// array('180E'),
- array('2000'),
- array('2001'),
- array('2002'),
- array('2003'),
- array('2004'),
- array('2005'),
- array('2006'),
- array('2007'),
- array('2008'),
- array('2009'),
- array('200A'),
- array('2028'),
- array('2029'),
- array('202F'),
- array('205F'),
- array('3000'),
- // controls
- array('0009'),
- array('000A'),
- array('000B'),
- array('000C'),
- array('000D'),
- array('0085'),
- // zero width space
-// array('200B'),
- );
- }
}
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypePerformanceTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypePerformanceTest.php
index 0685946fc1..83430d935c 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypePerformanceTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypePerformanceTest.php
@@ -30,7 +30,7 @@ class ChoiceTypePerformanceTest extends FormPerformanceTestCase
$choices = range(1, 300);
for ($i = 0; $i < 100; ++$i) {
- $this->factory->create('choice', rand(1, 400), array(
+ $this->factory->create('choice', mt_rand(1, 400), array(
'choices' => $choices,
));
}
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php
index 8e79b72199..32fa8b1af7 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php
@@ -186,6 +186,32 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase
}
}
+ public function testExpandedChoicesOptionsAreFlattenedObjectChoices()
+ {
+ $obj1 = (object) array('id' => 1, 'name' => 'Bernhard');
+ $obj2 = (object) array('id' => 2, 'name' => 'Fabien');
+ $obj3 = (object) array('id' => 3, 'name' => 'Kris');
+ $obj4 = (object) array('id' => 4, 'name' => 'Jon');
+ $obj5 = (object) array('id' => 5, 'name' => 'Roman');
+
+ $form = $this->factory->create('choice', null, array(
+ 'expanded' => true,
+ 'choices' => array(
+ 'Symfony' => array($obj1, $obj2, $obj3),
+ 'Doctrine' => array($obj4, $obj5),
+ ),
+ 'choices_as_values' => true,
+ 'choice_name' => 'id',
+ ));
+
+ $this->assertSame(5, $form->count(), 'Each nested choice should become a new field, not the groups');
+ $this->assertTrue($form->has(1));
+ $this->assertTrue($form->has(2));
+ $this->assertTrue($form->has(3));
+ $this->assertTrue($form->has(4));
+ $this->assertTrue($form->has(5));
+ }
+
public function testExpandedCheckboxesAreNeverRequired()
{
$form = $this->factory->create('choice', null, array(
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php
index d5bab9834d..f66441e43c 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php
@@ -627,6 +627,20 @@ class DateTypeTest extends TestCase
$this->assertFalse(isset($view->vars['date_pattern']));
}
+ public function testDatePatternFormatWithQuotedStrings()
+ {
+ \Locale::setDefault('es_ES');
+
+ $form = $this->factory->create('date', null, array(
+ // EEEE, d 'de' MMMM 'de' y
+ 'format' => \IntlDateFormatter::FULL,
+ ));
+
+ $view = $form->createView();
+
+ $this->assertEquals('{{ day }}{{ month }}{{ year }}', $view->vars['date_pattern']);
+ }
+
public function testPassWidgetToView()
{
$form = $this->factory->create('date', null, array(
diff --git a/src/Symfony/Component/Form/Tests/Util/StringUtilTest.php b/src/Symfony/Component/Form/Tests/Util/StringUtilTest.php
new file mode 100644
index 0000000000..7836852100
--- /dev/null
+++ b/src/Symfony/Component/Form/Tests/Util/StringUtilTest.php
@@ -0,0 +1,72 @@
+assertEquals('Foo!', StringUtil::trim($data));
+ }
+
+ /**
+ * @dataProvider spaceProvider
+ */
+ public function testTrimUtf8Separators($hex)
+ {
+ if (!function_exists('mb_convert_encoding')) {
+ $this->markTestSkipped('The "mb_convert_encoding" function is not available');
+ }
+
+ // Convert hexadecimal representation into binary
+ // H: hex string, high nibble first (UCS-2BE)
+ // *: repeat until end of string
+ $binary = pack('H*', $hex);
+
+ // Convert UCS-2BE to UTF-8
+ $symbol = mb_convert_encoding($binary, 'UTF-8', 'UCS-2BE');
+ $symbol = $symbol."ab\ncd".$symbol;
+
+ $this->assertSame("ab\ncd", StringUtil::trim($symbol));
+ }
+
+ public function spaceProvider()
+ {
+ return array(
+ // separators
+ array('0020'),
+ array('00A0'),
+ array('1680'),
+// array('180E'),
+ array('2000'),
+ array('2001'),
+ array('2002'),
+ array('2003'),
+ array('2004'),
+ array('2005'),
+ array('2006'),
+ array('2007'),
+ array('2008'),
+ array('2009'),
+ array('200A'),
+ array('2028'),
+ array('2029'),
+ array('202F'),
+ array('205F'),
+ array('3000'),
+ // controls
+ array('0009'),
+ array('000A'),
+ array('000B'),
+ array('000C'),
+ array('000D'),
+ array('0085'),
+ // zero width space
+// array('200B'),
+ );
+ }
+}
diff --git a/src/Symfony/Component/Form/Util/StringUtil.php b/src/Symfony/Component/Form/Util/StringUtil.php
new file mode 100644
index 0000000000..2f51e74afc
--- /dev/null
+++ b/src/Symfony/Component/Form/Util/StringUtil.php
@@ -0,0 +1,42 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Form\Util;
+
+/**
+ * @author Issei Murasawa
+ * @author Bernhard Schussek
+ */
+class StringUtil
+{
+ /**
+ * This class should not be instantiated.
+ */
+ private function __construct()
+ {
+ }
+
+ /**
+ * Returns the trimmed data.
+ *
+ * @param string $string
+ *
+ * @return string
+ */
+ public static function trim($string)
+ {
+ if (null !== $result = @preg_replace('/^[\pZ\p{Cc}]+|[\pZ\p{Cc}]+$/u', '', $string)) {
+ return $result;
+ }
+
+ return trim($string);
+ }
+}
diff --git a/src/Symfony/Component/HttpFoundation/JsonResponse.php b/src/Symfony/Component/HttpFoundation/JsonResponse.php
index f33d96e64e..0445a9a6ce 100644
--- a/src/Symfony/Component/HttpFoundation/JsonResponse.php
+++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php
@@ -95,34 +95,58 @@ class JsonResponse extends Response
*/
public function setData($data = array())
{
- $errorHandler = null;
- $errorHandler = set_error_handler(function () use (&$errorHandler) {
- if (JSON_ERROR_NONE !== json_last_error()) {
- return;
+ if (defined('HHVM_VERSION')) {
+ // HHVM does not trigger any warnings and let exceptions
+ // thrown from a JsonSerializable object pass through.
+ // If only PHP did the same...
+ $data = json_encode($data, $this->encodingOptions);
+ } else {
+ try {
+ if (PHP_VERSION_ID < 50400) {
+ // PHP 5.3 triggers annoying warnings for some
+ // types that can't be serialized as JSON (INF, resources, etc.)
+ // but doesn't provide the JsonSerializable interface.
+ set_error_handler('var_dump', 0);
+ $data = @json_encode($data, $this->encodingOptions);
+ } else {
+ // PHP 5.4 and up wrap exceptions thrown by JsonSerializable
+ // objects in a new exception that needs to be removed.
+ // Fortunately, PHP 5.5 and up do not trigger any warning anymore.
+ if (PHP_VERSION_ID < 50500) {
+ // Clear json_last_error()
+ json_encode(null);
+ $errorHandler = set_error_handler('var_dump');
+ restore_error_handler();
+ set_error_handler(function () use ($errorHandler) {
+ if (JSON_ERROR_NONE === json_last_error()) {
+ return $errorHandler && false !== call_user_func_array($errorHandler, func_get_args());
+ }
+ });
+ }
+
+ $data = json_encode($data, $this->encodingOptions);
+ }
+
+ if (PHP_VERSION_ID < 50500) {
+ restore_error_handler();
+ }
+ } catch (\Exception $e) {
+ if (PHP_VERSION_ID < 50500) {
+ restore_error_handler();
+ }
+ if (PHP_VERSION_ID >= 50400 && 'Exception' === get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) {
+ throw $e->getPrevious() ?: $e;
+ }
+ throw $e;
}
-
- if ($errorHandler) {
- call_user_func_array($errorHandler, func_get_args());
- }
- });
-
- try {
- // Clear json_last_error()
- json_encode(null);
-
- $this->data = json_encode($data, $this->encodingOptions);
-
- restore_error_handler();
- } catch (\Exception $exception) {
- restore_error_handler();
-
- throw $exception;
}
if (JSON_ERROR_NONE !== json_last_error()) {
throw new \InvalidArgumentException(json_last_error_msg());
}
+ $this->data = $data;
+
return $this->update();
}
diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php
index c2b7640468..d5a026f067 100644
--- a/src/Symfony/Component/HttpFoundation/Request.php
+++ b/src/Symfony/Component/HttpFoundation/Request.php
@@ -517,10 +517,17 @@ class Request
*/
public function __toString()
{
+ $content = '';
+ try {
+ $content = $this->getContent();
+ } catch (\LogicException $e) {
+ return trigger_error($e, E_USER_ERROR);
+ }
+
return
sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n".
$this->headers."\r\n".
- $this->getContent();
+ $content;
}
/**
diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php
index 38174dd969..c641cf62de 100644
--- a/src/Symfony/Component/HttpFoundation/Response.php
+++ b/src/Symfony/Component/HttpFoundation/Response.php
@@ -1247,15 +1247,9 @@ class Response
{
$status = ob_get_status(true);
$level = count($status);
+ $flags = PHP_VERSION_ID >= 50400 ? PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? PHP_OUTPUT_HANDLER_FLUSHABLE : PHP_OUTPUT_HANDLER_CLEANABLE) : -1;
- while ($level-- > $targetLevel
- && (!empty($status[$level]['del'])
- || (isset($status[$level]['flags'])
- && ($status[$level]['flags'] & PHP_OUTPUT_HANDLER_REMOVABLE)
- && ($status[$level]['flags'] & ($flush ? PHP_OUTPUT_HANDLER_FLUSHABLE : PHP_OUTPUT_HANDLER_CLEANABLE))
- )
- )
- ) {
+ while ($level-- > $targetLevel && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || $flags === ($s['flags'] & $flags) : $s['del'])) {
if ($flush) {
ob_end_flush();
} else {
diff --git a/src/Symfony/Component/HttpFoundation/Tests/ClockMock.php b/src/Symfony/Component/HttpFoundation/Tests/ClockMock.php
new file mode 100644
index 0000000000..04a842d9b5
--- /dev/null
+++ b/src/Symfony/Component/HttpFoundation/Tests/ClockMock.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+function time($asFloat = false)
+{
+ return Tests\time();
+}
+
+namespace Symfony\Component\HttpFoundation\Tests;
+
+function time()
+{
+ return $_SERVER['REQUEST_TIME'];
+}
diff --git a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php
index 0aaeb6baa1..b8474db15f 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php
@@ -13,6 +13,8 @@ namespace Symfony\Component\HttpFoundation\Tests;
use Symfony\Component\HttpFoundation\Cookie;
+require_once __DIR__.'/ClockMock.php';
+
/**
* CookieTest.
*
diff --git a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php
index 48b86038a7..f1ea565700 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php
@@ -203,9 +203,8 @@ class JsonResponseTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Exception
- * @expectedExceptionMessage Failed calling Symfony\Component\HttpFoundation\Tests\JsonSerializableObject::jsonSerialize()
- * @link http://php.net/manual/en/jsonserializable.jsonserialize.php#114688
+ * @expectedException \Exception
+ * @expectedExceptionMessage This error is expected
*/
public function testSetContentJsonSerializeError()
{
@@ -224,9 +223,7 @@ if (interface_exists('JsonSerializable')) {
{
public function jsonSerialize()
{
- trigger_error('This error is expected', E_USER_WARNING);
-
- return array();
+ throw new \Exception('This error is expected');
}
}
}
diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php
index ec739b592b..0fa198e098 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php
@@ -14,6 +14,8 @@ namespace Symfony\Component\HttpFoundation\Tests;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\Cookie;
+require_once __DIR__.'/ClockMock.php';
+
class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase
{
/**
@@ -118,7 +120,7 @@ class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase
$bag->clearCookie('foo');
- $this->assertContains('Set-Cookie: foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; path=/; httponly', explode("\r\n", $bag->__toString()));
+ $this->assertRegExp('#^Set-Cookie: foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; path=/; httponly#m', $bag->__toString());
}
public function testClearCookieSecureNotHttpOnly()
@@ -127,7 +129,7 @@ class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase
$bag->clearCookie('foo', '/', null, true, false);
- $this->assertContains("Set-Cookie: foo=deleted; expires=".gmdate("D, d-M-Y H:i:s T", time() - 31536001)."; path=/; secure", explode("\r\n", $bag->__toString()));
+ $this->assertRegExp('#^Set-Cookie: foo=deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; path=/; secure#m', $bag->__toString());
}
public function testReplace()
diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php
index b0a1c10948..dde654e52c 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php
@@ -190,7 +190,6 @@ class NativeSessionStorageTest extends \PHPUnit_Framework_TestCase
{
$storage = $this->getStorage();
- $this->assertFalse(isset($_SESSION));
$this->assertFalse($storage->getSaveHandler()->isActive());
$this->assertFalse($storage->isStarted());
diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php
index 02328dfe5c..b349277a50 100644
--- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php
+++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php
@@ -63,7 +63,6 @@ class PhpBridgeSessionStorageTest extends \PHPUnit_Framework_TestCase
{
$storage = $this->getStorage();
- $this->assertFalse(isset($_SESSION));
$this->assertFalse($storage->getSaveHandler()->isActive());
$this->assertFalse($storage->isStarted());
diff --git a/src/Symfony/Component/Intl/DateFormatter/DateFormat/FullTransformer.php b/src/Symfony/Component/Intl/DateFormatter/DateFormat/FullTransformer.php
index dcabf24915..ea7d8ac85e 100644
--- a/src/Symfony/Component/Intl/DateFormatter/DateFormat/FullTransformer.php
+++ b/src/Symfony/Component/Intl/DateFormatter/DateFormat/FullTransformer.php
@@ -121,7 +121,7 @@ class FullTransformer
// handle unimplemented characters
if (false !== strpos($this->notImplementedChars, $dateChars[0])) {
- throw new NotImplementedException(sprintf("Unimplemented date character '%s' in format '%s'", $dateChars[0], $this->pattern));
+ throw new NotImplementedException(sprintf('Unimplemented date character "%s" in format "%s"', $dateChars[0], $this->pattern));
}
}
diff --git a/src/Symfony/Component/Intl/Tests/Data/Bundle/Writer/JsonBundleWriterTest.php b/src/Symfony/Component/Intl/Tests/Data/Bundle/Writer/JsonBundleWriterTest.php
index f2e7b4fce4..39c656a34f 100644
--- a/src/Symfony/Component/Intl/Tests/Data/Bundle/Writer/JsonBundleWriterTest.php
+++ b/src/Symfony/Component/Intl/Tests/Data/Bundle/Writer/JsonBundleWriterTest.php
@@ -35,7 +35,7 @@ class JsonBundleWriterTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->writer = new JsonBundleWriter();
- $this->directory = sys_get_temp_dir().'/JsonBundleWriterTest/'.rand(1000, 9999);
+ $this->directory = sys_get_temp_dir().'/JsonBundleWriterTest/'.mt_rand(1000, 9999);
$this->filesystem = new Filesystem();
$this->filesystem->mkdir($this->directory);
diff --git a/src/Symfony/Component/Intl/Tests/Data/Bundle/Writer/PhpBundleWriterTest.php b/src/Symfony/Component/Intl/Tests/Data/Bundle/Writer/PhpBundleWriterTest.php
index ca3fd71238..a855fbffef 100644
--- a/src/Symfony/Component/Intl/Tests/Data/Bundle/Writer/PhpBundleWriterTest.php
+++ b/src/Symfony/Component/Intl/Tests/Data/Bundle/Writer/PhpBundleWriterTest.php
@@ -35,7 +35,7 @@ class PhpBundleWriterTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->writer = new PhpBundleWriter();
- $this->directory = sys_get_temp_dir().'/PhpBundleWriterTest/'.rand(1000, 9999);
+ $this->directory = sys_get_temp_dir().'/PhpBundleWriterTest/'.mt_rand(1000, 9999);
$this->filesystem = new Filesystem();
$this->filesystem->mkdir($this->directory);
diff --git a/src/Symfony/Component/Intl/Tests/Data/Bundle/Writer/TextBundleWriterTest.php b/src/Symfony/Component/Intl/Tests/Data/Bundle/Writer/TextBundleWriterTest.php
index 1252be82d1..197a4e1fc0 100644
--- a/src/Symfony/Component/Intl/Tests/Data/Bundle/Writer/TextBundleWriterTest.php
+++ b/src/Symfony/Component/Intl/Tests/Data/Bundle/Writer/TextBundleWriterTest.php
@@ -36,7 +36,7 @@ class TextBundleWriterTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->writer = new TextBundleWriter();
- $this->directory = sys_get_temp_dir().'/TextBundleWriterTest/'.rand(1000, 9999);
+ $this->directory = sys_get_temp_dir().'/TextBundleWriterTest/'.mt_rand(1000, 9999);
$this->filesystem = new Filesystem();
$this->filesystem->mkdir($this->directory);
diff --git a/src/Symfony/Component/Intl/Tests/Data/Util/LocaleScannerTest.php b/src/Symfony/Component/Intl/Tests/Data/Util/LocaleScannerTest.php
index 34d9713481..7c37c80720 100644
--- a/src/Symfony/Component/Intl/Tests/Data/Util/LocaleScannerTest.php
+++ b/src/Symfony/Component/Intl/Tests/Data/Util/LocaleScannerTest.php
@@ -33,7 +33,7 @@ class LocaleScannerTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
- $this->directory = sys_get_temp_dir().'/LocaleScannerTest/'.rand(1000, 9999);
+ $this->directory = sys_get_temp_dir().'/LocaleScannerTest/'.mt_rand(1000, 9999);
$this->filesystem = new Filesystem();
$this->scanner = new LocaleScanner();
diff --git a/src/Symfony/Component/Process/PhpExecutableFinder.php b/src/Symfony/Component/Process/PhpExecutableFinder.php
index 91d6d78a67..f8f57cc536 100644
--- a/src/Symfony/Component/Process/PhpExecutableFinder.php
+++ b/src/Symfony/Component/Process/PhpExecutableFinder.php
@@ -37,7 +37,7 @@ class PhpExecutableFinder
{
// HHVM support
if (defined('HHVM_VERSION')) {
- return (false !== ($hhvm = getenv('PHP_BINARY')) ? $hhvm : PHP_BINARY).($includeArgs ? ' '.implode(' ', $this->findArguments()) : '');
+ return (getenv('PHP_BINARY') ?: PHP_BINARY).($includeArgs ? ' '.implode(' ', $this->findArguments()) : '');
}
// PHP_BINARY return the current sapi executable
diff --git a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php
index ccf6d94721..8324b6829c 100644
--- a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php
+++ b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php
@@ -11,21 +11,30 @@
namespace Symfony\Component\Process\Tests;
-use Symfony\Component\Process\Exception\ProcessTimedOutException;
use Symfony\Component\Process\Exception\LogicException;
+use Symfony\Component\Process\Exception\ProcessTimedOutException;
+use Symfony\Component\Process\Exception\RuntimeException;
+use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\Pipes\PipesInterface;
use Symfony\Component\Process\Process;
-use Symfony\Component\Process\Exception\RuntimeException;
/**
* @author Robert Schönthal
*/
abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
{
+ protected static $phpBin;
+
+ public static function setUpBeforeClass()
+ {
+ $phpBin = new PhpExecutableFinder();
+ self::$phpBin = $phpBin->find();
+ }
+
public function testThatProcessDoesNotThrowWarningDuringRun()
{
@trigger_error('Test Error', E_USER_NOTICE);
- $process = $this->getProcess("php -r 'sleep(3)'");
+ $process = $this->getProcess(self::$phpBin." -r 'sleep(3)'");
$process->run();
$actualError = error_get_last();
$this->assertEquals('Test Error', $actualError['message']);
@@ -95,7 +104,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$expectedOutputSize = PipesInterface::CHUNK_SIZE * 2 + 2;
$code = sprintf('echo str_repeat(\'*\', %d);', $expectedOutputSize);
- $p = $this->getProcess(sprintf('php -r %s', escapeshellarg($code)));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code)));
$p->start();
// Let's wait enough time for process to finish...
@@ -134,7 +143,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
*/
public function testProcessResponses($expected, $getter, $code)
{
- $p = $this->getProcess(sprintf('php -r %s', escapeshellarg($code)));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code)));
$p->run();
$this->assertSame($expected, $p->$getter());
@@ -150,7 +159,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$expected = str_repeat(str_repeat('*', 1024), $size).'!';
$expectedLength = (1024 * $size) + 1;
- $p = $this->getProcess(sprintf('php -r %s', escapeshellarg($code)));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code)));
$p->setInput($expected);
$p->run();
@@ -170,7 +179,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
fwrite($stream, $expected);
rewind($stream);
- $p = $this->getProcess(sprintf('php -r %s', escapeshellarg($code)));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code)));
$p->setInput($stream);
$p->run();
@@ -182,7 +191,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testSetInputWhileRunningThrowsAnException()
{
- $process = $this->getProcess('php -r "usleep(500000);"');
+ $process = $this->getProcess(self::$phpBin.' -r "usleep(500000);"');
$process->start();
try {
$process->setInput('foobar');
@@ -201,7 +210,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
*/
public function testInvalidInput($value)
{
- $process = $this->getProcess('php -v');
+ $process = $this->getProcess(self::$phpBin.' -v');
$process->setInput($value);
}
@@ -218,7 +227,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
*/
public function testValidInput($expected, $value)
{
- $process = $this->getProcess('php -v');
+ $process = $this->getProcess(self::$phpBin.' -v');
$process->setInput($value);
$this->assertSame($expected, $process->getInput());
}
@@ -258,7 +267,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testCallbackIsExecutedForOutput()
{
- $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('echo \'foo\';')));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('echo \'foo\';')));
$called = false;
$p->run(function ($type, $buffer) use (&$called) {
@@ -270,7 +279,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testGetErrorOutput()
{
- $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }')));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }')));
$p->run();
$this->assertEquals(3, preg_match_all('/ERROR/', $p->getErrorOutput(), $matches));
@@ -283,7 +292,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$lock = tempnam(sys_get_temp_dir(), get_class($this).'Lock');
file_put_contents($lock, 'W');
- $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }')));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }')));
$p->start();
while ($p->isRunning()) {
@@ -299,7 +308,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testFlushErrorOutput()
{
- $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }')));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }')));
$p->run();
$p->clearErrorOutput();
@@ -313,7 +322,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$lock = tempnam(sys_get_temp_dir(), get_class($this).'Lock');
file_put_contents($lock, 'W');
- $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }')));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }')));
$p->start();
@@ -339,7 +348,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testGetOutput()
{
- $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n = 0; while ($n < 3) { echo \' foo \'; $n++; }')));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { echo \' foo \'; $n++; }')));
$p->run();
$this->assertEquals(3, preg_match_all('/foo/', $p->getOutput(), $matches));
@@ -352,7 +361,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$lock = tempnam(sys_get_temp_dir(), get_class($this).'Lock');
file_put_contents($lock, 'W');
- $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { echo \' foo \'; $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }')));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { echo \' foo \'; $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }')));
$p->start();
while ($p->isRunning()) {
@@ -368,7 +377,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testFlushOutput()
{
- $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n=0;while ($n<3) {echo \' foo \';$n++;}')));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n=0;while ($n<3) {echo \' foo \';$n++;}')));
$p->run();
$p->clearOutput();
@@ -382,7 +391,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$lock = tempnam(sys_get_temp_dir(), get_class($this).'Lock');
file_put_contents($lock, 'W');
- $p = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { echo \' foo \'; $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }')));
+ $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { echo \' foo \'; $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }')));
$p->start();
@@ -528,7 +537,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testStartIsNonBlocking()
{
- $process = $this->getProcess('php -r "usleep(500000);"');
+ $process = $this->getProcess(self::$phpBin.' -r "usleep(500000);"');
$start = microtime(true);
$process->start();
$end = microtime(true);
@@ -538,14 +547,14 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testUpdateStatus()
{
- $process = $this->getProcess('php -h');
+ $process = $this->getProcess(self::$phpBin.' -v');
$process->run();
$this->assertTrue(strlen($process->getOutput()) > 0);
}
public function testGetExitCodeIsNullOnStart()
{
- $process = $this->getProcess('php -r "usleep(200000);"');
+ $process = $this->getProcess(self::$phpBin.' -r "usleep(200000);"');
$this->assertNull($process->getExitCode());
$process->start();
$this->assertNull($process->getExitCode());
@@ -555,7 +564,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testGetExitCodeIsNullOnWhenStartingAgain()
{
- $process = $this->getProcess('php -r "usleep(200000);"');
+ $process = $this->getProcess(self::$phpBin.' -r "usleep(200000);"');
$process->run();
$this->assertEquals(0, $process->getExitCode());
$process->start();
@@ -566,14 +575,14 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testGetExitCode()
{
- $process = $this->getProcess('php -m');
+ $process = $this->getProcess(self::$phpBin.' -v');
$process->run();
$this->assertSame(0, $process->getExitCode());
}
public function testStatus()
{
- $process = $this->getProcess('php -r "usleep(500000);"');
+ $process = $this->getProcess(self::$phpBin.' -r "usleep(500000);"');
$this->assertFalse($process->isRunning());
$this->assertFalse($process->isStarted());
$this->assertFalse($process->isTerminated());
@@ -592,7 +601,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testStop()
{
- $process = $this->getProcess('php -r "sleep(4);"');
+ $process = $this->getProcess(self::$phpBin.' -r "sleep(4);"');
$process->start();
$this->assertTrue($process->isRunning());
$process->stop();
@@ -601,14 +610,14 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testIsSuccessful()
{
- $process = $this->getProcess('php -m');
+ $process = $this->getProcess(self::$phpBin.' -v');
$process->run();
$this->assertTrue($process->isSuccessful());
}
public function testIsSuccessfulOnlyAfterTerminated()
{
- $process = $this->getProcess('php -r "sleep(1);"');
+ $process = $this->getProcess(self::$phpBin.' -r "sleep(1);"');
$process->start();
while ($process->isRunning()) {
$this->assertFalse($process->isSuccessful());
@@ -620,7 +629,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testIsNotSuccessful()
{
- $process = $this->getProcess('php -r "usleep(500000);throw new \Exception(\'BOUM\');"');
+ $process = $this->getProcess(self::$phpBin.' -r "usleep(500000);throw new \Exception(\'BOUM\');"');
$process->start();
$this->assertTrue($process->isRunning());
$process->wait();
@@ -633,7 +642,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$this->markTestSkipped('Windows does not support POSIX signals');
}
- $process = $this->getProcess('php -m');
+ $process = $this->getProcess(self::$phpBin.' -v');
$process->run();
$this->assertFalse($process->hasBeenSignaled());
}
@@ -644,7 +653,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$this->markTestSkipped('Windows does not support POSIX signals');
}
- $process = $this->getProcess('php -m');
+ $process = $this->getProcess(self::$phpBin.' -v');
$process->run();
$this->assertFalse($process->hasBeenSignaled());
}
@@ -655,7 +664,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$this->markTestSkipped('Windows does not support POSIX signals');
}
- $process = $this->getProcess('php -m');
+ $process = $this->getProcess(self::$phpBin.' -v');
$process->run();
$this->assertEquals(0, $process->getTermSignal());
}
@@ -666,7 +675,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$this->markTestSkipped('Windows does not support POSIX signals');
}
- $process = $this->getProcess('php -r "sleep(4);"');
+ $process = $this->getProcess(self::$phpBin.' -r "sleep(4);"');
$process->start();
$process->stop();
$this->assertTrue($process->hasBeenSignaled());
@@ -681,7 +690,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
// SIGTERM is only defined if pcntl extension is present
$termSignal = defined('SIGTERM') ? SIGTERM : 15;
- $process = $this->getProcess('php -r "sleep(4);"');
+ $process = $this->getProcess(self::$phpBin.' -r "sleep(4);"');
$process->start();
$process->stop();
@@ -710,7 +719,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testRestart()
{
- $process1 = $this->getProcess('php -r "echo getmypid();"');
+ $process1 = $this->getProcess(self::$phpBin.' -r "echo getmypid();"');
$process1->run();
$process2 = $process1->restart();
@@ -732,7 +741,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
// Sleep doesn't work as it will allow the process to handle signals and close
// file handles from the other end.
- $process = $this->getProcess('php -r "while (true) {}"');
+ $process = $this->getProcess(self::$phpBin.' -r "while (true) {}"');
$process->start();
// PHP will deadlock when it tries to cleanup $process
@@ -741,7 +750,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testRunProcessWithTimeout()
{
$timeout = 0.5;
- $process = $this->getProcess('php -r "usleep(600000);"');
+ $process = $this->getProcess(self::$phpBin.' -r "usleep(600000);"');
$process->setTimeout($timeout);
$start = microtime(true);
try {
@@ -763,13 +772,13 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testCheckTimeoutOnNonStartedProcess()
{
- $process = $this->getProcess('php -r "sleep(3);"');
+ $process = $this->getProcess(self::$phpBin.' -r "sleep(3);"');
$process->checkTimeout();
}
public function testCheckTimeoutOnTerminatedProcess()
{
- $process = $this->getProcess('php -v');
+ $process = $this->getProcess(self::$phpBin.' -v');
$process->run();
$process->checkTimeout();
}
@@ -778,7 +787,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
{
$timeout = 0.5;
$precision = 100000;
- $process = $this->getProcess('php -r "sleep(3);"');
+ $process = $this->getProcess(self::$phpBin.' -r "sleep(3);"');
$process->setTimeout($timeout);
$start = microtime(true);
@@ -800,7 +809,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testIdleTimeout()
{
- $process = $this->getProcess('php -r "sleep(3);"');
+ $process = $this->getProcess(self::$phpBin.' -r "sleep(3);"');
$process->setTimeout(10);
$process->setIdleTimeout(0.5);
@@ -817,7 +826,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testIdleTimeoutNotExceededWhenOutputIsSent()
{
- $process = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n = 30; while ($n--) {echo "foo\n"; usleep(100000); }')));
+ $process = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 30; while ($n--) {echo "foo\n"; usleep(100000); }')));
$process->setTimeout(2);
$process->setIdleTimeout(1);
@@ -833,7 +842,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testStartAfterATimeout()
{
- $process = $this->getProcess(sprintf('php -r %s', escapeshellarg('$n = 1000; while ($n--) {echo \'\'; usleep(1000); }')));
+ $process = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 1000; while ($n--) {echo \'\'; usleep(1000); }')));
$process->setTimeout(0.1);
try {
@@ -848,7 +857,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testGetPid()
{
- $process = $this->getProcess('php -r "usleep(500000);"');
+ $process = $this->getProcess(self::$phpBin.' -r "usleep(500000);"');
$process->start();
$this->assertGreaterThan(0, $process->getPid());
$process->wait();
@@ -856,13 +865,13 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testGetPidIsNullBeforeStart()
{
- $process = $this->getProcess('php -r "sleep(1);"');
+ $process = $this->getProcess(self::$phpBin.' -r "sleep(1);"');
$this->assertNull($process->getPid());
}
public function testGetPidIsNullAfterRun()
{
- $process = $this->getProcess('php -m');
+ $process = $this->getProcess(self::$phpBin.' -v');
$process->run();
$this->assertNull($process->getPid());
}
@@ -907,7 +916,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testSignalProcessNotRunning()
{
$this->verifyPosixIsEnabled();
- $process = $this->getProcess('php -m');
+ $process = $this->getProcess(self::$phpBin.' -v');
$process->signal(SIGHUP);
}
@@ -916,7 +925,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
*/
public function testMethodsThatNeedARunningProcess($method)
{
- $process = $this->getProcess('php -m');
+ $process = $this->getProcess(self::$phpBin.' -v');
$this->setExpectedException('Symfony\Component\Process\Exception\LogicException', sprintf('Process must be started before calling %s.', $method));
$process->{$method}();
}
@@ -937,7 +946,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
*/
public function testMethodsThatNeedATerminatedProcess($method)
{
- $process = $this->getProcess('php -r "sleep(1);"');
+ $process = $this->getProcess(self::$phpBin.' -r "sleep(1);"');
$process->start();
try {
$process->{$method}();
@@ -979,7 +988,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$this->markTestSkipped('POSIX signals do not work on Windows');
}
- $process = $this->getProcess('php -r "sleep(3);"');
+ $process = $this->getProcess(self::$phpBin.' -r "sleep(3);"');
$process->start();
$process->signal(-4);
}
@@ -993,14 +1002,14 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$this->markTestSkipped('POSIX signals do not work on Windows');
}
- $process = $this->getProcess('php -r "sleep(3);"');
+ $process = $this->getProcess(self::$phpBin.' -r "sleep(3);"');
$process->start();
$process->signal('Céphalopodes');
}
public function testDisableOutputDisablesTheOutput()
{
- $p = $this->getProcess('php -r "usleep(500000);"');
+ $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"');
$this->assertFalse($p->isOutputDisabled());
$p->disableOutput();
$this->assertTrue($p->isOutputDisabled());
@@ -1010,7 +1019,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testDisableOutputWhileRunningThrowsException()
{
- $p = $this->getProcess('php -r "usleep(500000);"');
+ $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"');
$p->start();
$this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'Disabling output while the process is running is not possible.');
$p->disableOutput();
@@ -1018,7 +1027,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testEnableOutputWhileRunningThrowsException()
{
- $p = $this->getProcess('php -r "usleep(500000);"');
+ $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"');
$p->disableOutput();
$p->start();
$this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'Enabling output while the process is running is not possible.');
@@ -1027,7 +1036,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
public function testEnableOrDisableOutputAfterRunDoesNotThrowException()
{
- $p = $this->getProcess('php -r "usleep(500000);"');
+ $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"');
$p->disableOutput();
$p->start();
$p->wait();
@@ -1063,7 +1072,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
*/
public function testStartWithACallbackAndDisabledOutput($startMethod, $exception, $exceptionMessage)
{
- $p = $this->getProcess('php -r "usleep(500000);"');
+ $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"');
$p->disableOutput();
$this->setExpectedException($exception, $exceptionMessage);
$p->{$startMethod}(function () {});
@@ -1083,7 +1092,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
*/
public function testGetOutputWhileDisabled($fetchMethod)
{
- $p = $this->getProcess('php -r "usleep(500000);"');
+ $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"');
$p->disableOutput();
$p->start();
$this->setExpectedException('Symfony\Component\Process\Exception\LogicException', 'Output has been disabled.');
diff --git a/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php b/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php
index 20b12b1c3c..61a471b4f6 100644
--- a/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php
+++ b/src/Symfony/Component/Process/Tests/ExecutableFinderTest.php
@@ -102,7 +102,7 @@ class ExecutableFinderTest extends \PHPUnit_Framework_TestCase
$this->markTestSkipped('Cannot test when open_basedir is set');
}
- $this->iniSet('open_basedir', dirname(PHP_BINARY).PATH_SEPARATOR.'/');
+ $this->iniSet('open_basedir', dirname(PHP_BINARY).(!defined('HHVM_VERSION') ? PATH_SEPARATOR.'/' : ''));
$finder = new ExecutableFinder();
$result = $finder->find($this->getPhpBinaryName());
@@ -125,7 +125,7 @@ class ExecutableFinderTest extends \PHPUnit_Framework_TestCase
}
$this->setPath('');
- $this->iniSet('open_basedir', PHP_BINARY.PATH_SEPARATOR.'/');
+ $this->iniSet('open_basedir', PHP_BINARY.(!defined('HHVM_VERSION') ? PATH_SEPARATOR.'/' : ''));
$finder = new ExecutableFinder();
$result = $finder->find($this->getPhpBinaryName(), false);
diff --git a/src/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php b/src/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php
index 8f8623930f..cd4abedc9d 100644
--- a/src/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php
+++ b/src/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php
@@ -53,10 +53,10 @@ class PhpExecutableFinderTest extends \PHPUnit_Framework_TestCase
$f = new PhpExecutableFinder();
- $current = $f->find();
+ $current = getenv('PHP_BINARY') ?: PHP_BINARY;
- $this->assertEquals($f->find(), $current.' --php', '::find() returns the executable PHP');
- $this->assertEquals($f->find(false), $current, '::find() returns the executable PHP');
+ $this->assertEquals($current.' --php', $f->find(), '::find() returns the executable PHP');
+ $this->assertEquals($current, $f->find(false), '::find() returns the executable PHP');
}
/**
diff --git a/src/Symfony/Component/Process/Tests/SimpleProcessTest.php b/src/Symfony/Component/Process/Tests/SimpleProcessTest.php
index 4bf9ad87c6..98eeb0ecbc 100644
--- a/src/Symfony/Component/Process/Tests/SimpleProcessTest.php
+++ b/src/Symfony/Component/Process/Tests/SimpleProcessTest.php
@@ -150,7 +150,7 @@ class SimpleProcessTest extends AbstractProcessTest
public function testStopTerminatesProcessCleanly()
{
try {
- $process = $this->getProcess('php -r "echo \'foo\'; sleep(1); echo \'bar\';"');
+ $process = $this->getProcess(self::$phpBin.' -r "echo \'foo\'; sleep(1); echo \'bar\';"');
$process->run(function () use ($process) {
$process->stop();
});
@@ -164,7 +164,7 @@ class SimpleProcessTest extends AbstractProcessTest
$this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.');
try {
- $process = $this->getProcess('php -r "echo \'foo\'; sleep(1); echo \'bar\';"');
+ $process = $this->getProcess(self::$phpBin.' -r "echo \'foo\'; sleep(1); echo \'bar\';"');
$process->run(function () use ($process) {
if ($process->isRunning()) {
$process->signal(defined('SIGKILL') ? SIGKILL : 9);
@@ -180,7 +180,7 @@ class SimpleProcessTest extends AbstractProcessTest
$this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.');
try {
- $process = $this->getProcess('php -r "echo \'foo\'; sleep(1); echo \'bar\';"');
+ $process = $this->getProcess(self::$phpBin.' -r "echo \'foo\'; sleep(1); echo \'bar\';"');
$process->run(function () use ($process) {
if ($process->isRunning()) {
$process->signal(defined('SIGTERM') ? SIGTERM : 15);
diff --git a/src/Symfony/Component/Routing/Annotation/Route.php b/src/Symfony/Component/Routing/Annotation/Route.php
index 401474a289..47cd06bfc1 100644
--- a/src/Symfony/Component/Routing/Annotation/Route.php
+++ b/src/Symfony/Component/Routing/Annotation/Route.php
@@ -48,7 +48,7 @@ class Route
foreach ($data as $key => $value) {
$method = 'set'.str_replace('_', '', $key);
if (!method_exists($this, $method)) {
- throw new \BadMethodCallException(sprintf("Unknown property '%s' on annotation '%s'.", $key, get_class($this)));
+ throw new \BadMethodCallException(sprintf('Unknown property "%s" on annotation "%s".', $key, get_class($this)));
}
$this->$method($value);
}
diff --git a/src/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php b/src/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php
index 6fbf7e2203..525b9f5693 100644
--- a/src/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php
+++ b/src/Symfony/Component/Routing/Tests/Generator/Dumper/PhpGeneratorDumperTest.php
@@ -39,7 +39,7 @@ class PhpGeneratorDumperTest extends \PHPUnit_Framework_TestCase
$this->routeCollection = new RouteCollection();
$this->generatorDumper = new PhpGeneratorDumper($this->routeCollection);
- $this->testTmpFilepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'php_generator.php';
+ $this->testTmpFilepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'php_generator.'.$this->getName().'.php';
@unlink($this->testTmpFilepath);
}
diff --git a/src/Symfony/Component/Security/Core/Exception/AccessDeniedException.php b/src/Symfony/Component/Security/Core/Exception/AccessDeniedException.php
index 7c16afb464..736a36b5f7 100644
--- a/src/Symfony/Component/Security/Core/Exception/AccessDeniedException.php
+++ b/src/Symfony/Component/Security/Core/Exception/AccessDeniedException.php
@@ -18,7 +18,7 @@ namespace Symfony\Component\Security\Core\Exception;
*/
class AccessDeniedException extends \RuntimeException
{
- public function __construct($message = 'Access Denied', \Exception $previous = null)
+ public function __construct($message = 'Access Denied.', \Exception $previous = null)
{
parent::__construct($message, 403, $previous);
}
diff --git a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php
index 5fc56e7032..8746d2bea8 100644
--- a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php
@@ -162,7 +162,8 @@ class SwitchUserListener implements ListenerInterface
}
if (null !== $this->dispatcher) {
- $switchEvent = new SwitchUserEvent($request, $original->getUser());
+ $user = $this->provider->refreshUser($original->getUser());
+ $switchEvent = new SwitchUserEvent($request, $user);
$this->dispatcher->dispatch(SecurityEvents::SWITCH_USER, $switchEvent);
}
diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php
index 3b6442deef..f43b564322 100644
--- a/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php
+++ b/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php
@@ -11,7 +11,9 @@
namespace Symfony\Component\Security\Http\Tests\Firewall;
+use Symfony\Component\Security\Http\Event\SwitchUserEvent;
use Symfony\Component\Security\Http\Firewall\SwitchUserListener;
+use Symfony\Component\Security\Http\SecurityEvents;
class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
{
@@ -100,6 +102,62 @@ class SwitchUserListenerTest extends \PHPUnit_Framework_TestCase
$listener->handle($this->event);
}
+ public function testExitUserDispatchesEventWithRefreshedUser()
+ {
+ $originalUser = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
+ $refreshedUser = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
+ $this
+ ->userProvider
+ ->expects($this->any())
+ ->method('refreshUser')
+ ->with($originalUser)
+ ->willReturn($refreshedUser);
+ $originalToken = $this->getToken();
+ $originalToken
+ ->expects($this->any())
+ ->method('getUser')
+ ->willReturn($originalUser);
+ $role = $this
+ ->getMockBuilder('Symfony\Component\Security\Core\Role\SwitchUserRole')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $role->expects($this->any())->method('getSource')->willReturn($originalToken);
+ $this
+ ->tokenStorage
+ ->expects($this->any())
+ ->method('getToken')
+ ->willReturn($this->getToken(array($role)));
+ $this
+ ->request
+ ->expects($this->any())
+ ->method('get')
+ ->with('_switch_user')
+ ->willReturn('_exit');
+ $this
+ ->request
+ ->expects($this->any())
+ ->method('getUri')
+ ->willReturn('/');
+ $this
+ ->request
+ ->query
+ ->expects($this->any())
+ ->method('all')
+ ->will($this->returnValue(array()));
+
+ $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
+ $dispatcher
+ ->expects($this->once())
+ ->method('dispatch')
+ ->with(SecurityEvents::SWITCH_USER, $this->callback(function (SwitchUserEvent $event) use ($refreshedUser) {
+ return $event->getTargetUser() === $refreshedUser;
+ }))
+ ;
+
+ $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher);
+ $listener->handle($this->event);
+ }
+
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException
*/
diff --git a/src/Symfony/Component/Serializer/Annotation/Groups.php b/src/Symfony/Component/Serializer/Annotation/Groups.php
index e88ffa71d7..9e7801f842 100644
--- a/src/Symfony/Component/Serializer/Annotation/Groups.php
+++ b/src/Symfony/Component/Serializer/Annotation/Groups.php
@@ -35,16 +35,16 @@ class Groups
public function __construct(array $data)
{
if (!isset($data['value']) || !$data['value']) {
- throw new InvalidArgumentException(sprintf("Parameter of annotation '%s' cannot be empty.", get_class($this)));
+ throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" cannot be empty.', get_class($this)));
}
if (!is_array($data['value'])) {
- throw new InvalidArgumentException(sprintf("Parameter of annotation '%s' must be an array of strings.", get_class($this)));
+ throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" must be an array of strings.', get_class($this)));
}
foreach ($data['value'] as $group) {
if (!is_string($group)) {
- throw new InvalidArgumentException(sprintf("Parameter of annotation '%s' must be an array of strings.", get_class($this)));
+ throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" must be an array of strings.', get_class($this)));
}
}
diff --git a/src/Symfony/Component/Stopwatch/Tests/ClockMock.php b/src/Symfony/Component/Stopwatch/Tests/ClockMock.php
new file mode 100644
index 0000000000..5bbe6b1db8
--- /dev/null
+++ b/src/Symfony/Component/Stopwatch/Tests/ClockMock.php
@@ -0,0 +1,39 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Stopwatch;
+
+function microtime($asFloat = false)
+{
+ return Tests\microtime($asFloat);
+}
+
+namespace Symfony\Component\Stopwatch\Tests;
+
+function usleep($us)
+{
+ static $now;
+
+ if (null === $now) {
+ $now = \microtime(true);
+ }
+
+ return $now += $us / 1000000;
+}
+
+function microtime($asFloat = false)
+{
+ if (!$asFloat) {
+ return \microtime(false);
+ }
+
+ return usleep(1);
+}
diff --git a/src/Symfony/Component/Stopwatch/Tests/StopwatchEventTest.php b/src/Symfony/Component/Stopwatch/Tests/StopwatchEventTest.php
index 309fc3e2a3..4386d94fca 100644
--- a/src/Symfony/Component/Stopwatch/Tests/StopwatchEventTest.php
+++ b/src/Symfony/Component/Stopwatch/Tests/StopwatchEventTest.php
@@ -13,6 +13,8 @@ namespace Symfony\Component\Stopwatch\Tests;
use Symfony\Component\Stopwatch\StopwatchEvent;
+require_once __DIR__.'/ClockMock.php';
+
/**
* StopwatchEventTest.
*
@@ -137,12 +139,12 @@ class StopwatchEventTest extends \PHPUnit_Framework_TestCase
public function testStartTime()
{
$event = new StopwatchEvent(microtime(true) * 1000);
- $this->assertTrue($event->getStartTime() < 0.5);
+ $this->assertLessThanOrEqual(0.5, $event->getStartTime());
$event = new StopwatchEvent(microtime(true) * 1000);
$event->start();
$event->stop();
- $this->assertTrue($event->getStartTime() < 1);
+ $this->assertLessThanOrEqual(1, $event->getStartTime());
$event = new StopwatchEvent(microtime(true) * 1000);
$event->start();
diff --git a/src/Symfony/Component/Stopwatch/Tests/StopwatchTest.php b/src/Symfony/Component/Stopwatch/Tests/StopwatchTest.php
index a14b6e80ea..0d05e8f800 100644
--- a/src/Symfony/Component/Stopwatch/Tests/StopwatchTest.php
+++ b/src/Symfony/Component/Stopwatch/Tests/StopwatchTest.php
@@ -13,6 +13,8 @@ namespace Symfony\Component\Stopwatch\Tests;
use Symfony\Component\Stopwatch\Stopwatch;
+require_once __DIR__.'/ClockMock.php';
+
/**
* StopwatchTest.
*
diff --git a/src/Symfony/Component/Templating/Tests/Loader/CacheLoaderTest.php b/src/Symfony/Component/Templating/Tests/Loader/CacheLoaderTest.php
index eff379a178..01896c2e18 100644
--- a/src/Symfony/Component/Templating/Tests/Loader/CacheLoaderTest.php
+++ b/src/Symfony/Component/Templating/Tests/Loader/CacheLoaderTest.php
@@ -28,7 +28,7 @@ class CacheLoaderTest extends \PHPUnit_Framework_TestCase
public function testLoad()
{
- $dir = sys_get_temp_dir().DIRECTORY_SEPARATOR.rand(111111, 999999);
+ $dir = sys_get_temp_dir().DIRECTORY_SEPARATOR.mt_rand(111111, 999999);
mkdir($dir, 0777, true);
$loader = new ProjectTemplateLoader($varLoader = new ProjectTemplateLoaderVar(), $dir);
diff --git a/src/Symfony/Component/Translation/PluralizationRules.php b/src/Symfony/Component/Translation/PluralizationRules.php
index e1eac82ce9..3ef8f00b6e 100644
--- a/src/Symfony/Component/Translation/PluralizationRules.php
+++ b/src/Symfony/Component/Translation/PluralizationRules.php
@@ -55,6 +55,7 @@ class PluralizationRules
* Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
*/
switch ($locale) {
+ case 'az':
case 'bo':
case 'dz':
case 'id':
@@ -73,7 +74,6 @@ class PluralizationRules
break;
case 'af':
- case 'az':
case 'bn':
case 'bg':
case 'ca':
diff --git a/src/Symfony/Component/Validator/ConstraintViolationInterface.php b/src/Symfony/Component/Validator/ConstraintViolationInterface.php
index 232fb5513f..d772b45d12 100644
--- a/src/Symfony/Component/Validator/ConstraintViolationInterface.php
+++ b/src/Symfony/Component/Validator/ConstraintViolationInterface.php
@@ -130,7 +130,7 @@ interface ConstraintViolationInterface
/**
* Returns a machine-digestible error code for the violation.
*
- * @return mixed The error code.
+ * @return string|null The error code.
*/
public function getCode();
}
diff --git a/src/Symfony/Component/Validator/Constraints/AbstractComparison.php b/src/Symfony/Component/Validator/Constraints/AbstractComparison.php
index fb1f1f3ef7..78db943f74 100644
--- a/src/Symfony/Component/Validator/Constraints/AbstractComparison.php
+++ b/src/Symfony/Component/Validator/Constraints/AbstractComparison.php
@@ -18,6 +18,7 @@ use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
* Used for the comparison of values.
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
abstract class AbstractComparison extends Constraint
{
diff --git a/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php b/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php
index 67d73a5ee2..ce0487403b 100644
--- a/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php
@@ -60,12 +60,14 @@ abstract class AbstractComparisonValidator extends ConstraintValidator
->setParameter('{{ value }}', $this->formatValue($value, self::OBJECT_TO_STRING | self::PRETTY_DATE))
->setParameter('{{ compared_value }}', $this->formatValue($comparedValue, self::OBJECT_TO_STRING | self::PRETTY_DATE))
->setParameter('{{ compared_value_type }}', $this->formatTypeOf($comparedValue))
+ ->setCode($this->getErrorCode())
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value, self::OBJECT_TO_STRING | self::PRETTY_DATE))
->setParameter('{{ compared_value }}', $this->formatValue($comparedValue, self::OBJECT_TO_STRING | self::PRETTY_DATE))
->setParameter('{{ compared_value_type }}', $this->formatTypeOf($comparedValue))
+ ->setCode($this->getErrorCode())
->addViolation();
}
}
@@ -80,4 +82,13 @@ abstract class AbstractComparisonValidator extends ConstraintValidator
* @return bool true if the relationship is valid, false otherwise
*/
abstract protected function compareValues($value1, $value2);
+
+ /**
+ * Returns the error code used if the comparison fails.
+ *
+ * @return string|null The error code or `null` if no code should be set
+ */
+ protected function getErrorCode()
+ {
+ }
}
diff --git a/src/Symfony/Component/Validator/Constraints/Blank.php b/src/Symfony/Component/Validator/Constraints/Blank.php
index 766ce6c7bb..f74050a1c7 100644
--- a/src/Symfony/Component/Validator/Constraints/Blank.php
+++ b/src/Symfony/Component/Validator/Constraints/Blank.php
@@ -23,5 +23,11 @@ use Symfony\Component\Validator\Constraint;
*/
class Blank extends Constraint
{
+ const NOT_BLANK_ERROR = '183ad2de-533d-4796-a439-6d3c3852b549';
+
+ protected static $errorNames = array(
+ self::NOT_BLANK_ERROR => 'NOT_BLANK_ERROR',
+ );
+
public $message = 'This value should be blank.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/BlankValidator.php b/src/Symfony/Component/Validator/Constraints/BlankValidator.php
index 2d26e4a91b..2d76c77e8f 100644
--- a/src/Symfony/Component/Validator/Constraints/BlankValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/BlankValidator.php
@@ -36,10 +36,12 @@ class BlankValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Blank::NOT_BLANK_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Blank::NOT_BLANK_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/CallbackValidator.php b/src/Symfony/Component/Validator/Constraints/CallbackValidator.php
index 9939306cb8..eaf2f3c011 100644
--- a/src/Symfony/Component/Validator/Constraints/CallbackValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/CallbackValidator.php
@@ -60,7 +60,7 @@ class CallbackValidator extends ConstraintValidator
call_user_func($method, $object, $this->context);
} elseif (null !== $object) {
if (!method_exists($object, $method)) {
- throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist', $method));
+ throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist in class %s', $method, get_class($object)));
}
$reflMethod = new \ReflectionMethod($object, $method);
diff --git a/src/Symfony/Component/Validator/Constraints/CardScheme.php b/src/Symfony/Component/Validator/Constraints/CardScheme.php
index 14f3b5d8cf..40c32e879e 100644
--- a/src/Symfony/Component/Validator/Constraints/CardScheme.php
+++ b/src/Symfony/Component/Validator/Constraints/CardScheme.php
@@ -24,8 +24,8 @@ use Symfony\Component\Validator\Constraint;
*/
class CardScheme extends Constraint
{
- const NOT_NUMERIC_ERROR = 1;
- const INVALID_FORMAT_ERROR = 2;
+ const NOT_NUMERIC_ERROR = 'a2ad9231-e827-485f-8a1e-ef4d9a6d5c2e';
+ const INVALID_FORMAT_ERROR = 'a8faedbf-1c2f-4695-8d22-55783be8efed';
protected static $errorNames = array(
self::NOT_NUMERIC_ERROR => 'NOT_NUMERIC_ERROR',
diff --git a/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php b/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php
index 708ae09390..229e0d2c18 100644
--- a/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php
@@ -24,6 +24,7 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
*
* @see http://en.wikipedia.org/wiki/Bank_card_number
* @see http://www.regular-expressions.info/creditcard.html
+ * @see http://www.barclaycard.co.uk/business/files/Ranges_and_Rules_September_2014.pdf
*/
class CardSchemeValidator extends ConstraintValidator
{
@@ -64,10 +65,13 @@ class CardSchemeValidator extends ConstraintValidator
'LASER' => array(
'/^(6304|670[69]|6771)[0-9]{12,15}$/',
),
- // Maestro cards begin with either 5018, 5020, 5038, 5893, 6304, 6759, 6761, 6762, 6763 or 0604
- // They have between 12 and 19 digits.
+ // Maestro international cards begin with 675900..675999 and have between 12 and 19 digits.
+ // Maestro UK cards begin with either 500000..509999 or 560000..699999 and have between 12 and 19 digits.
'MAESTRO' => array(
- '/^(5018|5020|5038|6304|6759|6761|676[23]|0604)[0-9]{8,15}$/',
+ '/^(6759[0-9]{2})[0-9]{6,13}$/',
+ '/^(50[0-9]{4})[0-9]{6,13}$/',
+ '/^5[6-9][0-9]{10,17}$/',
+ '/^6[0-9]{11,18}$/',
),
// All MasterCard numbers start with the numbers 51 through 55. All have 16 digits.
'MASTERCARD' => array(
diff --git a/src/Symfony/Component/Validator/Constraints/Choice.php b/src/Symfony/Component/Validator/Constraints/Choice.php
index 39a64574d0..302df202b0 100644
--- a/src/Symfony/Component/Validator/Constraints/Choice.php
+++ b/src/Symfony/Component/Validator/Constraints/Choice.php
@@ -23,9 +23,9 @@ use Symfony\Component\Validator\Constraint;
*/
class Choice extends Constraint
{
- const NO_SUCH_CHOICE_ERROR = 1;
- const TOO_FEW_ERROR = 2;
- const TOO_MANY_ERROR = 3;
+ const NO_SUCH_CHOICE_ERROR = '8e179f1b-97aa-4560-a02f-2a8b42e49df7';
+ const TOO_FEW_ERROR = '11edd7eb-5872-4b6e-9f12-89923999fd0e';
+ const TOO_MANY_ERROR = '9bd98e49-211c-433f-8630-fd1c2d0f08c3';
protected static $errorNames = array(
self::NO_SUCH_CHOICE_ERROR => 'NO_SUCH_CHOICE_ERROR',
diff --git a/src/Symfony/Component/Validator/Constraints/Collection.php b/src/Symfony/Component/Validator/Constraints/Collection.php
index 708c8ed477..57fc93832f 100644
--- a/src/Symfony/Component/Validator/Constraints/Collection.php
+++ b/src/Symfony/Component/Validator/Constraints/Collection.php
@@ -23,8 +23,8 @@ use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
*/
class Collection extends Composite
{
- const MISSING_FIELD_ERROR = 1;
- const NO_SUCH_FIELD_ERROR = 2;
+ const MISSING_FIELD_ERROR = '2fa2158c-2a7f-484b-98aa-975522539ff8';
+ const NO_SUCH_FIELD_ERROR = '7703c766-b5d5-4cef-ace7-ae0dd82304e9';
protected static $errorNames = array(
self::MISSING_FIELD_ERROR => 'MISSING_FIELD_ERROR',
diff --git a/src/Symfony/Component/Validator/Constraints/Count.php b/src/Symfony/Component/Validator/Constraints/Count.php
index a3e12fe134..4fe9710469 100644
--- a/src/Symfony/Component/Validator/Constraints/Count.php
+++ b/src/Symfony/Component/Validator/Constraints/Count.php
@@ -24,8 +24,8 @@ use Symfony\Component\Validator\Exception\MissingOptionsException;
*/
class Count extends Constraint
{
- const TOO_FEW_ERROR = 1;
- const TOO_MANY_ERROR = 2;
+ const TOO_FEW_ERROR = 'bef8e338-6ae5-4caf-b8e2-50e7b0579e69';
+ const TOO_MANY_ERROR = '756b1212-697c-468d-a9ad-50dd783bb169';
protected static $errorNames = array(
self::TOO_FEW_ERROR => 'TOO_FEW_ERROR',
diff --git a/src/Symfony/Component/Validator/Constraints/Country.php b/src/Symfony/Component/Validator/Constraints/Country.php
index ff6f3d0e0a..c3e91fb123 100644
--- a/src/Symfony/Component/Validator/Constraints/Country.php
+++ b/src/Symfony/Component/Validator/Constraints/Country.php
@@ -23,5 +23,11 @@ use Symfony\Component\Validator\Constraint;
*/
class Country extends Constraint
{
+ const NO_SUCH_COUNTRY_ERROR = '8f900c12-61bd-455d-9398-996cd040f7f0';
+
+ protected static $errorNames = array(
+ self::NO_SUCH_COUNTRY_ERROR => 'NO_SUCH_COUNTRY_ERROR',
+ );
+
public $message = 'This value is not a valid country.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/CountryValidator.php b/src/Symfony/Component/Validator/Constraints/CountryValidator.php
index 8139adf943..0e1d385196 100644
--- a/src/Symfony/Component/Validator/Constraints/CountryValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/CountryValidator.php
@@ -50,10 +50,12 @@ class CountryValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Country::NO_SUCH_COUNTRY_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Country::NO_SUCH_COUNTRY_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/Currency.php b/src/Symfony/Component/Validator/Constraints/Currency.php
index c09fe88bf2..9f68afa46a 100644
--- a/src/Symfony/Component/Validator/Constraints/Currency.php
+++ b/src/Symfony/Component/Validator/Constraints/Currency.php
@@ -18,10 +18,17 @@ use Symfony\Component\Validator\Constraint;
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*
* @author Miha Vrhovnik
+ * @author Bernhard Schussek
*
* @api
*/
class Currency extends Constraint
{
+ const NO_SUCH_CURRENCY_ERROR = '69945ac1-2db4-405f-bec7-d2772f73df52';
+
+ protected static $errorNames = array(
+ self::NO_SUCH_CURRENCY_ERROR => 'NO_SUCH_CURRENCY_ERROR',
+ );
+
public $message = 'This value is not a valid currency.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/CurrencyValidator.php b/src/Symfony/Component/Validator/Constraints/CurrencyValidator.php
index 9c41dc4a10..e06e911b4f 100644
--- a/src/Symfony/Component/Validator/Constraints/CurrencyValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/CurrencyValidator.php
@@ -21,6 +21,7 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
* Validates whether a value is a valid currency.
*
* @author Miha Vrhovnik
+ * @author Bernhard Schussek
*
* @api
*/
@@ -50,10 +51,12 @@ class CurrencyValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Currency::NO_SUCH_CURRENCY_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Currency::NO_SUCH_CURRENCY_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/Date.php b/src/Symfony/Component/Validator/Constraints/Date.php
index 2bc444f71a..f960ac765d 100644
--- a/src/Symfony/Component/Validator/Constraints/Date.php
+++ b/src/Symfony/Component/Validator/Constraints/Date.php
@@ -23,8 +23,8 @@ use Symfony\Component\Validator\Constraint;
*/
class Date extends Constraint
{
- const INVALID_FORMAT_ERROR = 1;
- const INVALID_DATE_ERROR = 2;
+ const INVALID_FORMAT_ERROR = '69819696-02ac-4a99-9ff0-14e127c4d1bc';
+ const INVALID_DATE_ERROR = '3c184ce5-b31d-4de7-8b76-326da7b2be93';
protected static $errorNames = array(
self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR',
diff --git a/src/Symfony/Component/Validator/Constraints/DateTime.php b/src/Symfony/Component/Validator/Constraints/DateTime.php
index ae67ff30ef..a1e9d22df7 100644
--- a/src/Symfony/Component/Validator/Constraints/DateTime.php
+++ b/src/Symfony/Component/Validator/Constraints/DateTime.php
@@ -23,9 +23,9 @@ use Symfony\Component\Validator\Constraint;
*/
class DateTime extends Constraint
{
- const INVALID_FORMAT_ERROR = 1;
- const INVALID_DATE_ERROR = 2;
- const INVALID_TIME_ERROR = 3;
+ const INVALID_FORMAT_ERROR = '1a9da513-2640-4f84-9b6a-4d99dcddc628';
+ const INVALID_DATE_ERROR = 'd52afa47-620d-4d99-9f08-f4d85b36e33c';
+ const INVALID_TIME_ERROR = '5e797c9d-74f7-4098-baa3-94390c447b27';
protected static $errorNames = array(
self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR',
diff --git a/src/Symfony/Component/Validator/Constraints/Email.php b/src/Symfony/Component/Validator/Constraints/Email.php
index 36977177bd..d1191a4313 100644
--- a/src/Symfony/Component/Validator/Constraints/Email.php
+++ b/src/Symfony/Component/Validator/Constraints/Email.php
@@ -23,9 +23,9 @@ use Symfony\Component\Validator\Constraint;
*/
class Email extends Constraint
{
- const INVALID_FORMAT_ERROR = 1;
- const MX_CHECK_FAILED_ERROR = 2;
- const HOST_CHECK_FAILED_ERROR = 3;
+ const INVALID_FORMAT_ERROR = 'bd79c0ab-ddba-46cc-a703-a7a4b08de310';
+ const MX_CHECK_FAILED_ERROR = 'bf447c1c-0266-4e10-9c6c-573df282e413';
+ const HOST_CHECK_FAILED_ERROR = '7da53a8b-56f3-4288-bb3e-ee9ede4ef9a1';
protected static $errorNames = array(
self::INVALID_FORMAT_ERROR => 'STRICT_CHECK_FAILED_ERROR',
diff --git a/src/Symfony/Component/Validator/Constraints/EmailValidator.php b/src/Symfony/Component/Validator/Constraints/EmailValidator.php
index 95f9aa123b..ab1e9ba8fb 100644
--- a/src/Symfony/Component/Validator/Constraints/EmailValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/EmailValidator.php
@@ -25,8 +25,6 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
class EmailValidator extends ConstraintValidator
{
/**
- * isStrict
- *
* @var bool
*/
private $isStrict;
@@ -81,7 +79,7 @@ class EmailValidator extends ConstraintValidator
return;
}
- } elseif (!preg_match('/.+\@.+\..+/', $value)) {
+ } elseif (!preg_match('/^.+\@\S+\.\S+$/', $value)) {
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
diff --git a/src/Symfony/Component/Validator/Constraints/EqualTo.php b/src/Symfony/Component/Validator/Constraints/EqualTo.php
index 8d3d7524dd..4b22c6dcca 100644
--- a/src/Symfony/Component/Validator/Constraints/EqualTo.php
+++ b/src/Symfony/Component/Validator/Constraints/EqualTo.php
@@ -16,8 +16,15 @@ namespace Symfony\Component\Validator\Constraints;
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class EqualTo extends AbstractComparison
{
+ const NOT_EQUAL_ERROR = '478618a7-95ba-473d-9101-cabd45e49115';
+
+ protected static $errorNames = array(
+ self::NOT_EQUAL_ERROR => 'NOT_EQUAL_ERROR',
+ );
+
public $message = 'This value should be equal to {{ compared_value }}.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/EqualToValidator.php b/src/Symfony/Component/Validator/Constraints/EqualToValidator.php
index 3739dbebfe..fe1f3620ff 100644
--- a/src/Symfony/Component/Validator/Constraints/EqualToValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/EqualToValidator.php
@@ -15,6 +15,7 @@ namespace Symfony\Component\Validator\Constraints;
* Validates values are equal (==).
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class EqualToValidator extends AbstractComparisonValidator
{
@@ -25,4 +26,12 @@ class EqualToValidator extends AbstractComparisonValidator
{
return $value1 == $value2;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getErrorCode()
+ {
+ return EqualTo::NOT_EQUAL_ERROR;
+ }
}
diff --git a/src/Symfony/Component/Validator/Constraints/Expression.php b/src/Symfony/Component/Validator/Constraints/Expression.php
index dfa242c31a..3329bd2494 100644
--- a/src/Symfony/Component/Validator/Constraints/Expression.php
+++ b/src/Symfony/Component/Validator/Constraints/Expression.php
@@ -22,6 +22,12 @@ use Symfony\Component\Validator\Constraint;
*/
class Expression extends Constraint
{
+ const EXPRESSION_FAILED_ERROR = '6b3befbc-2f01-4ddf-be21-b57898905284';
+
+ protected static $errorNames = array(
+ self::EXPRESSION_FAILED_ERROR => 'EXPRESSION_FAILED_ERROR',
+ );
+
public $message = 'This value is not valid.';
public $expression;
diff --git a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php
index 15d51f9ff1..031bf420ce 100644
--- a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php
@@ -88,10 +88,12 @@ class ExpressionValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Expression::EXPRESSION_FAILED_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Expression::EXPRESSION_FAILED_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/File.php b/src/Symfony/Component/Validator/Constraints/File.php
index ae0ad67395..ce0c102842 100644
--- a/src/Symfony/Component/Validator/Constraints/File.php
+++ b/src/Symfony/Component/Validator/Constraints/File.php
@@ -26,11 +26,11 @@ class File extends Constraint
{
// Check the Image constraint for clashes if adding new constants here
- const NOT_FOUND_ERROR = 1;
- const NOT_READABLE_ERROR = 2;
- const EMPTY_ERROR = 3;
- const TOO_LARGE_ERROR = 4;
- const INVALID_MIME_TYPE_ERROR = 5;
+ const NOT_FOUND_ERROR = 'd2a3fb6e-7ddc-4210-8fbf-2ab345ce1998';
+ const NOT_READABLE_ERROR = 'c20c92a4-5bfa-4202-9477-28e800e0f6ff';
+ const EMPTY_ERROR = '5d743385-9775-4aa5-8ff5-495fb1e60137';
+ const TOO_LARGE_ERROR = 'df8637af-d466-48c6-a59d-e7126250a654';
+ const INVALID_MIME_TYPE_ERROR = '744f00bc-4389-4c74-92de-9a43cde55534';
protected static $errorNames = array(
self::NOT_FOUND_ERROR => 'NOT_FOUND_ERROR',
diff --git a/src/Symfony/Component/Validator/Constraints/GreaterThan.php b/src/Symfony/Component/Validator/Constraints/GreaterThan.php
index ec7fafb3a4..c2ca2dcb82 100644
--- a/src/Symfony/Component/Validator/Constraints/GreaterThan.php
+++ b/src/Symfony/Component/Validator/Constraints/GreaterThan.php
@@ -16,8 +16,15 @@ namespace Symfony\Component\Validator\Constraints;
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class GreaterThan extends AbstractComparison
{
+ const TOO_LOW_ERROR = '778b7ae0-84d3-481a-9dec-35fdb64b1d78';
+
+ protected static $errorNames = array(
+ self::TOO_LOW_ERROR => 'TOO_LOW_ERROR',
+ );
+
public $message = 'This value should be greater than {{ compared_value }}.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/GreaterThanOrEqual.php b/src/Symfony/Component/Validator/Constraints/GreaterThanOrEqual.php
index 36fdd9c097..9b3743d073 100644
--- a/src/Symfony/Component/Validator/Constraints/GreaterThanOrEqual.php
+++ b/src/Symfony/Component/Validator/Constraints/GreaterThanOrEqual.php
@@ -16,8 +16,15 @@ namespace Symfony\Component\Validator\Constraints;
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class GreaterThanOrEqual extends AbstractComparison
{
+ const TOO_LOW_ERROR = 'ea4e51d1-3342-48bd-87f1-9e672cd90cad';
+
+ protected static $errorNames = array(
+ self::TOO_LOW_ERROR => 'TOO_LOW_ERROR',
+ );
+
public $message = 'This value should be greater than or equal to {{ compared_value }}.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/GreaterThanOrEqualValidator.php b/src/Symfony/Component/Validator/Constraints/GreaterThanOrEqualValidator.php
index 2363204174..e196e688f3 100644
--- a/src/Symfony/Component/Validator/Constraints/GreaterThanOrEqualValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/GreaterThanOrEqualValidator.php
@@ -15,6 +15,7 @@ namespace Symfony\Component\Validator\Constraints;
* Validates values are greater than or equal to the previous (>=).
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class GreaterThanOrEqualValidator extends AbstractComparisonValidator
{
@@ -25,4 +26,12 @@ class GreaterThanOrEqualValidator extends AbstractComparisonValidator
{
return $value1 >= $value2;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getErrorCode()
+ {
+ return GreaterThanOrEqual::TOO_LOW_ERROR;
+ }
}
diff --git a/src/Symfony/Component/Validator/Constraints/GreaterThanValidator.php b/src/Symfony/Component/Validator/Constraints/GreaterThanValidator.php
index fdcf0c1f94..9029e8fc46 100644
--- a/src/Symfony/Component/Validator/Constraints/GreaterThanValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/GreaterThanValidator.php
@@ -15,6 +15,7 @@ namespace Symfony\Component\Validator\Constraints;
* Validates values are greater than the previous (>).
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class GreaterThanValidator extends AbstractComparisonValidator
{
@@ -25,4 +26,12 @@ class GreaterThanValidator extends AbstractComparisonValidator
{
return $value1 > $value2;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getErrorCode()
+ {
+ return GreaterThan::TOO_LOW_ERROR;
+ }
}
diff --git a/src/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php b/src/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php
index 3904473412..8a3fe6300f 100644
--- a/src/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php
+++ b/src/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php
@@ -16,6 +16,8 @@ namespace Symfony\Component\Validator\Constraints;
*
* @Annotation
* @Target({"CLASS", "ANNOTATION"})
+ *
+ * @author Bernhard Schussek
*/
class GroupSequenceProvider
{
diff --git a/src/Symfony/Component/Validator/Constraints/Iban.php b/src/Symfony/Component/Validator/Constraints/Iban.php
index 66ce09ae1a..a0d6b0982d 100644
--- a/src/Symfony/Component/Validator/Constraints/Iban.php
+++ b/src/Symfony/Component/Validator/Constraints/Iban.php
@@ -23,11 +23,11 @@ use Symfony\Component\Validator\Constraint;
*/
class Iban extends Constraint
{
- const TOO_SHORT_ERROR = 1;
- const INVALID_COUNTRY_CODE_ERROR = 2;
- const INVALID_CHARACTERS_ERROR = 3;
- const INVALID_CASE_ERROR = 4;
- const CHECKSUM_FAILED_ERROR = 5;
+ const TOO_SHORT_ERROR = '88e5e319-0aeb-4979-a27e-3d9ce0c16166';
+ const INVALID_COUNTRY_CODE_ERROR = 'de78ee2c-bd50-44e2-aec8-3d8228aeadb9';
+ const INVALID_CHARACTERS_ERROR = '8d3d85e4-784f-4719-a5bc-d9e40d45a3a5';
+ const INVALID_CASE_ERROR = 'f4bf62fe-03ec-42af-a53b-68e21b1e7274';
+ const CHECKSUM_FAILED_ERROR = 'b9401321-f9bf-4dcb-83c1-f31094440795';
protected static $errorNames = array(
self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR',
diff --git a/src/Symfony/Component/Validator/Constraints/IdenticalTo.php b/src/Symfony/Component/Validator/Constraints/IdenticalTo.php
index 6d00286d23..a7dadff833 100644
--- a/src/Symfony/Component/Validator/Constraints/IdenticalTo.php
+++ b/src/Symfony/Component/Validator/Constraints/IdenticalTo.php
@@ -16,8 +16,15 @@ namespace Symfony\Component\Validator\Constraints;
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class IdenticalTo extends AbstractComparison
{
+ const NOT_IDENTICAL_ERROR = '2a8cc50f-58a2-4536-875e-060a2ce69ed5';
+
+ protected static $errorNames = array(
+ self::NOT_IDENTICAL_ERROR => 'NOT_IDENTICAL_ERROR',
+ );
+
public $message = 'This value should be identical to {{ compared_value_type }} {{ compared_value }}.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/IdenticalToValidator.php b/src/Symfony/Component/Validator/Constraints/IdenticalToValidator.php
index a1867262aa..304f71f191 100644
--- a/src/Symfony/Component/Validator/Constraints/IdenticalToValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/IdenticalToValidator.php
@@ -15,6 +15,7 @@ namespace Symfony\Component\Validator\Constraints;
* Validates values are identical (===).
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class IdenticalToValidator extends AbstractComparisonValidator
{
@@ -25,4 +26,12 @@ class IdenticalToValidator extends AbstractComparisonValidator
{
return $value1 === $value2;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getErrorCode()
+ {
+ return IdenticalTo::NOT_IDENTICAL_ERROR;
+ }
}
diff --git a/src/Symfony/Component/Validator/Constraints/Image.php b/src/Symfony/Component/Validator/Constraints/Image.php
index 904ef97b49..6d9d2c5046 100644
--- a/src/Symfony/Component/Validator/Constraints/Image.php
+++ b/src/Symfony/Component/Validator/Constraints/Image.php
@@ -22,18 +22,16 @@ namespace Symfony\Component\Validator\Constraints;
*/
class Image extends File
{
- // Don't reuse values used in File
-
- const SIZE_NOT_DETECTED_ERROR = 10;
- const TOO_WIDE_ERROR = 11;
- const TOO_NARROW_ERROR = 12;
- const TOO_HIGH_ERROR = 13;
- const TOO_LOW_ERROR = 14;
- const RATIO_TOO_BIG_ERROR = 15;
- const RATIO_TOO_SMALL_ERROR = 16;
- const SQUARE_NOT_ALLOWED_ERROR = 17;
- const LANDSCAPE_NOT_ALLOWED_ERROR = 18;
- const PORTRAIT_NOT_ALLOWED_ERROR = 19;
+ const SIZE_NOT_DETECTED_ERROR = '6d55c3f4-e58e-4fe3-91ee-74b492199956';
+ const TOO_WIDE_ERROR = '7f87163d-878f-47f5-99ba-a8eb723a1ab2';
+ const TOO_NARROW_ERROR = '9afbd561-4f90-4a27-be62-1780fc43604a';
+ const TOO_HIGH_ERROR = '7efae81c-4877-47ba-aa65-d01ccb0d4645';
+ const TOO_LOW_ERROR = 'aef0cb6a-c07f-4894-bc08-1781420d7b4c';
+ const RATIO_TOO_BIG_ERROR = '70cafca6-168f-41c9-8c8c-4e47a52be643';
+ const RATIO_TOO_SMALL_ERROR = '59b8c6ef-bcf2-4ceb-afff-4642ed92f12e';
+ const SQUARE_NOT_ALLOWED_ERROR = '5d41425b-facb-47f7-a55a-de9fbe45cb46';
+ const LANDSCAPE_NOT_ALLOWED_ERROR = '6f895685-7cf2-4d65-b3da-9029c5581d88';
+ const PORTRAIT_NOT_ALLOWED_ERROR = '65608156-77da-4c79-a88c-02ef6d18c782';
// Include the mapping from the base class
diff --git a/src/Symfony/Component/Validator/Constraints/Ip.php b/src/Symfony/Component/Validator/Constraints/Ip.php
index 27f0b2d0fd..2633f46732 100644
--- a/src/Symfony/Component/Validator/Constraints/Ip.php
+++ b/src/Symfony/Component/Validator/Constraints/Ip.php
@@ -46,6 +46,8 @@ class Ip extends Constraint
const V6_ONLY_PUBLIC = '6_public';
const ALL_ONLY_PUBLIC = 'all_public';
+ const INVALID_IP_ERROR = 'b1b427ae-9f6f-41b0-aa9b-84511fbb3c5b';
+
protected static $versions = array(
self::V4,
self::V6,
@@ -64,6 +66,10 @@ class Ip extends Constraint
self::ALL_ONLY_PUBLIC,
);
+ protected static $errorNames = array(
+ self::INVALID_IP_ERROR => 'INVALID_IP_ERROR',
+ );
+
public $version = self::V4;
public $message = 'This is not a valid IP address.';
diff --git a/src/Symfony/Component/Validator/Constraints/IpValidator.php b/src/Symfony/Component/Validator/Constraints/IpValidator.php
index 8ec8068e79..7815510f08 100644
--- a/src/Symfony/Component/Validator/Constraints/IpValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/IpValidator.php
@@ -99,10 +99,12 @@ class IpValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Ip::INVALID_IP_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Ip::INVALID_IP_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/IsFalse.php b/src/Symfony/Component/Validator/Constraints/IsFalse.php
index 7b1b72bd51..945f3a2cde 100644
--- a/src/Symfony/Component/Validator/Constraints/IsFalse.php
+++ b/src/Symfony/Component/Validator/Constraints/IsFalse.php
@@ -23,5 +23,11 @@ use Symfony\Component\Validator\Constraint;
*/
class IsFalse extends Constraint
{
+ const NOT_FALSE_ERROR = 'd53a91b0-def3-426a-83d7-269da7ab4200';
+
+ protected static $errorNames = array(
+ self::NOT_FALSE_ERROR => 'NOT_FALSE_ERROR',
+ );
+
public $message = 'This value should be false.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/IsFalseValidator.php b/src/Symfony/Component/Validator/Constraints/IsFalseValidator.php
index f5215588f2..7e330e4dd7 100644
--- a/src/Symfony/Component/Validator/Constraints/IsFalseValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/IsFalseValidator.php
@@ -39,10 +39,12 @@ class IsFalseValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(IsFalse::NOT_FALSE_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(IsFalse::NOT_FALSE_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/IsNull.php b/src/Symfony/Component/Validator/Constraints/IsNull.php
index 3e7fef112c..ea0b0febba 100644
--- a/src/Symfony/Component/Validator/Constraints/IsNull.php
+++ b/src/Symfony/Component/Validator/Constraints/IsNull.php
@@ -23,5 +23,11 @@ use Symfony\Component\Validator\Constraint;
*/
class IsNull extends Constraint
{
+ const NOT_NULL_ERROR = '60d2f30b-8cfa-4372-b155-9656634de120';
+
+ protected static $errorNames = array(
+ self::NOT_NULL_ERROR => 'NOT_NULL_ERROR',
+ );
+
public $message = 'This value should be null.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/IsNullValidator.php b/src/Symfony/Component/Validator/Constraints/IsNullValidator.php
index 162f6182ff..4a7ada8387 100644
--- a/src/Symfony/Component/Validator/Constraints/IsNullValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/IsNullValidator.php
@@ -36,10 +36,12 @@ class IsNullValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(IsNull::NOT_NULL_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(IsNull::NOT_NULL_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/IsTrue.php b/src/Symfony/Component/Validator/Constraints/IsTrue.php
index c0be6b8272..37049ebb3f 100644
--- a/src/Symfony/Component/Validator/Constraints/IsTrue.php
+++ b/src/Symfony/Component/Validator/Constraints/IsTrue.php
@@ -23,5 +23,11 @@ use Symfony\Component\Validator\Constraint;
*/
class IsTrue extends Constraint
{
+ const NOT_TRUE_ERROR = '2beabf1c-54c0-4882-a928-05249b26e23b';
+
+ protected static $errorNames = array(
+ self::NOT_TRUE_ERROR => 'NOT_TRUE_ERROR',
+ );
+
public $message = 'This value should be true.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/IsTrueValidator.php b/src/Symfony/Component/Validator/Constraints/IsTrueValidator.php
index 206c63d9a7..fc044ca59c 100644
--- a/src/Symfony/Component/Validator/Constraints/IsTrueValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/IsTrueValidator.php
@@ -40,10 +40,12 @@ class IsTrueValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(IsTrue::NOT_TRUE_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(IsTrue::NOT_TRUE_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/Isbn.php b/src/Symfony/Component/Validator/Constraints/Isbn.php
index 35cb82204e..3c4251b39e 100644
--- a/src/Symfony/Component/Validator/Constraints/Isbn.php
+++ b/src/Symfony/Component/Validator/Constraints/Isbn.php
@@ -23,11 +23,11 @@ use Symfony\Component\Validator\Constraint;
*/
class Isbn extends Constraint
{
- const TOO_SHORT_ERROR = 1;
- const TOO_LONG_ERROR = 2;
- const INVALID_CHARACTERS_ERROR = 3;
- const CHECKSUM_FAILED_ERROR = 4;
- const TYPE_NOT_RECOGNIZED_ERROR = 5;
+ const TOO_SHORT_ERROR = '949acbb0-8ef5-43ed-a0e9-032dfd08ae45';
+ const TOO_LONG_ERROR = '3171387d-f80a-47b3-bd6e-60598545316a';
+ const INVALID_CHARACTERS_ERROR = '23d21cea-da99-453d-98b1-a7d916fbb339';
+ const CHECKSUM_FAILED_ERROR = '2881c032-660f-46b6-8153-d352d9706640';
+ const TYPE_NOT_RECOGNIZED_ERROR = 'fa54a457-f042-441f-89c4-066ee5bdd3e1';
protected static $errorNames = array(
self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR',
diff --git a/src/Symfony/Component/Validator/Constraints/Issn.php b/src/Symfony/Component/Validator/Constraints/Issn.php
index 39716a28cc..a2fecdd35c 100644
--- a/src/Symfony/Component/Validator/Constraints/Issn.php
+++ b/src/Symfony/Component/Validator/Constraints/Issn.php
@@ -22,12 +22,12 @@ use Symfony\Component\Validator\Constraint;
*/
class Issn extends Constraint
{
- const TOO_SHORT_ERROR = 1;
- const TOO_LONG_ERROR = 2;
- const MISSING_HYPHEN_ERROR = 3;
- const INVALID_CHARACTERS_ERROR = 4;
- const INVALID_CASE_ERROR = 5;
- const CHECKSUM_FAILED_ERROR = 6;
+ const TOO_SHORT_ERROR = '6a20dd3d-f463-4460-8e7b-18a1b98abbfb';
+ const TOO_LONG_ERROR = '37cef893-5871-464e-8b12-7fb79324833c';
+ const MISSING_HYPHEN_ERROR = '2983286f-8134-4693-957a-1ec4ef887b15';
+ const INVALID_CHARACTERS_ERROR = 'a663d266-37c2-4ece-a914-ae891940c588';
+ const INVALID_CASE_ERROR = '7b6dd393-7523-4a6c-b84d-72b91bba5e1a';
+ const CHECKSUM_FAILED_ERROR = 'b0f92dbc-667c-48de-b526-ad9586d43e85';
protected static $errorNames = array(
self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR',
diff --git a/src/Symfony/Component/Validator/Constraints/Language.php b/src/Symfony/Component/Validator/Constraints/Language.php
index e7c29dc64b..190885ce86 100644
--- a/src/Symfony/Component/Validator/Constraints/Language.php
+++ b/src/Symfony/Component/Validator/Constraints/Language.php
@@ -23,5 +23,11 @@ use Symfony\Component\Validator\Constraint;
*/
class Language extends Constraint
{
+ const NO_SUCH_LANGUAGE_ERROR = 'ee65fec4-9a20-4202-9f39-ca558cd7bdf7';
+
+ protected static $errorNames = array(
+ self::NO_SUCH_LANGUAGE_ERROR => 'NO_SUCH_LANGUAGE_ERROR',
+ );
+
public $message = 'This value is not a valid language.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/LanguageValidator.php b/src/Symfony/Component/Validator/Constraints/LanguageValidator.php
index cc8581f819..a0f89bbbee 100644
--- a/src/Symfony/Component/Validator/Constraints/LanguageValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/LanguageValidator.php
@@ -50,10 +50,12 @@ class LanguageValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Language::NO_SUCH_LANGUAGE_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Language::NO_SUCH_LANGUAGE_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/Length.php b/src/Symfony/Component/Validator/Constraints/Length.php
index 8d004805cb..356dea0db3 100644
--- a/src/Symfony/Component/Validator/Constraints/Length.php
+++ b/src/Symfony/Component/Validator/Constraints/Length.php
@@ -24,12 +24,14 @@ use Symfony\Component\Validator\Exception\MissingOptionsException;
*/
class Length extends Constraint
{
- const TOO_SHORT_ERROR = 1;
- const TOO_LONG_ERROR = 2;
+ const TOO_SHORT_ERROR = '9ff3fdc4-b214-49db-8718-39c315e33d45';
+ const TOO_LONG_ERROR = 'd94b19cc-114f-4f44-9cc4-4138e80a87b9';
+ const INVALID_CHARACTERS_ERROR = '35e6a710-aa2e-4719-b58e-24b35749b767';
protected static $errorNames = array(
self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR',
self::TOO_LONG_ERROR => 'TOO_LONG_ERROR',
+ self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR',
);
public $maxMessage = 'This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less.';
diff --git a/src/Symfony/Component/Validator/Constraints/LengthValidator.php b/src/Symfony/Component/Validator/Constraints/LengthValidator.php
index bfa7b19f34..9597f3869a 100644
--- a/src/Symfony/Component/Validator/Constraints/LengthValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/LengthValidator.php
@@ -70,12 +70,14 @@ class LengthValidator extends ConstraintValidator
->setParameter('{{ value }}', $this->formatValue($stringValue))
->setParameter('{{ charset }}', $constraint->charset)
->setInvalidValue($value)
+ ->setCode(Length::INVALID_CHARACTERS_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->charsetMessage)
->setParameter('{{ value }}', $this->formatValue($stringValue))
->setParameter('{{ charset }}', $constraint->charset)
->setInvalidValue($value)
+ ->setCode(Length::INVALID_CHARACTERS_ERROR)
->addViolation();
}
diff --git a/src/Symfony/Component/Validator/Constraints/LessThan.php b/src/Symfony/Component/Validator/Constraints/LessThan.php
index b116320037..1bbb50878b 100644
--- a/src/Symfony/Component/Validator/Constraints/LessThan.php
+++ b/src/Symfony/Component/Validator/Constraints/LessThan.php
@@ -16,8 +16,15 @@ namespace Symfony\Component\Validator\Constraints;
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class LessThan extends AbstractComparison
{
+ const TOO_HIGH_ERROR = '079d7420-2d13-460c-8756-de810eeb37d2';
+
+ protected static $errorNames = array(
+ self::TOO_HIGH_ERROR => 'TOO_HIGH_ERROR',
+ );
+
public $message = 'This value should be less than {{ compared_value }}.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/LessThanOrEqual.php b/src/Symfony/Component/Validator/Constraints/LessThanOrEqual.php
index 7faca84221..d118942385 100644
--- a/src/Symfony/Component/Validator/Constraints/LessThanOrEqual.php
+++ b/src/Symfony/Component/Validator/Constraints/LessThanOrEqual.php
@@ -16,8 +16,15 @@ namespace Symfony\Component\Validator\Constraints;
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class LessThanOrEqual extends AbstractComparison
{
+ const TOO_HIGH_ERROR = '079d7420-2d13-460c-8756-de810eeb37d2';
+
+ protected static $errorNames = array(
+ self::TOO_HIGH_ERROR => 'TOO_HIGH_ERROR',
+ );
+
public $message = 'This value should be less than or equal to {{ compared_value }}.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/LessThanOrEqualValidator.php b/src/Symfony/Component/Validator/Constraints/LessThanOrEqualValidator.php
index dcc93b2503..54281eef5a 100644
--- a/src/Symfony/Component/Validator/Constraints/LessThanOrEqualValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/LessThanOrEqualValidator.php
@@ -15,6 +15,7 @@ namespace Symfony\Component\Validator\Constraints;
* Validates values are less than or equal to the previous (<=).
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class LessThanOrEqualValidator extends AbstractComparisonValidator
{
@@ -25,4 +26,12 @@ class LessThanOrEqualValidator extends AbstractComparisonValidator
{
return $value1 <= $value2;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getErrorCode()
+ {
+ return LessThanOrEqual::TOO_HIGH_ERROR;
+ }
}
diff --git a/src/Symfony/Component/Validator/Constraints/LessThanValidator.php b/src/Symfony/Component/Validator/Constraints/LessThanValidator.php
index 081316a588..ef7535fc99 100644
--- a/src/Symfony/Component/Validator/Constraints/LessThanValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/LessThanValidator.php
@@ -15,6 +15,7 @@ namespace Symfony\Component\Validator\Constraints;
* Validates values are less than the previous (<).
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class LessThanValidator extends AbstractComparisonValidator
{
@@ -25,4 +26,12 @@ class LessThanValidator extends AbstractComparisonValidator
{
return $value1 < $value2;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getErrorCode()
+ {
+ return LessThan::TOO_HIGH_ERROR;
+ }
}
diff --git a/src/Symfony/Component/Validator/Constraints/Locale.php b/src/Symfony/Component/Validator/Constraints/Locale.php
index 12a55464a6..bb85be246a 100644
--- a/src/Symfony/Component/Validator/Constraints/Locale.php
+++ b/src/Symfony/Component/Validator/Constraints/Locale.php
@@ -23,5 +23,11 @@ use Symfony\Component\Validator\Constraint;
*/
class Locale extends Constraint
{
+ const NO_SUCH_LOCALE_ERROR = 'a0af4293-1f1a-4a1c-a328-979cba6182a2';
+
+ protected static $errorNames = array(
+ self::NO_SUCH_LOCALE_ERROR => 'NO_SUCH_LOCALE_ERROR',
+ );
+
public $message = 'This value is not a valid locale.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/LocaleValidator.php b/src/Symfony/Component/Validator/Constraints/LocaleValidator.php
index a5f69271e6..daf404c141 100644
--- a/src/Symfony/Component/Validator/Constraints/LocaleValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/LocaleValidator.php
@@ -50,10 +50,12 @@ class LocaleValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Locale::NO_SUCH_LOCALE_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Locale::NO_SUCH_LOCALE_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/Luhn.php b/src/Symfony/Component/Validator/Constraints/Luhn.php
index 24f5bc77ab..67f152d29d 100644
--- a/src/Symfony/Component/Validator/Constraints/Luhn.php
+++ b/src/Symfony/Component/Validator/Constraints/Luhn.php
@@ -25,8 +25,8 @@ use Symfony\Component\Validator\Constraint;
*/
class Luhn extends Constraint
{
- const INVALID_CHARACTERS_ERROR = 1;
- const CHECKSUM_FAILED_ERROR = 2;
+ const INVALID_CHARACTERS_ERROR = 'dfad6d23-1b74-4374-929b-5cbb56fc0d9e';
+ const CHECKSUM_FAILED_ERROR = '4d760774-3f50-4cd5-a6d5-b10a3299d8d3';
protected static $errorNames = array(
self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR',
diff --git a/src/Symfony/Component/Validator/Constraints/NotBlank.php b/src/Symfony/Component/Validator/Constraints/NotBlank.php
index c578c6d81f..f7242ce0d1 100644
--- a/src/Symfony/Component/Validator/Constraints/NotBlank.php
+++ b/src/Symfony/Component/Validator/Constraints/NotBlank.php
@@ -23,5 +23,11 @@ use Symfony\Component\Validator\Constraint;
*/
class NotBlank extends Constraint
{
+ const IS_BLANK_ERROR = 'c1051bb4-d103-4f74-8988-acbcafc7fdc3';
+
+ protected static $errorNames = array(
+ self::IS_BLANK_ERROR => 'IS_BLANK_ERROR',
+ );
+
public $message = 'This value should not be blank.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/NotBlankValidator.php b/src/Symfony/Component/Validator/Constraints/NotBlankValidator.php
index a435701cf2..3714d7930e 100644
--- a/src/Symfony/Component/Validator/Constraints/NotBlankValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/NotBlankValidator.php
@@ -36,10 +36,12 @@ class NotBlankValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(NotBlank::IS_BLANK_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(NotBlank::IS_BLANK_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/NotEqualTo.php b/src/Symfony/Component/Validator/Constraints/NotEqualTo.php
index abd80920fb..8c5abddaee 100644
--- a/src/Symfony/Component/Validator/Constraints/NotEqualTo.php
+++ b/src/Symfony/Component/Validator/Constraints/NotEqualTo.php
@@ -16,8 +16,15 @@ namespace Symfony\Component\Validator\Constraints;
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class NotEqualTo extends AbstractComparison
{
+ const IS_EQUAL_ERROR = 'aa2e33da-25c8-4d76-8c6c-812f02ea89dd';
+
+ protected static $errorNames = array(
+ self::IS_EQUAL_ERROR => 'IS_EQUAL_ERROR',
+ );
+
public $message = 'This value should not be equal to {{ compared_value }}.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/NotEqualToValidator.php b/src/Symfony/Component/Validator/Constraints/NotEqualToValidator.php
index 5710a85b93..b80c5eaeda 100644
--- a/src/Symfony/Component/Validator/Constraints/NotEqualToValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/NotEqualToValidator.php
@@ -15,6 +15,7 @@ namespace Symfony\Component\Validator\Constraints;
* Validates values are all unequal (!=).
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class NotEqualToValidator extends AbstractComparisonValidator
{
@@ -25,4 +26,12 @@ class NotEqualToValidator extends AbstractComparisonValidator
{
return $value1 != $value2;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getErrorCode()
+ {
+ return NotEqualTo::IS_EQUAL_ERROR;
+ }
}
diff --git a/src/Symfony/Component/Validator/Constraints/NotIdenticalTo.php b/src/Symfony/Component/Validator/Constraints/NotIdenticalTo.php
index fb4ef3f3c1..4c9c63ea61 100644
--- a/src/Symfony/Component/Validator/Constraints/NotIdenticalTo.php
+++ b/src/Symfony/Component/Validator/Constraints/NotIdenticalTo.php
@@ -16,8 +16,15 @@ namespace Symfony\Component\Validator\Constraints;
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class NotIdenticalTo extends AbstractComparison
{
+ const IS_IDENTICAL_ERROR = '4aaac518-0dda-4129-a6d9-e216b9b454a0';
+
+ protected static $errorNames = array(
+ self::IS_IDENTICAL_ERROR => 'IS_IDENTICAL_ERROR',
+ );
+
public $message = 'This value should not be identical to {{ compared_value_type }} {{ compared_value }}.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/NotIdenticalToValidator.php b/src/Symfony/Component/Validator/Constraints/NotIdenticalToValidator.php
index ed8dc1c0dd..3ea8b5ac25 100644
--- a/src/Symfony/Component/Validator/Constraints/NotIdenticalToValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/NotIdenticalToValidator.php
@@ -15,6 +15,7 @@ namespace Symfony\Component\Validator\Constraints;
* Validates values aren't identical (!==).
*
* @author Daniel Holmes
+ * @author Bernhard Schussek
*/
class NotIdenticalToValidator extends AbstractComparisonValidator
{
@@ -25,4 +26,12 @@ class NotIdenticalToValidator extends AbstractComparisonValidator
{
return $value1 !== $value2;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getErrorCode()
+ {
+ return NotIdenticalTo::IS_IDENTICAL_ERROR;
+ }
}
diff --git a/src/Symfony/Component/Validator/Constraints/NotNull.php b/src/Symfony/Component/Validator/Constraints/NotNull.php
index 60416c76ec..1701bf7bdc 100644
--- a/src/Symfony/Component/Validator/Constraints/NotNull.php
+++ b/src/Symfony/Component/Validator/Constraints/NotNull.php
@@ -23,5 +23,11 @@ use Symfony\Component\Validator\Constraint;
*/
class NotNull extends Constraint
{
+ const IS_NULL_ERROR = 'ad32d13f-c3d4-423b-909a-857b961eb720';
+
+ protected static $errorNames = array(
+ self::IS_NULL_ERROR => 'IS_NULL_ERROR',
+ );
+
public $message = 'This value should not be null.';
}
diff --git a/src/Symfony/Component/Validator/Constraints/NotNullValidator.php b/src/Symfony/Component/Validator/Constraints/NotNullValidator.php
index a7a905ae14..e43b7a4c5e 100644
--- a/src/Symfony/Component/Validator/Constraints/NotNullValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/NotNullValidator.php
@@ -13,6 +13,7 @@ namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
/**
@@ -32,7 +33,17 @@ class NotNullValidator extends ConstraintValidator
}
if (null === $value) {
- $this->context->addViolation($constraint->message);
+ if ($this->context instanceof ExecutionContextInterface) {
+ $this->context->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(NotNull::IS_NULL_ERROR)
+ ->addViolation();
+ } else {
+ $this->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(NotNull::IS_NULL_ERROR)
+ ->addViolation();
+ }
}
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/Range.php b/src/Symfony/Component/Validator/Constraints/Range.php
index a12afffbed..26d2546cc2 100644
--- a/src/Symfony/Component/Validator/Constraints/Range.php
+++ b/src/Symfony/Component/Validator/Constraints/Range.php
@@ -24,14 +24,32 @@ use Symfony\Component\Validator\Exception\MissingOptionsException;
*/
class Range extends Constraint
{
- const INVALID_VALUE_ERROR = 1;
- const BEYOND_RANGE_ERROR = 2;
- const BELOW_RANGE_ERROR = 3;
+ const INVALID_CHARACTERS_ERROR = 'ad9a9798-7a99-4df7-8ce9-46e416a1e60b';
+ const TOO_HIGH_ERROR = '2d28afcb-e32e-45fb-a815-01c431a86a69';
+ const TOO_LOW_ERROR = '76454e69-502c-46c5-9643-f447d837c4d5';
+
+ /**
+ * @deprecated Deprecated since version 2.8, to be removed in 3.0. Use
+ * {@link INVALID_CHARACTERS_ERROR} instead.
+ */
+ const INVALID_VALUE_ERROR = self::INVALID_CHARACTERS_ERROR;
+
+ /**
+ * @deprecated Deprecated since version 2.8, to be removed in 3.0. Use
+ * {@link TOO_HIGH_ERROR} instead.
+ */
+ const BEYOND_RANGE_ERROR = self::TOO_HIGH_ERROR;
+
+ /**
+ * @deprecated Deprecated since version 2.8, to be removed in 3.0. Use
+ * {@link TOO_LOW_ERROR} instead.
+ */
+ const BELOW_RANGE_ERROR = self::TOO_LOW_ERROR;
protected static $errorNames = array(
- self::INVALID_VALUE_ERROR => 'INVALID_VALUE_ERROR',
- self::BEYOND_RANGE_ERROR => 'BEYOND_RANGE_ERROR',
- self::BELOW_RANGE_ERROR => 'BELOW_RANGE_ERROR',
+ self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR',
+ self::TOO_HIGH_ERROR => 'TOO_HIGH_ERROR',
+ self::TOO_LOW_ERROR => 'TOO_LOW_ERROR',
);
public $minMessage = 'This value should be {{ limit }} or more.';
diff --git a/src/Symfony/Component/Validator/Constraints/RangeValidator.php b/src/Symfony/Component/Validator/Constraints/RangeValidator.php
index 8f5fddac2a..05ef3b47c7 100644
--- a/src/Symfony/Component/Validator/Constraints/RangeValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/RangeValidator.php
@@ -38,12 +38,12 @@ class RangeValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->invalidMessage)
->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE))
- ->setCode(Range::INVALID_VALUE_ERROR)
+ ->setCode(Range::INVALID_CHARACTERS_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->invalidMessage)
->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE))
- ->setCode(Range::INVALID_VALUE_ERROR)
+ ->setCode(Range::INVALID_CHARACTERS_ERROR)
->addViolation();
}
@@ -72,13 +72,13 @@ class RangeValidator extends ConstraintValidator
$this->context->buildViolation($constraint->maxMessage)
->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE))
->setParameter('{{ limit }}', $this->formatValue($max, self::PRETTY_DATE))
- ->setCode(Range::BEYOND_RANGE_ERROR)
+ ->setCode(Range::TOO_HIGH_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->maxMessage)
->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE))
->setParameter('{{ limit }}', $this->formatValue($max, self::PRETTY_DATE))
- ->setCode(Range::BEYOND_RANGE_ERROR)
+ ->setCode(Range::TOO_HIGH_ERROR)
->addViolation();
}
@@ -90,13 +90,13 @@ class RangeValidator extends ConstraintValidator
$this->context->buildViolation($constraint->minMessage)
->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE))
->setParameter('{{ limit }}', $this->formatValue($min, self::PRETTY_DATE))
- ->setCode(Range::BELOW_RANGE_ERROR)
+ ->setCode(Range::TOO_LOW_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->minMessage)
->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE))
->setParameter('{{ limit }}', $this->formatValue($min, self::PRETTY_DATE))
- ->setCode(Range::BELOW_RANGE_ERROR)
+ ->setCode(Range::TOO_LOW_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/Regex.php b/src/Symfony/Component/Validator/Constraints/Regex.php
index 3cdf5146fd..e0a11b5c08 100644
--- a/src/Symfony/Component/Validator/Constraints/Regex.php
+++ b/src/Symfony/Component/Validator/Constraints/Regex.php
@@ -23,6 +23,12 @@ use Symfony\Component\Validator\Constraint;
*/
class Regex extends Constraint
{
+ const REGEX_FAILED_ERROR = 'de1e3db3-5ed4-4941-aae4-59f3667cc3a3';
+
+ protected static $errorNames = array(
+ self::REGEX_FAILED_ERROR => 'REGEX_FAILED_ERROR',
+ );
+
public $message = 'This value is not valid.';
public $pattern;
public $htmlPattern;
diff --git a/src/Symfony/Component/Validator/Constraints/RegexValidator.php b/src/Symfony/Component/Validator/Constraints/RegexValidator.php
index 45ba9793ef..1edbde1923 100644
--- a/src/Symfony/Component/Validator/Constraints/RegexValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/RegexValidator.php
@@ -49,10 +49,12 @@ class RegexValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Regex::REGEX_FAILED_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Regex::REGEX_FAILED_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/Time.php b/src/Symfony/Component/Validator/Constraints/Time.php
index 7998c6f951..e65ebc00d4 100644
--- a/src/Symfony/Component/Validator/Constraints/Time.php
+++ b/src/Symfony/Component/Validator/Constraints/Time.php
@@ -23,8 +23,8 @@ use Symfony\Component\Validator\Constraint;
*/
class Time extends Constraint
{
- const INVALID_FORMAT_ERROR = 1;
- const INVALID_TIME_ERROR = 2;
+ const INVALID_FORMAT_ERROR = '9d27b2bb-f755-4fbf-b725-39b1edbdebdf';
+ const INVALID_TIME_ERROR = '8532f9e1-84b2-4d67-8989-0818bc38533b';
protected static $errorNames = array(
self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR',
diff --git a/src/Symfony/Component/Validator/Constraints/Type.php b/src/Symfony/Component/Validator/Constraints/Type.php
index fc4cc72eb6..f8ff9d88bd 100644
--- a/src/Symfony/Component/Validator/Constraints/Type.php
+++ b/src/Symfony/Component/Validator/Constraints/Type.php
@@ -23,6 +23,12 @@ use Symfony\Component\Validator\Constraint;
*/
class Type extends Constraint
{
+ const INVALID_TYPE_ERROR = 'ba785a8c-82cb-4283-967c-3cf342181b40';
+
+ protected static $errorNames = array(
+ self::INVALID_TYPE_ERROR => 'INVALID_TYPE_ERROR',
+ );
+
public $message = 'This value should be of type {{ type }}.';
public $type;
diff --git a/src/Symfony/Component/Validator/Constraints/TypeValidator.php b/src/Symfony/Component/Validator/Constraints/TypeValidator.php
index 30ad278de1..55a27bec3a 100644
--- a/src/Symfony/Component/Validator/Constraints/TypeValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/TypeValidator.php
@@ -53,11 +53,13 @@ class TypeValidator extends ConstraintValidator
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
->setParameter('{{ type }}', $constraint->type)
+ ->setCode(Type::INVALID_TYPE_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
->setParameter('{{ type }}', $constraint->type)
+ ->setCode(Type::INVALID_TYPE_ERROR)
->addViolation();
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/Url.php b/src/Symfony/Component/Validator/Constraints/Url.php
index 7b8ef3fb62..6c8ebb7744 100644
--- a/src/Symfony/Component/Validator/Constraints/Url.php
+++ b/src/Symfony/Component/Validator/Constraints/Url.php
@@ -23,6 +23,12 @@ use Symfony\Component\Validator\Constraint;
*/
class Url extends Constraint
{
+ const INVALID_URL_ERROR = '57c2f299-1154-4870-89bb-ef3b1f5ad229';
+
+ protected static $errorNames = array(
+ self::INVALID_URL_ERROR => 'INVALID_URL_ERROR',
+ );
+
public $message = 'This value is not a valid URL.';
public $dnsMessage = 'The host could not be resolved.';
public $protocols = array('http', 'https');
diff --git a/src/Symfony/Component/Validator/Constraints/UrlValidator.php b/src/Symfony/Component/Validator/Constraints/UrlValidator.php
index b38f8dafab..b308b20e64 100644
--- a/src/Symfony/Component/Validator/Constraints/UrlValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/UrlValidator.php
@@ -63,10 +63,12 @@ class UrlValidator extends ConstraintValidator
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Url::INVALID_URL_ERROR)
->addViolation();
} else {
$this->buildViolation($constraint->message)
->setParameter('{{ value }}', $this->formatValue($value))
+ ->setCode(Url::INVALID_URL_ERROR)
->addViolation();
}
@@ -79,12 +81,14 @@ class UrlValidator extends ConstraintValidator
if (!checkdnsrr($host, 'ANY')) {
if ($this->context instanceof ExecutionContextInterface) {
$this->context->buildViolation($constraint->dnsMessage)
- ->setParameter('{{ value }}', $this->formatValue($host))
- ->addViolation();
+ ->setParameter('{{ value }}', $this->formatValue($host))
+ ->setCode(Url::INVALID_URL_ERROR)
+ ->addViolation();
} else {
$this->buildViolation($constraint->dnsMessage)
- ->setParameter('{{ value }}', $this->formatValue($host))
- ->addViolation();
+ ->setParameter('{{ value }}', $this->formatValue($host))
+ ->setCode(Url::INVALID_URL_ERROR)
+ ->addViolation();
}
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/Uuid.php b/src/Symfony/Component/Validator/Constraints/Uuid.php
index 3c67a3af0c..8362780079 100644
--- a/src/Symfony/Component/Validator/Constraints/Uuid.php
+++ b/src/Symfony/Component/Validator/Constraints/Uuid.php
@@ -21,12 +21,12 @@ use Symfony\Component\Validator\Constraint;
*/
class Uuid extends Constraint
{
- const TOO_SHORT_ERROR = 1;
- const TOO_LONG_ERROR = 2;
- const INVALID_CHARACTERS_ERROR = 3;
- const INVALID_HYPHEN_PLACEMENT_ERROR = 4;
- const INVALID_VERSION_ERROR = 5;
- const INVALID_VARIANT_ERROR = 6;
+ const TOO_SHORT_ERROR = 'aa314679-dac9-4f54-bf97-b2049df8f2a3';
+ const TOO_LONG_ERROR = '494897dd-36f8-4d31-8923-71a8d5f3000d';
+ const INVALID_CHARACTERS_ERROR = '51120b12-a2bc-41bf-aa53-cd73daf330d0';
+ const INVALID_HYPHEN_PLACEMENT_ERROR = '98469c83-0309-4f5d-bf95-a496dcaa869c';
+ const INVALID_VERSION_ERROR = '21ba13b4-b185-4882-ac6f-d147355987eb';
+ const INVALID_VARIANT_ERROR = '164ef693-2b9d-46de-ad7f-836201f0c2db';
protected static $errorNames = array(
self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR',
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.it.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.it.xlf
index 5a411eaa0a..b1dcb1e7b6 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.it.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.it.xlf
@@ -40,7 +40,7 @@
- Questo campo è manca.
+ Questo campo è mancante.
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php b/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php
index 37ce4805f4..dab59aa57f 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/AbstractComparisonValidatorTestCase.php
@@ -136,6 +136,7 @@ abstract class AbstractComparisonValidatorTestCase extends AbstractConstraintVal
->setParameter('{{ value }}', $dirtyValueAsString)
->setParameter('{{ compared_value }}', $comparedValueString)
->setParameter('{{ compared_value_type }}', $comparedValueType)
+ ->setCode($this->getErrorCode())
->assertRaised();
}
@@ -166,4 +167,11 @@ abstract class AbstractComparisonValidatorTestCase extends AbstractConstraintVal
* @return Constraint
*/
abstract protected function createConstraint(array $options);
+
+ /**
+ * @return string|null
+ */
+ protected function getErrorCode()
+ {
+ }
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.php
index a7f3d7dd58..17d8bfbc2e 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.php
@@ -54,6 +54,7 @@ class BlankValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', $valueAsString)
+ ->setCode(Blank::NOT_BLANK_ERROR)
->assertRaised();
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php
index aab54e590f..2d623c9784 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php
@@ -97,8 +97,10 @@ class CardSchemeValidatorTest extends AbstractConstraintValidatorTest
array('LASER', '6771656738314582216'),
array('MAESTRO', '6759744069209'),
array('MAESTRO', '5020507657408074712'),
+ array('MAESTRO', '5612559223580173965'),
array('MAESTRO', '6759744069209'),
array('MAESTRO', '6759744069209'),
+ array('MAESTRO', '6594371785970435599'),
array('MASTERCARD', '5555555555554444'),
array('MASTERCARD', '5105105105105100'),
array('VISA', '4111111111111111'),
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php
index b13351181a..1f66de2aa9 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php
@@ -89,6 +89,7 @@ class CountryValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$country.'"')
+ ->setCode(Country::NO_SUCH_COUNTRY_ERROR)
->assertRaised();
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php
index e5bb060d9c..c59fc638f7 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php
@@ -103,6 +103,7 @@ class CurrencyValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$currency.'"')
+ ->setCode(Currency::NO_SUCH_CURRENCY_ERROR)
->assertRaised();
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php
index 0361333fdc..7e7a5cc70f 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php
@@ -91,6 +91,7 @@ class EmailValidatorTest extends AbstractConstraintValidatorTest
array('example'),
array('example@'),
array('example@localhost'),
+ array('foo@example.com bar'),
);
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php
index c20db1550b..47f1e483fb 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/EqualToValidatorTest.php
@@ -35,6 +35,11 @@ class EqualToValidatorTest extends AbstractComparisonValidatorTestCase
return new EqualTo($options);
}
+ protected function getErrorCode()
+ {
+ return EqualTo::NOT_EQUAL_ERROR;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php
index 3d4ef75978..742c2027c5 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/ExpressionValidatorTest.php
@@ -40,6 +40,7 @@ class ExpressionValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', 'null')
+ ->setCode(Expression::EXPRESSION_FAILED_ERROR)
->assertRaised();
}
@@ -54,6 +55,7 @@ class ExpressionValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '""')
+ ->setCode(Expression::EXPRESSION_FAILED_ERROR)
->assertRaised();
}
@@ -87,6 +89,7 @@ class ExpressionValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', 'object')
+ ->setCode(Expression::EXPRESSION_FAILED_ERROR)
->assertRaised();
}
@@ -123,8 +126,9 @@ class ExpressionValidatorTest extends AbstractConstraintValidatorTest
$this->validator->validate('2', $constraint);
$this->buildViolation('myMessage')
- ->setParameter('{{ value }}', '"2"')
->atPath('data')
+ ->setParameter('{{ value }}', '"2"')
+ ->setCode(Expression::EXPRESSION_FAILED_ERROR)
->assertRaised();
}
@@ -167,8 +171,9 @@ class ExpressionValidatorTest extends AbstractConstraintValidatorTest
$this->validator->validate('2', $constraint);
$this->buildViolation('myMessage')
- ->setParameter('{{ value }}', '"2"')
->atPath('reference.data')
+ ->setParameter('{{ value }}', '"2"')
+ ->setCode(Expression::EXPRESSION_FAILED_ERROR)
->assertRaised();
}
@@ -207,8 +212,9 @@ class ExpressionValidatorTest extends AbstractConstraintValidatorTest
$this->validator->validate('2', $constraint);
$this->buildViolation('myMessage')
- ->setParameter('{{ value }}', '"2"')
->atPath('')
+ ->setParameter('{{ value }}', '"2"')
+ ->setCode(Expression::EXPRESSION_FAILED_ERROR)
->assertRaised();
}
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/FileTest.php b/src/Symfony/Component/Validator/Tests/Constraints/FileTest.php
index 2ee46813bf..4b28fd44f3 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/FileTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/FileTest.php
@@ -17,8 +17,8 @@ class FileTest extends \PHPUnit_Framework_TestCase
{
/**
* @param mixed $maxSize
- * @param int bytes
- * @param bool $bytes
+ * @param int $bytes
+ * @param bool $binaryFormat
* @dataProvider provideValidSizes
*/
public function testMaxSize($maxSize, $bytes, $binaryFormat)
@@ -31,13 +31,12 @@ class FileTest extends \PHPUnit_Framework_TestCase
/**
* @param mixed $maxSize
- * @param int $bytes
* @dataProvider provideInValidSizes
- * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
*/
- public function testInvalideMaxSize($maxSize)
+ public function testInvalidMaxSize($maxSize)
{
- $file = new File(array('maxSize' => $maxSize));
+ new File(array('maxSize' => $maxSize));
}
/**
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanOrEqualValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanOrEqualValidatorTest.php
index 41708f65c9..41899b2ef1 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanOrEqualValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanOrEqualValidatorTest.php
@@ -35,6 +35,11 @@ class GreaterThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCas
return new GreaterThanOrEqual($options);
}
+ protected function getErrorCode()
+ {
+ return GreaterThanOrEqual::TOO_LOW_ERROR;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php
index 85a2b1dad1..080928c2e6 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/GreaterThanValidatorTest.php
@@ -35,6 +35,11 @@ class GreaterThanValidatorTest extends AbstractComparisonValidatorTestCase
return new GreaterThan($options);
}
+ protected function getErrorCode()
+ {
+ return GreaterThan::TOO_LOW_ERROR;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php
index 8550e1159f..ae07c77bd1 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/IdenticalToValidatorTest.php
@@ -35,6 +35,11 @@ class IdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
return new IdenticalTo($options);
}
+ protected function getErrorCode()
+ {
+ return IdenticalTo::NOT_IDENTICAL_ERROR;
+ }
+
public function provideAllValidComparisons()
{
$this->setDefaultTimezone('UTC');
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php
index fc40e6104e..439d45cc05 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php
@@ -153,6 +153,7 @@ class IpValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$ip.'"')
+ ->setCode(Ip::INVALID_IP_ERROR)
->assertRaised();
}
@@ -185,6 +186,7 @@ class IpValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$ip.'"')
+ ->setCode(Ip::INVALID_IP_ERROR)
->assertRaised();
}
@@ -211,6 +213,7 @@ class IpValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$ip.'"')
+ ->setCode(Ip::INVALID_IP_ERROR)
->assertRaised();
}
@@ -237,6 +240,7 @@ class IpValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$ip.'"')
+ ->setCode(Ip::INVALID_IP_ERROR)
->assertRaised();
}
@@ -259,6 +263,7 @@ class IpValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$ip.'"')
+ ->setCode(Ip::INVALID_IP_ERROR)
->assertRaised();
}
@@ -295,6 +300,7 @@ class IpValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$ip.'"')
+ ->setCode(Ip::INVALID_IP_ERROR)
->assertRaised();
}
@@ -321,6 +327,7 @@ class IpValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$ip.'"')
+ ->setCode(Ip::INVALID_IP_ERROR)
->assertRaised();
}
@@ -346,6 +353,7 @@ class IpValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$ip.'"')
+ ->setCode(Ip::INVALID_IP_ERROR)
->assertRaised();
}
@@ -368,6 +376,7 @@ class IpValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$ip.'"')
+ ->setCode(Ip::INVALID_IP_ERROR)
->assertRaised();
}
@@ -390,6 +399,7 @@ class IpValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$ip.'"')
+ ->setCode(Ip::INVALID_IP_ERROR)
->assertRaised();
}
@@ -412,6 +422,7 @@ class IpValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$ip.'"')
+ ->setCode(Ip::INVALID_IP_ERROR)
->assertRaised();
}
@@ -434,6 +445,7 @@ class IpValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$ip.'"')
+ ->setCode(Ip::INVALID_IP_ERROR)
->assertRaised();
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/IsFalseValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/IsFalseValidatorTest.php
index a63d8466ad..46cadecaf6 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/IsFalseValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/IsFalseValidatorTest.php
@@ -51,6 +51,7 @@ class IsFalseValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', 'true')
+ ->setCode(IsFalse::NOT_FALSE_ERROR)
->assertRaised();
}
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/IsNullValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/IsNullValidatorTest.php
index 885048b9bd..5a5575313b 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/IsNullValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/IsNullValidatorTest.php
@@ -47,6 +47,7 @@ class IsNullValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', $valueAsString)
+ ->setCode(IsNull::NOT_NULL_ERROR)
->assertRaised();
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/IsTrueValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/IsTrueValidatorTest.php
index a4f0a4aaeb..1c5927da4b 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/IsTrueValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/IsTrueValidatorTest.php
@@ -51,6 +51,7 @@ class IsTrueValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', 'false')
+ ->setCode(IsTrue::NOT_TRUE_ERROR)
->assertRaised();
}
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php
index 6f7c3900e5..56824b785b 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php
@@ -89,6 +89,7 @@ class LanguageValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$language.'"')
+ ->setCode(Language::NO_SUCH_LANGUAGE_ERROR)
->assertRaised();
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/LengthValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/LengthValidatorTest.php
index 24b63064d0..75a3d6ee62 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/LengthValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/LengthValidatorTest.php
@@ -241,6 +241,7 @@ class LengthValidatorTest extends AbstractConstraintValidatorTest
->setParameter('{{ value }}', '"'.$value.'"')
->setParameter('{{ charset }}', $charset)
->setInvalidValue($value)
+ ->setCode(Length::INVALID_CHARACTERS_ERROR)
->assertRaised();
}
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php
index 7518135510..8b1adef180 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/LessThanOrEqualValidatorTest.php
@@ -35,6 +35,11 @@ class LessThanOrEqualValidatorTest extends AbstractComparisonValidatorTestCase
return new LessThanOrEqual($options);
}
+ protected function getErrorCode()
+ {
+ return LessThanOrEqual::TOO_HIGH_ERROR;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php
index d555870c12..c3dea687be 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/LessThanValidatorTest.php
@@ -35,6 +35,11 @@ class LessThanValidatorTest extends AbstractComparisonValidatorTestCase
return new LessThan($options);
}
+ protected function getErrorCode()
+ {
+ return LessThan::TOO_HIGH_ERROR;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.php
index e5e2f3009f..ad27a74e2a 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.php
@@ -91,6 +91,7 @@ class LocaleValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$locale.'"')
+ ->setCode(Locale::NO_SUCH_LOCALE_ERROR)
->assertRaised();
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php
index c248246e43..c7c081a63b 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php
@@ -58,6 +58,7 @@ class NotBlankValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', 'null')
+ ->setCode(NotBlank::IS_BLANK_ERROR)
->assertRaised();
}
@@ -71,6 +72,7 @@ class NotBlankValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '""')
+ ->setCode(NotBlank::IS_BLANK_ERROR)
->assertRaised();
}
@@ -84,6 +86,7 @@ class NotBlankValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', 'false')
+ ->setCode(NotBlank::IS_BLANK_ERROR)
->assertRaised();
}
@@ -97,6 +100,7 @@ class NotBlankValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', 'array')
+ ->setCode(NotBlank::IS_BLANK_ERROR)
->assertRaised();
}
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php
index bc2c348efa..1ee8a54ac3 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/NotEqualToValidatorTest.php
@@ -35,6 +35,11 @@ class NotEqualToValidatorTest extends AbstractComparisonValidatorTestCase
return new NotEqualTo($options);
}
+ protected function getErrorCode()
+ {
+ return NotEqualTo::IS_EQUAL_ERROR;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php
index e59c0945c4..68dddeb290 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/NotIdenticalToValidatorTest.php
@@ -35,6 +35,11 @@ class NotIdenticalToValidatorTest extends AbstractComparisonValidatorTestCase
return new NotIdenticalTo($options);
}
+ protected function getErrorCode()
+ {
+ return NotIdenticalTo::IS_IDENTICAL_ERROR;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.php
index d338f31f79..a244f6382b 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.php
@@ -55,6 +55,9 @@ class NotNullValidatorTest extends AbstractConstraintValidatorTest
$this->validator->validate(null, $constraint);
- $this->buildViolation('myMessage')->assertRaised();
+ $this->buildViolation('myMessage')
+ ->setParameter('{{ value }}', 'null')
+ ->setCode(NotNull::IS_NULL_ERROR)
+ ->assertRaised();
}
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php
index 6e6990c39f..08ebd12825 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php
@@ -117,7 +117,7 @@ class RangeValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', $formattedValue)
->setParameter('{{ limit }}', 10)
- ->setCode(Range::BELOW_RANGE_ERROR)
+ ->setCode(Range::TOO_LOW_ERROR)
->assertRaised();
}
@@ -136,7 +136,7 @@ class RangeValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', $formattedValue)
->setParameter('{{ limit }}', 20)
- ->setCode(Range::BEYOND_RANGE_ERROR)
+ ->setCode(Range::TOO_HIGH_ERROR)
->assertRaised();
}
@@ -157,7 +157,7 @@ class RangeValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMaxMessage')
->setParameter('{{ value }}', $formattedValue)
->setParameter('{{ limit }}', 20)
- ->setCode(Range::BEYOND_RANGE_ERROR)
+ ->setCode(Range::TOO_HIGH_ERROR)
->assertRaised();
}
@@ -178,7 +178,7 @@ class RangeValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMinMessage')
->setParameter('{{ value }}', $formattedValue)
->setParameter('{{ limit }}', 10)
- ->setCode(Range::BELOW_RANGE_ERROR)
+ ->setCode(Range::TOO_LOW_ERROR)
->assertRaised();
}
@@ -293,7 +293,7 @@ class RangeValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', $dateTimeAsString)
->setParameter('{{ limit }}', 'Mar 10, 2014, 12:00 AM')
- ->setCode(Range::BELOW_RANGE_ERROR)
+ ->setCode(Range::TOO_LOW_ERROR)
->assertRaised();
}
@@ -316,7 +316,7 @@ class RangeValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', $dateTimeAsString)
->setParameter('{{ limit }}', 'Mar 20, 2014, 12:00 AM')
- ->setCode(Range::BEYOND_RANGE_ERROR)
+ ->setCode(Range::TOO_HIGH_ERROR)
->assertRaised();
}
@@ -341,7 +341,7 @@ class RangeValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMaxMessage')
->setParameter('{{ value }}', $dateTimeAsString)
->setParameter('{{ limit }}', 'Mar 20, 2014, 12:00 AM')
- ->setCode(Range::BEYOND_RANGE_ERROR)
+ ->setCode(Range::TOO_HIGH_ERROR)
->assertRaised();
}
@@ -366,7 +366,7 @@ class RangeValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMinMessage')
->setParameter('{{ value }}', $dateTimeAsString)
->setParameter('{{ limit }}', 'Mar 10, 2014, 12:00 AM')
- ->setCode(Range::BELOW_RANGE_ERROR)
+ ->setCode(Range::TOO_LOW_ERROR)
->assertRaised();
}
@@ -391,7 +391,7 @@ class RangeValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"abcd"')
- ->setCode(Range::INVALID_VALUE_ERROR)
+ ->setCode(Range::INVALID_CHARACTERS_ERROR)
->assertRaised();
}
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.php
index 61917e355c..88e69966b5 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.php
@@ -84,6 +84,7 @@ class RegexValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$value.'"')
+ ->setCode(Regex::REGEX_FAILED_ERROR)
->assertRaised();
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php
index 4836928014..51bd992d8f 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php
@@ -59,6 +59,7 @@ class TypeValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '""')
->setParameter('{{ type }}', 'integer')
+ ->setCode(Type::INVALID_TYPE_ERROR)
->assertRaised();
}
@@ -126,6 +127,7 @@ class TypeValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', $valueAsString)
->setParameter('{{ type }}', $type)
+ ->setCode(Type::INVALID_TYPE_ERROR)
->assertRaised();
}
diff --git a/src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php
index 3358c7923a..edc4dc8aab 100644
--- a/src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php
+++ b/src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php
@@ -126,6 +126,7 @@ class UrlValidatorTest extends AbstractConstraintValidatorTest
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$url.'"')
+ ->setCode(Url::INVALID_URL_ERROR)
->assertRaised();
}
diff --git a/src/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php b/src/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php
index 2451a25a6b..725f7149e4 100644
--- a/src/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php
+++ b/src/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php
@@ -75,6 +75,12 @@ abstract class Abstract2Dot5ApiTest extends AbstractValidatorTest
$this->assertCount(1, $violations);
}
+ public function testValidateWithEmptyArrayAsConstraint()
+ {
+ $violations = $this->validator->validate('value', array());
+ $this->assertCount(0, $violations);
+ }
+
public function testGroupSequenceAbortsAfterFailedGroup()
{
$entity = new Entity();
diff --git a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidator2Dot5ApiTest.php b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidator2Dot5ApiTest.php
index 05961269a5..b27e6454be 100644
--- a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidator2Dot5ApiTest.php
+++ b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidator2Dot5ApiTest.php
@@ -15,6 +15,7 @@ use Symfony\Component\Translation\IdentityTranslator;
use Symfony\Component\Validator\ConstraintValidatorFactory;
use Symfony\Component\Validator\Context\ExecutionContextFactory;
use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
use Symfony\Component\Validator\Validator\RecursiveValidator;
class RecursiveValidator2Dot5ApiTest extends Abstract2Dot5ApiTest
@@ -29,4 +30,28 @@ class RecursiveValidator2Dot5ApiTest extends Abstract2Dot5ApiTest
return new RecursiveValidator($contextFactory, $metadataFactory, $validatorFactory, $objectInitializers);
}
+
+ public function testEmptyGroupsArrayDoesNotTriggerDeprecation()
+ {
+ $entity = new Entity();
+
+ $validatorContext = $this->getMock('Symfony\Component\Validator\Validator\ContextualValidatorInterface');
+ $validatorContext
+ ->expects($this->once())
+ ->method('validate')
+ ->with($entity, null, array())
+ ->willReturnSelf();
+
+ $validator = $this
+ ->getMockBuilder('Symfony\Component\Validator\Validator\RecursiveValidator')
+ ->disableOriginalConstructor()
+ ->setMethods(array('startContext'))
+ ->getMock();
+ $validator
+ ->expects($this->once())
+ ->method('startContext')
+ ->willReturn($validatorContext);
+
+ $validator->validate($entity, null, array());
+ }
}
diff --git a/src/Symfony/Component/Validator/Validator/RecursiveValidator.php b/src/Symfony/Component/Validator/Validator/RecursiveValidator.php
index 2d66a23fe3..e4dc0fb057 100644
--- a/src/Symfony/Component/Validator/Validator/RecursiveValidator.php
+++ b/src/Symfony/Component/Validator/Validator/RecursiveValidator.php
@@ -25,6 +25,7 @@ use Symfony\Component\Validator\ValidatorInterface as LegacyValidatorInterface;
* Recursive implementation of {@link ValidatorInterface}.
*
* @since 2.5
+ *
* @author Bernhard Schussek
*/
class RecursiveValidator implements ValidatorInterface, LegacyValidatorInterface
@@ -177,11 +178,11 @@ class RecursiveValidator implements ValidatorInterface, LegacyValidatorInterface
private static function testConstraints($constraints)
{
- return null === $constraints || $constraints instanceof Constraint || (is_array($constraints) && current($constraints) instanceof Constraint);
+ return null === $constraints || $constraints instanceof Constraint || (is_array($constraints) && (0 === count($constraints) || current($constraints) instanceof Constraint));
}
private static function testGroups($groups)
{
- return null === $groups || is_string($groups) || $groups instanceof GroupSequence || (is_array($groups) && (is_string(current($groups)) || current($groups) instanceof GroupSequence));
+ return null === $groups || is_string($groups) || $groups instanceof GroupSequence || (is_array($groups) && (0 === count($groups) || is_string(current($groups)) || current($groups) instanceof GroupSequence));
}
}
diff --git a/src/Symfony/Component/Validator/Violation/ConstraintViolationBuilderInterface.php b/src/Symfony/Component/Validator/Violation/ConstraintViolationBuilderInterface.php
index 3dc270a154..e0d8d22c91 100644
--- a/src/Symfony/Component/Validator/Violation/ConstraintViolationBuilderInterface.php
+++ b/src/Symfony/Component/Validator/Violation/ConstraintViolationBuilderInterface.php
@@ -93,7 +93,7 @@ interface ConstraintViolationBuilderInterface
/**
* Sets the violation code.
*
- * @param int $code The violation code
+ * @param string|null $code The violation code
*
* @return ConstraintViolationBuilderInterface This builder
*/
diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/PdoCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/PdoCasterTest.php
index eaed9dbb16..445b712ec9 100644
--- a/src/Symfony/Component/VarDumper/Tests/Caster/PdoCasterTest.php
+++ b/src/Symfony/Component/VarDumper/Tests/Caster/PdoCasterTest.php
@@ -45,13 +45,11 @@ class PdoCasterTest extends \PHPUnit_Framework_TestCase
'ORACLE_NULLS' => $attr['ORACLE_NULLS'],
'CLIENT_VERSION' => $pdo->getAttribute(\PDO::ATTR_CLIENT_VERSION),
'SERVER_VERSION' => $pdo->getAttribute(\PDO::ATTR_SERVER_VERSION),
- 'STATEMENT_CLASS' => array(
- 'PDOStatement',
- array($pdo),
- ),
+ 'STATEMENT_CLASS' => array('PDOStatement'),
'DEFAULT_FETCH_MODE' => $attr['DEFAULT_FETCH_MODE'],
),
);
+ unset($cast["\0~\0attributes"]['STATEMENT_CLASS'][1]);
$this->assertSame($xCast, $cast);
}
diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php
index fe3c65042f..abd1e07698 100644
--- a/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php
+++ b/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php
@@ -26,36 +26,31 @@ class ReflectionCasterTest extends VarDumperTestCase
<<<'EOTXT'
ReflectionClass {
+name: "ReflectionClass"
- implements: array:1 [
+%Aimplements: array:%d [
0 => "Reflector"
- ]
+%A]
constants: array:3 [
"IS_IMPLICIT_ABSTRACT" => 16
"IS_EXPLICIT_ABSTRACT" => 32
"IS_FINAL" => 64
]
- properties: array:1 [
+ properties: array:%d [
"name" => ReflectionProperty {
- +name: "name"
+%A +name: "name"
+class: "ReflectionClass"
- modifiers: "public"
+%A modifiers: "public"
extra: null
}
- ]
+%A]
methods: array:%d [
%A
"export" => ReflectionMethod {
+name: "export"
+class: "ReflectionClass"
parameters: array:2 [
- "$argument" => ReflectionParameter {
- +name: "argument"
- position: 0
- }
- "$return" => ReflectionParameter {
- +name: "return"
- position: 1
- }
+ "$%s" => ReflectionParameter {
+%A position: 0
+%A }
]
modifiers: "public static"
}
diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php
index 121428ccfe..0bcce0c4bb 100644
--- a/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php
+++ b/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php
@@ -23,7 +23,7 @@ class SplCasterTest extends VarDumperTestCase
return array(
array(__FILE__, <<<'EOTXT'
SplFileInfo {
- path: "%s/Tests/Caster"
+%Apath: "%s/Tests/Caster"
filename: "SplCasterTest.php"
basename: "SplCasterTest.php"
pathname: "%s/Tests/Caster/SplCasterTest.php"
@@ -49,7 +49,7 @@ EOTXT
),
array('https://google.com/about', <<<'EOTXT'
SplFileInfo {
- path: "https://google.com"
+%Apath: "https://google.com"
filename: "about"
basename: "about"
pathname: "https://google.com/about"
@@ -79,7 +79,7 @@ EOTXT
$var->setFlags(\SplFileObject::DROP_NEW_LINE | \SplFileObject::SKIP_EMPTY);
$dump = <<<'EOTXT'
SplFileObject {
- path: "%s/Tests/Caster"
+%Apath: "%s/Tests/Caster"
filename: "SplCasterTest.php"
basename: "SplCasterTest.php"
pathname: "%s/Tests/Caster/SplCasterTest.php"
diff --git a/src/Symfony/Component/VarDumper/Tests/CliDumperTest.php b/src/Symfony/Component/VarDumper/Tests/CliDumperTest.php
index 05c16b37ba..5145cacba6 100644
--- a/src/Symfony/Component/VarDumper/Tests/CliDumperTest.php
+++ b/src/Symfony/Component/VarDumper/Tests/CliDumperTest.php
@@ -29,7 +29,7 @@ class CliDumperTest extends VarDumperTestCase
$cloner = new VarCloner();
$cloner->addCasters(array(
':stream' => function ($res, $a) {
- unset($a['uri']);
+ unset($a['uri'], $a['wrapper_data']);
return $a;
},
@@ -41,12 +41,12 @@ class CliDumperTest extends VarDumperTestCase
$out = ob_get_clean();
$out = preg_replace('/[ \t]+$/m', '', $out);
$intMax = PHP_INT_MAX;
- $res1 = (int) $var['res'];
- $res2 = (int) $var[8];
+ $res = (int) $var['res'];
+ $r = defined('HHVM_VERSION') ? '' : '#%d';
$this->assertStringMatchesFormat(
<< 1
0 => &1 null
"const" => 1.1
@@ -59,7 +59,7 @@ array:25 [
"str" => "déjà\\n"
7 => b"é\\x00"
"[]" => []
- "res" => stream resource {@{$res1}
+ "res" => stream resource {@{$res}
wrapper_type: "plainfile"
stream_type: "STDIO"
mode: "r"
@@ -70,14 +70,13 @@ array:25 [
eof: false
options: []
}
- 8 => Unknown resource @{$res2}
"obj" => Symfony\Component\VarDumper\Tests\Fixture\DumbFoo {#%d
+foo: "foo"
+"bar": "bar"
}
- "closure" => Closure {#%d
+ "closure" => Closure {{$r}
class: "Symfony\Component\VarDumper\Tests\CliDumperTest"
- this: Symfony\Component\VarDumper\Tests\CliDumperTest {#%d …}
+ this: Symfony\Component\VarDumper\Tests\CliDumperTest {{$r} …}
parameters: array:2 [
"\$a" => []
"&\$b" => array:2 [
@@ -95,7 +94,7 @@ array:25 [
"recurs" => &4 array:1 [
0 => &4 array:1 [&4]
]
- 9 => &1 null
+ 8 => &1 null
"sobj" => Symfony\Component\VarDumper\Tests\Fixture\DumbFoo {#%d}
"snobj" => &3 {#%d}
"snobj2" => {#%d}
@@ -117,11 +116,11 @@ EOTXT
$var = xml_parser_create();
- $this->assertDumpEquals(
+ $this->assertDumpMatchesFormat(
<<markTestSkipped();
+ }
+
+ $var = fopen(__FILE__, 'r');
+ fclose($var);
+
+ $dumper = new CliDumper('php://output');
+ $dumper->setColors(false);
+ $cloner = new VarCloner();
+ $data = $cloner->cloneVar($var);
+
+ ob_start();
+ $dumper->dump($data);
+ $out = ob_get_clean();
+ $res = (int) $var;
+
+ $this->assertStringMatchesFormat(
+ <<setColors(false);
$cloner = new VarCloner();
+ $cloner->addCasters(array(
+ ':stream' => function ($res, $a) {
+ unset($a['wrapper_data']);
+
+ return $a;
+ },
+ ));
$cloner->addCasters(array(
':stream' => function () {
throw new \Exception('Foobar');
@@ -152,12 +187,13 @@ EOTXT
rewind($out);
$out = stream_get_contents($out);
+ $r = defined('HHVM_VERSION') ? '' : '#%d';
$this->assertStringMatchesFormat(
<< array:2 [
- "call" => "%s{closure}()"
+ "call" => "%slosure%s()"
"file" => "{$file}:{$line}"
]
]
@@ -197,9 +233,10 @@ EOTXT
rewind($out);
$out = stream_get_contents($out);
+ $r = defined('HHVM_VERSION') ? '' : '#%d';
$this->assertStringMatchesFormat(
<<bar = 'bar';
$g = fopen(__FILE__, 'r');
-$h = fopen(__FILE__, 'r');
-fclose($h);
$var = array(
'number' => 1, null,
@@ -22,7 +20,6 @@ $var = array(
'str' => "déjà\n", "\xE9\x00",
'[]' => array(),
'res' => $g,
- $h,
'obj' => $foo,
'closure' => function ($a, \PDO &$b = null) {},
'line' => __LINE__ - 1,
@@ -40,4 +37,4 @@ $var['snobj2'] = $var['nobj'][0];
$var['file'] = __FILE__;
$var["bin-key-\xE9"] = '';
-unset($g, $h, $r);
+unset($g, $r);
diff --git a/src/Symfony/Component/VarDumper/Tests/HtmlDumperTest.php b/src/Symfony/Component/VarDumper/Tests/HtmlDumperTest.php
index b7c373a0f6..1a9feeebad 100644
--- a/src/Symfony/Component/VarDumper/Tests/HtmlDumperTest.php
+++ b/src/Symfony/Component/VarDumper/Tests/HtmlDumperTest.php
@@ -29,7 +29,7 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase
$cloner = new VarCloner();
$cloner->addCasters(array(
':stream' => function ($res, $a) {
- unset($a['uri']);
+ unset($a['uri'], $a['wrapper_data']);
return $a;
},
@@ -44,12 +44,12 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase
$intMax = PHP_INT_MAX;
preg_match('/sf-dump-\d+/', $out, $dumpId);
$dumpId = $dumpId[0];
- $res1 = (int) $var['res'];
- $res2 = (int) $var[8];
+ $res = (int) $var['res'];
+ $r = defined('HHVM_VERSION') ? '' : '#%d';
$this->assertStringMatchesFormat(
<<array:25 [
+array:24 [
"number" => 1
0 => &1 null
"const" => 1.1
@@ -62,7 +62,7 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase
"str" => "déjà\\n"
7 => b"é\\x00"
"[]" => []
- "res" => stream resource @{$res1}
+ "res" => stream resource @{$res}
wrapper_type: "plainfile"
stream_type: "STDIO"
mode: "r"
@@ -73,12 +73,11 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase
eof: false
options: []
}
- 8 => Unknown resource @{$res2}
"obj" => DumbFoo {#%d
+foo: "foo"
+"bar": "bar"
}
- "closure" => Closure {#%d
+ "closure" => Closure {{$r}
class: "Symfony\Component\VarDumper\Tests\HtmlDumperTest"
this: HtmlDumperTest {#%d …}
parameters: array:2 [
@@ -98,7 +97,7 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase
"recurs" => &4 array:1 [
0 => &4 array:1 [&4]
]
- 9 => &1 null
+ 8 => &1 null
"sobj" => DumbFoo {#%d}
"snobj" => &3 {#%d}
"snobj2" => {#%d}
diff --git a/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php b/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php
index 733bf35586..31e3a40ae0 100644
--- a/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php
+++ b/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php
@@ -81,7 +81,7 @@ Symfony\Component\VarDumper\Cloner\Data Object
[class] => stdClass
[value] =>
[cut] => 0
- [handle] => %d
+ [handle] => %i
[refCount] => 0
[position] => 1
)
@@ -96,7 +96,7 @@ Symfony\Component\VarDumper\Cloner\Data Object
[class] => stdClass
[value] =>
[cut] => 0
- [handle] => %d
+ [handle] => %i
[refCount] => 0
[position] => 2
)
@@ -107,7 +107,7 @@ Symfony\Component\VarDumper\Cloner\Data Object
[class] => stdClass
[value] =>
[cut] => 0
- [handle] => %d
+ [handle] => %i
[refCount] => 0
[position] => 3
)
@@ -162,7 +162,7 @@ Symfony\Component\VarDumper\Cloner\Data Object
[class] => %s
[value] =>
[cut] => 0
- [handle] => %d
+ [handle] => %i
[refCount] => 0
[position] => 1
)
diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php
index 320eb50721..0776e4fa8d 100644
--- a/src/Symfony/Component/Yaml/Tests/InlineTest.php
+++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php
@@ -50,15 +50,19 @@ class InlineTest extends \PHPUnit_Framework_TestCase
$this->markTestSkipped('Your platform does not support locales.');
}
- $required_locales = array('fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252');
- if (false === setlocale(LC_ALL, $required_locales)) {
- $this->markTestSkipped('Could not set any of required locales: '.implode(', ', $required_locales));
+ try {
+ $requiredLocales = array('fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252');
+ if (false === setlocale(LC_NUMERIC, $requiredLocales)) {
+ $this->markTestSkipped('Could not set any of required locales: '.implode(', ', $requiredLocales));
+ }
+
+ $this->assertEquals('1.2', Inline::dump(1.2));
+ $this->assertContains('fr', strtolower(setlocale(LC_NUMERIC, 0)));
+ setlocale(LC_NUMERIC, $locale);
+ } catch (\Exception $e) {
+ setlocale(LC_NUMERIC, $locale);
+ throw $e;
}
-
- $this->assertEquals('1.2', Inline::dump(1.2));
- $this->assertContains('fr', strtolower(setlocale(LC_NUMERIC, 0)));
-
- setlocale(LC_ALL, $locale);
}
public function testHashStringsResemblingExponentialNumericsShouldNotBeChangedToINF()