Skip to content

Commit

Permalink
Merge pull request #97 from php-annotations/37-readthedocs
Browse files Browse the repository at this point in the history
Initial documentation version
  • Loading branch information
Alexander Obuhovich committed Apr 11, 2015
2 parents f254702 + d7243b1 commit 630792b
Show file tree
Hide file tree
Showing 15 changed files with 1,142 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ https://github.com/php-annotations/php-annotations

For documentation and updates, please visit the project Wiki:

https://github.com/php-annotations/php-annotations/wiki
http://php-annotations.readthedocs.org/


## Project Structure
Expand Down
37 changes: 17 additions & 20 deletions demo/wiki-doc.php
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
<?php

## This script generates formatted documentation for the demo, in Wiki format.
## This script generates formatted documentation for the demo, in RST format.

header('Content-type: text/plain');
echo 'File: **demo/index.php**' . PHP_EOL;

echo '<table border="0" cellpadding="0" cellspacing="0">' . "\n";
echo '<tr><td valign="top" width="300">' . "\n";
echo "<h3>demo/index.php</h3>\n";
$codeStart = 1;

$code = false;

foreach (file('index.php') as $line) {
foreach (file('index.php') as $lineNumber => $line) {
if (substr(ltrim($line), 0, 2) == '##') {
if ($code) {
echo "</pre>\n";
echo "</td></tr>";
echo '<tr><td valign="top"><br/>' . "\n";
$code = false;
if ($codeStart !== false) {
echo PHP_EOL;
echo '.. literalinclude:: ../demo/index.php' . PHP_EOL;
echo ' :lines: ' . ($codeStart + 1) . '-' . $lineNumber . PHP_EOL;
echo PHP_EOL;
$codeStart = false;
}

echo htmlspecialchars(rtrim(substr(ltrim($line), 3))) . "\n";
echo str_replace('`', '``', rtrim(substr(ltrim($line), 3))) . PHP_EOL;
} else {
// it's code
if (!$code) {
echo '</td><td valign="top">' . "\n";
echo "<pre>";
$code = true;
if ($codeStart === false) {
$codeStart = $lineNumber;
}

echo htmlspecialchars($line);
}
}

echo '</table>';
echo PHP_EOL;
echo '.. literalinclude:: ../demo/index.php' . PHP_EOL;
echo ' :lines: ' . ($codeStart + 1) . '-' . ($lineNumber + 1) . PHP_EOL;
echo PHP_EOL;
1 change: 1 addition & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build
100 changes: 100 additions & 0 deletions docs/AnnotationLibrary.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
Standard annotations library
============================
A library of standard annotations will eventually be (**but is not currently**) part of this package.

.. note::
Experienced developers (primarily maintainers of libraries that rely on annotations), are encouraged to
contribute or suggest changes or additions to the standard library.

The standard library of annotations generally belong to one (or more) of the following categories:

* **Reflective annotations** to describe aspects of code semantics not natively supported by the PHP language.
* **Data annotations** to describe storage/schema aspects of persistent types.
* **Display annotations** to specify input types, labels, display-formatting and other UI-related aspects of your
domain- or view-models.
* **Validation annotations** to specify property/object validators for domain- or form-models, etc.
* **PHP-DOC annotations** - a subset of the standard PHP-DOC annotations.

Some of the annotations belong to more than one of these categories - the standard PHP-DOC annotations generally fall
into at least one of the other categories.

Most of the standard annotations were referenced from annotations that ship with other languages and frameworks that
support annotations natively, mainly .NET and Java. Due to the strict nature of these languages, as compared to the
loose nature of PHP, the standard annotations were not merely ported from other languages, but adapted to better fit
with good, modern PHP code.

Available Annotations
^^^^^^^^^^^^^^^^^^^^^

.. note::
The annotation library is not yet available, or still in development.

Category: Reflective, PHP-DOC
-----------------------------
+-------------------------+----------+------------------------------------------------------------+
| Annotation | Scope | Description |
+=========================+==========+============================================================+
| MethodAnnotation | Class | Defines a magic/virtual method. |
+-------------------------+----------+------------------------------------------------------------+
| ParamAnnotation | Method | Defines a method-parameter’s type. |
+-------------------------+----------+------------------------------------------------------------+
| PropertyAnnotation | Class | Defines a magic/virtual property and it’s type. |
+-------------------------+----------+------------------------------------------------------------+
| PropertyReadAnnotation | Class | Defines a magic/virtual read-only property and it’s type. |
+-------------------------+----------+------------------------------------------------------------+
| PropertyWriteAnnotation | Class | Defines a magic/virtual write-only property and it’s type. |
+-------------------------+----------+------------------------------------------------------------+
| ReturnAnnotation | Method | Defines the return-type of a function or method. |
+-------------------------+----------+------------------------------------------------------------+
| VarAnnotation | Property | Specifies validation of various common property types. |
+-------------------------+----------+------------------------------------------------------------+
| TypeAnnotation | Property | Specifies validation of various common property types. |
+-------------------------+----------+------------------------------------------------------------+

Category: Display
-----------------
+----------------------+----------------+-------------------------------------------------------+
| Annotation | Scope | Description |
+======================+================+=======================================================+
| DisplayAnnotation | Property | Defines various display-related metadata, such as |
| | | grouping and ordering. |
+----------------------+----------------+-------------------------------------------------------+
| EditableAnnotation | Property | Indicates whether a property should be user-editable |
| | | or not. |
+----------------------+----------------+-------------------------------------------------------+
| EditorAnnotation | Property | Specifies a view-name (or path, or helper) to use for |
| | | editing purposes - overrides ViewAnnotation when |
| | | rendering inputs. |
+----------------------+----------------+-------------------------------------------------------+
| FormatAnnotation | Property | Specifies how to display or format a property value. |
+----------------------+----------------+-------------------------------------------------------+
| TextAnnotation | Property | Defines various text (labels, hints, etc.) to be |
| | | displayed with the annotated property. |
+----------------------+----------------+-------------------------------------------------------+
| ViewAnnotation | Property/class | Specifies a view-name (or path) to use for |
| | | display/editing purposes. |
+----------------------+----------------+-------------------------------------------------------+

Category: Validation
--------------------
+----------------------+----------+--------------------------------------------------+
| Annotation | Scope | Description |
+======================+==========+==================================================+
| EnumAnnotation | Property | Specifies validation against a fixed enumeration |
| | | of valid choices. |
+----------------------+----------+--------------------------------------------------+
| LengthAnnotation | Property | Specifies validation of a string, requiring a |
| | | minimum and/or maximum length. |
+----------------------+----------+--------------------------------------------------+
| MatchAnnotation | Property | Specifies validation of a string against a |
| | | regular expression pattern. |
+----------------------+----------+--------------------------------------------------+
| RangeAnnotation | Property | Specifies validation against a minimum and/or |
| | | maximum numeric value. |
+----------------------+----------+--------------------------------------------------+
| RequiredAnnotation | Property | Specifies validation requiring a non-empty |
| | | value. |
+----------------------+----------+--------------------------------------------------+
| ValidateAnnotation | Class | Specifies a custom validation callback |
| | | method. |
+----------------------+----------+--------------------------------------------------+
88 changes: 88 additions & 0 deletions docs/ConsumingAnnotations.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
Working with the Annotation Manager
===================================
.. note:: Some programmers learn best by seeing a practical example - if you belong to those who learn best by seeing
things applied, you should start by taking a look at the :doc:`demo script <DemoScript>`, which provides
a minimal, yet practical, real-world example of applying and consuming source code annotations.

The annotation framework lives in the ``mindplay\annotations`` namespace, and the library
of :doc:`standard annotations <AnnotationLibrary>` lives in the `mindplay\\annotations\\standard`_ namespace.

The heart of the annotation framework is the `AnnotationManager`_ class, which provides the following functionality:

* Inspecting (and filtering) annotations
* Annotation registry and name-resolution
* Caching annotations in the local filesystem (underneath the hood)

Behind the scenes, the ``AnnotationManager`` relies on the `AnnotationParser`_ to perform the parsing and compilation
of annotations into cacheable scripts.

For convenience, a static (singleton) wrapper-class for the annotation manager is also available.
This class is named `Annotations`_ - we will use it in the following examples.

Loading and Importing
^^^^^^^^^^^^^^^^^^^^^
Going into details about `autoloading`_ and `importing`_ the annotation classes is beyond the scope of this article.

I will assume you are familiar with these language features, and in the following examples, it is implied that
the static wrapper-class has been imported, e.g.:

.. code-block:: php
use mindplay\annotations\Annotations;
Configuring the Annotation Manager
----------------------------------
For convenience, the static ``Annotations`` class provides a public ``$config`` array - the keys in this array are
applied the singleton ``AnnotationManager`` instance on first use, for example:

.. code-block:: php
Annotations::$config = array(
'cachePath' => sys_get_temp_dir()
);
In this example, when the ``AnnotationManager`` is initialized, the public ``$cachePath`` property is set to point
to the local temp-dir on your system.

Other configurable properties include:

+------------------+----------+---------------+
| Property | Type | Description |
+==================+==========+===============+
| ``$fileMode`` | int ||
+------------------+----------+---------------+
| ``$autoload`` | bool ||
+------------------+----------+---------------+
| ``$cachePath`` | string ||
+------------------+----------+---------------+
| ``$cacheSeed`` | string ||
+------------------+----------+---------------+
| ``$suffix`` | string ||
+------------------+----------+---------------+
| ``$namespace`` | string ||
+------------------+----------+---------------+
| ``$registry`` | array ||
+------------------+----------+---------------+

The Annotation Registry
-----------------------
...

Inspecting Annotations
^^^^^^^^^^^^^^^^^^^^^^
...

Annotation Name Resolution
--------------------------
...

Filtering Annotations
---------------------
...

.. _mindplay\\annotations\\standard: https://github.com/php-annotations/php-annotations/tree/master/src/annotations/standard
.. _AnnotationManager: https://github.com/php-annotations/php-annotations/blob/master/src/annotations/AnnotationManager.php
.. _AnnotationParser: https://github.com/php-annotations/php-annotations/blob/master/src/annotations/AnnotationParser.php
.. _Annotations: https://github.com/php-annotations/php-annotations/blob/master/src/annotations/Annotations.php
.. _autoloading: http://php.net/manual/en/language.oop5.autoload.php
.. _importing: http://php.net/manual/en/language.namespaces.importing.php
82 changes: 82 additions & 0 deletions docs/CustomAnnotations.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
Writing your own types of annotations
=====================================

What is an Annotation?
^^^^^^^^^^^^^^^^^^^^^^
An annotation is just a class - it is merely the way it gets initialized (and instantiated) that makes it an annotation.

In order for a class to work as an annotation, it must:

* have a constructor with no arguments - e.g.: ``function __construct()`` (or no constructor)
* implement the ``IAnnotation`` interface - e.g.: ``function initAnnotation($properties)``
* be annotated with an ``@usage`` annotation - see below for details.

Beyond the quantitative requirements, you should make some qualitative considerations. Here are some things to consider:

* Annotations are specifications - they can provide default values for various components, or define additional
behaviors or metadata. But your components should not *depend* on a specific annotation - if you find you're trying
to define an annotation that is *required* for your components to operate, there's a good chance you'd be better off
defining that behavior as an interface.
* Try to design your annotation types for general purposes, rather than for a specific purpose - there is a good chance
you may be able to use the same metadata in new ways at a later time. Choose broad terms for class-names (and
property-names) so as not to imply any specific meaning - just describe the information, not it's purpose.
* Do you need a new annotation type, or can one of the existing types be used to define what you're trying to specify?
Be careful not to duplicate your specifications, as this leads to situations where you'll be forced to write the same
metadata in two different formats - the point of annotations is to help eliminate this kind of redundancy and overhead.

UsageAnnotation
^^^^^^^^^^^^^^^
The `UsageAnnotation`_ class defines the constraints and behavior of an annotation.

An instance of the built-in ``@usage`` annotation must be applied to every annotation class, or to it's ancestor -
the ``@usage`` annotation itself is inheritable, and can be overridden by a child class.

The standard ``@length`` annotation, for example, defines it's use as follows:

.. code-block:: php
/**
* Specifies validation of a string, requiring a minimum and/or maximum length.
*
* @usage('property'=>true, 'inherited'=>true)
*/
class LengthAnnotation extends ValidationAnnotationBase
{
...
}
This specification indicates that the annotation may be applied to properties, and that the annotation can be
inherited by classes which extend a class to which the annotation was applied.

The ``@usage`` annotation is permissive; that is, all of it's properties are ``false`` by default - you have to turn
on any of the permissions/features that apply to your annotation class, by setting each property to ``true``.

Let's review the available properties.

* The ``$class``, ``$property`` and ``$method`` flags simply specify to which type(s) of source-code elements an
annotation is applicable.
* The ``$multiple`` flag specifies whether more than one annotation of this type may be applied to the same source-code
element
* The ``$inherited`` flag specifies whether the annotation(s) will be inherited by a class extending the class to which
the annotations were applied.

Different combinations of the ``$multiple`` and ``$inherited`` flags result in the following behavior:

+--------------------------+--------------------------+--------------------------+
| | ``$multiple=true`` | ``$multiple=false`` |
+--------------------------+--------------------------+--------------------------+
| ``$inherited=true`` | Multiples allowed and | Only one allowed, |
| | inherited | inherited with override |
+--------------------------+--------------------------+--------------------------+
| ``$inherited=false`` | Multiples allowed, not | Only one allowed, not |
| | inherited | inherited |
+--------------------------+--------------------------+--------------------------+

Note that annotations with ``$multiple=false`` and ``$inherited=true`` are a special case, in which only one
annotation is allowed on the same code-element, and is inherited - but can be overridden by a child-class
which would otherwise inherit the annotation.

When overriding an inherited annotation, it's important to understand that the individual properties of an annotation
are *not* inherited - the *entire* annotation is replaced by the overriding annotation.

.. _UsageAnnotation: https://github.com/php-annotations/php-annotations/blob/master/src/annotations/UsageAnnotation.php

0 comments on commit 630792b

Please sign in to comment.