1Custom Annotation Classes
2=========================
3
4If you want to define your own annotations you just have to group them in a namespace and register this namespace
5in the AnnotationRegistry. Annotation classes have to contain a class-level docblock with the text ``@Annotation``:
6
7.. code-block:: php
8
9    namespace MyCompany\Annotations;
10
11    /** @Annotation */
12    class Bar
13    {
14        // some code
15    }
16
17Inject annotation values
18------------------------
19
20The annotation parser check if the annotation constructor has arguments,
21if so then we will pass the value array, otherwise will try to inject values into public properties directly:
22
23
24.. code-block:: php
25
26    namespace MyCompany\Annotations;
27
28    /**
29     * @Annotation
30     *
31     * Some Annotation using a constructor
32     */
33    class Bar
34    {
35        private $foo;
36
37        public function __construct(array $values)
38        {
39            $this->foo = $values['foo'];
40        }
41    }
42
43    /**
44     * @Annotation
45     *
46     * Some Annotation without a constructor
47     */
48    class Foo
49    {
50        public $bar;
51    }
52
53Annotation Target
54-----------------
55
56``@Target`` indicates the kinds of class element to which an annotation type is applicable.
57Then you could define one or more targets:
58
59-  ``CLASS`` Allowed in the class docblock
60-  ``PROPERTY`` Allowed in the property docblock
61-  ``METHOD`` Allowed in the method docblock
62-  ``ALL`` Allowed in the class, property and method docblock
63-  ``ANNOTATION`` Allowed inside other annotations
64
65If the annotations is not allowed in the current context you got an ``AnnotationException``
66
67.. code-block:: php
68
69    namespace MyCompany\Annotations;
70
71    /**
72     * @Annotation
73     * @Target({"METHOD","PROPERTY"})
74     */
75    class Bar
76    {
77        // some code
78    }
79
80    /**
81     * @Annotation
82     * @Target("CLASS")
83     */
84    class Foo
85    {
86        // some code
87    }
88
89Attribute types
90---------------
91
92Annotation parser check the given parameters using the phpdoc annotation ``@var``,
93The data type could be validated using the ``@var`` annotation on the annotation properties
94or using the annotations ``@Attributes`` and ``@Attribute``.
95
96If the data type not match you got an ``AnnotationException``
97
98.. code-block:: php
99
100    namespace MyCompany\Annotations;
101
102    /**
103     * @Annotation
104     * @Target({"METHOD","PROPERTY"})
105     */
106    class Bar
107    {
108        /** @var mixed */
109        public $mixed;
110
111        /** @var boolean */
112        public $boolean;
113
114        /** @var bool */
115        public $bool;
116
117        /** @var float */
118        public $float;
119
120        /** @var string */
121        public $string;
122
123        /** @var integer */
124        public $integer;
125
126        /** @var array */
127        public $array;
128
129        /** @var SomeAnnotationClass */
130        public $annotation;
131
132        /** @var array<integer> */
133        public $arrayOfIntegers;
134
135        /** @var array<SomeAnnotationClass> */
136        public $arrayOfAnnotations;
137    }
138
139    /**
140     * @Annotation
141     * @Target({"METHOD","PROPERTY"})
142     * @Attributes({
143     *   @Attribute("stringProperty", type = "string"),
144     *   @Attribute("annotProperty",  type = "SomeAnnotationClass"),
145     * })
146     */
147    class Foo
148    {
149        public function __construct(array $values)
150        {
151            $this->stringProperty = $values['stringProperty'];
152            $this->annotProperty = $values['annotProperty'];
153        }
154
155        // some code
156    }
157
158Annotation Required
159-------------------
160
161``@Required`` indicates that the field must be specified when the annotation is used.
162If it is not used you get an ``AnnotationException`` stating that this value can not be null.
163
164Declaring a required field:
165
166.. code-block:: php
167
168    /**
169     * @Annotation
170     * @Target("ALL")
171     */
172    class Foo
173    {
174        /** @Required */
175        public $requiredField;
176    }
177
178Usage:
179
180.. code-block:: php
181
182    /** @Foo(requiredField="value") */
183    public $direction;                  // Valid
184
185     /** @Foo */
186    public $direction;                  // Required field missing, throws an AnnotationException
187
188
189Enumerated values
190-----------------
191
192- An annotation property marked with ``@Enum`` is a field that accept a fixed set of scalar values.
193- You should use ``@Enum`` fields any time you need to represent fixed values.
194- The annotation parser check the given value and throws an ``AnnotationException`` if the value not match.
195
196
197Declaring an enumerated property:
198
199.. code-block:: php
200
201    /**
202     * @Annotation
203     * @Target("ALL")
204     */
205    class Direction
206    {
207        /**
208         * @Enum({"NORTH", "SOUTH", "EAST", "WEST"})
209         */
210        public $value;
211    }
212
213Annotation usage:
214
215.. code-block:: php
216
217    /** @Direction("NORTH") */
218    public $direction;                  // Valid value
219
220     /** @Direction("NORTHEAST") */
221    public $direction;                  // Invalid value, throws an AnnotationException
222
223
224Constants
225---------
226
227The use of constants and class constants are available on the annotations parser.
228
229The following usage are allowed:
230
231.. code-block:: php
232
233    namespace MyCompany\Entity;
234
235    use MyCompany\Annotations\Foo;
236    use MyCompany\Annotations\Bar;
237    use MyCompany\Entity\SomeClass;
238
239    /**
240     * @Foo(PHP_EOL)
241     * @Bar(Bar::FOO)
242     * @Foo({SomeClass::FOO, SomeClass::BAR})
243     * @Bar({SomeClass::FOO_KEY = SomeClass::BAR_VALUE})
244     */
245    class User
246    {
247    }
248
249
250Be careful with constants and the cache !
251
252.. note::
253
254    The cached reader will not re-evaluate each time an annotation is loaded from cache.
255    When a constant is changed the cache must be cleaned.
256
257
258Usage
259-----
260
261Using the library API is simple. Using the annotations described in the previous section
262you can now annotate other classes with your annotations:
263
264.. code-block:: php
265
266    namespace MyCompany\Entity;
267
268    use MyCompany\Annotations\Foo;
269    use MyCompany\Annotations\Bar;
270
271    /**
272     * @Foo(bar="foo")
273     * @Bar(foo="bar")
274     */
275    class User
276    {
277    }
278
279Now we can write a script to get the annotations above:
280
281.. code-block:: php
282
283    $reflClass = new ReflectionClass('MyCompany\Entity\User');
284    $classAnnotations = $reader->getClassAnnotations($reflClass);
285
286    foreach ($classAnnotations AS $annot) {
287        if ($annot instanceof \MyCompany\Annotations\Foo) {
288            echo $annot->bar; // prints "foo";
289        } else if ($annot instanceof \MyCompany\Annotations\Bar) {
290            echo $annot->foo; // prints "bar";
291        }
292    }
293
294You have a complete API for retrieving annotation class instances
295from a class, property or method docblock:
296
297
298Reader API
299~~~~~~~~~~
300
301Access all annotations of a class
302^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
303
304.. code-block:: php
305
306    public function getClassAnnotations(\ReflectionClass $class);
307
308Access one annotation of a class
309^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
310
311.. code-block:: php
312
313    public function getClassAnnotation(\ReflectionClass $class, $annotationName);
314
315Access all annotations of a method
316^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
317
318.. code-block:: php
319
320    public function getMethodAnnotations(\ReflectionMethod $method);
321
322Access one annotation of a method
323^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
324
325.. code-block:: php
326
327    public function getMethodAnnotation(\ReflectionMethod $method, $annotationName);
328
329Access all annotations of a property
330^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
331
332.. code-block:: php
333
334    public function getPropertyAnnotations(\ReflectionProperty $property);
335
336Access one annotation of a property
337^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
338
339.. code-block:: php
340
341    public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName);
342