Package Home

Zend Framework 2 Documentation (Manual)

PHK Home

File: /_sources/modules/zend.stdlib.hydrator.filter.txt

Size:10078
Storage flags:no_autoload,compress/gzip (27%)

.. _zend.stdlib.hydrator.filter:

Zend\\Stdlib\\Hydrator\\Filter
==============================

The hydrator filters, allows you to manipulate the behavior, when you want to ``extract()`` your stuff to arrays.
This is especially useful, if you want to ``extract()`` your objects to the userland and strip some internals (e.g.
``getServiceManager()``).

It comes with a helpful Composite Implementation and a few filters for common use cases. The filters are implemented on
the ``AbstractHydrator``, so you can directly start using them if you extend it - even on custom hydrators.

.. code-block:: php
   :linenos:

   namespace Zend\Stdlib\Hydrator\Filter;

   interface FilterInterface
   {
       /**
        * Should return true, if the given filter
        * does not match
        *
        * @param string $property The name of the property
        * @return bool
        */
       public function filter($property);
   }

If it returns true, the key / value pairs will be in the extracted arrays - if it will return false, you'll not see
them again.

.. _zend.stdlib.hydrator.filter.implementations:

Filter implementations
----------------------

- **Zend\\Stdlib\\Hydrator\\Filter\\GetFilter**

  This filter is used in the ``ClassMethods`` hydrator, to decide that getters will be extracted.
  It checks, if the key that should be extracted starts with ``get`` or looks like this ``Zend\Foo\Bar::getFoo``

- **Zend\\Stdlib\\Hydrator\\Filter\\HasFilter**

  This filter is used in the ``ClassMethods`` hydrator, to decide that ``has`` methods will be extracted.
  It checks, if the key that should be extracted starts with ``has`` or looks like this ``Zend\Foo\Bar::hasFoo``

- **Zend\\Stdlib\\Hydrator\\Filter\\IsFilter**

  This filter is used in the ``ClassMethods`` hydrator, to decide that ``is`` methods will be extracted.
  It checks, if the key that should be extracted starts with ``is`` or looks like this ``Zend\Foo\Bar::isFoo``

- **Zend\\Stdlib\\Hydrator\\Filter\\MethodMatchFilter**

  This filter allows you to strip methods from the extraction with the correct condition in the composite.
  It checks, if the key that should be extracted matches a method name. Either ``getServiceLocator`` or
  ``Zend\Foo::getServicelocator``. The name of the method is specified in the constructor of this filter. The 2nd parameter
  decides whether to use white or blacklisting to decide. Default is blacklisting - pass ``false`` to change it.

- **Zend\\Stdlib\\Hydrator\\Filter\\NumberOfParameterFilter**

  This filter is used in the ``ClassMethods`` hydrator, to check the number of parameters. By convention, the ``get``, ``has``
  and ``is`` methods do not get any parameters - but it may happen. You can add your own number of needed parameters,
  simply add the number to the constructor. The default value is 0

.. _zend.stdlib.hydrator.filter.remove:

Remove filters
--------------

If you want to tell e.g. the ``ClassMethods`` hydrator, to not extract methods that start with ``is``, you can do so:

.. code-block:: php
   :linenos:

   $hydrator = new ClassMethods(false);
   $hydrator->removeFilter("is");

The key / value pairs for ``is`` methods will not end up in your extracted array anymore. The filters can be used in
any hydrator, but the ``ClassMethods`` hydrator is the only one, that has pre-registered filters:

.. code-block:: php
   :linenos:

   $this->filterComposite->addFilter("is", new IsFilter());
   $this->filterComposite->addFilter("has", new HasFilter());
   $this->filterComposite->addFilter("get", new GetFilter());
   $this->filterComposite->addFilter("parameter", new NumberOfParameterFilter(), FilterComposite::CONDITION_AND);

If you're not fine with this, you can unregister them as above.

.. note::

   The parameter for the filter on the ``ClassMethods`` looks like this by default ``Zend\Foo\Bar::methodName``

.. _zend.stdlib.hydrator.filter.add:

Add filters
-----------

You can easily add filters to any hydrator, that extends the ``AbstractHydrator``. You can use the ``FilterInterface``
or any callable:

.. code-block:: php
   :linenos:

   $hydrator->addFilter("len", function($property) {
       if (strlen($property) !== 3) {
           return false;
       }
       return true;
   });

By default, every filter you add will be added with a conditional ``or``. If you want to add it with ``and``
(as the ``NumberOfParameterFilter`` that is added to the ``ClassMethods`` hydrator by default) you can do that too:

.. code-block:: php
   :linenos:

   $hydrator->addFilter("len", function($property) {
       if (strlen($property) !== 3) {
           return false;
       }
       return true;
   }, FilterComposite::CONDITION_AND);

