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

This commit is contained in:
Bernhard Schussek 2011-01-19 16:24:36 +01:00
parent 2d7c47e488
commit d327a90ff2
8 changed files with 64 additions and 8 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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[

View File

@ -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')));

View File

@ -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')));

View File

@ -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">

View File

@ -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: