Merge remote branch 'schmittjoh/annotations' into annotations

This commit is contained in:
Johannes Schmitt 2011-04-29 08:39:00 +02:00
commit 7938fb3c28
15 changed files with 106 additions and 119 deletions

View File

@ -6,6 +6,83 @@ one. It only discusses changes that need to be done when using the "public"
API of the framework. If you "hack" the core, you should probably follow the API of the framework. If you "hack" the core, you should probably follow the
timeline closely anyway. timeline closely anyway.
beta1 to beta2
--------------
* The annotation parsing process has been changed. All annotations which are used
in a class must now be imported (just like you import PHP namespaces with the
"use" statement):
Before:
/**
* @orm:Entity
*/
class MyUser
{
/**
* @orm:Id
* @orm:GeneratedValue(strategy = "AUTO")
* @orm:Column(type="integer")
* @var integer
*/
private $id;
/**
* @orm:Column(type="string", nullable=false)
* @assert:NotBlank
* @var string
*/
private $name;
}
After:
/**
* @import("Doctrine\ORM\Mapping\*")
* @import("Symfony\Component\Validator\Constraints\*")
* @ignorePhpDoc
* @Entity
*/
class MyUser
{
/**
* @Id
* @GeneratedValue(strategy="AUTO")
* @Column(type="integer")
* @var integer
*/
private $id;
/**
* @Column(type="string", nullable=false)
* @NotBlank
* @var string
*/
private $name;
}
* The config under "framework.validation.annotations" has been removed and was
replaced with a boolean flag "framework.validation.enable_annotations" which
defaults to false.
* The Set constraint has been removed as it is not required anymore.
Before:
/**
* @assert:Set({@assert:Callback(...), @assert:Callback(...)})
*/
private $foo;
After:
/**
* @Callback(...)
* @Callback(...)
*/
private $foo;
PR12 to beta1 PR12 to beta1
------------- -------------

View File

