Skip to content

Commit 5ce1dc3

Browse files
committed
minor symfony#12201 [Validator] Fixed: The state of the XML/YAML loaders was changed even if an exception was thrown upon loading (webmozart)
This PR was merged into the 2.3 branch. Discussion ---------- [Validator] Fixed: The state of the XML/YAML loaders was changed even if an exception was thrown upon loading | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony#12158 | License | MIT | Doc PR | - Commits ------- 85d464a [Validator] Fixed: The state of the XML/YAML loaders was changed even if an exception was thrown upon loading
2 parents c6029aa + 85d464a commit 5ce1dc3

File tree

13 files changed

+331
-144
lines changed

13 files changed

+331
-144
lines changed

src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,39 @@
1414
use Symfony\Component\Validator\Exception\MappingException;
1515
use Symfony\Component\Validator\Constraint;
1616

17+
/**
18+
* Base loader for validation metadata.
19+
*
20+
* This loader supports the loading of constraints from Symfony's default
21+
* namespace (see {@link DEFAULT_NAMESPACE}) using the short class names of
22+
* those constraints. Constraints can also be loaded using their fully
23+
* qualified class names. At last, namespace aliases can be defined to load
24+
* constraints with the syntax "alias:ShortName".
25+
*
26+
* @author Bernhard Schussek <[email protected]>
27+
*/
1728
abstract class AbstractLoader implements LoaderInterface
1829
{
1930
/**
20-
* Contains all known namespaces indexed by their prefix.
21-
*
31+
* The namespace to load constraints from by default.
32+
*/
33+
const DEFAULT_NAMESPACE = '\\Symfony\\Component\\Validator\\Constraints\\';
34+
35+
/**
2236
* @var array
2337
*/
2438
protected $namespaces;
2539

2640
/**
2741
* Adds a namespace alias.
2842
*
43+
* The namespace alias can be used to reference constraints from specific
44+
* namespaces in {@link newConstraint()}:
45+
*
46+
* $this->addNamespaceAlias('mynamespace', '\\Acme\\Package\\Constraints\\');
47+
*
48+
* $constraint = $this->newConstraint('mynamespace:NotNull');
49+
*
2950
* @param string $alias The alias
3051
* @param string $namespace The PHP namespace
3152
*/
@@ -37,16 +58,19 @@ protected function addNamespaceAlias($alias, $namespace)
3758
/**
3859
* Creates a new constraint instance for the given constraint name.
3960
*
40-
* @param string $name The constraint name. Either a constraint relative
41-
* to the default constraint namespace, or a fully
42-
* qualified class name
43-
* @param mixed $options The constraint options
61+
* @param string $name The constraint name. Either a constraint relative
62+
* to the default constraint namespace, or a fully
63+
* qualified class name. Alternatively, the constraint
64+
* may be preceded by a namespace alias and a colon.
65+
* The namespace alias must have been defined using
66+
* {@link addNamespaceAlias()}.
67+
* @param mixed $options The constraint options
4468
*
4569
* @return Constraint
4670
*
4771
* @throws MappingException If the namespace prefix is undefined
4872
*/
49-
protected function newConstraint($name, $options)
73+
protected function newConstraint($name, $options = null)
5074
{
5175
if (strpos($name, '\\') !== false && class_exists($name)) {
5276
$className = (string) $name;
@@ -59,7 +83,7 @@ protected function newConstraint($name, $options)
5983

6084
$className = $this->namespaces[$prefix].$className;
6185
} else {
62-
$className = 'Symfony\\Component\\Validator\\Constraints\\'.$name;
86+
$className = self::DEFAULT_NAMESPACE.$name;
6387
}
6488

6589
return new $className($options);

src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,40 @@
1818
use Symfony\Component\Validator\Constraints\GroupSequenceProvider;
1919
use Symfony\Component\Validator\Constraint;
2020

21+
/**
22+
* Loads validation metadata using a Doctrine annotation {@link Reader}.
23+
*
24+
* @author Bernhard Schussek <[email protected]>
25+
*/
2126
class AnnotationLoader implements LoaderInterface
2227
{
28+
/**
29+
* @var Reader
30+
*/
2331
protected $reader;
2432

33+
/**
34+
* Creates a new loader.
35+
*
36+
* @param Reader $reader The annotation reader to use.
37+
*/
2538
public function __construct(Reader $reader)
2639
{
2740
$this->reader = $reader;
2841
}
2942

3043
/**
31-
* {@inheritdoc}
44+
* Loads the metadata using annotations defined in the class.
45+
*
46+
* @param ClassMetadata $metadata The class metadata to load
47+
*
48+
* @return bool Whether the loader succeeded
3249
*/
3350
public function loadClassMetadata(ClassMetadata $metadata)
3451
{
3552
$reflClass = $metadata->getReflectionClass();
3653
$className = $reflClass->name;
37-
$loaded = false;
54+
$success = false;
3855

3956
foreach ($this->reader->getClassAnnotations($reflClass) as $constraint) {
4057
if ($constraint instanceof GroupSequence) {
@@ -45,7 +62,7 @@ public function loadClassMetadata(ClassMetadata $metadata)
4562
$metadata->addConstraint($constraint);
4663
}
4764

48-
$loaded = true;
65+
$success = true;
4966
}
5067

5168
foreach ($reflClass->getProperties() as $property) {
@@ -55,7 +72,7 @@ public function loadClassMetadata(ClassMetadata $metadata)
5572
$metadata->addPropertyConstraint($property->name, $constraint);
5673
}
5774

58-
$loaded = true;
75+
$success = true;
5976
}
6077
}
6178
}
@@ -71,11 +88,11 @@ public function loadClassMetadata(ClassMetadata $metadata)
7188
}
7289
}
7390

