Skip to content

Tweaks to property info component #6896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 21, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 94 additions & 57 deletions components/property_info.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,14 @@
The PropertyInfo Component
==========================

The PropertyInfo component provides the functionality to get information
about class properties using metadata of popular sources.
The PropertyInfo component allows you to get information
about class properties by using different sources of metadata.

While the :doc:`PropertyAccess component </components/property_access>`
allows you to read and write values to/from objects and arrays, the PropertyInfo
component works solely with class definitions to provide information such
as data type and visibility about properties within that class.

Similar to PropertyAccess, the PropertyInfo component combines both class
properties (such as ``$property``) and properties defined via accessor and
mutator methods such as ``getProperty()``, ``isProperty()``, ``setProperty()``,
``addProperty()``, ``removeProperty()``, etc.
component works solely with class definitions to provide information about the
data type and visibility - including via getter or setter methods - of the properties
within that class.

.. versionadded:: 2.8
The PropertyInfo component was introduced in Symfony 2.8.
Expand All @@ -42,22 +38,48 @@ Additional dependencies may be required for some of the
Usage
-----

The entry point of this component is a new instance of the
:class:`Symfony\\Component\\PropertyInfo\\PropertyInfoExtractor`
class, providing sets of information extractors.
To use this component, create a new
:class:`Symfony\\Component\\PropertyInfo\\PropertyInfoExtractor` instance and
provide it with a set of information extractors.

.. code-block:: php

use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Example\Namespace\YourAwesomeCoolClass;

// a full list of extractors is shown further below
$phpDocExtractor = new PhpDocExtractor();
$reflectionExtractor = new ReflectionExtractor();

// array of PropertyListExtractorInterface
$listExtractors = array($reflectionExtractor);

// array of PropertyTypeExtractorInterface
$typeExtractors = array($phpDocExtractor, $reflectionExtractor);

// array of PropertyDescriptionExtractorInterface
$descriptionExtractors = array($phpDocExtractor);

// array of PropertyAccessExtractorInterface
$accessExtractors = array($reflectionExtractor);

$propertyInfo = new PropertyInfoExtractor(
$arrayOfListExtractors,
$arrayOfTypeExtractors,
$arrayOfDescriptionExtractors,
$arrayOfAccessExtractors
$listExtractors,
$typeExtractors,
$descriptionExtractors,
$accessExtractors
);

The order of extractor instances within an array matters, as the first non-null
// see below for more examples
$class = YourAwesomeCoolClass::class;
$properties = $propertyInfo->getProperties($class);

Extractor Ordering
~~~~~~~~~~~~~~~~~~

The order of extractor instances within an array matters: the first non-null
result will be returned. That is why you must provide each category of extractors
as a separate array, even if an extractor provides information for more than
one category.
Expand Down Expand Up @@ -101,21 +123,26 @@ Extractable Information
-----------------------

The :class:`Symfony\\Component\\PropertyInfo\\PropertyInfoExtractor`
class exposes public methods to extract four types of information: list,
type, description and access information. The first type of information is
about the class, while the remaining three are about the individual properties.
class exposes public methods to extract four types of information:

* :ref:`*List* of properties <property-info-list>`: `getProperties()`
* :ref:`Property *type* <property-info-type>`: `getTypes()`
* :ref:`Property *description* <property-info-description>`: `getShortDescription()` and `getLongDescription()`
* :ref:`Property *access* details <property-info-access>`: `isReadable()` and `isWritable()`

.. note::

When specifiying a class that the PropertyInfo component should work
with, use the fully-qualified class name. Do not directly pass an object
as some extractors (the
:class:`Symfony\\Component\\PropertyInfo\\Extractor\\SerializerExtractor`
is an example) may not automatically resolve objects to their class
names - use the ``get_class()`` function.
Be sure to pass a *class* name, not an object to the extractor methods::

// bad! It may work, but not with all extractors
$propertyInfo->getProperties($awesomeObject);

Since the PropertyInfo component requires PHP 5.5 or greater, you can
also make use of the `class constant`_.
// Good!
$propertyInfo->getProperties(get_class($awesomeObject));
$propertyInfo->getProperties('Example\Namespace\YourAwesomeClass');
$propertyInfo->getProperties(YourAwesomeClass::class);

.. _property-info-list:

List Information
~~~~~~~~~~~~~~~~
Expand All @@ -137,6 +164,8 @@ containing each property name as a string.
}
*/

.. _property-info-type:

Type Information
~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -164,6 +193,10 @@ for a property.
}
*/

See :ref:`components-property-info-type` for info about the ``Type`` class.

.. _property-info-description:

Description Information
~~~~~~~~~~~~~~~~~~~~~~~

Expand All @@ -189,6 +222,8 @@ strings.
It can span multiple lines.
*/

.. _property-info-access:

Access Information
~~~~~~~~~~~~~~~~~~

Expand All @@ -203,6 +238,11 @@ provide whether properties are readable or writable as booleans.
$propertyInfo->isWritable($class, $property);
// Example Result: bool(false)

The :class:`Symfony\\Component\\PropertyInfo\\Extractor\\ReflectionExtractor` looks
for getter/isser/setter method in addition to whether or not a property is public
to determine if it's accessible. This based on how the :doc:`PropertyAccess </components/property_access>`
works.

.. tip::

The main :class:`Symfony\\Component\\PropertyInfo\\PropertyInfoExtractor`
Expand All @@ -219,10 +259,9 @@ Type Objects
------------