Or you can add the shipped ones:

.. code-block:: php
   :linenos:

   $hydrator->addFilter(
     "servicemanager",
     new MethodMatchFilter("getServiceManager"),
     FilterComposite::CONDITION_AND
   );

The example above will exclude the ``getServiceManager`` method or the key from the extraction, even if the ``get``
filter wants to add it.

.. _zend.stdlib.hydrator.filter.composite:

Use the composite for complex filters
-------------------------------------

The composite implements the ``FilterInterface`` too, so you can add it as a regular filter to the hydrator. One goody
of this implementation, is that you can add the filters with a condition and you can do even more complex stuff with
different composites with different conditions. You can pass the condition to the 3rd parameter, when you add a filter:

**Zend\\Stdlib\\Hydrator\\Filter\\FilterComposite::CONDITION_OR**

  At one level of the composite, one of all filters in that condition block has to return true in order to get extracted

**Zend\\Stdlib\\Hydrator\\Filter\\FilterComposite::CONDITION_AND**

  At one level of the composite, all of the filters in that condition block has to return ``true`` in order to get extracted

This composition will have a similar logic as the if below:

.. code-block:: php
   :linenos:

    $composite = new FilterComposite();

    $composite->addFilter("one", $condition1);
    $composite->addFilter("two", $condition2);
    $composite->addFilter("three", $condition3);
    $composite->addFilter("four", $condition4, FilterComposite::CONDITION_AND);
    $composite->addFilter("five", $condition5, FilterComposite::CONDITION_AND);

    // This is what's happening internally
    if (
         (
            $condition1
            || $condition2
            || $condition3
         ) && (
            $condition4
            && $condition5
         )
     ) {
    //do extraction
    }

If you've only one condition (only ``and`` or ``or``) block, the other one will be completely ignored.

A bit more complex filter can look like this:

.. code-block:: php
   :linenos:

    $composite = new FilterComposite();
    $composite->addFilter(
        "servicemanager",
        new MethodMatchFilter("getServiceManager"),
        FilterComposite::CONDITION_AND
    );
    $composite->addFilter(
        "eventmanager",
        new MethodMatchFilter("getEventManager"),
        FilterComposite::CONDITION_AND
    );

    $hydrator->addFilter("excludes", $composite, FilterComposite::CONDITION_AND);

    // Internal
    if (
         (  // default composite inside the hydrator
            (
                $getFilter
                || $hasFilter
                || $isFilter
             ) && (
                $numberOfParameterFilter
             )
         ) && (  // new composite, added to the one above
            $serviceManagerFilter
            && $eventManagerFilter
         )
    ) {
    // do extraction
    }

If you perform this on the ``ClassMethods`` hydrator, all getters will get extracted, but not ``getServiceManager``
and ``getEventManager``.

.. _zend.stdlib.hydrator.filter.provider:

Using the provider interface
----------------------------

There is also a provider interface, that allows you to configure the behavior of the hydrator inside your objects.

.. code-block:: php
   :linenos:

    namespace Zend\Stdlib\Hydrator\Filter;

    interface FilterProviderInterface
    {
        /**
         * Provides a filter for hydration
         *
         * @return FilterInterface
         */
        public function getFilter();
    }

The ``getFilter()`` method is getting automatically excluded from ``extract()``. If the extracted object implements the
``Zend\Stdlib\Hydrator\Filter\FilterProviderInterface``, the returned ``FilterInterface`` instance can also be a
``FilterComposite``.

For example:

.. code-block:: php
   :linenos:

   Class Foo implements FilterProviderInterface
   {
        public function getFoo()
        {
            return "foo";
        }

        public function hasFoo()
        {
            return true;
        }

        public function getServiceManager()
        {
            return "servicemanager";
        }

        public function getEventManager()
        {
            return "eventmanager";
        }

        public function getFilter()
        {
            $composite = new FilterComposite();
            $composite->addFilter("get", new GetFilter());

            $exclusionComposite = new FilterComposite();
            $exclusionComposite->addFilter(
                "servicemanager",
                new MethodMatchFilter("getServiceManager"),
                FilterComposite::CONDITION_AND
                );
            $exclusionComposite->addFilter(
                "eventmanager",
                new MethodMatchFilter("getEventManager"),
                FilterComposite::CONDITION_AND
            );

            $composite->addFilter("excludes", $exclusionComposite, FilterComposite::CONDITION_AND);

            return $composite;
        }
   }

   $hydrator = new ClassMethods(false);
   $extractedArray = $hydrator->extract(new Foo());

The ``$extractedArray`` does only have "foo" => "foo" in. All of the others are excluded from the extraction.

.. note::

    All pre-registered filters from the ``ClassMethods`` hydrator are ignored if this interface is used.

For more information about the PHK package format: http://phk.tekwire.net