From 85d464a0108c37c426a03baddf2081f91f6305b8 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Fri, 10 Oct 2014 11:59:32 +0200 Subject: [PATCH 01/26] [Validator] Fixed: The state of the XML/YAML loaders was changed even if an exception was thrown upon loading --- .../Mapping/Loader/AbstractLoader.php | 32 +++- .../Mapping/Loader/AnnotationLoader.php | 29 +++- .../Validator/Mapping/Loader/FileLoader.php | 26 ++- .../Validator/Mapping/Loader/FilesLoader.php | 28 ++-- .../Validator/Mapping/Loader/LoaderChain.php | 25 +-- .../Mapping/Loader/LoaderInterface.php | 11 +- .../Mapping/Loader/StaticMethodLoader.php | 23 ++- .../Mapping/Loader/XmlFileLoader.php | 93 +++++++---- .../Mapping/Loader/XmlFilesLoader.php | 5 +- .../Mapping/Loader/YamlFileLoader.php | 150 +++++++++++------- .../Mapping/Loader/YamlFilesLoader.php | 5 +- .../Mapping/Loader/XmlFileLoaderTest.php | 24 ++- .../Mapping/Loader/YamlFileLoaderTest.php | 21 ++- 13 files changed, 329 insertions(+), 143 deletions(-) diff --git a/src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php index 18a7690080..24e87842ef 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php @@ -14,8 +14,24 @@ namespace Symfony\Component\Validator\Mapping\Loader; use Symfony\Component\Validator\Exception\MappingException; use Symfony\Component\Validator\Constraint; +/** + * Base loader for validation metadata. + * + * This loader supports the loading of constraints from Symfony's default + * namespace (see {@link DEFAULT_NAMESPACE}) using the short class names of + * those constraints. Constraints can also be loaded using their fully + * qualified class names. At last, namespace aliases can be defined to load + * constraints with the syntax "alias:ShortName". + * + * @author Bernhard Schussek + */ abstract class AbstractLoader implements LoaderInterface { + /** + * The namespace to load constraints from by default. + */ + const DEFAULT_NAMESPACE = '\\Symfony\\Component\\Validator\\Constraints\\'; + /** * Contains all known namespaces indexed by their prefix * @var array @@ -25,6 +41,13 @@ abstract class AbstractLoader implements LoaderInterface /** * Adds a namespace alias. * + * The namespace alias can be used to reference constraints from specific + * namespaces in {@link newConstraint()}: + * + * $this->addNamespaceAlias('mynamespace', '\\Acme\\Package\\Constraints\\'); + * + * $constraint = $this->newConstraint('mynamespace:NotNull'); + * * @param string $alias The alias * @param string $namespace The PHP namespace */ @@ -38,14 +61,17 @@ abstract class AbstractLoader implements LoaderInterface * * @param string $name The constraint name. Either a constraint relative * to the default constraint namespace, or a fully - * qualified class name + * qualified class name. Alternatively, the constraint + * may be preceded by a namespace alias and a colon. + * The namespace alias must have been defined using + * {@link addNamespaceAlias()}. * @param mixed $options The constraint options * * @return Constraint * * @throws MappingException If the namespace prefix is undefined */ - protected function newConstraint($name, $options) + protected function newConstraint($name, $options = null) { if (strpos($name, '\\') !== false && class_exists($name)) { $className = (string) $name; @@ -58,7 +84,7 @@ abstract class AbstractLoader implements LoaderInterface $className = $this->namespaces[$prefix].$className; } else { - $className = 'Symfony\\Component\\Validator\\Constraints\\'.$name; + $className = self::DEFAULT_NAMESPACE.$name; } return new $className($options); diff --git a/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php index ac04f61774..bb96be6354 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php @@ -18,23 +18,40 @@ use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\Constraints\GroupSequenceProvider; use Symfony\Component\Validator\Constraint; +/** + * Loads validation metadata using a Doctrine annotation {@link Reader}. + * + * @author Bernhard Schussek + */ class AnnotationLoader implements LoaderInterface { + /** + * @var Reader + */ protected $reader; + /** + * Creates a new loader. + * + * @param Reader $reader The annotation reader to use. + */ public function __construct(Reader $reader) { $this->reader = $reader; } /** - * {@inheritdoc} + * Loads the metadata using annotations defined in the class. + * + * @param ClassMetadata $metadata The class metadata to load + * + * @return bool Whether the loader succeeded */ public function loadClassMetadata(ClassMetadata $metadata) { $reflClass = $metadata->getReflectionClass(); $className = $reflClass->name; - $loaded = false; + $success = false; foreach ($this->reader->getClassAnnotations($reflClass) as $constraint) { if ($constraint instanceof GroupSequence) { @@ -45,7 +62,7 @@ class AnnotationLoader implements LoaderInterface $metadata->addConstraint($constraint); } - $loaded = true; + $success = true; } foreach ($reflClass->getProperties() as $property) { @@ -55,7 +72,7 @@ class AnnotationLoader implements LoaderInterface $metadata->addPropertyConstraint($property->name, $constraint); } - $loaded = true; + $success = true; } } } @@ -71,11 +88,11 @@ class AnnotationLoader implements LoaderInterface } } - $loaded = true; + $success = true; } } } - return $loaded; + return $success; } } diff --git a/src/Symfony/Component/Validator/Mapping/Loader/FileLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/FileLoader.php index 2b8c6c04c0..326bbdfe75 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/FileLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/FileLoader.php @@ -13,26 +13,42 @@ namespace Symfony\Component\Validator\Mapping\Loader; use Symfony\Component\Validator\Exception\MappingException; +/** + * Base loader for loading validation metadata from a file. + * + * @author Bernhard Schussek + * + * @see YamlFileLoader + * @see XmlFileLoader + */ abstract class FileLoader extends AbstractLoader { + /** + * The file to load. + * + * @var string + */ protected $file; /** - * Constructor. + * Creates a new loader. * * @param string $file The mapping file to load * - * @throws MappingException if the mapping file does not exist - * @throws MappingException if the mapping file is not readable + * @throws MappingException If the file does not exist or is not readable */ public function __construct($file) { if (!is_file($file)) { - throw new MappingException(sprintf('The mapping file %s does not exist', $file)); + throw new MappingException(sprintf('The mapping file "%s" does not exist', $file)); } if (!is_readable($file)) { - throw new MappingException(sprintf('The mapping file %s is not readable', $file)); + throw new MappingException(sprintf('The mapping file "%s" is not readable', $file)); + } + + if (!stream_is_local($this->file)) { + throw new MappingException(sprintf('The mapping file "%s" is not a local file', $file)); } $this->file = $file; diff --git a/src/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php index a20c797a0a..571c7e7abb 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php @@ -12,21 +12,20 @@ namespace Symfony\Component\Validator\Mapping\Loader; /** - * Creates mapping loaders for array of files. - * - * Abstract class, used by + * Base loader for loading validation metadata from a list of files. * * @author Bulat Shakirzyanov + * @author Bernhard Schussek * - * @see Symfony\Component\Validator\Mapping\Loader\YamlFileLoader - * @see Symfony\Component\Validator\Mapping\Loader\XmlFileLoader + * @see YamlFilesLoader + * @see XmlFilesLoader */ abstract class FilesLoader extends LoaderChain { /** - * Array of mapping files. + * Creates a new loader. * - * @param array $paths Array of file paths + * @param array $paths An array of file paths */ public function __construct(array $paths) { @@ -34,15 +33,16 @@ abstract class FilesLoader extends LoaderChain } /** - * Array of mapping files. + * Returns an array of file loaders for the given file paths. * - * @param array $paths Array of file paths + * @param array $paths An array of file paths * - * @return LoaderInterface[] Array of metadata loaders + * @return LoaderInterface[] The metadata loaders */ protected function getFileLoaders($paths) { $loaders = array(); + foreach ($paths as $path) { $loaders[] = $this->getFileLoaderInstance($path); } @@ -51,11 +51,11 @@ abstract class FilesLoader extends LoaderChain } /** - * Takes mapping file path. + * Creates a loader for the given file path. * - * @param string $file + * @param string $path The file path * - * @return LoaderInterface + * @return LoaderInterface The created loader */ - abstract protected function getFileLoaderInstance($file); + abstract protected function getFileLoaderInstance($path); } diff --git a/src/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php b/src/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php index 7378daf5e8..084b8b13b9 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php @@ -15,25 +15,27 @@ use Symfony\Component\Validator\Exception\MappingException; use Symfony\Component\Validator\Mapping\ClassMetadata; /** - * Calls multiple LoaderInterface instances in a chain + * Loads validation metadata from multiple {@link LoaderInterface} instances. * - * This class accepts multiple instances of LoaderInterface to be passed to the - * constructor. When loadClassMetadata() is called, the same method is called - * in all of these loaders, regardless of whether any of them was - * successful or not. + * Pass the loaders when constructing the chain. Once + * {@link loadClassMetadata()} is called, that method will be called on all + * loaders in the chain. * * @author Bernhard Schussek */ class LoaderChain implements LoaderInterface { + /** + * @var LoaderInterface[] + */ protected $loaders; /** - * Accepts a list of LoaderInterface instances + * Creates a new loader chain. * - * @param LoaderInterface[] $loaders An array of LoaderInterface instances + * @param LoaderInterface[] $loaders The metadata loaders to use * - * @throws MappingException If any of the loaders does not implement LoaderInterface + * @throws MappingException If any of the loaders has an invalid type */ public function __construct(array $loaders) { @@ -47,7 +49,12 @@ class LoaderChain implements LoaderInterface } /** - * {@inheritdoc} + * Calls {@link LoaderInterface::loadClassMetadata()} on all loaders in + * the chain. + * + * @param ClassMetadata $metadata The metadata to load + * + * @return bool Whether the loader succeeded */ public function loadClassMetadata(ClassMetadata $metadata) { diff --git a/src/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.php b/src/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.php index 43358ad1d9..5dadc82eb8 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.php @@ -13,14 +13,19 @@ namespace Symfony\Component\Validator\Mapping\Loader; use Symfony\Component\Validator\Mapping\ClassMetadata; +/** + * Loads validation metadata into {@link ClassMetadata} instances. + * + * @author Bernhard Schussek + */ interface LoaderInterface { /** - * Load a Class Metadata. + * Loads validation metadata into a {@link ClassMetadata} instance. * - * @param ClassMetadata $metadata A metadata + * @param ClassMetadata $metadata The metadata to load * - * @return bool + * @return bool Whether the loader succeeded */ public function loadClassMetadata(ClassMetadata $metadata); } diff --git a/src/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php index 54dcc57cc7..ee87ef5eeb 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php @@ -14,17 +14,38 @@ namespace Symfony\Component\Validator\Mapping\Loader; use Symfony\Component\Validator\Exception\MappingException; use Symfony\Component\Validator\Mapping\ClassMetadata; +/** + * Loads validation metadata by calling a static method on the loaded class. + * + * @author Bernhard Schussek + */ class StaticMethodLoader implements LoaderInterface { + /** + * The name of the method to call. + * + * @var string + */ protected $methodName; + /** + * Creates a new loader. + * + * @param string $methodName The name of the static method to call + */ public function __construct($methodName = 'loadValidatorMetadata') { $this->methodName = $methodName; } /** - * {@inheritdoc} + * Loads validation metadata by calling a static method in the class. + * + * The name of the static method is passed to {@link __construct()}. + * + * @param ClassMetadata $metadata The metadata to load + * + * @return bool Whether the loader succeeded */ public function loadClassMetadata(ClassMetadata $metadata) { diff --git a/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php index c7d82c449c..45dcb4f237 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php @@ -15,24 +15,36 @@ use Symfony\Component\Validator\Exception\MappingException; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Config\Util\XmlUtils; +/** + * Loads validation metadata from an XML file. + * + * @author Bernhard Schussek + */ class XmlFileLoader extends FileLoader { /** - * An array of SimpleXMLElement instances. + * The XML nodes of the mapping file. * * @var \SimpleXMLElement[] */ protected $classes = null; /** - * {@inheritdoc} + * Loads validation metadata using the metadata defined in the XML file. + * + * @param ClassMetadata $metadata The metadata to load + * + * @return bool Whether the loader succeeded */ public function loadClassMetadata(ClassMetadata $metadata) { if (null === $this->classes) { - $this->classes = array(); + // This method may throw an exception. Do not modify the class' + // state before it completes $xml = $this->parseFile($this->file); + $this->classes = array(); + foreach ($xml->namespace as $namespace) { $this->addNamespaceAlias((string) $namespace['prefix'], trim((string) $namespace)); } @@ -43,33 +55,9 @@ class XmlFileLoader extends FileLoader } if (isset($this->classes[$metadata->getClassName()])) { - $xml = $this->classes[$metadata->getClassName()]; + $classDescription = $this->classes[$metadata->getClassName()]; - foreach ($xml->{'group-sequence-provider'} as $provider) { - $metadata->setGroupSequenceProvider(true); - } - - foreach ($xml->{'group-sequence'} as $groupSequence) { - if (count($groupSequence->value) > 0) { - $metadata->setGroupSequence($this->parseValues($groupSequence[0]->value)); - } - } - - foreach ($this->parseConstraints($xml->constraint) as $constraint) { - $metadata->addConstraint($constraint); - } - - foreach ($xml->property as $property) { - foreach ($this->parseConstraints($property->constraint) as $constraint) { - $metadata->addPropertyConstraint((string) $property['name'], $constraint); - } - } - - foreach ($xml->getter as $getter) { - foreach ($this->parseConstraints($getter->constraint) as $constraint) { - $metadata->addGetterConstraint((string) $getter['property'], $constraint); - } - } + $this->loadClassMetadataFromXml($metadata, $classDescription); return true; } @@ -179,22 +167,57 @@ class XmlFileLoader extends FileLoader } /** - * Parse a XML File. + * Loads the XML class descriptions from the given file. * - * @param string $file Path of file + * @param string $path The path of the XML file * - * @return \SimpleXMLElement + * @return \SimpleXMLElement The class descriptions * - * @throws MappingException + * @throws MappingException If the file could not be loaded */ - protected function parseFile($file) + protected function parseFile($path) { try { - $dom = XmlUtils::loadFile($file, __DIR__.'/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd'); + $dom = XmlUtils::loadFile($path, __DIR__.'/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd'); } catch (\Exception $e) { throw new MappingException($e->getMessage(), $e->getCode(), $e); } return simplexml_import_dom($dom); } + + /** + * Loads the validation metadata from the given XML class description. + * + * @param ClassMetadata $metadata The metadata to load + * @param array $classDescription The XML class description + */ + private function loadClassMetadataFromXml(ClassMetadata $metadata, $classDescription) + { + foreach ($classDescription->{'group-sequence-provider'} as $_) { + $metadata->setGroupSequenceProvider(true); + } + + foreach ($classDescription->{'group-sequence'} as $groupSequence) { + if (count($groupSequence->value) > 0) { + $metadata->setGroupSequence($this->parseValues($groupSequence[0]->value)); + } + } + + foreach ($this->parseConstraints($classDescription->constraint) as $constraint) { + $metadata->addConstraint($constraint); + } + + foreach ($classDescription->property as $property) { + foreach ($this->parseConstraints($property->constraint) as $constraint) { + $metadata->addPropertyConstraint((string) $property['name'], $constraint); + } + } + + foreach ($classDescription->getter as $getter) { + foreach ($this->parseConstraints($getter->constraint) as $constraint) { + $metadata->addGetterConstraint((string) $getter['property'], $constraint); + } + } + } } diff --git a/src/Symfony/Component/Validator/Mapping/Loader/XmlFilesLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/XmlFilesLoader.php index 02989ffe89..6017c3f44d 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/XmlFilesLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/XmlFilesLoader.php @@ -12,11 +12,12 @@ namespace Symfony\Component\Validator\Mapping\Loader; /** - * Loads multiple xml mapping files + * Loads validation metadata from a list of XML files. * * @author Bulat Shakirzyanov + * @author Bernhard Schussek * - * @see Symfony\Component\Validator\Mapping\Loader\FilesLoader + * @see FilesLoader */ class XmlFilesLoader extends FilesLoader { diff --git a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php index 32d6c6ae7c..6d646e41a3 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php @@ -14,10 +14,13 @@ namespace Symfony\Component\Validator\Mapping\Loader; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Yaml\Parser as YamlParser; +/** + * Loads validation metadata from a YAML file. + * + * @author Bernhard Schussek + */ class YamlFileLoader extends FileLoader { - private $yamlParser; - /** * An array of YAML class descriptions * @@ -26,34 +29,33 @@ class YamlFileLoader extends FileLoader protected $classes = null; /** - * {@inheritdoc} + * Caches the used YAML parser. + * + * @var YamlParser + */ + private $yamlParser; + + /** + * Loads validation metadata using the metadata defined in the YAML file. + * + * @param ClassMetadata $metadata The metadata to load + * + * @return bool Whether the loader succeeded */ public function loadClassMetadata(ClassMetadata $metadata) { if (null === $this->classes) { - if (!stream_is_local($this->file)) { - throw new \InvalidArgumentException(sprintf('This is not a local file "%s".', $this->file)); - } - - if (!file_exists($this->file)) { - throw new \InvalidArgumentException(sprintf('File "%s" not found.', $this->file)); - } - if (null === $this->yamlParser) { $this->yamlParser = new YamlParser(); } - $this->classes = $this->yamlParser->parse(file_get_contents($this->file)); - - // empty file - if (null === $this->classes) { + // This method may throw an exception. Do not modify the class' + // state before it completes + if (false === ($classes = $this->parseFile($this->file))) { return false; } - // not an array - if (!is_array($this->classes)) { - throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $this->file)); - } + $this->classes = $classes; if (isset($this->classes['namespaces'])) { foreach ($this->classes['namespaces'] as $alias => $namespace) { @@ -64,44 +66,10 @@ class YamlFileLoader extends FileLoader } } - // TODO validation - if (isset($this->classes[$metadata->getClassName()])) { - $yaml = $this->classes[$metadata->getClassName()]; + $classDescription = $this->classes[$metadata->getClassName()]; - if (isset($yaml['group_sequence_provider'])) { - $metadata->setGroupSequenceProvider((bool) $yaml['group_sequence_provider']); - } - - if (isset($yaml['group_sequence'])) { - $metadata->setGroupSequence($yaml['group_sequence']); - } - - if (isset($yaml['constraints']) && is_array($yaml['constraints'])) { - foreach ($this->parseNodes($yaml['constraints']) as $constraint) { - $metadata->addConstraint($constraint); - } - } - - if (isset($yaml['properties']) && is_array($yaml['properties'])) { - foreach ($yaml['properties'] as $property => $constraints) { - if (null !== $constraints) { - foreach ($this->parseNodes($constraints) as $constraint) { - $metadata->addPropertyConstraint($property, $constraint); - } - } - } - } - - if (isset($yaml['getters']) && is_array($yaml['getters'])) { - foreach ($yaml['getters'] as $getter => $constraints) { - if (null !== $constraints) { - foreach ($this->parseNodes($constraints) as $constraint) { - $metadata->addGetterConstraint($getter, $constraint); - } - } - } - } + $this->loadClassMetadataFromYaml($metadata, $classDescription); return true; } @@ -140,4 +108,76 @@ class YamlFileLoader extends FileLoader return $values; } + + /** + * Loads the YAML class descriptions from the given file. + * + * @param string $path The path of the YAML file + * + * @return array|null The class descriptions or null, if the file was empty + * + * @throws \InvalidArgumentException If the file could not be loaded or did + * not contain a YAML array + */ + private function parseFile($path) + { + $classes = $this->yamlParser->parse(file_get_contents($path)); + + // empty file + if (null === $classes) { + return; + } + + // not an array + if (!is_array($classes)) { + throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $this->file)); + } + + return $classes; + } + + /** + * Loads the validation metadata from the given YAML class description. + * + * @param ClassMetadata $metadata The metadata to load + * @param array $classDescription The YAML class description + */ + private function loadClassMetadataFromYaml(ClassMetadata $metadata, array $classDescription) + { + if (isset($classDescription['group_sequence_provider'])) { + $metadata->setGroupSequenceProvider( + (bool) $classDescription['group_sequence_provider'] + ); + } + + if (isset($classDescription['group_sequence'])) { + $metadata->setGroupSequence($classDescription['group_sequence']); + } + + if (isset($classDescription['constraints']) && is_array($classDescription['constraints'])) { + foreach ($this->parseNodes($classDescription['constraints']) as $constraint) { + $metadata->addConstraint($constraint); + } + } + + if (isset($classDescription['properties']) && is_array($classDescription['properties'])) { + foreach ($classDescription['properties'] as $property => $constraints) { + if (null !== $constraints) { + foreach ($this->parseNodes($constraints) as $constraint) { + $metadata->addPropertyConstraint($property, $constraint); + } + } + } + } + + if (isset($classDescription['getters']) && is_array($classDescription['getters'])) { + foreach ($classDescription['getters'] as $getter => $constraints) { + if (null !== $constraints) { + foreach ($this->parseNodes($constraints) as $constraint) { + $metadata->addGetterConstraint($getter, $constraint); + } + } + } + } + } } diff --git a/src/Symfony/Component/Validator/Mapping/Loader/YamlFilesLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/YamlFilesLoader.php index 12cd1a0af1..235856f5b9 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/YamlFilesLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/YamlFilesLoader.php @@ -12,11 +12,12 @@ namespace Symfony\Component\Validator\Mapping\Loader; /** - * Loads multiple yaml mapping files + * Loads validation metadata from a list of YAML files. * * @author Bulat Shakirzyanov + * @author Bernhard Schussek * - * @see Symfony\Component\Validator\Mapping\Loader\FilesLoader + * @see FilesLoader */ class YamlFilesLoader extends FilesLoader { diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php index 7c6e355bd1..9efbb46b82 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php @@ -17,6 +17,7 @@ use Symfony\Component\Validator\Constraints\NotNull; use Symfony\Component\Validator\Constraints\Range; use Symfony\Component\Validator\Constraints\Choice; use Symfony\Component\Validator\Constraints\Regex; +use Symfony\Component\Validator\Exception\MappingException; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader; use Symfony\Component\Validator\Tests\Fixtures\ConstraintA; @@ -98,15 +99,28 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase $this->assertEquals($expected, $metadata); } - /** - * @expectedException \Symfony\Component\Validator\Exception\MappingException - * @expectedExceptionMessage Document types are not allowed. - */ - public function testDocTypeIsNotAllowed() + public function testThrowExceptionIfDocTypeIsSet() { $loader = new XmlFileLoader(__DIR__.'/withdoctype.xml'); $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity'); + $this->setExpectedException('\Symfony\Component\Validator\Exception\MappingException'); $loader->loadClassMetadata($metadata); } + + /** + * @see https://github.com/symfony/symfony/pull/12158 + */ + public function testDoNotModifyStateIfExceptionIsThrown() + { + $loader = new XmlFileLoader(__DIR__.'/withdoctype.xml'); + $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity'); + + try { + $loader->loadClassMetadata($metadata); + } catch (MappingException $e) { + $this->setExpectedException('\Symfony\Component\Validator\Exception\MappingException'); + $loader->loadClassMetadata($metadata); + } + } } diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php index 9e31cbb37d..c0d5cc6009 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php @@ -38,16 +38,31 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase $this->assertFalse($loader->loadClassMetadata($metadata)); } - /** - * @expectedException \InvalidArgumentException - */ public function testLoadClassMetadataThrowsExceptionIfNotAnArray() { $loader = new YamlFileLoader(__DIR__.'/nonvalid-mapping.yml'); $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity'); + + $this->setExpectedException('\InvalidArgumentException'); $loader->loadClassMetadata($metadata); } + /** + * @see https://github.com/symfony/symfony/pull/12158 + */ + public function testDoNotModifyStateIfExceptionIsThrown() + { + $loader = new YamlFileLoader(__DIR__.'/nonvalid-mapping.yml'); + $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity'); + try { + $loader->loadClassMetadata($metadata); + } catch (\InvalidArgumentException $e) { + // Call again. Again an exception should be thrown + $this->setExpectedException('\InvalidArgumentException'); + $loader->loadClassMetadata($metadata); + } + } + public function testLoadClassMetadataReturnsTrueIfSuccessful() { $loader = new YamlFileLoader(__DIR__.'/constraint-mapping.yml'); From bc501259d1a61a131d727af8c04e2d27a31687ec Mon Sep 17 00:00:00 2001 From: WouterJ Date: Sat, 7 Feb 2015 11:37:57 +0100 Subject: [PATCH 02/26] Fixed invalid feedback -> foodback singularization --- src/Symfony/Component/PropertyAccess/StringUtil.php | 2 +- src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/PropertyAccess/StringUtil.php b/src/Symfony/Component/PropertyAccess/StringUtil.php index 29da09755c..5fa1b1734f 100644 --- a/src/Symfony/Component/PropertyAccess/StringUtil.php +++ b/src/Symfony/Component/PropertyAccess/StringUtil.php @@ -197,7 +197,7 @@ class StringUtil } // Convert teeth to tooth, feet to foot - if (false !== ($pos = strpos($plural, 'ee')) && strlen($plural) > 3) { + if (false !== ($pos = strpos($plural, 'ee')) && strlen($plural) > 3 && 'feedback' !== $plural) { return substr_replace($plural, 'oo', $pos, 2); } diff --git a/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php b/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php index a9c07162fe..7c6376dbd6 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/StringUtilTest.php @@ -59,6 +59,7 @@ class StringUtilTest extends \PHPUnit_Framework_TestCase array('data', array('daton', 'datum')), array('days', 'day'), array('discos', 'disco'), + array('devices', array('devex', 'devix', 'device')), array('drives', 'drive'), array('drivers', 'driver'), array('dwarves', array('dwarf', 'dwarve', 'dwarff')), @@ -67,6 +68,7 @@ class StringUtilTest extends \PHPUnit_Framework_TestCase array('emphases', array('emphas', 'emphase', 'emphasis')), array('faxes', 'fax'), array('feet', 'foot'), + array('feedback', 'feedback'), array('foci', 'focus'), array('focuses', array('focus', 'focuse', 'focusis')), array('formulae', 'formula'), From 8542866dde79f37cde9bc79a260b649f58e3b7f0 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 10 Feb 2015 16:07:19 +0100 Subject: [PATCH 03/26] fixed possible race condition when creating a directory --- .../FrameworkBundle/DependencyInjection/FrameworkExtension.php | 2 +- src/Symfony/Component/HttpFoundation/File/File.php | 2 +- src/Symfony/Component/HttpKernel/Kernel.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 50c3f72fa7..56220995dc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -666,7 +666,7 @@ class FrameworkExtension extends Extension if ('file' === $config['cache']) { $cacheDir = $container->getParameterBag()->resolveValue($config['file_cache_dir']); - if (!is_dir($cacheDir) && false === @mkdir($cacheDir, 0777, true)) { + if (!is_dir($cacheDir) && false === @mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) { throw new \RuntimeException(sprintf('Could not create cache directory "%s".', $cacheDir)); } diff --git a/src/Symfony/Component/HttpFoundation/File/File.php b/src/Symfony/Component/HttpFoundation/File/File.php index 0b637d1a3e..dc0e2f7656 100644 --- a/src/Symfony/Component/HttpFoundation/File/File.php +++ b/src/Symfony/Component/HttpFoundation/File/File.php @@ -130,7 +130,7 @@ class File extends \SplFileInfo protected function getTargetFile($directory, $name = null) { if (!is_dir($directory)) { - if (false === @mkdir($directory, 0777, true)) { + if (false === @mkdir($directory, 0777, true) && !is_dir($directory)) { throw new FileException(sprintf('Unable to create the "%s" directory', $directory)); } } elseif (!is_writable($directory)) { diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index c6b7ee1142..7116a81d9f 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -605,7 +605,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface { foreach (array('cache' => $this->getCacheDir(), 'logs' => $this->getLogDir()) as $name => $dir) { if (!is_dir($dir)) { - if (false === @mkdir($dir, 0777, true)) { + if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) { throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, $dir)); } } elseif (!is_writable($dir)) { From a642e4b9f1212fb1a2887aa7dc8e11996a34d911 Mon Sep 17 00:00:00 2001 From: ryunosuke Date: Mon, 9 Feb 2015 15:10:45 +0900 Subject: [PATCH 04/26] [Console] fixed ArrayInput, if array contains 0 key. --- src/Symfony/Component/Console/Input/ArrayInput.php | 6 ++++-- .../Component/Console/Tests/Input/ArrayInputTest.php | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Console/Input/ArrayInput.php b/src/Symfony/Component/Console/Input/ArrayInput.php index f3222bb555..5743bb8af1 100644 --- a/src/Symfony/Component/Console/Input/ArrayInput.php +++ b/src/Symfony/Component/Console/Input/ArrayInput.php @@ -100,8 +100,10 @@ class ArrayInput extends Input $values = (array) $values; foreach ($this->parameters as $k => $v) { - if (is_int($k) && in_array($v, $values)) { - return true; + if (is_int($k)) { + if (in_array($v, $values)) { + return true; + } } elseif (in_array($k, $values)) { return $v; } diff --git a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php index 7cf28e8f49..cc89083c6b 100644 --- a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php +++ b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php @@ -38,6 +38,15 @@ class ArrayInputTest extends \PHPUnit_Framework_TestCase $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if an option is present in the passed parameters'); } + public function testGetParameterOption() + { + $input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar')); + $this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name'); + + $input = new ArrayInput(array('Fabien', '--foo' => 'bar')); + $this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name'); + } + public function testParseArguments() { $input = new ArrayInput(array('name' => 'foo'), new InputDefinition(array(new InputArgument('name')))); From 5f6d235a69ba47e1403d73bcd15fdf51ba053fb9 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 11 Feb 2015 14:35:55 +0100 Subject: [PATCH 05/26] removed redundant phpdocs --- .../Validator/Mapping/Loader/AnnotationLoader.php | 11 +---------- .../Validator/Mapping/Loader/LoaderChain.php | 7 +------ .../Validator/Mapping/Loader/StaticMethodLoader.php | 8 +------- .../Validator/Mapping/Loader/XmlFileLoader.php | 6 +----- .../Validator/Mapping/Loader/YamlFileLoader.php | 6 +----- 5 files changed, 5 insertions(+), 33 deletions(-) diff --git a/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php index bb96be6354..6e71b959bd 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php @@ -30,22 +30,13 @@ class AnnotationLoader implements LoaderInterface */ protected $reader; - /** - * Creates a new loader. - * - * @param Reader $reader The annotation reader to use. - */ public function __construct(Reader $reader) { $this->reader = $reader; } /** - * Loads the metadata using annotations defined in the class. - * - * @param ClassMetadata $metadata The class metadata to load - * - * @return bool Whether the loader succeeded + * {@inheritdoc} */ public function loadClassMetadata(ClassMetadata $metadata) { diff --git a/src/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php b/src/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php index 45744894c7..970d9068d8 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php @@ -47,12 +47,7 @@ class LoaderChain implements LoaderInterface } /** - * Calls {@link LoaderInterface::loadClassMetadata()} on all loaders in - * the chain. - * - * @param ClassMetadata $metadata The metadata to load - * - * @return bool Whether the loader succeeded + * {@inheritdoc} */ public function loadClassMetadata(ClassMetadata $metadata) { diff --git a/src/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php index ee87ef5eeb..4ff22573ac 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php @@ -39,13 +39,7 @@ class StaticMethodLoader implements LoaderInterface } /** - * Loads validation metadata by calling a static method in the class. - * - * The name of the static method is passed to {@link __construct()}. - * - * @param ClassMetadata $metadata The metadata to load - * - * @return bool Whether the loader succeeded + * {@inheritdoc} */ public function loadClassMetadata(ClassMetadata $metadata) { diff --git a/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php index 45dcb4f237..1ebb68a49d 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php @@ -30,11 +30,7 @@ class XmlFileLoader extends FileLoader protected $classes = null; /** - * Loads validation metadata using the metadata defined in the XML file. - * - * @param ClassMetadata $metadata The metadata to load - * - * @return bool Whether the loader succeeded + * {@inheritdoc} */ public function loadClassMetadata(ClassMetadata $metadata) { diff --git a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php index 34699fce1b..e293a6eb38 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php @@ -36,11 +36,7 @@ class YamlFileLoader extends FileLoader private $yamlParser; /** - * Loads validation metadata using the metadata defined in the YAML file. - * - * @param ClassMetadata $metadata The metadata to load - * - * @return bool Whether the loader succeeded + * {@inheritdoc} */ public function loadClassMetadata(ClassMetadata $metadata) { From 9d94dbf5ee448a3cd9208698d497ba2bd25e1939 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 12 Feb 2015 19:02:13 +0100 Subject: [PATCH 06/26] phpunit --colors=always --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index eba78dcddf..a20faf9fa4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,7 +39,7 @@ install: - if [ "$components" = "no" ]; then composer --prefer-source install; fi; script: - - if [ "$components" = "no" ]; then ls -d src/Symfony/*/* | parallel --gnu --keep-order 'echo -e "\\nRunning {} tests"; phpunit --exclude-group tty,benchmark,intl-data {} || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi; - - if [ "$components" = "no" ]; then echo -e "\\nRunning tests requiring tty"; phpunit --group tty || (echo -e "\\e[41mKO\\e[0m tty group" && $(exit 1)); fi; - - if [ "$components" = "high" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source update; phpunit --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi; - - if [ "$components" = "low" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; phpunit --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi; + - if [ "$components" = "no" ]; then ls -d src/Symfony/*/* | parallel --gnu --keep-order 'echo -e "\\nRunning {} tests"; phpunit --colors=always --exclude-group tty,benchmark,intl-data {} || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi; + - if [ "$components" = "no" ]; then echo -e "\\nRunning tests requiring tty"; phpunit --colors=always --group tty || (echo -e "\\e[41mKO\\e[0m tty group" && $(exit 1)); fi; + - if [ "$components" = "high" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source update; phpunit --colors=always --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi; + - if [ "$components" = "low" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; phpunit --colors=always --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi; From f77d7108813b7db43fa60d1fc3baa6842a7bca3c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 12 Feb 2015 19:15:41 +0100 Subject: [PATCH 07/26] Revert "minor #13673 phpunit --colors=always (nicolas-grekas)" This reverts commit dd1a5951aecfa1cc098d91607a5e0d536303b15d, reversing changes made to 5f6d235a69ba47e1403d73bcd15fdf51ba053fb9. --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index a20faf9fa4..eba78dcddf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,7 +39,7 @@ install: - if [ "$components" = "no" ]; then composer --prefer-source install; fi; script: - - if [ "$components" = "no" ]; then ls -d src/Symfony/*/* | parallel --gnu --keep-order 'echo -e "\\nRunning {} tests"; phpunit --colors=always --exclude-group tty,benchmark,intl-data {} || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi; - - if [ "$components" = "no" ]; then echo -e "\\nRunning tests requiring tty"; phpunit --colors=always --group tty || (echo -e "\\e[41mKO\\e[0m tty group" && $(exit 1)); fi; - - if [ "$components" = "high" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source update; phpunit --colors=always --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi; - - if [ "$components" = "low" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; phpunit --colors=always --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi; + - if [ "$components" = "no" ]; then ls -d src/Symfony/*/* | parallel --gnu --keep-order 'echo -e "\\nRunning {} tests"; phpunit --exclude-group tty,benchmark,intl-data {} || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi; + - if [ "$components" = "no" ]; then echo -e "\\nRunning tests requiring tty"; phpunit --group tty || (echo -e "\\e[41mKO\\e[0m tty group" && $(exit 1)); fi; + - if [ "$components" = "high" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source update; phpunit --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi; + - if [ "$components" = "low" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; phpunit --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi; From 34b489d01ebcd5c676269bdf87071bbd322326cf Mon Sep 17 00:00:00 2001 From: Bart Ruysseveldt Date: Fri, 13 Feb 2015 16:25:52 +0100 Subject: [PATCH 08/26] Fixes event listener attaching error | Q | A | ------------- | --- | Bug fix? | [yes] | New feature? | [no] | BC breaks? | [no] | Deprecations? | [no] | Tests pass? | [yes] | Fixed tickets | [none] | License | MIT | Doc PR | [none] --- .../Resources/views/Profiler/base_js.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig index 0db84ed771..b21c515c92 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig @@ -173,7 +173,7 @@ var addEventListener; - if (document.addEventListener) { + if (document.attachEvent) { addEventListener = function (element, eventName, callback) { element.attachEvent('on' + eventName, callback); }; From af0ea978ea11b8ea452c5acbf136d6edcd4e470b Mon Sep 17 00:00:00 2001 From: Kevin Bond Date: Fri, 13 Feb 2015 13:11:44 -0500 Subject: [PATCH 09/26] Fix for broken profiler layout --- .../Resources/views/Profiler/toolbar.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig index 9e96dc6d1a..378bab49e5 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.html.twig @@ -24,7 +24,7 @@
{% endif %} -
+
{% for name, template in templates %} {{ template.renderblock('toolbar', { 'collector': profile.getcollector(name), From a3a2f153c7e35dddc1331b8d442d18db99bb4ce9 Mon Sep 17 00:00:00 2001 From: Johnny Robeson Date: Sat, 14 Feb 2015 04:09:17 -0500 Subject: [PATCH 10/26] [WebProfilerBundle] fix html linting on empty onclick The request collector has an empty onclick="" attribute when {{ link }} isn't available. This tends to happen when rendering the debug toolbar. --- .../Resources/views/Collector/request.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig index 8f1d1332be..3380f5d9cc 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig @@ -5,7 +5,7 @@ {% if collector.controller.class is defined %} {% set link = collector.controller.file|file_link(collector.controller.line) %} {{ collector.controller.class|abbr_class }} - + {{ collector.controller.method }} {% else %} From 58bd16c3d3baf71274669f280d24aa304924afd8 Mon Sep 17 00:00:00 2001 From: Johnny Robeson Date: Sat, 14 Feb 2015 04:25:08 -0500 Subject: [PATCH 11/26] [WebProfilerBundle] fix html lint on (other) empty onclick *This is for the empty onclick that appeared in 2.6* The request collector has an empty onclick="" attribute when {{ link }} isn't available. This tends to happen when rendering the debug toolbar. --- .../Resources/views/Collector/request.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig index 42ff85fae5..d4d4e82cdc 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig @@ -10,7 +10,7 @@ {{ collector.controller.method }} {% else %} - {{ collector.controller.class|abbr_class }} + {{ collector.controller.class|abbr_class }} {% endif %} {% else %} {{ collector.controller }} From a025dea06ee6c636a4c9bc993131ccbc035019f5 Mon Sep 17 00:00:00 2001 From: Thomas Schulz Date: Sat, 14 Feb 2015 23:44:52 +0100 Subject: [PATCH 12/26] Fix dump.name for Windows file paths Wrong variables were used in line 118 ($file -> $name) --- .../Component/HttpKernel/DataCollector/DumpDataCollector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php index 05de7215e1..91851c901b 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php @@ -115,7 +115,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface if (false === $name) { $name = strtr($file, '\\', '/'); - $name = substr($file, strrpos($file, '/') + 1); + $name = substr($name, strrpos($name, '/') + 1); } $this->data[] = compact('data', 'name', 'file', 'line', 'fileExcerpt'); From 9aece5a33e7ca09cb3b894640d03398d28c16aa1 Mon Sep 17 00:00:00 2001 From: Thomas Schulz Date: Sun, 15 Feb 2015 15:36:33 +0100 Subject: [PATCH 13/26] [Finder] Fixed typo in phpdoc comment --- src/Symfony/Component/Finder/Finder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php index 0eeda75911..4f8caecb38 100644 --- a/src/Symfony/Component/Finder/Finder.php +++ b/src/Symfony/Component/Finder/Finder.php @@ -234,7 +234,7 @@ class Finder implements \IteratorAggregate, \Countable * $finder->date('> now - 2 hours'); * $finder->date('>= 2005-10-15'); * - * @param string $date A date rage string + * @param string $date A date range string * * @return Finder The current Finder instance * From 38e7b72371237043b19c15486befd806cd1ad614 Mon Sep 17 00:00:00 2001 From: Wouter J Date: Sat, 14 Feb 2015 14:55:30 +0100 Subject: [PATCH 14/26] [Console] Added a little explaination about Command#interact() --- src/Symfony/Component/Console/Command/Command.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php index 47e8432890..29625a26da 100644 --- a/src/Symfony/Component/Console/Command/Command.php +++ b/src/Symfony/Component/Console/Command/Command.php @@ -175,6 +175,10 @@ class Command /** * Interacts with the user. * + * This method is executed before the InputDefinition is validated. + * This means that this is the only place where the command can + * interactively ask for values of missing required arguments. + * * @param InputInterface $input An InputInterface instance * @param OutputInterface $output An OutputInterface instance */ From 89ca5851853c4ceaaf518c637b6e35e0a81e390e Mon Sep 17 00:00:00 2001 From: Artur Eshenbrener Date: Wed, 4 Feb 2015 11:30:41 +0300 Subject: [PATCH 15/26] Changed return type definition for some methods of NodeDefinition --- .../Definition/Builder/EnumNodeDefinition.php | 5 ++++ .../Definition/Builder/NodeDefinition.php | 28 +++++++++---------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php index c84e389bbd..dc25fcbd26 100644 --- a/src/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/EnumNodeDefinition.php @@ -22,6 +22,11 @@ class EnumNodeDefinition extends ScalarNodeDefinition { private $values; + /** + * @param array $values + * + * @return EnumNodeDefinition|$this + */ public function values(array $values) { $values = array_unique($values); diff --git a/src/Symfony/Component/Config/Definition/Builder/NodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/NodeDefinition.php index 260535916b..0039f3c0a1 100644 --- a/src/Symfony/Component/Config/Definition/Builder/NodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/NodeDefinition.php @@ -59,7 +59,7 @@ abstract class NodeDefinition implements NodeParentInterface * * @param NodeParentInterface $parent The parent * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function setParent(NodeParentInterface $parent) { @@ -73,7 +73,7 @@ abstract class NodeDefinition implements NodeParentInterface * * @param string $info The info text * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function info($info) { @@ -85,7 +85,7 @@ abstract class NodeDefinition implements NodeParentInterface * * @param string|array $example * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function example($example) { @@ -98,7 +98,7 @@ abstract class NodeDefinition implements NodeParentInterface * @param string $key * @param mixed $value * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function attribute($key, $value) { @@ -149,7 +149,7 @@ abstract class NodeDefinition implements NodeParentInterface * * @param mixed $value The default value * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function defaultValue($value) { @@ -162,7 +162,7 @@ abstract class NodeDefinition implements NodeParentInterface /** * Sets the node as required. * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function isRequired() { @@ -176,7 +176,7 @@ abstract class NodeDefinition implements NodeParentInterface * * @param mixed $value * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function treatNullLike($value) { @@ -190,7 +190,7 @@ abstract class NodeDefinition implements NodeParentInterface * * @param mixed $value * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function treatTrueLike($value) { @@ -204,7 +204,7 @@ abstract class NodeDefinition implements NodeParentInterface * * @param mixed $value * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function treatFalseLike($value) { @@ -216,7 +216,7 @@ abstract class NodeDefinition implements NodeParentInterface /** * Sets null as the default value. * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function defaultNull() { @@ -226,7 +226,7 @@ abstract class NodeDefinition implements NodeParentInterface /** * Sets true as the default value. * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function defaultTrue() { @@ -236,7 +236,7 @@ abstract class NodeDefinition implements NodeParentInterface /** * Sets false as the default value. * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function defaultFalse() { @@ -256,7 +256,7 @@ abstract class NodeDefinition implements NodeParentInterface /** * Denies the node value being empty. * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function cannotBeEmpty() { @@ -284,7 +284,7 @@ abstract class NodeDefinition implements NodeParentInterface * * @param bool $deny Whether the overwriting is forbidden or not * - * @return NodeDefinition + * @return NodeDefinition|$this */ public function cannotBeOverwritten($deny = true) { From 06a42e12e2941820eafb018d62374867a67bb9e3 Mon Sep 17 00:00:00 2001 From: Arnaud Kleinpeter Date: Tue, 17 Feb 2015 14:04:06 +0100 Subject: [PATCH 16/26] [Console] fix assertion in testGetOptionDefaults The default values expected n the test were not exactly the same as what is actually returned. --- .../Component/Console/Tests/Input/InputDefinitionTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php b/src/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php index be63311176..18bcb94b47 100644 --- a/src/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php +++ b/src/Symfony/Component/Console/Tests/Input/InputDefinitionTest.php @@ -341,7 +341,7 @@ class InputDefinitionTest extends \PHPUnit_Framework_TestCase new InputOption('foo7', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, '', array(1, 2)), )); $defaults = array( - 'foo1' => null, + 'foo1' => false, 'foo2' => null, 'foo3' => 'default', 'foo4' => null, @@ -349,7 +349,7 @@ class InputDefinitionTest extends \PHPUnit_Framework_TestCase 'foo6' => array(), 'foo7' => array(1, 2), ); - $this->assertEquals($defaults, $definition->getOptionDefaults(), '->getOptionDefaults() returns the default values for all options'); + $this->assertSame($defaults, $definition->getOptionDefaults(), '->getOptionDefaults() returns the default values for all options'); } public function testGetSynopsis() From e45d514bfc6724b62dc17c640e76519bee8a2614 Mon Sep 17 00:00:00 2001 From: Wouter J Date: Tue, 17 Feb 2015 14:25:32 +0100 Subject: [PATCH 17/26] Small syntax fix --- src/Symfony/Component/Form/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 4611542054..1060f57cd2 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -4,8 +4,8 @@ CHANGELOG 2.6.2 ----- -* Added back the `model_timezone` and `view_timezone` options for `TimeType`, `DateType` - and `BirthdayType` + * Added back the `model_timezone` and `view_timezone` options for `TimeType`, `DateType` + and `BirthdayType` 2.6.0 ----- From cbec76c099ed129956daf96ca08725da850a5454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Tue, 17 Feb 2015 17:50:34 +0100 Subject: [PATCH 18/26] [VarDumper] Ignore /vendor/ directory in git --- src/Symfony/Component/VarDumper/.gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/Symfony/Component/VarDumper/.gitignore diff --git a/src/Symfony/Component/VarDumper/.gitignore b/src/Symfony/Component/VarDumper/.gitignore new file mode 100644 index 0000000000..5414c2c655 --- /dev/null +++ b/src/Symfony/Component/VarDumper/.gitignore @@ -0,0 +1,3 @@ +composer.lock +phpunit.xml +vendor/ From 5c9835f230ae878a9268d9d2eaae7d585e7ceb36 Mon Sep 17 00:00:00 2001 From: Dariusz Ruminski Date: Wed, 18 Feb 2015 08:07:05 +0100 Subject: [PATCH 19/26] FilesLoader - fix git conflict --- .../Component/Validator/Mapping/Loader/FilesLoader.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php index e82d7ed189..571c7e7abb 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php @@ -17,13 +17,8 @@ namespace Symfony\Component\Validator\Mapping\Loader; * @author Bulat Shakirzyanov * @author Bernhard Schussek * -<<<<<<< HEAD - * @see YamlFileLoader - * @see XmlFileLoader -======= * @see YamlFilesLoader * @see XmlFilesLoader ->>>>>>> pull/12201 */ abstract class FilesLoader extends LoaderChain { From bcb2e09dc1d4beaa235e6a1b072287b18fa3efe2 Mon Sep 17 00:00:00 2001 From: Adrien Brault Date: Tue, 17 Feb 2015 15:33:38 -0800 Subject: [PATCH 20/26] Add phpdoc for SecurityFactoryInterface::getPosition --- .../Security/Factory/SecurityFactoryInterface.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php index 5e8773b742..0d75129fb9 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php @@ -23,6 +23,12 @@ interface SecurityFactoryInterface { public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint); + /** + * Defines the position at which the provider is called. + * Possible values: pre_auth, form, http, and remember_me. + * + * @return string + */ public function getPosition(); public function getKey(); From 1ae9f9ca0fb6cfbfb3c8bd3ab277cacbc3bdc2b0 Mon Sep 17 00:00:00 2001 From: Johnson Page Date: Thu, 19 Feb 2015 16:57:22 +1100 Subject: [PATCH 21/26] [HttpFoundation] Fix getHost and getPort functions in docblock --- src/Symfony/Component/HttpFoundation/Request.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index 12a083f41c..8a66e94567 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -575,8 +575,8 @@ class Request * The following header keys are supported: * * * Request::HEADER_CLIENT_IP: defaults to X-Forwarded-For (see getClientIp()) - * * Request::HEADER_CLIENT_HOST: defaults to X-Forwarded-Host (see getClientHost()) - * * Request::HEADER_CLIENT_PORT: defaults to X-Forwarded-Port (see getClientPort()) + * * Request::HEADER_CLIENT_HOST: defaults to X-Forwarded-Host (see getHost()) + * * Request::HEADER_CLIENT_PORT: defaults to X-Forwarded-Port (see getPort()) * * Request::HEADER_CLIENT_PROTO: defaults to X-Forwarded-Proto (see getScheme() and isSecure()) * * Setting an empty value allows to disable the trusted header for the given key. From 8299a44c27f555c3d299abf2d5e4b554740a6b82 Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Thu, 19 Feb 2015 09:39:13 +0000 Subject: [PATCH 22/26] [Security] Fix expectation in a test. --- .../Security/Http/Tests/Firewall/ContextListenerTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php index b06eda9836..00ec418c2d 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php @@ -220,8 +220,8 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue(true)); $event->expects($this->any()) - ->method('getRequestType') - ->will($this->returnValue(HttpKernelInterface::MASTER_REQUEST)); + ->method('isMasterRequest') + ->will($this->returnValue(true)); $event->expects($this->any()) ->method('getRequest') ->will($this->returnValue($request)); From 4e11c0710b601c1f6808aeaf80fd509c96b16aa6 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Wed, 18 Feb 2015 21:52:22 +0100 Subject: [PATCH 23/26] [PropertyAccess] refactor type checks to remove duplicate logic and thus improve performance --- .../PropertyAccess/PropertyAccessor.php | 17 ++--- .../Tests/PropertyAccessorTest.php | 64 +++++++------------ 2 files changed, 31 insertions(+), 50 deletions(-) diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index 92caf1e826..a71789f7e7 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -75,10 +75,6 @@ class PropertyAccessor implements PropertyAccessorInterface $objectOrArray = & $propertyValues[$i][self::VALUE]; if ($overwrite) { - if (!is_object($objectOrArray) && !is_array($objectOrArray)) { - throw new UnexpectedTypeException($objectOrArray, 'object or array'); - } - $property = $propertyPath->getElement($i); //$singular = $propertyPath->singulars[$i]; $singular = null; @@ -108,13 +104,13 @@ class PropertyAccessor implements PropertyAccessorInterface */ private function &readPropertiesUntil(&$objectOrArray, PropertyPathInterface $propertyPath, $lastIndex) { + if (!is_object($objectOrArray) && !is_array($objectOrArray)) { + throw new UnexpectedTypeException($objectOrArray, 'object or array'); + } + $propertyValues = array(); for ($i = 0; $i < $lastIndex; ++$i) { - if (!is_object($objectOrArray) && !is_array($objectOrArray)) { - throw new UnexpectedTypeException($objectOrArray, 'object or array'); - } - $property = $propertyPath->getElement($i); $isIndex = $propertyPath->isIndex($i); @@ -137,6 +133,11 @@ class PropertyAccessor implements PropertyAccessorInterface $objectOrArray = & $propertyValue[self::VALUE]; + // the final value of the path must not be validated + if ($i + 1 < $propertyPath->getLength() && !is_object($objectOrArray) && !is_array($objectOrArray)) { + throw new UnexpectedTypeException($objectOrArray, 'object or array'); + } + $propertyValues[] = & $propertyValue; } diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php index ca49be6012..fec4e14b09 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php @@ -29,6 +29,20 @@ class PropertyAccessorTest extends \PHPUnit_Framework_TestCase $this->propertyAccessor = new PropertyAccessor(); } + public function getPathsWithUnexpectedType() + { + return array( + array('', 'foobar'), + array('foo', 'foobar'), + array(null, 'foobar'), + array(123, 'foobar'), + array((object) array('prop' => null), 'prop.foobar'), + array((object) array('prop' => (object) array('subProp' => null)), 'prop.subProp.foobar'), + array(array('index' => null), '[index][foobar]'), + array(array('index' => array('subIndex' => null)), '[index][subIndex][foobar]'), + ); + } + public function testGetValueReadsArray() { $array = array('firstName' => 'Bernhard'); @@ -198,27 +212,13 @@ class PropertyAccessorTest extends \PHPUnit_Framework_TestCase } /** + * @dataProvider getPathsWithUnexpectedType * @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException + * @expectedExceptionMessage Expected argument of type "object or array" */ - public function testGetValueThrowsExceptionIfNotObjectOrArray() + public function testGetValueThrowsExceptionIfNotObjectOrArray($objectOrArray, $path) { - $this->propertyAccessor->getValue('baz', 'foobar'); - } - - /** - * @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException - */ - public function testGetValueThrowsExceptionIfNull() - { - $this->propertyAccessor->getValue(null, 'foobar'); - } - - /** - * @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException - */ - public function testGetValueThrowsExceptionIfEmpty() - { - $this->propertyAccessor->getValue('', 'foobar'); + $this->propertyAccessor->getValue($objectOrArray, $path); } public function testGetValueWhenArrayValueIsNull() @@ -311,33 +311,13 @@ class PropertyAccessorTest extends \PHPUnit_Framework_TestCase } /** + * @dataProvider getPathsWithUnexpectedType * @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException + * @expectedExceptionMessage Expected argument of type "object or array" */ - public function testSetValueThrowsExceptionIfNotObjectOrArray() + public function testSetValueThrowsExceptionIfNotObjectOrArray($objectOrArray, $path) { - $value = 'baz'; - - $this->propertyAccessor->setValue($value, 'foobar', 'bam'); - } - - /** - * @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException - */ - public function testSetValueThrowsExceptionIfNull() - { - $value = null; - - $this->propertyAccessor->setValue($value, 'foobar', 'bam'); - } - - /** - * @expectedException \Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException - */ - public function testSetValueThrowsExceptionIfEmpty() - { - $value = ''; - - $this->propertyAccessor->setValue($value, 'foobar', 'bam'); + $this->propertyAccessor->setValue($objectOrArray, $path, 'value'); } /** From 9cacecbf790b563a60e464c622b4364b7e8af9c7 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Thu, 19 Feb 2015 13:40:39 +0100 Subject: [PATCH 24/26] [PropertyAccess] the property path constructor already implements the type check --- src/Symfony/Component/PropertyAccess/PropertyAccessor.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index a71789f7e7..2aeb1a8a6e 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -40,10 +40,8 @@ class PropertyAccessor implements PropertyAccessorInterface */ public function getValue($objectOrArray, $propertyPath) { - if (is_string($propertyPath)) { + if (!$propertyPath instanceof PropertyPathInterface) { $propertyPath = new PropertyPath($propertyPath); - } elseif (!$propertyPath instanceof PropertyPathInterface) { - throw new UnexpectedTypeException($propertyPath, 'string or Symfony\Component\PropertyAccess\PropertyPathInterface'); } $propertyValues = & $this->readPropertiesUntil($objectOrArray, $propertyPath, $propertyPath->getLength()); @@ -56,10 +54,8 @@ class PropertyAccessor implements PropertyAccessorInterface */ public function setValue(&$objectOrArray, $propertyPath, $value) { - if (is_string($propertyPath)) { + if (!$propertyPath instanceof PropertyPathInterface) { $propertyPath = new PropertyPath($propertyPath); - } elseif (!$propertyPath instanceof PropertyPathInterface) { - throw new UnexpectedTypeException($propertyPath, 'string or Symfony\Component\PropertyAccess\PropertyPathInterface'); } $propertyValues = & $this->readPropertiesUntil($objectOrArray, $propertyPath, $propertyPath->getLength() - 1); From a10844587b4494c678e8e2095a05f1bb88d06cb2 Mon Sep 17 00:00:00 2001 From: Guilherme Blanco Date: Thu, 5 Feb 2015 17:41:00 +0000 Subject: [PATCH 25/26] Optimize EntityType by only loading choices for values in the same way that EntityLoader customization does (if you provide a query_builder). --- .../Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php index 964fbdc935..873e4b025e 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php @@ -218,8 +218,10 @@ class EntityChoiceList extends ObjectChoiceList if (!$this->loaded) { // Optimize performance in case we have an entity loader and // a single-field identifier - if ($this->idAsValue && $this->entityLoader) { - $unorderedEntities = $this->entityLoader->getEntitiesByIds($this->idField, $values); + if ($this->idAsValue) { + $unorderedEntities = $this->entityLoader + ? $this->entityLoader->getEntitiesByIds($this->idField, $values) + : $this->em->getRepository($this->class)->findBy(array($this->idField => $values)); $entitiesByValue = array(); $entities = array(); From f9ddaebe09bca1228509c1f9d6ffae1cb8245e5d Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Sat, 21 Feb 2015 13:54:33 +0100 Subject: [PATCH 26/26] [PropertyAccess] use data provider for isReadable/isWritable tests --- .../Tests/PropertyAccessorTest.php | 34 ++++++------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php index 39606a4032..58d4d74402 100644 --- a/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php +++ b/src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php @@ -316,19 +316,12 @@ class PropertyAccessorTest extends \PHPUnit_Framework_TestCase $this->assertTrue($this->propertyAccessor->isReadable(new TestClassMagicCall('Bernhard'), 'magicCallProperty')); } - public function testIsReadableThrowsExceptionIfNotObjectOrArray() + /** + * @dataProvider getPathsWithUnexpectedType + */ + public function testIsReadableReturnsFalseIfNotObjectOrArray($objectOrArray, $path) { - $this->assertFalse($this->propertyAccessor->isReadable('baz', 'foobar')); - } - - public function testIsReadableThrowsExceptionIfNull() - { - $this->assertFalse($this->propertyAccessor->isReadable(null, 'foobar')); - } - - public function testIsReadableThrowsExceptionIfEmpty() - { - $this->assertFalse($this->propertyAccessor->isReadable('', 'foobar')); + $this->assertFalse($this->propertyAccessor->isReadable($objectOrArray, $path)); } /** @@ -384,19 +377,12 @@ class PropertyAccessorTest extends \PHPUnit_Framework_TestCase $this->assertTrue($this->propertyAccessor->isWritable(new TestClassMagicCall('Bernhard'), 'magicCallProperty')); } - public function testNotObjectOrArrayIsNotWritable() + /** + * @dataProvider getPathsWithUnexpectedType + */ + public function testIsWritableReturnsFalseIfNotObjectOrArray($objectOrArray, $path) { - $this->assertFalse($this->propertyAccessor->isWritable('baz', 'foobar')); - } - - public function testNullIsNotWritable() - { - $this->assertFalse($this->propertyAccessor->isWritable(null, 'foobar')); - } - - public function testEmptyIsNotWritable() - { - $this->assertFalse($this->propertyAccessor->isWritable('', 'foobar')); + $this->assertFalse($this->propertyAccessor->isWritable($objectOrArray, $path)); } public function getValidPropertyPaths()