Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

[WIP] - Reuse doctrine common annotations #1581

Closed
wants to merge 9 commits into from

6 participants

@Ocramius
Collaborator

This PR introduces a dependency to doctrine/common and makes tests depend on composer for autoloading. I also removed some parts of tests/_autoload.php since Zend\Loader\StandardAutoloader can handle it.

If you don't know about annotations, please read http://docs.doctrine-project.org/projects/doctrine-common/en/latest/reference/annotations.html .

Basically, the idea is that the annotation parser in ZF2 can still exists, but doctrine/common (which is not to be confused with ORM) already has a quite well affirmed syntax that could be re-used and covers all use cases I can think of right now. We should suggest end-users to use this "standard" instead of suggesting a new one that will collide hard with what currently Symfony 2 and Flow3 use.

@ezimuel has already suggested a nice approach at doctrine/common#156 to help in the process of making doctrine annotations compatible with other formats that could be used (since its parser doesn't really like ZF2's annotations right now).

I hope everybody will agree that we don't really need a new format for annotations since the one in doctrine/common has been working for everyone since a couple of years.

About tests requiring composer run, @Maks3w suggested to use a constant. Will eventually do that later.

Build Status

library/Zend/Code/Reflection/PropertyReflection.php
@@ -81,14 +81,15 @@ public function getAnnotations(AnnotationManager $annotationManager)
return $this->annotations;
}
- if (($docComment = $this->getDocComment()) == '') {
- return false;
- }
+ $this->annotations = new \Zend\Code\Annotation\AnnotationCollection();
@Maks3w Collaborator
Maks3w added a note

import this classes instead of use FQDN

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
library/Zend/Code/Annotation/AnnotationManager.php
@@ -21,7 +21,9 @@
namespace Zend\Code\Annotation;
-use Zend\Code\Exception;
+use Zend\Code\Exception\InvalidArgumentException;
+use Zend\Code\Exception\RuntimeException;
+use SplObjectStorage;
@Maks3w Collaborator
Maks3w added a note

