Tim's super awesome and easy guide to making a WORKING presenter

Rules:
    - You need to create a presenter for every entity that you create! Don't cheat!

Steps:
    - First create a new presenter class named <MyEntityName>Presenter who is RESPONSIBLE for presenting your type of entity

    - Make your newly created presenter extend the BasePresenter class as defined in BasePresenter.php

    - By default you still need implement the presentSingle method. This method is responsible for presenting a single entity
        - Even though the presentSingle method does not use type hinting in the interface, please do add type hinting in
          documentation of your new method by setting the type in the @param tag

    - For your presenter to work properly you need to do a few things. But first I'll show an example of what you should have so far

        class MyEntityPresenter extends BasePresenter
        {
            /**
             * @param MyEntity $object
             * @return array|string|int|double
             * @throws PresenterException
             */
            public function presentSingle($object)
            {
                return array();
            }
        }

    - Your presenter always returns a value that can be mapped to an array key, so an array string int or double,
      some other types can also be mapped to an array but we can't encode those to XML or JSON safely so we never want
      to return those

    - If your encoding process is unsafe in some situations you can throw a PresenterException(string: message) in case something goes wrong

    - It's important to know that your presenter can be in 2 states, inline presenting and not-inline presenting (sorry don't have a better term)
        - The state of your presenter can be read from this $this->inline field which is either true or false
        - If your presenter is in inline mode then you are expected to present your object as a single value such as a string, int or double
        - If your presenter is not in inline mode you are expected to present your object as an object by converting it to an array
        - Confused? Check the following example

    public function presentSingle($object) {
        if ($this->inline === true) {
            return $object->getName();
        }

        return array(
            'id' => $object->getId(),
            'name' => $object->getName(),
            'age' => $object->getAge(),
            'birth_date' => $object->getBirthDate()->format('c'), // We cheated here because we should be using a DatePresenter and tell it to run in inline mode, IMO this situation can be an exception to this rule
        )
    }

    - Great you now have a presenter that can encode an object to a single value, or to an array depending on what the user of the object requested (inline|not-inline)

    - Next there are a few things you always need to check for
        - You need to have null handing, if the object argument is null you want to return null in most cases
        - You need to execute the presenterHooks (don't worry)

    - Below is an example presenter with all these steps included

        class MyEntityPresenter extends BasePresenter
        {
            /**
             * @param MyEntity $object
             * @return array|string|int|double
             * @throws PresenterException
             */
            public function presentSingle($object)
            {
                // Check if the argument is null, and execute any custom handling if needed
                if ($object === null) {
                    return null;
                }

                // Provide inline handling
                if ($this->inline === true) {
                    return $object->__toString(); // For example execute the toString method of an object to provide it's own inlining behavior
                }

                // Encode direct properties of your object such as text and numbers directly
                $data = array(
                    'id' => $object->getId(),
                    'name' => $object->getName(),
                    'password' => $object->getPassword(),
                );

                // Execute presenter hooks
                $data = $this->executeMappedChildPresenters($data, $account);
                $data = $this->executePresenterHooks($data, $object); // Any closures added to this presenter by the user will be executed and their response will be appended to the $data array

                return $data; // Finally return your object encoded to an array
            }
        }

    - And a copy paste version
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
namespace IssetBV\Core\YourBundle\Presenter;

use IssetBV\Core\PresenterBundle\Presenter\BasePresenter;
use IssetBV\Core\PresenterBundle\Exception\PresenterException;
use IssetBV\Core\PresenterBundle\Presenter\PresenterInterface;

/**
 *
 *
 */
class Presenter extends BasePresenter
{
    /**
     * @todo Provide a Type
     * @param Type $object
     * @return array|string|int|double
     * @throws PresenterException
     */
    public function presentSingle($object)
    {
        if ($object === null) {
            return null;
        }

        if ($this->inline === true) {
            return /** TODO: PROVIDE INLINE HANDLING */;
        }

        $data = array(
            'id' => $object->getId(),
            /** TODO: Encode properties of your object */
        );

        // Execute any child presenters your object may have
        if (true === isset($this->childPresenters['yourchildpresenter'])) {
            /** $childPresenter PresenterInterface */
            $childPresenter = $this->childPresenters['yourchildpresenter'];
            $data['school'] = $childPresenter->presentSingle($object->getSomething());
        } else if (true === isset($this->childPresenters['anyOtherPresenter'])) {
            // ...
        }

        $data = $this->executePresenterHooks($data, $object);

        return $data;
    }
}