PHP code example of kassko / data-mapper

1. Go to this page and download the library: Download kassko/data-mapper library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

kassko / data-mapper example snippets


composer 

$loader = \Common\Annotations\AnnotationRegistry::registerLoader($loader);

(new Kassko\DataMapper\DataMapperBuilder)->run();

$id = 1;
//Construct a person, set an id to it.
$person = new Kassko\Sample\Person($id);

echo $person->getName();//Implicitly load the name from the given id by fetching the source configured.

//Here some stuff to retrieve the entityManager.

$id = 1;
$person = $entityManager->getRepository('Kassko\Sample\Person')->find($id);

echo $person->getName();

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;
use Kassko\DataMapper\ObjectExtension\LoadableTrait;

class Person
{
    use LoadableTrait;

    private $id;
    /**
     * @DM\DataSource(class="Kassko\Sample\PersonDataSource", method="getData", args="#id", lazyLoading=true)
     */
    private $name;
    /**
     * @DM\DataSource(class="Kassko\Sample\PersonDataSource", method="getData", args="#id", lazyLoading=true)
     */
    private $email;

    public function __construct($id) { $this->id = $id; }
    public function getId() { return $this->id; }
    public function getName() { $this->loadProperty('name'); return $this->name; }
    public function getEmail() { $this->loadProperty('email'); return $this->email; }
}

namespace Kassko\Sample;

class PersonDataSource
{
    public function getData($id)
    {
        return [
          'name' => 'foo',
          'email' => '[email protected]'
        ];
    }  
}

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;
use Kassko\DataMapper\ObjectExtension\LoadableTrait;

/**
 * @DM\DataSourcesStore({
 *      @DM\DataSource(
 *          id="nameSource", 
 *          class="Kassko\Sample\PersonDataSource", 
 *          method="getData",
 *          args="#id",
 *          lazyLoading=true
 *      ),
 *      @DM\DataSource(
 *          id="emailSource", 
 *          class="Kassko\Sample\PersonDataSource", 
 *          method="getData",
 *          args="#id",
 *          lazyLoading=true
 *      )
 * })
 */
class Person
{
    use LoadableTrait;

    private $id;
    /**
     * @DM\RefSource(id="nameSource")
     */
    private $name;
    /**
     * @DM\RefSource(id="emailSource")
     */
    private $email;

    public function __construct($id) { $this->id = $id; }
    public function getId() { return $this->id; }
    public function getName() { $this->loadProperty('name'); return $this->name; }
    public function getEmail() { $this->loadProperty('email'); return $this->email; }
}

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;
use Kassko\DataMapper\ObjectExtension\LoadableTrait;

/**
 * @DM\DataSourcesStore({
 *      @DM\DataSource(
 *          id="personSource", 
 *          class="Kassko\Sample\PersonDataSource", 
 *          method="getData",
 *          args="#id", 
 *          lazyLoading=true,
 *          supplySeveralFields=true
 *      )
 * })
 */
class Person
{
    use LoadableTrait;

    private $id;
    /**
     * @DM\RefSource(id="personSource")
     * @DM\Field("name"="first_name")
     */
    private $firstName;
    /**
     * @DM\RefSource(id="personSource")
     */
    private $name;
    /**
     * @DM\RefSource(id="personSource")
     */
    private $email;
    /**
     * @DM\RefSource(id="personSource")
     */
    private $phone;

    public function __construct($id) { $this->id = $id; }
    public function getId() { return $this->id; }
    public function getFirstName() { $this->loadProperty('firstName'); return $this->firstName; }
    public function getName() { $this->loadProperty('name'); return $this->name; }
    public function getEmail() { $this->loadProperty('email'); return $this->email; }
    public function getPhone() { $this->loadProperty('phone'); return $this->phone; }
}

namespace Kassko\Sample;

class PersonDataSource
{
    public function getData($id)
    {
        return [
            'first_name' => 'foo',
            'name' => 'bar',
            'email' => 'foo@bar',
            'phone' => '01 02 03 04 05',
        ];
    }
}

(new Kassko\DataMapper\DataMapperBuilder)
    ->settings(['container' => ['instance' => ['person.data_source_id' => $personDataSourceInstance]]])
    ->run()
;

(new Kassko\DataMapper\DataMapperBuilder)
    ->settings(['container' => ['instance' => $container]])
    ->run()
;

(new Kassko\DataMapper\DataMapperBuilder)
    ->settings(['container' => ['instance' => $container, 'get_method_name' => 'get', 'has_method_name' => 'has']])
    ->run()
;

/**
 * @DM\DataSourcesStore({
 *      @DM\DataSource(
 *          id="personSource", 
 *          class="@person.data_source_id", 
 *          method="find", 
 *          args="#id",
 *          lazyLoading=true
 *      )
 * })
 */
class Person
{
}

namespace Kassko\Sample;

use Kassko\DataMapper\ObjectExtension\LoadableTrait;

/**
 * @DM\DataSourcesStore({
 *      @DM\DataSource(
 *          id="personSource", 
 *          class="Kassko\Sample\PersonDataSource", 
 *          method="getData", 
 *          args="#id", 
 *          lazyLoading=true,
 *          supplySeveralFields=true
 *      ),
 *      @DM\DataSource(
 *          id="carSource", 
 *          class="Kassko\Sample\CarRepository", 
 *          method="find", 
 *          args="expr(source('personSource')['car_id'])",
 *          lazyLoading=true
 *      )
 * })
 */