This import is not used

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
library/Zend/Code/Reflection/MethodReflection.php
((8 lines not shown))
}
- if (!$this->annotations) {
- $cachingFileScanner = new CachingFileScanner($this->getFileName());
- $nameInformation = $cachingFileScanner->getClassNameInformation($this->getDeclaringClass()->getName());
+ $this->annotations = new \Zend\Code\Annotation\AnnotationCollection();
@Maks3w Collaborator
Maks3w added a note

import this classes instead of use FQDN

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@Maks3w Maks3w commented on the diff
library/Zend/Code/Reflection/ClassReflection.php
@@ -79,14 +79,18 @@ public function getDocBlock()
*/
public function getAnnotations(Annotation\AnnotationManager $annotationManager)
{
- if (($docComment = $this->getDocComment()) == '') {
- return false;
+ if (null !== $this->annotations) {
+ return $this->annotations;
@Maks3w Collaborator
Maks3w added a note

Do a positive match:

if (null==annotations) {
initialize
}

return annotations

@Ocramius Collaborator

I'd return early on that, feels much more readable

@Maks3w Collaborator
Maks3w added a note

@macnibblet What is the problem? I see this as a safe way to code.

Yoda conditioning is the best kind of conditioning

@ralphschindler Collaborator

We have no standard on Yoda conditioning. If you feel comfortable writing it, fine, use it. This is not a blocker for inclusion of a PR. Further, don't rewrite a standard conditional to a yoda conditional unless you're refactoring the code, and likewise, don't rewrite a yoda conditional to standard conditional unless you're the primary lead on the component (the one who spends the majority of their time in it).

I think these are fair rules. And I, personally, feel like yoda conditionals slow down my reading of code, especially in non-simple conditionals.

With IDE's, github code review and unit tests, the focus should be on readability (write once then read and debug over 1000s of times).

@Ocramius Collaborator

I personally read Yoda much better :)
Anyway, good to know this rule. I've rewritten this one to return early, will keep those hints in mind in future.

@Maks3w Collaborator
Maks3w added a note

I'll still prefering Yoda conditioning because:

a) Is only one character the difference to make a bug and may you can't see the difference in a visual review.

b) The project use asignements in conditions so enable that alert in the IDE may throw false positives

@weierophinney Owner

@macnibblet Yoda conditioning is a valid and recommended way to prevent accidental assignment.

i only brought it upp because i didn't see anything about it in the coding standards.

Imho we should follow the rules ralph recommended

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@ralphschindler
Collaborator

I am an emphatic NO on this one. In fact, we should really have this discussion on the mailing list as its still the more canonical place to discuss these things and keep them around for archival purposes.

@Ocramius
Collaborator

@ralphschindler I'm not asking anyone to merge this right now. I would like to see this discussed Wednesday at the meeting.

@ralphschindler
Collaborator

Ok, in that case, it might be best to put WIP above the body text. I also think we should have this dicsussion on the mailing list first, IRC only limits this to the core developers, instead of all the ZF stakeholders who participate in the mailing list.

@weierophinney weierophinney commented on the diff
library/Zend/Code/Annotation/AnnotationManager.php
@@ -21,7 +21,8 @@
namespace Zend\Code\Annotation;
-use Zend\Code\Exception;
+use Zend\Code\Exception\InvalidArgumentException;
+use Zend\Code\Exception\RuntimeException;
@weierophinney Owner

Our convention is to import the exception namespace, not individual exceptions.

@Ocramius Collaborator

Did that because my IDE was complaining. Will revert :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@weierophinney weierophinney commented on the diff
library/Zend/Form/Annotation/Attributes.php
((9 lines not shown))
*/
- public function initialize($content)
+ public function __construct(array $data)
@weierophinney Owner

Confused here. In the AnnotationManager, you're still using clone + initialize(). Since this constructor has required parameters that derive from the individual annotations' content, how would this work?

@Ocramius Collaborator

I'm not registering this annotation as an instance, I'm just registering its FQCN. The initialization logic of the AnnotationManager is never reached, I only check if the AnnotationManager has this annotation registered. This is why the annotation class names and the annotation instances in the AnnotationManager are now out of sync.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@weierophinney

One other thing: adding a dependency on another project is not as easy as adding it to composer. Technically, we have additional requirements:

  • Need to add it to Pyrus (and I'm not even sure if Doctrine\Common is available via pear/pyrus at this time)
  • The full/minimal tarballs would need to include it
  • We create packages for phpcloud currently, which means they'd need to be updated to include it
  • etc.

Adding 3rd party dependencies is not easy, and should not be taken lightly.

As I've noted in IRC and the ML, I agree with the idea of standardizing our annotation syntax. I disagree with requiring that syntax in order to work with our AnnotationManager (which your patch neatly circumvents). The open question for me is how we can adopt the Doctrine annotation syntax in a way that will work easily across all installation vectors.

@Ocramius
Collaborator

@weierophinney we can simply copy the sources over, as said. No need to make things more complex than they already are. Anyway, a solution for including external libraries is highly NEEDED, and the problem needs some thinking (not a problem for now, but you already noticed what the trend is).

@weierophinney weierophinney commented on the diff
tests/_autoload.php
((26 lines not shown))
- default:
- $file = false;
- break;
- }
-
- if ($file) {
- $file .= implode('/', $segments) . '.php';
- if (file_exists($file)) {
- return include_once $file;
- }
- }
-
- $segments = explode('_', $class);
- $ns = array_shift($segments);
+if (!include_once __DIR__ . '/../vendor/autoload.php') {
+ throw new UnexpectedValueException('Coul not find composer, did you run `php composer.phar install`?');
@weierophinney Owner

s/Coul/Could/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@weierophinney weierophinney commented on the diff
tests/_autoload.php
((43 lines not shown))
- switch ($ns) {
- case 'Zend':
- $file = dirname(__DIR__) . '/library/Zend/';
- break;
- default:
- return false;
- }
- $file .= implode('/', $segments) . '.php';
- if (file_exists($file)) {
- return include_once $file;
- }
+require_once __DIR__ . '/../library/Zend/Loader/StandardAutoloader.php';
@weierophinney Owner

This shouldn't be necessary after running composer, as it will add a PSR-0 loader for the Zend namespace.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@Ocramius
Collaborator

@weierophinney should this PR be completed or are you thinking of rewriting the reflection classes on your own?

@weierophinney

I've got work done already on the annotation manager; I'll likely only use the changes to the annotation classes themselves that you've done. If you want to put those into a separate PR, I'll be able to merge them more cleanly.

@Ocramius
Collaborator

@weierophinney fine by me, I will strip the unrelated commits and rebase the work on your branch :)
Closing here

@Ocramius Ocramius closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 348 additions and 368 deletions.
  1. +2 −0  .travis.yml
  2. +2 −1  composer.json
  3. +49 −23 library/Zend/Code/Annotation/AnnotationManager.php
  4. +12 −6 library/Zend/Code/Reflection/ClassReflection.php
  5. +0 −1  library/Zend/Code/Reflection/DocBlockReflection.php
  6. +11 −7 library/Zend/Code/Reflection/MethodReflection.php
  7. +10 −7 library/Zend/Code/Reflection/PropertyReflection.php
  8. +1 −4 library/Zend/Di/Definition/Annotation/Inject.php
  9. +1 −4 library/Zend/Di/Definition/Annotation/Instantiator.php
  10. +9 −6 library/Zend/Form/Annotation/AbstractAnnotation.php
  11. +4 −2 library/Zend/Form/Annotation/AllowEmpty.php
  12. +42 −42 library/Zend/Form/Annotation/AnnotationBuilder.php
  13. +13 −14 library/Zend/Form/Annotation/Attributes.php
  14. +14 −18 library/Zend/Form/Annotation/ComposedObject.php
  15. +12 −16 library/Zend/Form/Annotation/ErrorMessage.php
  16. +3 −1 library/Zend/Form/Annotation/Exclude.php
  17. +12 −13 library/Zend/Form/Annotation/Filter.php
  18. +13 −14 library/Zend/Form/Annotation/Flags.php
  19. +12 −20 library/Zend/Form/Annotation/Hydrator.php
  20. +12 −16 library/Zend/Form/Annotation/Input.php
  21. +13 −21 library/Zend/Form/Annotation/InputFilter.php
  22. +11 −15 library/Zend/Form/Annotation/Name.php
  23. +16 −19 library/Zend/Form/Annotation/Required.php
  24. +12 −16 library/Zend/Form/Annotation/Type.php
  25. +12 −13 library/Zend/Form/Annotation/Validator.php
  26. +13 −0 tests/Zend/Code/Annotation/AnnotationManagerTest.php
  27. +1 −0  tests/Zend/Code/Annotation/TestAsset/Bar.php
  28. +1 −0  tests/Zend/Code/Annotation/TestAsset/Foo.php
  29. +1 −1  tests/Zend/Code/Reflection/ClassReflectionTest.php
  30. +3 −4 tests/Zend/Code/Reflection/PropertyReflectionTest.php
  31. +7 −1 tests/Zend/Code/Reflection/TestAsset/SampleAnnotation.php
  32. +2 −2 tests/Zend/Code/Reflection/TestAsset/TestSampleClass2.php
  33. +1 −0  tests/Zend/Code/Scanner/TestAsset/Annotation/Bar.php
  34. +1 −0  tests/Zend/Code/Scanner/TestAsset/Annotation/Foo.php
  35. +3 −3 tests/Zend/Form/TestAsset/Annotation/ComplexEntity.php
  36. +1 −1  tests/Zend/Form/TestAsset/Annotation/Entity.php
  37. +1 −1  tests/Zend/Form/TestAsset/Annotation/EntityComposingAnEntity.php
  38. +1 −1  tests/Zend/Form/TestAsset/Annotation/ExtendedEntity.php
  39. +3 −3 tests/Zend/Form/TestAsset/Annotation/TypedEntity.php
  40. +11 −52 tests/_autoload.php
View
2  .travis.yml
@@ -7,6 +7,8 @@ php:
before_install:
- cp tests/TestConfiguration.php.travis tests/TestConfiguration.php
+ - curl -s http://getcomposer.org/installer | php
+ - php composer.phar install
script:
- php ./tests/run-tests.php
View
3  composer.json
@@ -9,7 +9,8 @@
"homepage": "http://framework.zend.com/",
"license": "BSD-3-Clause",
"require": {
- "php": ">=5.3.3"
+ "php": ">=5.3.3",
+ "doctrine/common": ">=2.1"
},
"autoload": {
"psr-0": {
View
72 library/Zend/Code/Annotation/AnnotationManager.php
@@ -21,7 +21,8 @@
namespace Zend\Code\Annotation;
-use Zend\Code\Exception;
+use Zend\Code\Exception\InvalidArgumentException;
+use Zend\Code\Exception\RuntimeException;
@weierophinney Owner

Our convention is to import the exception namespace, not individual exceptions.

@Ocramius Collaborator

Did that because my IDE was complaining. Will revert :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
/**
* @category Zend
@@ -65,31 +66,55 @@ public function __construct(array $annotations = array())
* Register annotations
*
* @param AnnotationInterface $annotation
- * @throws Exception\InvalidArgumentException
+ * @throws InvalidArgumentException
*/
public function registerAnnotation(AnnotationInterface $annotation)
{
$class = get_class($annotation);
- if (in_array($class, $this->annotationNames)) {
- throw new Exception\InvalidArgumentException('An annotation for this class ' . $class . ' already exists');
+ if (isset($this->annotationNames[$class])) {
+ throw new InvalidArgumentException('An annotation for this class ' . $class . ' already exists');
}
- $this->annotations[] = $annotation;
- $this->annotationNames[] = $class;
+ $this->annotations[$class] = $annotation;
+ $this->registerAnnotationClassName($class);
+ }
+
+ /**
+ * Register annotation name
+ *
+ * @param string $annotationClassName
+ * @throws InvalidArgumentException
+ * @return bool true if the annotation was registered, false if it was already set
+ */
+ public function registerAnnotationClassName($annotationClassName)
+ {
+ if (isset($this->annotationNames[$annotationClassName])) {
+ return false;
+ }
+
+ if (!class_exists($annotationClassName)) {
+ throw new InvalidArgumentException(
+ 'Could not find class "' . $annotationClassName . '" when trying to register annotation class name'
+ );
+ }
+
+ $this->annotationNames[$annotationClassName] = true;
+ return true;
}
/**
* Alias an annotation name
- *
- * @param string $alias
+ *
+ * @param string $alias
* @param string $class May be either a registered annotation name or another alias
* @return AnnotationManager
+ * @throws InvalidArgumentException
*/
public function setAlias($alias, $class)
{
- if (!in_array($class, $this->annotationNames) && !$this->hasAlias($class)) {
- throw new Exception\InvalidArgumentException(sprintf(
+ if (!isset($this->annotationNames[$class]) && !$this->hasAlias($class)) {
+ throw new InvalidArgumentException(sprintf(
'%s: Cannot alias "%s" to "%s", as class "%s" is not currently a registered annotation or alias',
__METHOD__,
$alias,
@@ -106,12 +131,12 @@ public function setAlias($alias, $class)
/**
* Checks if the manager has annotations for a class
*
- * @param $class
+ * @param string $class
* @return bool
*/
public function hasAnnotation($class)
{
- if (in_array($class, $this->annotationNames)) {
+ if (isset($this->annotationNames[$class])) {
return true;
}
@@ -127,23 +152,24 @@ public function hasAnnotation($class)
*
* @param string $class
* @param null|string $content
- * @throws Exception\RuntimeException
+ * @throws RuntimeException
* @return AnnotationInterface
*/
public function createAnnotation($class, $content = null)
{
if (!$this->hasAnnotation($class)) {
- throw new Exception\RuntimeException('This annotation class is not supported by this annotation manager');
+ throw new RuntimeException('This annotation class is not supported by this annotation manager');
}
if ($this->hasAlias($class)) {
$class = $this->resolveAlias($class);
}
- $index = array_search($class, $this->annotationNames);
- $annotation = $this->annotations[$index];
+ if (!isset($this->annotations[$class])) {
+ throw new RuntimeException('Cannot instantiate annotation of type "' . $class . '", no blueprint registered');
+ }
- $newAnnotation = clone $annotation;
+ $newAnnotation = clone $this->annotations[$class];
if ($content) {
$newAnnotation->initialize($content);
}
@@ -152,8 +178,8 @@ public function createAnnotation($class, $content = null)
/**
* Normalize an alias name
- *
- * @param string $alias
+ *
+ * @param string $alias
* @return string
*/
protected function normalizeAlias($alias)
@@ -163,8 +189,8 @@ protected function normalizeAlias($alias)
/**
* Do we have an alias by the provided name?
- *
- * @param string $alias
+ *
+ * @param string $alias
* @return bool
*/
protected function hasAlias($alias)
@@ -175,8 +201,8 @@ protected function hasAlias($alias)
/**
* Resolve an alias to a class name
- *
- * @param string $alias
+ *
+ * @param string $alias
* @return string
*/
protected function resolveAlias($alias)
View
18 library/Zend/Code/Reflection/ClassReflection.php
@@ -25,6 +25,8 @@
use Zend\Code\Scanner\FileScanner;
use Zend\Code\Annotation;
use Zend\Code\Scanner\AnnotationScanner;
+use Zend\Code\Annotation\AnnotationCollection;
+use Doctrine\Common\Annotations\AnnotationReader;
/**
* @category Zend
@@ -79,14 +81,18 @@ public function getDocBlock()
*/
public function getAnnotations(Annotation\AnnotationManager $annotationManager)
{
- if (($docComment = $this->getDocComment()) == '') {
- return false;
+ if (null !== $this->annotations) {
+ return $this->annotations;
@Maks3w Collaborator
Maks3w added a note

Do a positive match:

if (null==annotations) {
initialize
}

return annotations

@Ocramius Collaborator

I'd return early on that, feels much more readable

@Maks3w Collaborator
Maks3w added a note

@macnibblet What is the problem? I see this as a safe way to code.

Yoda conditioning is the best kind of conditioning

@ralphschindler Collaborator

We have no standard on Yoda conditioning. If you feel comfortable writing it, fine, use it. This is not a blocker for inclusion of a PR. Further, don't rewrite a standard conditional to a yoda conditional unless you're refactoring the code, and likewise, don't rewrite a yoda conditional to standard conditional unless you're the primary lead on the component (the one who spends the majority of their time in it).

I think these are fair rules. And I, personally, feel like yoda conditionals slow down my reading of code, especially in non-simple conditionals.

With IDE's, github code review and unit tests, the focus should be on readability (write once then read and debug over 1000s of times).

@Ocramius Collaborator

I personally read Yoda much better :)
Anyway, good to know this rule. I've rewritten this one to return early, will keep those hints in mind in future.

@Maks3w Collaborator
Maks3w added a note

I'll still prefering Yoda conditioning because:

a) Is only one character the difference to make a bug and may you can't see the difference in a visual review.

b) The project use asignements in conditions so enable that alert in the IDE may throw false positives

@weierophinney Owner

@macnibblet Yoda conditioning is a valid and recommended way to prevent accidental assignment.

i only brought it upp because i didn't see anything about it in the coding standards.

Imho we should follow the rules ralph recommended

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
}
- if (!$this->annotations) {
- $fileScanner = new FileScanner($this->getFileName());
- $nameInformation = $fileScanner->getClassNameInformation($this->getName());
- $this->annotations = new AnnotationScanner($annotationManager, $docComment, $nameInformation);
+ $this->annotations = new AnnotationCollection();
+ $reader = new AnnotationReader();
+ $annotations = $reader->getClassAnnotations($this);
+
+ foreach ($annotations as $annotation) {
+ if ($annotationManager->hasAnnotation(get_class($annotation))) {
+ $this->annotations[] = $annotation;
+ }
}
return $this->annotations;
View
1  library/Zend/Code/Reflection/DocBlockReflection.php
@@ -22,7 +22,6 @@
use Reflector;
use Zend\Code\Scanner\DocBlockScanner;
-use Zend\Code\Annotation\AnnotationManager;
/**
* @category Zend
View
18 library/Zend/Code/Reflection/MethodReflection.php
@@ -25,6 +25,7 @@
use Zend\Code\Annotation\AnnotationManager;
use Zend\Code\Scanner\CachingFileScanner;
use Zend\Code\Scanner\AnnotationScanner;
+use Doctrine\Common\Annotations\AnnotationReader;
/**
* @category Zend
@@ -43,7 +44,7 @@ class MethodReflection extends PhpReflectionMethod implements ReflectionInterfac
/**
* Retrieve method DocBlock reflection
*
- * @return DocBlockReflection|false
+ * @return DocBlockReflection|bool false if no DocBlock is available
*/
public function getDocBlock()
{
@@ -61,15 +62,18 @@ public function getDocBlock()
*/
public function getAnnotations(AnnotationManager $annotationManager)
{
- if (($docComment = $this->getDocComment()) == '') {
- return false;
+ if (null !== $this->annotations) {
+ return $this->annotations;
}
- if (!$this->annotations) {
- $cachingFileScanner = new CachingFileScanner($this->getFileName());
- $nameInformation = $cachingFileScanner->getClassNameInformation($this->getDeclaringClass()->getName());
+ $this->annotations = new AnnotationCollection();
+ $reader = new AnnotationReader();
+ $annotations = $reader->getMethodAnnotations($this);
- $this->annotations = new AnnotationScanner($annotationManager, $docComment, $nameInformation);
+ foreach ($annotations as $annotation) {
+ if ($annotationManager->hasAnnotation(get_class($annotation))) {
+ $this->annotations[] = $annotation;
+ }
}
return $this->annotations;
View
17 library/Zend/Code/Reflection/PropertyReflection.php
@@ -24,6 +24,8 @@
use Zend\Code\Annotation\AnnotationManager;
use Zend\Code\Scanner\AnnotationScanner;
use Zend\Code\Scanner\CachingFileScanner;
+use Zend\Code\Annotation\AnnotationCollection;
+use Doctrine\Common\Annotations\AnnotationReader;
/**
* @todo implement line numbers
@@ -81,14 +83,15 @@ public function getAnnotations(AnnotationManager $annotationManager)
return $this->annotations;
}
- if (($docComment = $this->getDocComment()) == '') {
- return false;
- }
+ $this->annotations = new AnnotationCollection();
+ $reader = new AnnotationReader();
+ $annotations = $reader->getPropertyAnnotations($this);
- $class = $this->getDeclaringClass();
- $cachingFileScanner = new CachingFileScanner($class->getFileName());
- $nameInformation = $cachingFileScanner->getClassNameInformation($class->getName());
- $this->annotations = new AnnotationScanner($annotationManager, $docComment, $nameInformation);
+ foreach ($annotations as $annotation) {
+ if ($annotationManager->hasAnnotation(get_class($annotation))) {
+ $this->annotations[] = $annotation;
+ }
+ }
return $this->annotations;
}
View
5 library/Zend/Di/Definition/Annotation/Inject.php
@@ -4,13 +4,10 @@
use Zend\Code\Annotation\AnnotationInterface;
+/** @Annotation */
class Inject implements AnnotationInterface
{
-
- protected $content = null;
-
public function initialize($content)
{
- $this->content = $content;
}
}
View
5 library/Zend/Di/Definition/Annotation/Instantiator.php
@@ -4,13 +4,10 @@
use Zend\Code\Annotation\AnnotationInterface;
+/** @Annotation */
class Instantiator implements AnnotationInterface
{
-
- protected $content = null;
-
public function initialize($content)
{
- $this->content = $content;
}
}
View
15 library/Zend/Form/Annotation/AbstractAnnotation.php
@@ -29,8 +29,8 @@
/**
* Base annotation for use with form annotation builder.
*
- * Provides a stub for initialize(), allowing for "presence only" annotations
- * (i.e., annotations that define behavior simply by being present).
+ * Provides a stub for initialize(), allowing for "presence only" annotations
+ * (i.e., annotations that define behavior simply by being present).
* Additionally, provides a method for parsing the contents of an annotation
* if provided as a JSON entity.
*
@@ -39,13 +39,16 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
abstract class AbstractAnnotation implements AnnotationInterface
{
+
/**
* Basic annotation; presence only is required
- *
- * @param mixed $content
+ *
+ * @param mixed $content
* @return void
*/
public function initialize($content)
@@ -54,8 +57,8 @@ public function initialize($content)
/**
* Parse and return JSON content
- *
- * @param string $content
+ *
+ * @param string $content
* @return mixed
* @throws JsonException
*/
View
6 library/Zend/Form/Annotation/AllowEmpty.php
@@ -24,7 +24,7 @@
/**
* AllowEmpty annotation
*
- * Presence of this annotation is a hint that the associated
+ * Presence of this annotation is a hint that the associated
* \Zend\InputFilter\Input should enable the allow_empty flag.
*
* @category Zend
@@ -32,7 +32,9 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class AllowEmpty extends AbstractAnnotation
+class AllowEmpty
{
}
View
84 library/Zend/Form/Annotation/AnnotationBuilder.php
@@ -34,7 +34,7 @@
use Zend\Stdlib\ArrayUtils;
/**
- * Parses a class' properties for annotations in order to create a form and
+ * Parses a class' properties for annotations in order to create a form and
* input filter definition.
*
* @category Zend
@@ -46,17 +46,17 @@
class AnnotationBuilder implements EventManagerAwareInterface
{
/**
- * @var AnnotationManager
+ * @var AnnotationManager
*/
protected $annotationManager;
- /**
- * @var EventManagerInterface
+ /**
+ * @var EventManagerInterface
*/
protected $events;
- /**
- * @var Factory
+ /**
+ * @var Factory
*/
protected $formFactory;
@@ -82,8 +82,8 @@ class AnnotationBuilder implements EventManagerAwareInterface
/**
* Set form factory to use when building form from annotations
- *
- * @param Factory $formFactory
+ *
+ * @param Factory $formFactory
* @return AnnotationBuilder
*/
public function setFormFactory(Factory $formFactory)
@@ -94,24 +94,24 @@ public function setFormFactory(Factory $formFactory)
/**
* Set annotation manager to use when building form from annotations
- *
- * @param AnnotationManager $annotationManager
+ *
+ * @param AnnotationManager $annotationManager
* @return AnnotationBuilder
*/
public function setAnnotationManager(AnnotationManager $annotationManager)
{
foreach ($this->defaultAnnotations as $annotationName) {
- $class = __NAMESPACE__ . '\\' . $annotationName;
- $annotationManager->registerAnnotation(new $class);
+ $annotationManager->registerAnnotationClassName(__NAMESPACE__ . '\\' . $annotationName);
}
+
$this->annotationManager = $annotationManager;
return $this;
}
/**
* Set event manager instance
- *
- * @param EventManagerInterface $events
+ *
+ * @param EventManagerInterface $events
* @return AnnotationBuilder
*/
public function setEventManager(EventManagerInterface $events)
@@ -130,7 +130,7 @@ public function setEventManager(EventManagerInterface $events)
* Retrieve form factory
*
* Lazy-loads the default form factory if none is currently set.
- *
+ *
* @return Factory
*/
public function getFormFactory()
@@ -147,7 +147,7 @@ public function getFormFactory()
* Retrieve annotation manager
*
* If none is currently set, creates one with default annotations.
- *
+ *
* @return AnnotationManager
*/
public function getAnnotationManager()
@@ -162,7 +162,7 @@ public function getAnnotationManager()
/**
* Get event manager
- *
+ *
* @return EventManagerInterface
*/
public function events()
@@ -176,10 +176,10 @@ public function events()
/**
* Creates and returns a form specification for use with a factory
*
- * Parses the object provided, and processes annotations for the class and
- * all properties. Information from annotations is then used to create
+ * Parses the object provided, and processes annotations for the class and
+ * all properties. Information from annotations is then used to create
* specifications for a form, its elements, and its input filter.
- *
+ *
* @param string|object $entity Either an instance or a valid class name for an entity
* @return ArrayObject
*/
@@ -226,7 +226,7 @@ public function getFormSpecification($entity)
/**
* Create a form from an object.
*
- * @param string|object $entity
+ * @param string|object $entity
* @return \Zend\Form\Form
*/
public function createForm($entity)
@@ -238,11 +238,11 @@ public function createForm($entity)
/**
* Configure the form specification from annotations
- *
- * @param AnnotationCollection $annotations
- * @param ClassReflection $reflection
- * @param ArrayObject $formSpec
- * @param ArrayObject $filterSpec
+ *
+ * @param AnnotationCollection $annotations
+ * @param ClassReflection $reflection
+ * @param ArrayObject $formSpec
+ * @param ArrayObject $filterSpec
* @return void
* @triggers discoverName
* @triggers configureForm
@@ -258,9 +258,9 @@ protected function configureForm($annotations, $reflection, $formSpec, $filterSp
$events = $this->events();
foreach ($annotations as $annotation) {
$events->trigger(__FUNCTION__, $this, array(
- 'annotation' => $annotation,
+ 'annotation' => $annotation,
'name' => $name,
- 'formSpec' => $formSpec,
+ 'formSpec' => $formSpec,
'filterSpec' => $filterSpec,
));
}
@@ -268,11 +268,11 @@ protected function configureForm($annotations, $reflection, $formSpec, $filterSp
/**
* Configure an element from annotations
- *
- * @param AnnotationCollection $annotations
- * @param \Zend\Code\Reflection\PropertyReflection $reflection
- * @param ArrayObject $formSpec
- * @param ArrayObject $filterSpec
+ *
+ * @param AnnotationCollection $annotations
+ * @param \Zend\Code\Reflection\PropertyReflection $reflection
+ * @param ArrayObject $formSpec
+ * @param ArrayObject $filterSpec
* @return void
* @triggers checkForExclude
* @triggers discoverName
@@ -303,7 +303,7 @@ protected function configureElement($annotations, $reflection, $formSpec, $filte
'name' => $name,
'elementSpec' => $elementSpec,
'inputSpec' => $inputSpec,
- 'formSpec' => $formSpec,
+ 'formSpec' => $formSpec,
'filterSpec' => $filterSpec,
));
foreach ($annotations as $annotation) {
@@ -334,9 +334,9 @@ protected function configureElement($annotations, $reflection, $formSpec, $filte
/**
* Discover the name of the given form or element
- *
- * @param AnnotationCollection $annotations
- * @param \Reflector $reflection
+ *
+ * @param AnnotationCollection $annotations
+ * @param \Reflector $reflection
* @return string
*/
protected function discoverName($annotations, $reflection)
@@ -352,8 +352,8 @@ protected function discoverName($annotations, $reflection)
/**
* Determine if an element is marked to exclude from the definitions
- *
- * @param AnnotationCollection $annotations
+ *
+ * @param AnnotationCollection $annotations
* @return true|false
*/
protected function checkForExclude($annotations)
@@ -369,10 +369,10 @@ protected function checkForExclude($annotations)
/**
* Determine if the type represents a fieldset
*
- * For PHP versions >= 5.3.7, uses is_subclass_of; otherwise, uses
+ * For PHP versions >= 5.3.7, uses is_subclass_of; otherwise, uses
* reflection to determine the interfaces implemented.
- *
- * @param string $type
+ *
+ * @param string $type
* @return bool
*/
protected function isFieldset($type)
View
27 library/Zend/Form/Annotation/Attributes.php
@@ -27,7 +27,7 @@
* Attributes annotation
*
* Expects a JSON-encoded object/associative array as the content. The value is
- * used to set any attributes on the related form object (element, fieldset, or
+ * used to set any attributes on the related form object (element, fieldset, or
* form).
*
* @category Zend
@@ -35,8 +35,10 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class Attributes extends AbstractAnnotation
+class Attributes
{
/**
* @var array
@@ -44,27 +46,24 @@ class Attributes extends AbstractAnnotation
protected $attributes;
/**
- * Receive and process the contents of an annotation
- *
- * @param string $content
- * @return void
+ * @param array $data
*/
- public function initialize($content)
+ public function __construct(array $data)
@weierophinney Owner

Confused here. In the AnnotationManager, you're still using clone + initialize(). Since this constructor has required parameters that derive from the individual annotations' content, how would this work?

@Ocramius Collaborator

I'm not registering this annotation as an instance, I'm just registering its FQCN. The initialization logic of the AnnotationManager is never reached, I only check if the AnnotationManager has this annotation registered. This is why the annotation class names and the annotation instances in the AnnotationManager are now out of sync.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
{
- $attributes = $this->parseJsonContent($content, __METHOD__);
- if (!is_array($attributes)) {
+ if (!isset($data['value']) && !is_array($data['value'])) {
throw new Exception\DomainException(sprintf(
- '%s expects the annotation to define a JSON object or array; received "%s"',
- __METHOD__,
- gettype($attributes)
+ 'Annotation %s expects the annotation to define an array as value, %s given',
+ __CLASS__,
+ gettype($data['value'])
));
}
- $this->attributes = $attributes;
+
+ $this->attributes = $data['value'];
}
/**
* Retrieve the attributes
- *
+ *
* @return null|array
*/
public function getAttributes()
View
32 library/Zend/Form/Annotation/ComposedObject.php
@@ -26,9 +26,9 @@
/**
* ComposedObject annotation
*
- * Use this annotation to specify another object with annotations to parse
- * which you can then add to the form as a fieldset. The value should be a bare
- * string or a JSON-encoded string indicating the fully qualified class name of
+ * Use this annotation to specify another object with annotations to parse
+ * which you can then add to the form as a fieldset. The value should be a bare
+ * string or a JSON-encoded string indicating the fully qualified class name of
* the composed object to use.
*
* @category Zend
@@ -36,8 +36,10 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class ComposedObject extends AbstractAnnotation
+class ComposedObject
{
/**
* @var string
@@ -45,30 +47,24 @@ class ComposedObject extends AbstractAnnotation
protected $composedObject;
/**
- * Receive and process the contents of an annotation
- *
- * @param string $content
- * @return void
+ * @param array $data
*/
- public function initialize($content)
+ public function __construct(array $data)
{
- $input = $content;
- if ('"' === substr($content, 0, 1)) {
- $input = $this->parseJsonContent($content, __METHOD__);
- }
- if (!is_string($input)) {
+ if (!isset($data['value']) && !is_string($data['value'])) {
throw new Exception\DomainException(sprintf(
- '%s expects the annotation to define a string or a JSON string; received "%s"',
+ '%s expects the annotation to define a string; received "%s"',
__METHOD__,
- gettype($input)
+ gettype($data['value'])
));
}
- $this->composedObject = $input;
+
+ $this->composedObject = $data['value'];
}
/**
* Retrieve the composed object classname
- *
+ *
* @return null|string
*/
public function getComposedObject()
View
28 library/Zend/Form/Annotation/ErrorMessage.php
@@ -26,7 +26,7 @@
/**
* ErrorMessage annotation
*
- * Allows providing an error message to seed the Input specification for a
+ * Allows providing an error message to seed the Input specification for a
* given element. The content may either be a bare string or a JSON-encoded
* string.
*
@@ -35,8 +35,10 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class ErrorMessage extends AbstractAnnotation
+class ErrorMessage
{
/**
* @var string
@@ -44,30 +46,24 @@ class ErrorMessage extends AbstractAnnotation
protected $message;
/**
- * Receive and process the contents of an annotation
- *
- * @param string $content
- * @return void
+ * @param array $data
*/
- public function initialize($content)
+ public function __construct(array $data)
{
- $message = $content;
- if ('"' === substr($content, 0, 1)) {
- $message = $this->parseJsonContent($content, __METHOD__);
- }
- if (!is_string($message)) {
+ if (!isset($data['value']) || !(is_string($data['value']) || is_array($data['value']))) {
throw new Exception\DomainException(sprintf(
- '%s expects the annotation to define a string or a JSON string; received "%s"',
+ '%s expects the annotation to define a string or array; received "%s"',
__METHOD__,
- gettype($content)
+ gettype($data['value'])
));
}
- $this->message = $message;
+
+ $this->message = $data['value'];
}
/**
* Retrieve the message
- *
+ *
* @return null|string
*/
public function getMessage()
View
4 library/Zend/Form/Annotation/Exclude.php
@@ -32,7 +32,9 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class Exclude extends AbstractAnnotation
+class Exclude
{
}
View
25 library/Zend/Form/Annotation/Filter.php
@@ -26,7 +26,7 @@
/**
* Filter annotation
*
- * Expects a JSON-encoded object/associative array defining the filter.
+ * Expects a JSON-encoded object/associative array defining the filter.
* Typically, this includes the "name" with an associated string value
* indicating the filter name or class, and optionally an "options" key
* with an object/associative array value of options to pass to the
@@ -40,8 +40,10 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class Filter extends AbstractAnnotation
+class Filter
{
/**
* @var array
@@ -49,27 +51,24 @@ class Filter extends AbstractAnnotation
protected $filter;
/**
- * Receive and process the contents of an annotation
- *
- * @param string $content
- * @return void
+ * @param array $data
*/
- public function initialize($content)
+ public function __construct(array $data)
{
- $filter = $this->parseJsonContent($content, __METHOD__);
- if (!is_array($filter)) {
+ if (!isset($data['value']) && is_array($data['value'])) {
throw new Exception\DomainException(sprintf(
- '%s expects the annotation to define a JSON object or array; received "%s"',
+ '%s expects the annotation to define an array; received "%s"',
__METHOD__,
- gettype($filter)
+ gettype($data['value'])
));
}
- $this->filter = $filter;
+
+ $this->filter = $data['value'];
}
/**
* Retrieve the filter specification
- *
+ *
* @return null|array
*/
public function getFilter()
View
27 library/Zend/Form/Annotation/Flags.php
@@ -26,8 +26,8 @@
/**
* Flags annotation
*
- * Allows passing flags to the form factory. These flags are used to indicate
- * metadata, and typically the priority (order) in which an element will be
+ * Allows passing flags to the form factory. These flags are used to indicate
+ * metadata, and typically the priority (order) in which an element will be
* included.
*
* The value should be a JSON-encoded object/associative array.
@@ -37,8 +37,10 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class Flags extends AbstractAnnotation
+class Flags
{
/**
* @var array
@@ -46,27 +48,24 @@ class Flags extends AbstractAnnotation
protected $flags;
/**
- * Receive and process the contents of an annotation
- *
- * @param string $content
- * @return void
+ * @param array $data
*/
- public function initialize($content)
+ public function __construct(array $data)
{
- $flags = $this->parseJsonContent($content, __METHOD__);
- if (!is_array($flags)) {
+ if (!isset($data['value']) && is_array($data['value'])) {
throw new Exception\DomainException(sprintf(
- '%s expects the annotation to define a JSON object or array; received "%s"',
+ '%s expects the annotation to define an array; received "%s"',
__METHOD__,
- gettype($flags)
+ gettype($data['value'])
));
}
- $this->flags = $flags;
+
+ $this->flags = $data['value'];
}
/**
* Retrieve the flags
- *
+ *
* @return null|array
*/
public function getFlags()
View
32 library/Zend/Form/Annotation/Hydrator.php
@@ -27,7 +27,7 @@
* Hydrator annotation
*
* Use this annotation to specify a specific hydrator class to use with the form.
- * The value should be a bare string or a JSON-encoded string indicating the
+ * The value should be a bare string or a JSON-encoded string indicating the
* fully qualified class name of the hydrator to use.
*
* @category Zend
@@ -35,8 +35,10 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class Hydrator extends AbstractAnnotation
+class Hydrator
{
/**
* @var string
@@ -44,34 +46,24 @@ class Hydrator extends AbstractAnnotation
protected $hydrator;
/**
- * Receive and process the contents of an annotation
- *
- * @param string $content
- * @return void
+ * @param array $data
*/
- public function initialize($content)
+ public function __construct(array $data)
{
- $hydrator = $content;
-
- if ('"' === substr($hydrator, 0, 1)) {
- // Look for unescaped NS, and escape them so the parser knows what to do
- $hydrator = preg_replace('#(\\\\)(?!\\\\)#', '$1$1', $hydrator);
- $hydrator = $this->parseJsonContent($hydrator, __METHOD__);
- }
-
- if (!is_string($hydrator)) {
+ if (!isset($data['value']) && !is_string($data['value'])) {
throw new Exception\DomainException(sprintf(
- '%s expects the annotation to define a string or a JSON string; received "%s"',
+ '%s expects the annotation to define a string; received "%s"',
__METHOD__,
- gettype($hydrator)
+ gettype($data['value'])
));
}
- $this->hydrator = $hydrator;
+
+ $this->hydrator = $data['value'];
}
/**
* Retrieve the hydrator class
- *
+ *
* @return null|string
*/
public function getHydrator()
View
28 library/Zend/Form/Annotation/Input.php
@@ -27,7 +27,7 @@
* Input annotation
*
* Use this annotation to specify a specific input class to use with an element.
- * The value should be a bare string or a JSON-encoded string indicating the
+ * The value should be a bare string or a JSON-encoded string indicating the
* fully qualified class name of the input to use.
*
* @category Zend
@@ -35,8 +35,10 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class Input extends AbstractAnnotation
+class Input
{
/**
* @var string
@@ -44,30 +46,24 @@ class Input extends AbstractAnnotation
protected $input;
/**
- * Receive and process the contents of an annotation
- *
- * @param string $content
- * @return void
+ * @param array $data
*/
- public function initialize($content)
+ public function __construct(array $data)
{
- $input = $content;
- if ('"' === substr($content, 0, 1)) {
- $input = $this->parseJsonContent($content, __METHOD__);
- }
- if (!is_string($input)) {
+ if (!isset($data['value']) && !is_string($data['value'])) {
throw new Exception\DomainException(sprintf(
- '%s expects the annotation to define a string or a JSON string; received "%s"',
+ '%s expects the annotation to define a string; received "%s"',
__METHOD__,
- gettype($input)
+ gettype($data['value'])
));
}
- $this->input = $input;
+
+ $this->input = $data['value'];
}
/**
* Retrieve the input class
- *
+ *
* @return null|string
*/
public function getInput()
View
34 library/Zend/Form/Annotation/InputFilter.php
@@ -26,8 +26,8 @@
/**
* InputFilter annotation
*
- * Use this annotation to specify a specific input filter class to use with the
- * form. The value should be a bare string or a JSON-encoded string indicating
+ * Use this annotation to specify a specific input filter class to use with the
+ * form. The value should be a bare string or a JSON-encoded string indicating
* the fully qualified class name of the input filter to use.
*
* @category Zend
@@ -35,8 +35,10 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class InputFilter extends AbstractAnnotation
+class InputFilter
{
/**
* @var string
@@ -44,34 +46,24 @@ class InputFilter extends AbstractAnnotation
protected $inputFilter;
/**
- * Receive and process the contents of an annotation
- *
- * @param string $content
- * @return void
+ * @param array $data
*/
- public function initialize($content)
+ public function __construct(array $data)
{
- $inputFilter = $content;
-
- if ('"' === substr($inputFilter, 0, 1)) {
- // Look for unescaped NS, and escape them so the parser knows what to do
- $inputFilter = preg_replace('#(\\\\)(?!\\\\)#', '$1$1', $inputFilter);
- $inputFilter = $this->parseJsonContent($inputFilter, __METHOD__);
- }
-
- if (!is_string($inputFilter)) {
+ if (!isset($data['value']) && !is_string($data['value'])) {
throw new Exception\DomainException(sprintf(
- '%s expects the annotation to define a string or a JSON string; received "%s"',
+ '%s expects the annotation to define a string; received "%s"',
__METHOD__,
- gettype($inputFilter)
+ gettype($data['value'])
));
}
- $this->inputFilter = $inputFilter;
+
+ $this->inputFilter = $data['value'];
}
/**
* Retrieve the input filter class
- *
+ *
* @return null|string
*/
public function getInputFilter()
View
26 library/Zend/Form/Annotation/Name.php
@@ -35,8 +35,10 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class Name extends AbstractAnnotation
+class Name
{
/**
* @var string
@@ -44,30 +46,24 @@ class Name extends AbstractAnnotation
protected $name;
/**
- * Receive and process the contents of an annotation
- *
- * @param string $content
- * @return void
+ * @param array $data
*/
- public function initialize($content)
+ public function __construct(array $data)
{
- $name = $content;
- if ('"' === substr($content, 0, 1)) {
- $name = $this->parseJsonContent($content, __METHOD__);
- }
- if (!is_string($name)) {
+ if (!isset($data['value']) && !is_string($data['value'])) {
throw new Exception\DomainException(sprintf(
- '%s expects the annotation to define a string or a JSON string; received "%s"',
+ '%s expects the annotation to define a string; received "%s"',
__METHOD__,
- gettype($name)
+ gettype($data['value'])
));
}
- $this->name = $name;
+
+ $this->name = $data['value'];
}
/**
* Retrieve the name
- *
+ *
* @return null|string
*/
public function getName()
View
35 library/Zend/Form/Annotation/Required.php
@@ -21,7 +21,7 @@
namespace Zend\Form\Annotation;
-use Zend\Filter\Boolean as BooleanFilter;
+use Zend\Form\Exception;
/**
* Required annotation
@@ -37,43 +37,40 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class Required extends AbstractAnnotation
+class Required
{
/**
* @var bool
*/
- protected $required = true;
+ protected $value = true;
/**
- * Receive and process the contents of an annotation
- *
- * @param string $content
- * @return void
+ * @param array $data
*/
- public function initialize($content)
+ public function __construct(array $data)
{
- $required = $content;
- if ('"' === substr($content, 0, 1)) {
- $required = $this->parseJsonContent($content, __METHOD__);
- }
-
- if (!is_bool($required)) {
- $filter = new BooleanFilter();
- $required = $filter->filter($required);
+ if (!isset($data['value']) && !is_bool($data['value'])) {
+ throw new Exception\DomainException(sprintf(
+ '%s expects the annotation to define a boolean; received "%s"',
+ __METHOD__,
+ gettype($data['value'])
+ ));
}
- $this->required = $required;
+ $this->value = $data['value'];
}
/**
* Get value of required flag
- *
+ *
* @return bool
*/
public function getRequired()
{
- return $this->required;
+ return $this->value;
}
}
View
28 library/Zend/Form/Annotation/Type.php
@@ -26,7 +26,7 @@
/**
* Type annotation
*
- * Use this annotation to specify the specific \Zend\Form class to use when
+ * Use this annotation to specify the specific \Zend\Form class to use when
* building the form, fieldset, or element. The value should be a bare string
* or JSON-encoded string, and represent a fully qualified classname.
*
@@ -35,8 +35,10 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class Type extends AbstractAnnotation
+class Type
{
/**
* @var string
@@ -44,30 +46,24 @@ class Type extends AbstractAnnotation
protected $type;
/**
- * Receive and process the contents of an annotation
- *
- * @param string $content
- * @return void
+ * @param array $data
*/
- public function initialize($content)
+ public function __construct(array $data)
{
- $type = $content;
- if ('"' === substr($content, 0, 1)) {
- $type = $this->parseJsonContent($content, __METHOD__);
- }
- if (!is_string($type)) {
+ if (!isset($data['value']) && !is_string($data['value'])) {
throw new Exception\DomainException(sprintf(
- '%s expects the annotation to define a string or a JSON string; received "%s"',
+ '%s expects the annotation to define a string; received "%s"',
__METHOD__,
- gettype($type)
+ gettype($data['value'])
));
}
- $this->type = $type;
+
+ $this->type = $data['value'];
}
/**
* Retrieve the class type
- *
+ *
* @return null|string
*/
public function getType()
View
25 library/Zend/Form/Annotation/Validator.php
@@ -26,7 +26,7 @@
/**
* Validator annotation
*
- * Expects a JSON-encoded object/associative array defining the validator.
+ * Expects a JSON-encoded object/associative array defining the validator.
* Typically, this includes the "name" with an associated string value
* indicating the validator name or class, and optionally an "options" key
* with an object/associative array value of options to pass to the
@@ -40,8 +40,10 @@
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @Annotation
*/
-class Validator extends AbstractAnnotation
+class Validator
{
/**
* @var array
@@ -49,27 +51,24 @@ class Validator extends AbstractAnnotation
protected $validator;
/**
- * Receive and process the contents of an annotation
- *
- * @param string $content
- * @return void
+ * @param array $data
*/
- public function initialize($content)
+ public function __construct(array $data)
{
- $validator = $this->parseJsonContent($content, __METHOD__);
- if (!is_array($validator)) {
+ if (!(isset($data['value']) && is_array($data['value']))) {
throw new Exception\DomainException(sprintf(
- '%s expects the annotation to define a JSON object or array; received "%s"',
+ '%s expects the annotation to define an array; received "%s"',
__METHOD__,
- gettype($validator)
+ gettype($data['value'])
));
}
- $this->validator = $validator;
+
+ $this->validator = $data['value'];
}
/**
* Retrieve the validator specification
- *
+ *
* @return null|array
*/
public function getValidator()
View
13 tests/Zend/Code/Annotation/AnnotationManagerTest.php
@@ -26,6 +26,11 @@
class AnnotationManagerTest extends TestCase
{
+ /**
+ * @var \Zend\Code\Annotation\AnnotationManager
+ */
+ protected $manager;
+
public function setUp()
{
$this->manager = new Annotation\AnnotationManager();
@@ -79,4 +84,12 @@ public function testAllowsSpecifyingAliases()
$this->assertNotSame($bar, $test);
$this->assertEquals('test content', $test->content);
}
+
+ public function testAllowsRegisteringClassNames()
+ {
+ $this->manager->registerAnnotationClassName(__NAMESPACE__ . '\TestAsset\Bar');
+ $this->assertTrue($this->manager->hasAnnotation(__NAMESPACE__ . '\TestAsset\Bar'));
+ $this->setExpectedException('Zend\Code\Exception\RuntimeException');
+ $this->manager->createAnnotation(__NAMESPACE__ . '\TestAsset\Bar');
+ }
}
View
1  tests/Zend/Code/Annotation/TestAsset/Bar.php
@@ -23,6 +23,7 @@
use Zend\Code\Annotation\AnnotationInterface;
+/** @Annotation */
class Bar implements AnnotationInterface
{
public $content;
View
1  tests/Zend/Code/Annotation/TestAsset/Foo.php
@@ -23,6 +23,7 @@
use Zend\Code\Annotation\AnnotationInterface;
+/** @Annotation */
class Foo implements AnnotationInterface
{
public $content;
View
2  tests/Zend/Code/Reflection/ClassReflectionTest.php
@@ -97,7 +97,7 @@ public function testGetContentsReturnsContents()
protected \$_prop1 = null;
/**
- * @Sample({"foo":"bar"})
+ * @Sample(content="{""foo"":""bar""}")
*/
protected \$_prop2 = null;
View
7 tests/Zend/Code/Reflection/PropertyReflectionTest.php
@@ -43,15 +43,14 @@ public function testDeclaringClassReturn()
public function testAnnotationScanningIsPossible()
{
- $manager = new AnnotationManager(array(
- new TestAsset\SampleAnnotation(),
- ));
+ $manager = new AnnotationManager();
+ $manager->registerAnnotationClassName('ZendTest\Code\Reflection\TestAsset\SampleAnnotation');
$property = new \Zend\Code\Reflection\PropertyReflection('ZendTest\Code\Reflection\TestAsset\TestSampleClass2', '_prop2');
$annotations = $property->getAnnotations($manager);
$this->assertInstanceOf('Zend\Code\Annotation\AnnotationCollection', $annotations);
$this->assertTrue($annotations->hasAnnotation('ZendTest\Code\Reflection\TestAsset\SampleAnnotation'));
$found = false;
- foreach ($annotations as $key => $annotation) {
+ foreach ($annotations as $annotation) {
if (!$annotation instanceof TestAsset\SampleAnnotation) {
continue;
}
View
8 tests/Zend/Code/Reflection/TestAsset/SampleAnnotation.php
@@ -4,12 +4,18 @@
use Zend\Code\Annotation\AnnotationInterface;
+/** @Annotation */
class SampleAnnotation implements AnnotationInterface
{
public $content;
+ public function __construct($data)
+ {
+ $this->content = __CLASS__ . ': ' . $data['content'];
+ }
+
public function initialize($content)
{
- $this->content = __CLASS__ . ': ' . $content;
+ // @todo remove
}
}
View
4 tests/Zend/Code/Reflection/TestAsset/TestSampleClass2.php
@@ -1,4 +1,4 @@
-<?php
+<?php
namespace ZendTest\Code\Reflection\TestAsset;
@@ -9,7 +9,7 @@ class TestSampleClass2 implements \IteratorAggregate
protected $_prop1 = null;
/**
- * @Sample({"foo":"bar"})
+ * @Sample(content="{""foo"":""bar""}")
*/
protected $_prop2 = null;
View
1  tests/Zend/Code/Scanner/TestAsset/Annotation/Bar.php
@@ -4,6 +4,7 @@
use Zend\Code\Annotation\AnnotationInterface;
+/** @Annotation */
class Bar implements AnnotationInterface
{
protected $content = null;
View
1  tests/Zend/Code/Scanner/TestAsset/Annotation/Foo.php
@@ -4,6 +4,7 @@
use Zend\Code\Annotation\AnnotationInterface;
+/** @Annotation */
class Foo implements AnnotationInterface
{
protected $content = null;
View
6 tests/Zend/Form/TestAsset/Annotation/ComplexEntity.php
@@ -6,12 +6,12 @@
/**
* @Annotation\Name("user")
* @Annotation\Attributes({"legend":"Register"})
- * @Annotation\Hydrator(Zend\Stdlib\Hydrator\ObjectProperty)
+ * @Annotation\Hydrator("Zend\Stdlib\Hydrator\ObjectProperty")
*/
class ComplexEntity
{
/**
- * @Annotation\ErrorMessage('Invalid or missing username')
+ * @Annotation\ErrorMessage("Invalid or missing username")
* @Annotation\Filter({"name":"StringTrim"})
* @Annotation\Validator({"name":"NotEmpty"})
* @Annotation\Validator({"name":"StringLength","options":{"min":3,"max":25}})
@@ -38,7 +38,7 @@ class ComplexEntity
* @Annotation\AllowEmpty()
* @Annotation\Required(false)
* @Annotation\Attributes({"type":"text","label":"Provide a URL for your avatar (optional):"})