@ -8,11 +8,12 @@ $loader = new UniversalClassLoader();
$loader->registerNamespaces(array( $loader->registerNamespaces(array(
'Symfony\\Tests' => __DIR__.'/tests', 'Symfony\\Tests' => __DIR__.'/tests',
'Symfony' => __DIR__.'/src', 'Symfony' => __DIR__.'/src',
'Doctrine\\Common' => __DIR__.'/vendor/doctrine-common/lib', 'Doctrine\\Common' => array(__DIR__.'/vendor/annotations/compat-src', __DIR__.'/vendor/doctrine-common/lib'),
'Doctrine\\DBAL' => __DIR__.'/vendor/doctrine-dbal/lib', 'Doctrine\\DBAL' => __DIR__.'/vendor/doctrine-dbal/lib',
'Doctrine' => __DIR__.'/vendor/doctrine/lib', 'Doctrine' => __DIR__.'/vendor/doctrine/lib',
'Assetic' => __DIR__.'/vendor/assetic/src', 'Assetic' => __DIR__.'/vendor/assetic/src',
'Monolog' => __DIR__.'/vendor/monolog/src', 'Monolog' => __DIR__.'/vendor/monolog/src',
'Annotations' => __DIR__.'/vendor/annotations/src',
)); ));
$loader->registerPrefixes(array( $loader->registerPrefixes(array(
'Swift_' => __DIR__.'/vendor/swiftmailer/lib/classes', 'Swift_' => __DIR__.'/vendor/swiftmailer/lib/classes',

View File

@ -5,7 +5,7 @@ framework:
csrf_protection: csrf_protection:
enabled: true enabled: true
router: { resource: "%kernel.root_dir%/config/routing.yml" } router: { resource: "%kernel.root_dir%/config/routing.yml" }
validation: { enabled: true, annotations: true } validation: { enabled: true, enable_annotations: true }
templating: { engines: ['twig', 'php'] } templating: { engines: ['twig', 'php'] }
session: session:
default_locale: en default_locale: en

View File

@ -37,12 +37,7 @@
<services> <services>
<!--- Annotation Metadata Reader Service --> <!--- Annotation Metadata Reader Service -->
<service id="doctrine.orm.metadata.annotation_reader" class="%doctrine.orm.metadata.annotation_reader.class%" public="false"> <service id="doctrine.orm.metadata.annotation_reader" class="%doctrine.orm.metadata.annotation_reader.class%" public="false" />
<call method="setAnnotationNamespaceAlias">
<argument>Doctrine\ORM\Mapping\</argument>
<argument>orm</argument>
</call>
</service>
<service id="doctrine.orm.proxy_cache_warmer" class="%doctrine.orm.proxy_cache_warmer.class%" public="false"> <service id="doctrine.orm.proxy_cache_warmer" class="%doctrine.orm.proxy_cache_warmer.class%" public="false">
<tag name="kernel.cache_warmer" /> <tag name="kernel.cache_warmer" />

View File

@ -244,30 +244,10 @@ class Configuration implements ConfigurationInterface
->children() ->children()
->arrayNode('validation') ->arrayNode('validation')
->canBeUnset() ->canBeUnset()
// For XML, namespace is a child of validation, so it must be moved under annotations
->beforeNormalization()
->ifTrue(function($v) { return is_array($v) && !empty($v['annotations']) && !empty($v['namespace']); })
->then(function($v){
$v['annotations'] = array('namespace' => $v['namespace']);
unset($v['namespace']);
return $v;
})
->end()
->children() ->children()
->booleanNode('enabled')->end() ->booleanNode('enabled')->end()
->scalarNode('cache')->end() ->scalarNode('cache')->end()
->arrayNode('annotations') ->booleanNode('enable_annotations')->defaultFalse()->end()
->canBeUnset()
->treatNullLike(array())
->treatTrueLike(array())
->fixXmlConfig('namespace')
->children()
->arrayNode('namespaces')
->useAttributeAsKey('prefix')
->prototype('scalar')->end()
->end()
->end()
->end()
->end() ->end()
->end() ->end()
->end() ->end()

View File

@ -484,19 +484,7 @@ class FrameworkExtension extends Extension
->replaceArgument(0, $this->getValidatorYamlMappingFiles($container)) ->replaceArgument(0, $this->getValidatorYamlMappingFiles($container))
; ;
if (isset($config['annotations'])) { if ($config['enable_annotations']) {
$namespaces = array('assert' => 'Symfony\\Component\\Validator\\Constraints\\');
// Register prefixes for constraint namespaces
if (!empty($config['annotations']['namespaces'])) {
$namespaces = array_merge($namespaces, $config['annotations']['namespaces']);
}
// Register annotation loader
$container
->getDefinition('validator.mapping.loader.annotation_loader')
->replaceArgument(0, $namespaces)
;
$loaderChain = $container->getDefinition('validator.mapping.loader.loader_chain'); $loaderChain = $container->getDefinition('validator.mapping.loader.loader_chain');
$arguments = $loaderChain->getArguments(); $arguments = $loaderChain->getArguments();
array_unshift($arguments[0], new Reference('validator.mapping.loader.annotation_loader')); array_unshift($arguments[0], new Reference('validator.mapping.loader.annotation_loader'));

View File

@ -114,20 +114,8 @@
</xsd:complexType> </xsd:complexType>
<xsd:complexType name="validation"> <xsd:complexType name="validation">
<xsd:sequence>
<xsd:element name="namespace" type="validation_namespace" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="enabled" type="xsd:boolean" /> <xsd:attribute name="enabled" type="xsd:boolean" />
<xsd:attribute name="cache" type="xsd:string" /> <xsd:attribute name="cache" type="xsd:string" />
<xsd:attribute name="annotations" type="xsd:boolean" /> <xsd:attribute name="enable-annotations" type="xsd:boolean" />
</xsd:complexType>
<xsd:complexType name="validation_namespace">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="prefix" type="xsd:string" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType> </xsd:complexType>
</xsd:schema> </xsd:schema>

View File

@ -48,7 +48,6 @@
<service id="validator.mapping.loader.static_method_loader" class="%validator.mapping.loader.static_method_loader.class%" public="false" /> <service id="validator.mapping.loader.static_method_loader" class="%validator.mapping.loader.static_method_loader.class%" public="false" />
<service id="validator.mapping.loader.annotation_loader" class="%validator.mapping.loader.annotation_loader.class%" public="false"> <service id="validator.mapping.loader.annotation_loader" class="%validator.mapping.loader.annotation_loader.class%" public="false">
<argument /> <!-- namespaces -->
</service> </service>
<service id="validator.mapping.loader.xml_files_loader" class="%validator.mapping.loader.xml_files_loader.class%" public="false"> <service id="validator.mapping.loader.xml_files_loader" class="%validator.mapping.loader.xml_files_loader.class%" public="false">

View File

@ -4,10 +4,6 @@ $container->loadFromExtension('framework', array(
'secret' => 's3cr3t', 'secret' => 's3cr3t',
'validation' => array( 'validation' => array(
'enabled' => true, 'enabled' => true,
'annotations' => array( 'enable_annotations' => true,
'namespaces' => array(
'app' => 'Application\\Validator\\Constraints\\',
),
),
), ),
)); ));

View File

@ -7,8 +7,6 @@
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd"> http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
<framework:config secret="s3cr3t"> <framework:config secret="s3cr3t">
<framework:validation enabled="true" annotations="true"> <framework:validation enabled="true" enable-annotations="true" />
<framework:namespace prefix="app">Application\Validator\Constraints\</framework:namespace>
</framework:validation>
</framework:config> </framework:config>
</container> </container>

View File

@ -2,6 +2,4 @@ framework:
secret: s3cr3t secret: s3cr3t
validation: validation:
enabled: true enabled: true
annotations: enable_annotations: true
namespaces:
app: Application\Validator\Constraints\

View File

@ -166,10 +166,14 @@ abstract class FrameworkExtensionTest extends TestCase
$container = $this->createContainerFromFile('validation_annotations'); $container = $this->createContainerFromFile('validation_annotations');
$this->assertTrue($container->hasDefinition('validator.mapping.loader.annotation_loader'), '->registerValidationConfiguration() defines the annotation loader'); $this->assertTrue($container->hasDefinition('validator.mapping.loader.annotation_loader'), '->registerValidationConfiguration() defines the annotation loader');
$loaders = $container->getDefinition('validator.mapping.loader.loader_chain')->getArgument(0);
$argument = $container->getDefinition('validator.mapping.loader.annotation_loader')->getArgument(0); $found = false;
$this->assertEquals('Symfony\\Component\\Validator\\Constraints\\', $argument['assert'], '->registerValidationConfiguration() loads the default "assert" prefix'); foreach ($loaders as $loader) {
$this->assertEquals('Application\\Validator\\Constraints\\', $argument['app'], '->registerValidationConfiguration() loads custom validation namespaces'); if ('validator.mapping.loader.annotation_loader' === (string) $loader) {
$found = true;
}
}
$this->assertTrue($found, 'validator.mapping.loader.annotation_loader is added to the loader chain.');
} }
public function testValidationPaths() public function testValidationPaths()

View File

@ -1,22 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator\Constraints;
class Set
{
public $constraints;
public function __construct(array $constraints)
{
$this->constraints = $constraints['value'];
}
}

View File

@ -11,9 +11,9 @@
namespace Symfony\Component\Validator\Mapping\Loader; namespace Symfony\Component\Validator\Mapping\Loader;
use Annotations\Reader;
use Symfony\Component\Validator\Exception\MappingException; use Symfony\Component\Validator\Exception\MappingException;
use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\ClassMetadata;
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Validator\Constraints\Set; use Symfony\Component\Validator\Constraints\Set;
use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\Constraints\GroupSequence;
use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraint;
@ -22,18 +22,12 @@ class AnnotationLoader implements LoaderInterface
{ {
protected $reader; protected $reader;
public function __construct(array $paths = null) public function __construct()
{ {
if (null === $paths) { $this->reader = new Reader();
$paths = array('assert' => 'Symfony\\Component\\Validator\\Constraints\\');
}
$this->reader = new AnnotationReader();
$this->reader->setAutoloadAnnotations(true); $this->reader->setAutoloadAnnotations(true);
$this->reader->setIgnoreNotImportedAnnotations(false);
foreach ($paths as $prefix => $path) { $this->reader->setIndexByClass(false);
$this->reader->setAnnotationNamespaceAlias($path, $prefix);
}
} }
/** /**
@ -46,11 +40,7 @@ class AnnotationLoader implements LoaderInterface
$loaded = false; $loaded = false;
foreach ($this->reader->getClassAnnotations($reflClass) as $constraint) { foreach ($this->reader->getClassAnnotations($reflClass) as $constraint) {
if ($constraint instanceof Set) { if ($constraint instanceof GroupSequence) {
foreach ($constraint->constraints as $constraint) {
$metadata->addConstraint($constraint);
}
} elseif ($constraint instanceof GroupSequence) {
$metadata->setGroupSequence($constraint->groups); $metadata->setGroupSequence($constraint->groups);
} elseif ($constraint instanceof Constraint) { } elseif ($constraint instanceof Constraint) {
$metadata->addConstraint($constraint); $metadata->addConstraint($constraint);
@ -62,11 +52,7 @@ class AnnotationLoader implements LoaderInterface
foreach ($reflClass->getProperties() as $property) { foreach ($reflClass->getProperties() as $property) {
if ($property->getDeclaringClass()->getName() == $className) { if ($property->getDeclaringClass()->getName() == $className) {
foreach ($this->reader->getPropertyAnnotations($property) as $constraint) { foreach ($this->reader->getPropertyAnnotations($property) as $constraint) {
if ($constraint instanceof Set) { if ($constraint instanceof Constraint) {
foreach ($constraint->constraints as $constraint) {
$metadata->addPropertyConstraint($property->getName(), $constraint);
}
} elseif ($constraint instanceof Constraint) {
$metadata->addPropertyConstraint($property->getName(), $constraint); $metadata->addPropertyConstraint($property->getName(), $constraint);
} }
@ -81,11 +67,7 @@ class AnnotationLoader implements LoaderInterface
// TODO: clean this up // TODO: clean this up
$name = lcfirst(substr($method->getName(), 0, 3)=='get' ? substr($method->getName(), 3) : substr($method->getName(), 2)); $name = lcfirst(substr($method->getName(), 0, 3)=='get' ? substr($method->getName(), 3) : substr($method->getName(), 2));
if ($constraint instanceof Set) { if ($constraint instanceof Constraint) {
foreach ($constraint->constraints as $constraint) {
$metadata->addGetterConstraint($name, $constraint);
}
} elseif ($constraint instanceof Constraint) {
$metadata->addGetterConstraint($name, $constraint); $metadata->addGetterConstraint($name, $constraint);
} }

View File

@ -52,6 +52,9 @@ install_git doctrine-migrations git://github.com/doctrine/migrations.git
# Monolog # Monolog
install_git monolog git://github.com/Seldaek/monolog.git install_git monolog git://github.com/Seldaek/monolog.git
# Annotations
install_git annotations git://github.com/schmittjoh/annotations.git
# Swiftmailer # Swiftmailer
install_git swiftmailer git://github.com/swiftmailer/swiftmailer.git origin/4.1 install_git swiftmailer git://github.com/swiftmailer/swiftmailer.git origin/4.1