class Person
{
    private $id;
    /**
     * @DM\RefSource(id="personSource")
     */
    private $firstName;
    /**
     * @DM\RefSource(id="personSource")
     */
    private $name;
    /**
     * @DM\RefSource(id="personSource")
     */
    private $email;
    /**
     * @DM\RefSource(id="personSource")
     */
    private $phone;
    /**
     * @DM\RefSource(id="carSource")
     */
    private $car;

    public function __construct($id) { $this->id = $id; }
    public function getId() { return $this->id; }
    public function getFirstName() { return $this->firstName; }
    public function getName() { return $this->name; }
    public function getEmail() { return $this->email; }
    public function getPhone() { return $this->phone; }
    public function getCar() { return $this->car; }
}

namespace Kassko\Sample;

class PersonDataSource
{
    public function getData($id)
    {
        return [
            'first_name' => 'foo',
            'name' => 'bar',
            'email' => 'foo@bar',
            'phone' => '01 02 03 04 05',
        ];
    }
}

namespace Kassko\Sample;

use Doctrine\ORM\EntityRepository;

/**
 * CarRepository is a Doctrine source that feed the property $car.
 */
class CarRepository extends EntityRepository
{
}

namespace Kassko\Sample;

class Watch
{
        private $brand;
        private $color;

        public function getBrand() { return $this->brand; }
        public function setBrand($brand) { $this->brand = $brand; }
        public function getColor() { return $this->color; }
        public function setColor($color) { $this->color = $color; }
}

$data = [
        0 => [
                'brand' => 'some brand',
                'color' => 'blue',
        ],
        1 => [
                'brand' => 'some other brand',
                'color' => 'green',
        ],
];

$dataMapper = (new Kassko\DataMapper\DataMapperBuilder)->instance();

$dataMapper->resultBuilder('Kassko\Sample\Watch', $data)->all();//The result will be an array with two objects.
$dataMapper->resultBuilder('Kassko\Sample\Watch', $data)->first();//The result will be a watch object representing the first record.

array(2) {
    ["brand"]=>
    string(10) "some brand"
    ["color"]=>
    string(4) "blue"
}

$dataMapper = (new Kassko\DataMapper\DataMapperBuilder)->instance();

$dataMapper->resultBuilder('Kassko\Sample\Watch')->raw($object);
$dataMapper->resultBuilder('Kassko\Sample\Watch')->raw($collection);

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;

class Watch
{
        private $brand;

        /**
         * @DM\Fields(name="COLOR")
         */
        private $color;

        public function getBrand() { return $this->brand; }
        public function setBrand($brand) { $this->brand = $brand; }
        public function getColor() { return $this->color; }
        public function setColor($color) { $this->color = $color; }
}

$loader = \Common\Annotations\AnnotationRegistry::registerLoader(array($loader, 'loadClass'));

$dataMapper = (new Kassko\DataMapper\DataMapperBuilder)->instance();
$dataMapper->resultBuilder('Kassko\Sample\Watch', $data)->all();

        /*
        Return an array of objects.
        So return an array with only one object, if only one fullfill the request.
        */
        $resultBuilder->all();

        /*
        Return the object found.

        If more than one result are found, throw an exception
        Kassko\DataMapper\Result\Exception\NonUniqueResultException.

        If no result found, throw an exception
        Kassko\DataMapper\Result\Exception\NoResultException.
        */
        $resultBuilder->single();

        /*
        Return the object found or null.
        */
        $resultBuilder->one();

        /*
        Return the object found or a default result (like false).
        */
        $resultBuilder->one(false);

        /*
        If more than one result are found, throw an exception
        Kassko\DataMapper\Result\Exception\NonUniqueResultException.
        */

        /*
        Return the first object found or null.
        */
        $resultBuilder->first();

        /*
        Return the first object found or a default result (like value false).
        */
        $resultBuilder->first(false);

        /*
        If no result found, throw an exception
        Kassko\DataMapper\Result\Exception\NoResultException.
        */

        /*
        Return an array indexed by a property value.

        If the index does not exists (allIndexedByUnknown()), throw an exception Kassko\DataMapper\Result\Exception\NotFoundIndexException.

        If the same index is found twice, throw an exception
        Kassko\DataMapper\Result\Exception\DuplicatedIndexException.

        Examples:

        allIndexedByBrand() will index by brand value:
        [
                'BrandA' => $theWatchInstanceWithBrandA,
                'BrandB' => $theWatchInstanceWithBrandB,
        ]

        allIndexedByColor() will index by color value:
        [
                'Blue' => $theWatchInstanceWithColorBlue,
                'Red' => $theWatchInstanceWithColorRed,
        ]

        allIndexedByUnknown() will throw a Kassko\DataMapper\Result\Exception\NotFoundIndexException.
        */
        $resultBuilder->allIndexedByBrand();//Indexed by brand value
        //or
        $resultBuilder->allIndexedByColor();//Indexed by color value

        /*
        Return an iterator.

        Result will not be hydrated immediately but only when you will iterate the results (with "foreach" for example).
        */
        $result = $resultBuilder->iterable();
        foreach ($result as $object) {//$object is hydrated

                if ($object->getColor() === 'blue') {
                        break;

                        //We found the good object then we stop the loop and others objects in results will not be hydrated.
                }
        }

        /*
        Return an iterator indexed by a property value.

        If the index does not exists, throw an exception Kassko\DataMapper\Result\Exception\NotFoundIndexException.

        If the same index is found twice, throw an exception Kassko\DataMapper\Result\Exception\DuplicatedIndexException.
        */
        $resultBuilder->iterableIndexedByBrand();
        //or
        $resultBuilder->iterableIndexedByColor();

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;
use Kassko\DataMapper\Hydrator\HydrationContextInterface;
use Kassko\DataMapper\Hydrator\Value;
use \DateTime;

class Watch
{
        private static $brandCodeToLabelMap = [1 => 'Brand A', 2 => 'Brand B'];
        private static $brandLabelToCodeMap = ['Brand A' => 1, 'Brand B' => 2];

        /**
         * @DM\Field(readConverter="readBrand", writeConverter="writeBrand")
         */
        private $brand;

        /**
         * @DM\Field(readConverter="hydrateBool", writeConverter="extractBool")
         */
        private $waterProof;

        /**
         * @DM\Field(readConverter="hydrateBoolFromSymbol", writeConverter="extractBoolToSymbol")
         */
        private $stopWatch;

        /**
         * @DM\Field(type="date", readDateConverter="Y-m-d H:i:s", writeDateConverter="Y-m-d H:i:s")
         */
        private $createdDate;

        public function getBrand() { return $this->brand; }
        public function setBrand($brand) { $this->brand = $brand; }
        public function isWaterProof() { return $this->waterProof; }
        public function setWaterProof($waterProof) { $this->waterProof = $waterProof; }
        public function hasStopWatch() { return $this->stopWatch; }
        public function setStopWatch($stopWatch) { $this->stopWatch = $stopWatch; }
        public function getCreatedDate() { return $this->createdDate; }
        public function setCreatedDate(DateTime $createdDate) { $this->createdDate = $createdDate; }

        public static function readBrand(Value $value, HydrationContextInterface $context)
        {
                if (isset(self::$brandCodeToLabelMap[$value->value])) {
                        $value->value = self::$brandCodeToLabelMap[$value->value];
                }
        }

        public static function writeBrand(Value $value, HydrationContextInterface $context)
        {
                if (isset(self::$brandLabelToCodeMap[$value->value])) {
                        $value->value = self::$brandLabelToCodeMap[$value->value];
                }
        }

        public static function hydrateBool(Value $value, HydrationContextInterface $context)
        {
                $value->value = $value->value == '1';
        }

        public static function extractBool(Value $value, HydrationContextInterface $context)
        {
                $value->value = $value->value ? '1' : '0';
        }

        public static function hydrateBoolFromSymbol(Value $value, HydrationContextInterface $context)
        {
                $value->value = $value->value == 'X';
        }

        public static function extractBoolToSymbol(Value $value, HydrationContextInterface $context)
        {
                $value->value = $value->value ? 'X' : ' ';
        }
}

$data = [
        'brand' => '1',
        'waterProof' => '1',
        'stopWatch' => 'X',
        'created_date' => '2014-09-14 12:36:52',
];

$dataMapper = (new Kassko\DataMapper\DataMapperBuilder)->instance();
$object = new Kassko\Sample\Watch;
$dataMapper->hydrator('Kassko\Sample\Watch')->hydrate($data, $object);
var_dump($object);

object(Watch)#283 (8) {
        ["brand":"Watch":private]=> string(10) "Brand A"
        ["waterProof":"Watch":private]=> bool(true)
        ["stopWatch":"Watch":private]=> bool(true)
        ["createdDate":"Watch":private]=>
                object(DateTime)#320 (3) { ["date"]=> string(19) "2014-09-14 12:36:52" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/Berlin" }
}

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;

class Watch
{
        /**
         * @DM\Field
         */
        private $brand;

        /**
         * @DM\Field
         */
        private $waterProof;

        /**
         * @DM\Field
         */
        private $stopWatch;

        public function getBrand() { return $this->brand; }
        public function setBrand($brand) { $this->brand = $brand; }
        public function isWaterProof() { return $this->waterProof; }
        public function setWaterProof($waterProof) { $this->waterProof = $waterProof; }
        public function hasStopWatch() { return $this->stopWatch; }
        public function setStopWatch($stopWatch) { $this->stopWatch = $stopWatch; }
}

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;

class Watch
{
        /**
         * @DM\Field(prefix="is")
         */
        private $waterProof;

        /**
         * @DM\Getter(prefix="has")
         */
        private $alarm;

        /**
         * @DM\Getter(prefix="are")
         */
        private $handsYellow;

        /**
         * @DM\Field(name="hasStopWatch")
         */
        private $stopWatch;

        /**
         * @DM\Getter(name="canColorChange")
         * @DM\Setter(name="colorCanChange")
         */
        private $variableColor;

        public function isWaterProof() { return $this->waterProof; }
        public function setWaterProof($waterProof) { $this->waterProof = $waterProof; }
        public function hasAlarm() { return $this->alarm; }
        public function setAlarm($stopWatch) { $this->alarm = $alarm; }
        public function areHandsYellow() { return $this->handsYellow; }
        public function setHandsyellow($handsYellow) { $this->handsYellow = $handsYellow; }
        public function hasStopWatch() { return $this->stopWatch; }
        public function setStopWatch($stopWatch) { $this->stopWatch = $stopWatch; }
        public function canColorChange() { return $this->variableColor; }
        public function colorCanChange($colorCanChange) { $this->variableColor = $colorCanChange; }
}

namespace Kassko\Sample;

class Color
{
        private $red;
        private $green;
        private $blue;