Compared to the other extractors, type information extractors provide much
more information than can be represented as simple scalar values - because
of this, type extractors return an array of objects. The array will contain
an instance of the :class:`Symfony\\Component\\PropertyInfo\\Type`
class for each type that the property supports.
more information than can be represented as simple scalar values. Because
of this, type extractors return an array of :class:`Symfony\\Component\\PropertyInfo\\Type`
objects for each type that the property supports.

For example, if a property supports both ``integer`` and ``string`` (via
the ``@return int|string`` annotation),
Expand All @@ -236,15 +275,12 @@ class.
instance. The :class:`Symfony\\Component\\PropertyInfo\\Extractor\\PhpDocExtractor`
is currently the only extractor that returns multiple instances in the array.

Each object will provide 6 attributes; the first four (built-in type, nullable,
class and collection) are scalar values and the last two (collection key
type and collection value type) are more instances of the :class:`Symfony\\Component\\PropertyInfo\\Type`
class again if collection is ``true``.
Each object will provide 6 attributes, available in the 6 methods:

.. _`components-property-info-type-builtin`:

Built-in Type
~~~~~~~~~~~~~
Type::getBuiltInType()
~~~~~~~~~~~~~~~~~~~~~~

The :method:`Type::getBuiltinType() <Symfony\\Component\\PropertyInfo\\Type::getBuiltinType>`
method will return the built-in PHP data type, which can be one of 9 possible
Expand All @@ -254,22 +290,22 @@ string values: ``array``, ``bool``, ``callable``, ``float``, ``int``, ``null``,
Constants inside the :class:`Symfony\\Component\\PropertyInfo\\Type`
class, in the form ``Type::BUILTIN_TYPE_*``, are provided for convenience.

Nullable
~~~~~~~~
Type::isNullable()
~~~~~~~~~~~~~~~~~~

The :method:`Type::isNullable() <Symfony\\Component\\PropertyInfo\\Type::isNullable>`
method will return a boolean value indicating whether the property parameter
can be set to ``null``.

Class
~~~~~
Type::getClassName()
~~~~~~~~~~~~~~~~~~~~

If the :ref:`built-in PHP data type <components-property-info-type-builtin>`
is ``object``, the :method:`Type::getClassName() <Symfony\\Component\\PropertyInfo\\Type::getClassName>`
method will return the fully-qualified class or interface name accepted.

Collection
~~~~~~~~~~
Type::isCollection()
~~~~~~~~~~~~~~~~~~~~

The :method:`Type::isCollection() <Symfony\\Component\\PropertyInfo\\Type::isCollection>`
method will return a boolean value indicating if the property parameter is
Expand All @@ -281,8 +317,8 @@ this returns ``true`` if:
* The mutator method the property is derived from has a prefix of ``add``
or ``remove`` (which are defined as the list of array mutator prefixes).

Collection Key & Value Types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Type::getCollectionKeyType() & Type::getCollectionValueType()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If the property is a collection, additional type objects may be returned
for both the key and value types of the collection (if the information is
Expand Down Expand Up @@ -315,13 +351,14 @@ Using PHP reflection, the :class:`Symfony\\Component\\PropertyInfo\\Extractor\\R
provides list, type and access information from setter and accessor methods.
It can also provide return and scalar types for PHP 7+.

This service is automatically registered with the ``property_info`` service.
This service is automatically registered with the ``property_info`` service in
the Symfony Framework.

.. code-block:: php

use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;

$reflectionExtractor = new ReflectionExtractor;
$reflectionExtractor = new ReflectionExtractor();

// List information.
$reflectionExtractor->getProperties($class);
Expand All @@ -341,13 +378,14 @@ PhpDocExtractor
Using `phpDocumentor Reflection`_ to parse property and method annotations,
the :class:`Symfony\\Component\\PropertyInfo\\Extractor\\PhpDocExtractor`
provides type and description information. This extractor is automatically
registered with the ``property_info`` providing its dependencies are detected.
registered with the ``property_info`` in the Symfony Framework *if* the dependent
library is present.

.. code-block:: php

use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;

$phpDocExtractor = new PhpDocExtractor;
$phpDocExtractor = new PhpDocExtractor();

// Type information.
$phpDocExtractor->getTypes($class, $property);
Expand All @@ -362,10 +400,11 @@ SerializerExtractor

This extractor depends on the `symfony/serializer`_ library.

Using groups metadata from the :doc:`Serializer component </components/serializer>`,
Using :ref:`groups metadata <serializer-using-serialization-groups-annotations>`
from the :doc:`Serializer component </components/serializer>`,
the :class:`Symfony\\Component\\PropertyInfo\\Extractor\\SerializerExtractor`
provides list information. This extractor is not registered automatically
with the ``property_info`` service.
provides list information. This extractor is *not* registered automatically
with the ``property_info`` service in the Symfony Framework.

.. code-block:: php

Expand All @@ -392,9 +431,8 @@ DoctrineExtractor

Using entity mapping data from `Doctrine ORM`_, the
:class:`Symfony\\Bridge\\Doctrine\\PropertyInfo\\DoctrineExtractor`
- located in the Doctrine bridge - provides list and type information.
This extractor is not registered automatically with the ``property_info``
service.
provides list and type information. This extractor is not registered automatically
with the ``property_info`` service in the Symfony Framework.

.. code-block:: php

Expand Down Expand Up @@ -443,4 +481,3 @@ service by defining it as a service with one or more of the following
.. _`symfony/serializer`: https://packagist.org/packages/symfony/serializer
.. _`symfony/doctrine-bridge`: https://packagist.org/packages/symfony/doctrine-bridge
.. _`doctrine/orm`: https://packagist.org/packages/doctrine/orm
.. _`class constant`: http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.class