Преглед на файлове

[Validator] Added namespace prefix support for XML and YAML loaders

Bernhard Schussek преди 14 години
родител
ревизия
d327a90ff2

+ 14 - 0
src/Symfony/Component/Validator/Mapping/Loader/FileLoader.php

@@ -19,6 +19,12 @@ abstract class FileLoader implements LoaderInterface
 {
     protected $file;
 
+    /**
+     * Contains all known namespaces indexed by their prefix
+     * @var array
+     */
+    protected $namespaces;
+
     public function __construct($file)
     {
         if (!file_exists($file)) {
@@ -46,6 +52,14 @@ abstract class FileLoader implements LoaderInterface
     {
         if (strpos($name, '\\') !== false && class_exists($name)) {
             $className = (string)$name;
+        } else if (strpos($name, ':') !== false) {
+            list($prefix, $className) = explode(':', $name);
+
+            if (!isset($this->namespaces[$prefix])) {
+                throw new MappingException(sprintf('Undefined namespace prefix "%s"', $prefix));
+            }
+
+            $className = $this->namespaces[$prefix].$className;
         } else {
             $className = 'Symfony\\Component\\Validator\\Constraints\\'.$name;
         }

+ 4 - 0
src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php

@@ -31,6 +31,10 @@ class XmlFileLoader extends FileLoader
             $this->classes = array();
             $xml = $this->parseFile($this->file);
 
+            foreach ($xml->namespace as $namespace) {
+                $this->namespaces[(string)$namespace['prefix']] = trim((string)$namespace);
+            }
+
             foreach ($xml->class as $class) {
                 $this->classes[(string)$class['name']] = $class;
             }

+ 16 - 8
src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php

@@ -30,16 +30,24 @@ class YamlFileLoader extends FileLoader
     {
         if (null === $this->classes) {
             $this->classes = Yaml::load($this->file);
-        }
 
-        // empty file
-        if (null === $this->classes) {
-            return false;
-        }
+            // empty file
+            if (null === $this->classes) {
+                return false;
+            }
 
-        // not an array
-        if (!is_array($this->classes)) {
-            throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $this->file));
+            // not an array
+            if (!is_array($this->classes)) {
+                throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $this->file));
+            }
+
+            if (isset($this->classes['namespaces'])) {
+                foreach ($this->classes['namespaces'] as $prefix => $namespace) {
+                    $this->namespaces[$prefix] = $namespace;
+                }
+
+                unset($this->classes['namespaces']);
+            }
         }
 
         // TODO validation

+ 14 - 0
src/Symfony/Component/Validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd

@@ -24,10 +24,24 @@
       ]]></xsd:documentation>
     </xsd:annotation>
     <xsd:sequence>
+      <xsd:element name="namespace" type="namespace" maxOccurs="unbounded" />
       <xsd:element name="class" type="class" maxOccurs="unbounded" />
     </xsd:sequence>
   </xsd:complexType>
   