        public function getRed() { return $this->red; }
        public function setRed($red) { $this->red = $red; }
        public function getGreen() { return $this->green; }
        public function setGreen($green) { $this->green = $green; }
        public function getBlue() { return $this->blue; }
        public function setBlue($blue) { $this->blue = $blue; }
}

//color_es.php

return [
        'fields' => [
                'red' => 'rojo',
                'green' => 'verde',
                'blue' => 'azul',
        ],
];

use DataMapper\Configuration\RuntimeConfiguration;

$data = [
        'red' => '255',
        'green' => '0',
        'blue' => '127',
];

$resultBuilder = $dataMapper->resultBuilder('Kassko\Sample\Color', $data);
$resultBuilder->setRuntimeConfiguration(
        (new RuntimeConfiguration)
        ->addClassMetadataDir('Color', 'some_resource_dir')//Optional, if not specified Configuration::defaultClassMetadataResourceDir is used.
        ->addMappingResourceInfo('Color', 'color_en.yml', 'inner_yaml')
);

$resultBuilder->single();

use DataMapper\Configuration\RuntimeConfiguration;

$data = [
        'rouge' => '255',
        'vert' => '0',
        'bleu' => '127',
];

$resultBuilder = $dataMapper->resultBuilder('Kassko\Sample\Color', $data);
$resultBuilder->setRuntimeConfiguration(
        (new RuntimeConfiguration)
        ->addClassMetadataDir('Color', 'some_resource_dir')
        ->addMappingResourceInfo('Color', 'color_fr.yml', 'inner_yaml')
);

$resultBuilder->single();

use DataMapper\Configuration\RuntimeConfiguration;

$data = [
        'rojo' => '255',
        'verde' => '0',
        'azul' => '127',
];

$resultBuilder = $dataMapper->resultBuilder('Kassko\Sample\Color', $data);
$resultBuilder->setRuntimeConfiguration(
        (new RuntimeConfiguration)
        ->addClassMetadataDir('Color', 'some_resource_dir')
        ->addMappingResourceInfo('Color', 'color_es.php', 'inner_php')
);

$resultBuilder->single();

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;

class Customer
{
        /**
         * @DM\Field
         * @DM\Id
         */
        private $id;

        /**
         * @DM\Field(class="Kassko\Sample\Address")
         * @DM\Config(mappingResourceType="yaml", mappingResourceName="billing_address.yml")
         */
        private $billingAddress;//$billingAddress is a value object.

        /**
         * @DM\Field(class="Kassko\Sample\Address")
         * @DM\Config(mappingResourceType="yaml", mappingResourceName="shipping_address.yml")
         */
        private $shippingAddress;//$shippingAddress is a value object too.
}

namespace Kassko\Sample;

class Address
{
        private $street;
        private $town;
        private $postalCode;
        private $country;
}


$data = [
        'id' => 1,
        'billing_street' => '12 smarties street',
        'billing_town' => 'Nuts',
        'billing_postal_code' => '654321'
        'billing_country' => 'England',
        'shipping_street' => '23 smarties street',
        'shipping_town' => 'Mars',
        'shipping_postal_code' => '987654'
        'shipping_country' => 'England',
];

$dataMapper->resultBuilder('Kassko\Sample\Customer', $data)->single();

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;

class Information
{
    /**
     * @DM\DataSource(class="Kassko\Sample\ShopDataSource", method="getBestShop")
     * @DM\Field(class='Kassko\Sample\Shop')
     */
    private $bestShop;

    /**
     * @DM\DataSource(class="Kassko\Sample\ShopDataSource", method="getNbShops")
     */
    private $nbShops;

    public function getBestShop() { return $this->bestShop; }
    public function setBestShop(Shop $shop) { $this->bestShop = $bestShop; }
}

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;

class Shop
{
    /**
     * @DM\Field
     */
    private $name;

    /**
     * @DM\Field
     */
    private $address;
}

namespace Kassko\Sample;

class ShopDataSource
{
    public function getBestShop()
    {
        return [
            'name' => 'The best',
            'address' => 'Street of the bests',
        ];
    }

    public function getNbShops()
    {
        return 25;
    }
}

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;
use Kassko\DataMapper\ObjectExtension\LazyLoadableTrait;

class Information
{
    use LazyLoadableTrait;

        /**
         * @DM\DataSource(class="Kassko\Sample\ShopDataSource", method="getBestShop", lazyLoading=true)
         * @DM\Field(class='Kassko\Sample\Shop')
         */
        private $bestShop;

        /**
         * @DM\DataSource(class="Kassko\Sample\ShopDataSource", method="getNbShops", lazyLoading=true)
         */
        private $nbShops;

        public function getBestShop()
        {
                $this->loadProperty('bestShop');//<= Load the best shop from the property name if not loaded.
                return $this->bestShop;
        }

        public function getNbShop()
        {
                $this->loadProperty('nbShops');//<= Load the best shop from the property name if not loaded.
                return $this->nbShops;
        }
}

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;

class Shop
{
        /**
         * @DM\Field
         */
        private $name;

        /**
         * @DM\Field
         */
        private $address;
}

namespace Kassko\Sample;

class ShopDataSource
{
    public function getBestShop()
    {
        return [
            'name' => 'The best',
            'address' => 'Street of the bests',
        ];
    }

    public function getNbShops()
    {
        return 25;
    }
}

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;

class Person
{
    /**
     * @DM\DataSource(class="Kassko\Sample\PersonDataSource", method="getData", lazyLoading=true, supplySeveralFields=true)
     */
    private $name;

    /**
     * @DM\DataSource(class="Kassko\Sample\PersonDataSource", method="getData", lazyLoading=true, supplySeveralFields=true)
     */
    private $address;

    /**
     * @DM\DataSource(class="Kassko\Sample\PersonDataSource", method="getData", lazyLoading=true, supplySeveralFields=true)
     */
    private $phone;

    /**
     * @DM\DataSource(class="Kassko\Sample\PersonDataSource", method="getData", lazyLoading=true, supplySeveralFields=true)
     */
    private $email;
}

namespace Kassko\Sample;

class PersonDataSource
{
    public function getData()
    {
        return [
            'name' => 'Foo',
            'address' => 'Blue road',
            'phone' => '01 02 03 04 05',
            'email' => '[email protected]',
        ];
    }
}

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\DataSourcesStore({
 *      @DM\DataSource(
 *          id="some_source", class="Kassko\Sample\PersonDataSource", method="getData", lazyLoading=true
 *      )
 * })
 */
class Person
{
    /**
     * @DM\RefSource(id="some_source")
     */
    private $name;

    /**
     * @DM\RefSource(id="some_source")
     */
    private $address;

    /**
     * @DM\RefSource(id="some_source")
     */
    private $phone;

    /**
     * @DM\RefSource(id="some_source")
     */
    private $email;
}

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\DataSourcesStore({
 *      @DM\DataSource(
 *          id="sourceA", class="Kassko\Sample\ShopDataSource", method="getData", lazyLoading=true,
 *          fallbackSourceId="sourceB", onFail="checkException", exceptionClass="Kassko\Sample\NotStableSourceException"
 *      )
 * })
 */
class Person
{
}

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\DataSourcesStore({
 *      @DM\DataSource(
 *          id="sourceA", class="Kassko\Sample\ShopDataSource", method="getData", lazyLoading=true,
 *          fallbackSourceId="sourceB", onFail="checkReturnValue", badReturnValue="null"
 *      )
 * })
 */
class Person
{
}

namespace Kassko\Sample;

use Kassko\DataMapper\Annotation as DM;

class Key
{
    use LazyLoadableTrait;

    private $note;
    private $octave = 3;

    /**
     * @DM\DataSource(
     * id="ida", 
     * class="Kassko\Samples\KeyLLManager", 
     * method="getData", supplySeveralFields=true,
     * preprocessors = @DM\Methods({
     *  @DM\Method(method="somePreprocessor"),
     *  @DM\Method(class="Kassko\Sample\KeyProcessor", method="preprocess", args="##this")
     * })
     * processors = @DM\Methods({
     *  @DM\Method(method="someProcessor"),
     *  @DM\Method(class="Kassko\Sample\KeyProcessor", method="process", args="##this")
     * })
     *)
     */
    public $color;

    public function getColor() 
    {
        $this->loadProperty('color');
        return $this->color;
    }

    public function somePrepocessor()
    {
        //Some stuff
    }

    public function someProcessor())
    {
        //Some stuff
    }
}

namespace Kassko\Sample;

class KeyPreprocessor
{
    public function preprocess(Key $key)
    {
        $this->logger->info(sprintf('Before key hydration %s', $key->getId()));
    }

    public function process($keyColor)
    {
        $this->logger->info(sprintf('After key hydration %s', $key->getId()));
    }
}

class Key
{
    use LazyLoadableTrait;

    private $note;
    private $octave = 3;

    /**
     * @DM\DataSource(
     * id="ida", 
     * class="Kassko\Samples\KeyLLManager", 
     * method="getData", supplySeveralFields=true,
     * preprocessor = @DM\Method(method="somePreprocessor"),  
     * processor = @DM\Method(method="someProcessor")
     *)
     */
    public $color;

    public function getColor() 
    {
        $this->loadProperty('color');
        return $this->color;
    }

    public function somePrepocessor()
    {
        //Some stuff
    }

    public function someProcessor())
    {
        //Some stuff
    }
}

[
    'mapping' =>
    [
        //Default is "annotations" or other type (1).
        'default_resource_type' => 'annotations',

        //Optional key.
        'default_resource_dir' => 'some_dir',

        //Optional key. Has only sense if you use inner_php or inner_yaml format.
        //It's the method whereby you provide the mapping.
        'default_provider_method' => 'some_method_name',

        //Optional section.
        'groups' =>
        [
            'some_group' =>
            [
                //Default is "annotations" or other type (1).
                'resource_type' => annotations,

                //The resource dir of the given bundle.
                'resource_dir' => 'some_dir',

                //Default value is null.
                'provider_method' => null,
            ],
        ],

        //Optional section
        'objects':
        [
            [
                //Required (the full qualified object class name).
                'class' => 'some_fqcn',

                //Optional key. Allows to inherit settings from a group if there are not specified.
                'group' => 'some_group',

                //Optional key.
                'resource_type' => 'yaml_file',

                //Optional key.
                //The resource directory with the resource name.
                //If not defined, data-mapper fallback to resource_name and prepend to it a resource_dir (this object resource_dir or a group resource_dir or the default_resource_dir).
                //So if resource_path is not defined, keys resource_name and a resource_dir should be defined.
                'resource_path' => 'some_path',

                //Optional key. Only the resource name (so without the directory).
                'resource_name' => 'some_ressource.yml',

                //Optional key. Override default_provider_method.
                'provider_method' => 'some_method_name',
            ],
        ],
    ],

    //Optional section.
    'cache' =>
    [
        //Optional section. The cache for mapping metadata.
        'metadata_cache' =>
        [
            //A cache instance which implements Kassko\Cache\CacheInterface. Default is Kassko\Cache\ArrayCache.
            //If you use a third-party cache provider, maybe you need to wrap it into an adapter to enforce compatibility with Kassko\Cache\CacheInterface.
            'instance' => $someCacheInstance,

            //Default value is 0.
            //0 means the data will never been deleted from the cache.
            //Obviously, 'life_time' has no sense with an "ArrayCache" implementation.
            'life_time' => 0,

            //Default value is false. Indicates if the cache is shared or not.
            //If you don't specify it, you're not wrong. It optimises the
            'is_shared' => false,
        ],

        //Optional section. The cache for query results.
        //This section has the same keys as 'metadata_cache' section.
        'result_cache': => [],
    ],

    //Optional key. A logger instance which implements Psr\Logger\LoggerInterface.
    'logger' => $logger,

    //Optional key. Needed to retrieve repositories specified in 'repository_class' mapping attributes and which creation is assigned to a creator (a factory, a container, a callable).
    'class_resolver' => $someClassResolver,

    //Optional key. Needed to retrieve object listener specified in 'object_listener' mapping attributes and which creation is assigned to a creator (a factory, a container, a callable).
    'object_listener_resolver' => $someObjectListenerResolver,
]

use Kassko\DataMapper\Annotation as DM;

class SomeClass
{
    /**
     * @DM\Config(
     *      class="\ValueObjectClass",
     *      mappingResourceName="valueObjectResourceName",
     *      mappingResourcePath="valueObjectResourcePath",
     *      mappingResourceType="valueObjectResourceType"
     * )
     */
    protected $firstField;

[
    'fields' => ['firstField'],
    'config' => [
        'firstField'    => [
            'class' => '\ValueObjectClass',
            'mappingResourceName' => 'valueObjectResourceName',
            'mappingResourcePath' => 'valueObjectResourcePath',
            'mappingResourceType' => 'valueObjectResourceType'
        ]
    ]
];

use Kassko\DataMapper\Annotation as DM;

/**
 * Class SomeClass
 * 
 * @DM\CustomHydrator(
 *      class="SomeClassHydrator",
 *      hydrateMethod="hydrateMethod",
 *      extractMethod="extractMethod"
 * )
 */
class SomeClass
{
}

[
    'object'    => [
        'customHydrator'    => [
            'class' => 'SomeClassHydrator',
            'hydrateMethod' => 'hydrateMethod',
            'extractMethod' => 'extractMethod'
        ]
    ]
];

class SomeClassHydrator
{
    /**
     * Hydrate a SomeClass object from raw data $data.
     *
     * @param array The raw data
     * @return SomeClass
     */
    public function hydrateMethod(array $data)
    {
    }

    /**
     * Extract data from a SomeClass instance $object.
     *
     * @param SomeClass The object
     * @return array
     */
    public function extractMethod(SomeClass $object)
    {
    }
}

use Kassko\DataMapper\Annotation as DM;

class SomeClass
{
    /**
     * @DM\DataSource(
     *      id="firstFieldId",
     *      lazyLoading=true,
     *      supplySeveralFields=true,
     *      depends={"depend#1","depend#2"},
     *      onFail="checkException",
     *      exceptionClass="\RuntimeException",
     *      badReturnValue="emptyString",
     *      fallbackSourceId="firstFieldFallbackSourceId",
     *      preprocessor=@DM\Method(method="fooPreprocessor"),
     *      processors = @DM\Methods({
     *          @DM\Method(method="barProcessor"),
     *          @DM\Method(method="bazProcessor")
     *      })
     *      class="\stdClass",
     *      method="someMethod",
     *      args={"argument#1", "argument#2"}
     * )
     */
     protected $firstField;
}

[
    'fields' => [
        'firstField' => [
            'name'       => 'originalFieldName',
            'dataSource' => [
                'id'                  => 'firstFieldId',
                'lazyLoading'         => true,
                'supplySeveralFields' => true,
                'depends'             => ['depend#1', 'depend#2'],
                'onFail'              => 'checkException',
                'exceptionClass'      => '\RuntimeException',
                'badReturnValue'      => 'emptyString',
                'fallbackSourceId'    => 'firstFieldFallbackSourceId',
                'preprocessor'        => [
                    'class'  => '##this',
                    'method' => 'fooPreprocessor',
                    'args'   => []
                ],
                'processor'           => [],
                'preprocessors'       => [],
                'processors'          => [
                    ['method' => 'barProcessor'],
                    ['method' => 'bazProcessor'],
                ],
                'class'               => '\stdClass',
                'method'              => 'someMethod',
                'args'                => ['argument#1', 'argument#2']
            ]
        ]
    ]
];

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\DataSourcesStore({
 *      @DM\DataSource(
 *          id="personSource",
 *          class="Kassko\Sample\PersonDataSource",
 *          method="getData",
 *          args="#id",
 *          lazyLoading=true,
 *          supplySeveralFields=true,
 *          onFail="checkException",
 *          exceptionClass="\RuntimeException",
 *          badReturnValue="emptyString",
 *          fallbackSourceId="testFallbackSourceId",
 *          depends="#dependsFirst",
 *          preprocessor = @DM\Method(method="somePreprocessor"),
 *          processor = @DM\Method(method="someProcessor")
 *      )
 * })
 */
class SomeClass
{
}

[
    'object'    => [
        'dataSourcesStore'    => [
            [
                'id'=> 'personSource',
                'class'=> 'Kassko\Sample\PersonDataSource',
                'method'=> 'getData',
                'args' => ['#id'],
                'lazyLoading' => true,
                'supplySeveralFields' => true,
                'onFail'    => 'checkException',
                'exceptionClass' => '\RuntimeException',
                'badReturnValue' => 'emptyString',
                'fallbackSourceId' => 'testFallbackSourceId',
                'depends' => ['#dependsFirst'],
                'preprocessor' => [
                    'class' => '',
                    'method' => 'somePreprocessor',
                    'args' => []
                ],
                'processor' => [
                    'class' => '',
                    'method' => 'someProcessor',
                    'args' => []
                ]
            ]
        ]
    ]
];

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\RefImplicitSource(id="RefImplicitSourceId")
 */
class SomeClass
{
    protected $fieldToBindAutoToImplicitSource;

    protected $anotherFieldToBindAutoToImplicitSource;

    /**
     *@DM\ExcludeImplicitSource
     */
    protected $fieldNotToBindAutoToImplicitSource;
}

[
    'object' => [
        'RefImplicitSource' => 'RefImplicitSourceId'
    ],
    'fields' => [
        'fieldToBindAutoToImplicitSource' => [
            'name'      => 'fieldToBindAutoToImplicitSource',
        ],
        'anotherFieldToBindAutoToImplicitSource' => [
            'name'      => 'anotherFieldToBindAutoToImplicitSource',
        ],
        'fieldNotToBindAutoToImplicitSource' => [
            'name'      => 'fieldNotToBindAutoToImplicitSource',
        ]
    ],
    'fieldsNotToBindToImplicitSource' => [
        'fieldNotToBindAutoToImplicitSource'
    ]
];

use Kassko\DataMapper\Annotation as DM;

class SomeClass
{
    /**
     * @DM\Field(
     *      name="FirstField",
     *      type="string",
     *      class="stdClass",
     *      readConverter="readConvertFirstField",
     *      writeConverter="writeConvertFirstField",
     *      fieldMappingExtensionClass="ExtensionClass"
     * )
     */
    protected $fieldOne;

    /**
     * @DM\Field(
     *      name="SecondField",
     *      type="integer",
     *      class="\DateTime",
     *      readDateConverter="readDateConvertSecondField",
     *      writeDateConverter="writeDateConvertSecondField",
     *      fieldMappingExtensionClass="ExtensionClass",
     *      defaultValue="12"
     * )
     */
    protected $fieldTwo;

    /**
     * @DM\Field(
     *      name="DateField",
     *      type="date"
     * )
     */
    protected $dateField;
}

[
    'fields' => [
        'fieldOne'  => [
            'name'                       => 'FirstField',
            'type'                       => 'string',
            'class'                      => 'stdClass',
            'readConverter'              => 'readConvertFirstField',
            'writeConverter'             => 'writeConvertFirstField',
            'fieldMappingExtensionClass' => 'ExtensionClass',
        ],
        'fieldTwo'  => [
            'name'                       => 'SecondField',
            'type'                       => 'integer',
            'class'                      => '\DateTime',
            'readDateConverter'          => 'readDateConvertSecondField',
            'writeDateConverter'         => 'writeDateConvertSecondField',
            'fieldMappingExtensionClass' => 'ExtensionClass',
            'defaultValue'               => 12
        ],
        'dateField' => [
            'name'                       => 'DateField',
            'type'                       => 'date'
        ]
    ]
];

use Kassko\DataMapper\Annotation as DM;

class SomeClass
{
    /**
     * @DM\Getter(
     *      name="getterName"
     * )
     */
    protected $firstField;

    /**
     * @DM\Getter(
     *      prefix="is"
     * )
     */
    protected $secondField;
}

[
    'fields'    => [
        'firstField'    => [
            'name'      => 'firstField',
            'getter'    => ['name' => 'getterName'],
        ],
        'secondField'    => [
            'name'      => 'secondField',
            'getter'    => ['prefix' => 'is'],
        ],
    ]
];

use Kassko\DataMapper\Annotation as DM;

class SomeClass
{
    /**
     * @DM\Id
     */
    protected $firstField;
}

[
    'id'        => 'firstField',
    'fields'    => ['firstField']
];

use Kassko\DataMapper\Annotation as DM;

class SomeClass
{
    /**
     * @DM\IdCompositePart
     */
    protected $firstField;

    /**
     * @DM\IdCompositePart
     */
    protected $secondField;
}

[
    'idComposite'   => ['firstField', 'secondField'],
    'fields'    => ['firstField', 'secondField']
];

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\Listeners(
 *  preHydrate = @DM\Methods({
 *      @DM\Method(class="SomeClass", method="preHydrateMethodName")   
 * }),
 *  postHydrate = @DM\Methods({
 *      @DM\Method(class="SomeClass", method="postHydrateMethodName"),
 *      @DM\Method(class="SomeClassB", method="postHydrateMethodName") 
 * }),
 *  preExtract = @DM\Methods({
 *      @DM\Method(class="SomeClass", method="preExtractMethodName", args="foo")   
 * }),
 *  postExtract = @DM\Methods({
 *      @DM\Method(class="SomeClass", method="postExtractMethodName", args={"foo", "#bar"})   
 * })
 * )
 */
class SomeClass
{
}

[
    'listeners' => [
        'preHydrate' => ['class' => 'SomeClass', 'method' => 'preHydrateMethodName'],                
        'postHydrate' => 
        [
            ['class' => 'SomeClass', 'method' => 'postHydrateMethodName'],
            ['class' => 'SomeClassB', 'method' => 'postHydrateMethodName'],
        ], 
        'preExtract' => ['class' => 'SomeClass', 'method' => 'preExtractMethodName', 'args' => 'foo'],
        'postExtract' => ['class' => 'SomeClass', 'method' => 'postExtractMethodName', 'args' => ['foo', '#bar']],
    ]
];

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\Method(method="someMethod")
 * @DM\Method(class="SomeClass", method="someMethod", args="abc")
 * @DM\Method(class="@some_object_created_from_factory_or_container", method="someMethod", args= {"##this", "abc"}
 */

[
    'method' => 'someMethod',
]

[
    'class' => 'SomeClass',
    'method' => 'someMethod',
    'args' => 'abc'
]

[
    'class' => '@some_object_created_from_factory_or_container',
    'method' => 'someMethod',
    'args' => ['##this', 'abc']
]

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\Object(
 *      fieldExclusionPolicy="exclude_all",
 *      providerClass="testProviderClass",
 *      readDateConverter="testReadDateConverter",
 *      writeDateConverter="testWriteDateConverter",
 *      propertyAccessStrategy=true,
 *      fieldMappingExtensionClass="testFieldMappingExtensionClass",
 *      classMappingExtensionClass="testClassMappingExtensionClass"
 * )
 */
class SomeClass
{

}

[
    'fieldExclusionPolicy'  => 'exclude_all',
    'object'    => [
        'providerClass'         => 'testProviderClass',
        'readDateConverter'     => 'testReadDateConverter',
        'writeDateConverter'    => 'testWriteDateConverter',
        'propertyAccessStrategy'=> true,
        'fieldMappingExtensionClass' => 'testFieldMappingExtensionClass',
        'classMappingExtensionClass' => 'testClassMappingExtensionClass'
    ]
];

use Kassko\DataMapper\Annotation as DM;

/** 
 * @DM\ObjectListeners(
 *      classList={"SomeListenerAClass", "SomeListenerBClass"}
 * )
 */
class SomeClass
{
}

[
    'objectListeners'   => ['SomeListenerAClass', 'SomeListenerBClass']
];

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\Object(classMappingExtensionClass="mappingExtensionClass")
 *
 * @DM\PostExtract(method="postExtractMethodName")
 */
class SomeClass
{
}

[
    'object' => ['classMappingExtensionClass' => 'mappingExtensionClass'],
    'interceptors'  => [
        'postExtract'    => 'postExtractMethodName'
    ]
];

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\Object(classMappingExtensionClass="mappingExtensionClass")
 *
 * @DM\PostHydrate(method="postHydrateMethodName")
 */
class SomeClass
{
}

[
    'object' => ['classMappingExtensionClass' => 'mappingExtensionClass'],
    'interceptors'  => [
        'postHydrate'    => 'postHydrateMethodName'
    ]
];

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\Object(classMappingExtensionClass="mappingExtensionClass")
 *
 * @DM\PreExtract(
 *      method="preExtractMethodName"
 * )
 */
class SomeClass
{
}

[
    'object' => ['classMappingExtensionClass' => 'mappingExtensionClass'],
    'interceptors'  => [
        'preExtract'    => 'preExtractMethodName'
    ]
];

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\Object(classMappingExtensionClass="mappingExtensionClass")
 *
 * @DM\PreHydrate(method="preHydrateMethodName")
 */
class SomeClass
{
}

[
    'object' => ['classMappingExtensionClass' => 'mappingExtensionClass'],
    'interceptors'  => [
        'preHydrate'    => 'preHydrateMethodName'
    ]
];

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\RefImplicitSource(id="RefImplicitSourceId")
 */
class SomeClass
{

}

[
    'object' => [
        'RefImplicitSource' => 'RefImplicitSourceId'
    ],
    'fields' => [
        'mockField' => [
            'name'      => 'mockFieldName',
        ]
    ]
];

use Kassko\DataMapper\Annotation as DM;

/**
 * @DM\DataSourcesStore({
 *      @DM\DataSource(
 *          id="someDataSource",
 *          class="Kassko\Sample\PersonDataSource",
 *          method="getData"
 *      )
 * })
 */
class SomeClass
{
    /**
     * @DM\RefSource(id="someDataSource")
     */
    private $fieldOne;
}

[
    'object'    => [
        'dataSourcesStore'    => [
            [
                'id'=> 'personSource',
                'class'=> 'Kassko\Sample\PersonDataSource',
                'method'=> 'getData',
            ]
        ]
    ],
    'fields'    => [
        'fieldOne' => [
            'name'  => 'fieldOne',
            'refSource' => 'someDataSource',
        ]
    ],
];
### Setter config

Annotation format:

[
    'fields'    => [
        'firstField'    => [
            'name'      => 'firstField',
            'setter'    => ['name' => 'setterName'],
        ]
    ]
];

use Kassko\DataMapper\Annotation as DM;

/**
 * Optional because it's the default settings for fieldExclusionPolicy.
 * @DM\Object(fieldExclusionPolicy="}

[
    /*
    //Optional because it's the default settings for fieldExclusionPolicy.
    'object' => [
        'fieldExclusionPolicy' => ''     => 'excludedField'
        ],
        'anotherField'         => [
            'name'     => 'anotherField'
        ]
    ]
];