74-
$loaded = true;
91+
$success = true;
7592
}
7693
}
7794
}
7895

79-
return $loaded;
96+
return $success;
8097
}
8198
}

src/Symfony/Component/Validator/Mapping/Loader/FileLoader.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,42 @@
1313

1414
use Symfony\Component\Validator\Exception\MappingException;
1515

16+
/**
17+
* Base loader for loading validation metadata from a file.
18+
*
19+
* @author Bernhard Schussek <[email protected]>
20+
*
21+
* @see YamlFileLoader
22+
* @see XmlFileLoader
23+
*/
1624
abstract class FileLoader extends AbstractLoader
1725
{
26+
/**
27+
* The file to load.
28+
*
29+
* @var string
30+
*/
1831
protected $file;
1932

2033
/**
21-
* Constructor.
34+
* Creates a new loader.
2235
*
2336
* @param string $file The mapping file to load
2437
*
25-
* @throws MappingException if the mapping file does not exist
26-
* @throws MappingException if the mapping file is not readable
38+
* @throws MappingException If the file does not exist or is not readable
2739
*/
2840
public function __construct($file)
2941
{
3042
if (!is_file($file)) {
31-
throw new MappingException(sprintf('The mapping file %s does not exist', $file));
43+
throw new MappingException(sprintf('The mapping file "%s" does not exist', $file));
3244
}
3345

3446
if (!is_readable($file)) {
35-
throw new MappingException(sprintf('The mapping file %s is not readable', $file));
47+
throw new MappingException(sprintf('The mapping file "%s" is not readable', $file));
48+
}
49+
50+
if (!stream_is_local($this->file)) {
51+
throw new MappingException(sprintf('The mapping file "%s" is not a local file', $file));
3652
}
3753

3854
$this->file = $file;

src/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,42 @@
1212
namespace Symfony\Component\Validator\Mapping\Loader;
1313

1414
/**
15-
* Creates mapping loaders for array of files.
16-
*
17-
* Abstract class, used by
15+
* Base loader for loading validation metadata from a list of files.
1816
*
1917
* @author Bulat Shakirzyanov <[email protected]>
18+
* @author Bernhard Schussek <[email protected]>
2019
*
20+
<<<<<<< HEAD
2121
* @see YamlFileLoader
2222
* @see XmlFileLoader
23+
=======
24+
* @see YamlFilesLoader
25+
* @see XmlFilesLoader
26+
>>>>>>> pull/12201
2327
*/
2428
abstract class FilesLoader extends LoaderChain
2529
{
2630
/**
27-
* Array of mapping files.
31+
* Creates a new loader.
2832
*
29-
* @param array $paths Array of file paths
33+
* @param array $paths An array of file paths
3034
*/
3135
public function __construct(array $paths)
3236
{
3337
parent::__construct($this->getFileLoaders($paths));
3438
}
3539

3640
/**
37-
* Array of mapping files.
41+
* Returns an array of file loaders for the given file paths.
3842
*
39-
* @param array $paths Array of file paths
43+
* @param array $paths An array of file paths
4044
*
41-
* @return LoaderInterface[] Array of metadata loaders
45+
* @return LoaderInterface[] The metadata loaders
4246
*/
4347
protected function getFileLoaders($paths)
4448
{
4549
$loaders = array();
50+
4651
foreach ($paths as $path) {
4752
$loaders[] = $this->getFileLoaderInstance($path);
4853
}
@@ -51,11 +56,11 @@ protected function getFileLoaders($paths)
5156
}
5257

5358
/**
54-
* Takes mapping file path.
59+
* Creates a loader for the given file path.
5560
*
56-
* @param string $file
61+
* @param string $path The file path
5762
*
58-
* @return LoaderInterface
63+
* @return LoaderInterface The created loader
5964
*/
60-
abstract protected function getFileLoaderInstance($file);
65+
abstract protected function getFileLoaderInstance($path);
6166
}

src/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,25 @@
1515
use Symfony\Component\Validator\Mapping\ClassMetadata;
1616

1717
/**
18-
* Calls multiple LoaderInterface instances in a chain.
18+
* Loads validation metadata from multiple {@link LoaderInterface} instances.
1919
*
20-
* This class accepts multiple instances of LoaderInterface to be passed to the
21-
* constructor. When loadClassMetadata() is called, the same method is called
22-
* in <em>all</em> of these loaders, regardless of whether any of them was
23-
* successful or not.
20+
* Pass the loaders when constructing the chain. Once
21+
* {@link loadClassMetadata()} is called, that method will be called on all
22+
* loaders in the chain.
2423
*
2524
* @author Bernhard Schussek <[email protected]>
2625
*/
2726
class LoaderChain implements LoaderInterface
2827
{
28+
/**
29+
* @var LoaderInterface[]
30+
*/
2931
protected $loaders;
3032

3133
/**
32-
* Accepts a list of LoaderInterface instances.
33-
*
34-
* @param LoaderInterface[] $loaders An array of LoaderInterface instances
34+
* @param LoaderInterface[] $loaders The metadata loaders to use
3535
*
36-
* @throws MappingException If any of the loaders does not implement LoaderInterface
36+
* @throws MappingException If any of the loaders has an invalid type
3737
*/
3838
public function __construct(array $loaders)
3939
{
@@ -47,7 +47,12 @@ public function __construct(array $loaders)
4747
}
4848

4949
/**
50-
* {@inheritdoc}
50+
* Calls {@link LoaderInterface::loadClassMetadata()} on all loaders in
51+
* the chain.
52+
*
53+
* @param ClassMetadata $metadata The metadata to load
54+
*
55+
* @return bool Whether the loader succeeded
5156
*/
5257
public function loadClassMetadata(ClassMetadata $metadata)
5358
{

src/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,19 @@
1313

1414
use Symfony\Component\Validator\Mapping\ClassMetadata;
1515

16+
/**
17+
* Loads validation metadata into {@link ClassMetadata} instances.
18+
*
19+
* @author Bernhard Schussek <[email protected]>
20+
*/
1621
interface LoaderInterface
1722
{
1823
/**
19-
* Load a Class Metadata.
24+
* Loads validation metadata into a {@link ClassMetadata} instance.
2025
*
21-
* @param ClassMetadata $metadata A metadata
26+
* @param ClassMetadata $metadata The metadata to load
2227
*
23-
* @return bool
28+
* @return bool Whether the loader succeeded
2429
*/
2530
public function loadClassMetadata(ClassMetadata $metadata);
2631
}

src/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,38 @@
1414
use Symfony\Component\Validator\Exception\MappingException;
1515
use Symfony\Component\Validator\Mapping\ClassMetadata;
1616

17+
/**
18+
* Loads validation metadata by calling a static method on the loaded class.
19+
*
20+
* @author Bernhard Schussek <[email protected]>
21+
*/
1722
class StaticMethodLoader implements LoaderInterface
1823
{
24+
/**
25+
* The name of the method to call.
26+
*
27+
* @var string
28+
*/
1929
protected $methodName;
2030

31+
/**
32+
* Creates a new loader.
33+
*
34+
* @param string $methodName The name of the static method to call
35+
*/
2136
public function __construct($methodName = 'loadValidatorMetadata')
2237
{
2338
$this->methodName = $methodName;
2439
}
2540

2641
/**
27-
* {@inheritdoc}
42+
* Loads validation metadata by calling a static method in the class.
43+
*
44+
* The name of the static method is passed to {@link __construct()}.
45+
*
46+
* @param ClassMetadata $metadata The metadata to load
47+
*
48+
* @return bool Whether the loader succeeded
2849
*/
2950
public function loadClassMetadata(ClassMetadata $metadata)
3051
{

0 commit comments

Comments
 (0)