+  <xsd:complexType name="namespace">
+    <xsd:annotation>
+      <xsd:documentation><![CDATA[
+        Contains the abbreviation for a namespace.
+      ]]></xsd:documentation>
+    </xsd:annotation>
+    <xsd:simpleContent>
+      <xsd:extension base="xsd:string">
+        <xsd:attribute name="prefix" type="xsd:string" use="required" />
+      </xsd:extension>
+    </xsd:simpleContent>
+  </xsd:complexType>
+  
   <xsd:complexType name="class">
     <xsd:annotation>
       <xsd:documentation><![CDATA[

+ 3 - 0
tests/Symfony/Tests/Component/Validator/Mapping/Loader/XmlFileLoaderTest.php

@@ -13,6 +13,7 @@ namespace Symfony\Tests\Component\Validator\Mapping\Loader;
 
 require_once __DIR__.'/../../Fixtures/Entity.php';
 require_once __DIR__.'/../../Fixtures/ConstraintA.php';
+require_once __DIR__.'/../../Fixtures/ConstraintB.php';
 
 use Symfony\Component\Validator\Constraints\All;
 use Symfony\Component\Validator\Constraints\Collection;
@@ -22,6 +23,7 @@ use Symfony\Component\Validator\Constraints\Choice;
 use Symfony\Component\Validator\Mapping\ClassMetadata;
 use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader;
 use Symfony\Tests\Component\Validator\Fixtures\ConstraintA;
+use Symfony\Tests\Component\Validator\Fixtures\ConstraintB;
 
 class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
 {
@@ -50,6 +52,7 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
 
         $expected = new ClassMetadata('Symfony\Tests\Component\Validator\Fixtures\Entity');
         $expected->addConstraint(new ConstraintA());
+        $expected->addConstraint(new ConstraintB());
         $expected->addPropertyConstraint('firstName', new NotNull());
         $expected->addPropertyConstraint('firstName', new Min(3));
         $expected->addPropertyConstraint('firstName', new Choice(array('A', 'B')));

+ 3 - 0
tests/Symfony/Tests/Component/Validator/Mapping/Loader/YamlFileLoaderTest.php

@@ -13,6 +13,7 @@ namespace Symfony\Tests\Component\Validator\Mapping\Loader;
 
 require_once __DIR__.'/../../Fixtures/Entity.php';
 require_once __DIR__.'/../../Fixtures/ConstraintA.php';
+require_once __DIR__.'/../../Fixtures/ConstraintB.php';
 
 use Symfony\Component\Validator\Constraints\All;
 use Symfony\Component\Validator\Constraints\Collection;
@@ -22,6 +23,7 @@ use Symfony\Component\Validator\Constraints\Choice;
 use Symfony\Component\Validator\Mapping\ClassMetadata;
 use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader;
 use Symfony\Tests\Component\Validator\Fixtures\ConstraintA;
+use Symfony\Tests\Component\Validator\Fixtures\ConstraintB;
 
 class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
 {
@@ -68,6 +70,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
 
         $expected = new ClassMetadata('Symfony\Tests\Component\Validator\Fixtures\Entity');
         $expected->addConstraint(new ConstraintA());
+        $expected->addConstraint(new ConstraintB());
         $expected->addPropertyConstraint('firstName', new NotNull());
         $expected->addPropertyConstraint('firstName', new Min(3));
         $expected->addPropertyConstraint('firstName', new Choice(array('A', 'B')));

+ 5 - 0
tests/Symfony/Tests/Component/Validator/Mapping/Loader/constraint-mapping.xml

@@ -3,6 +3,8 @@
 <constraint-mapping xmlns="http://www.symfony-project.org/schema/dic/constraint-mapping"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.symfony-project.org/schema/dic/constraint-mapping http://www.symfony-project.org/schema/dic/services/constraint-mapping-1.0.xsd">
+    
+  <namespace prefix="custom">Symfony\Tests\Component\Validator\Fixtures\</namespace>
 
   <class name="Symfony\Tests\Component\Validator\Fixtures\Entity">
 
@@ -11,6 +13,9 @@
     <!-- Custom constraint -->
     <constraint name="Symfony\Tests\Component\Validator\Fixtures\ConstraintA" />
 
+    <!-- Custom constraint with namespace abbreviation-->
+    <constraint name="custom:ConstraintB" />
+
     <!-- PROPERTY CONSTRAINTS -->
 
     <property name="firstName">

+ 5 - 0
tests/Symfony/Tests/Component/Validator/Mapping/Loader/constraint-mapping.yml

@@ -1,7 +1,12 @@
+namespaces:
+  custom: Symfony\Tests\Component\Validator\Fixtures\
+
 Symfony\Tests\Component\Validator\Fixtures\Entity:
   constraints:
     # Custom constraint
     - Symfony\Tests\Component\Validator\Fixtures\ConstraintA: ~
+    # Custom constraint with namespaces prefix
+    - "custom:ConstraintB": ~
       
   properties:
     firstName: