Butochnikov
9/14/2016 - 9:01 AM

Презентеры в Laravel.

Презентеры в Laravel.

<?php

namespace App\Exceptions;

use Exception;

class PresenterNotFoundException extends Exception
{
    /**
     * Create a new presenter not found exception.
     *
     * @param string      $class
     * @param string|null $message
     * @param int         $code
     * @param Exception   $previous
     */
    public function __construct($class, $message = null, $code = 0, Exception $previous = null)
    {
        if (!$message) {
            $message = $class.' not found. Please set the $presenter property to your presenter path.';
        }

        parent::__construct($message, $code, $previous);
    }
}
<?php

namespace App\Presenters;

use App\Exceptions\PresenterNotFoundException;

trait Presentable
{
    /**
     * View presenter instance
     *
     * @var AbstractPresenter
     */
    protected $presenterInstance;

    /**
     * Default presenters namespace.
     * 
     * @var string
     */
    protected $presentersNamespace = 'App\\Presenters\\';

    /**
     * Prepare a new or cached presenter instance
     *
     * @throws PresenterNotFoundException
     * @return AbstractPresenter
     */
    public function present()
    {
        $presenter_class_name = $this->presenter ?? $this->presentersNamespace . class_basename($this) . 'Presenter';

        if (!class_exists($presenter_class_name, true)) {
            throw new PresenterNotFoundException($presenter_class_name);
        }

        if (!$this->presenterInstance) {
            $this->presenterInstance = new $presenter_class_name($this);
        }

        return $this->presenterInstance;
    }
}
<?php

namespace App\Presenters;

abstract class AbstractPresenter
{
    /**
     * The resource that is the object that was decorated.
     *
     * @var mixed
     */
    protected $entity;

    /**
     * @param $entity
     */
    public function __construct($entity)
    {
        $this->entity = $entity;
    }

    /**
     * Allow for property-style retrieval
     *
     * @param $property
     * @return mixed
     */
    public function __get($property)
    {
        if ($this->presentMethodExists($property)) {
            $method = $this->getPresentMethod($property);
            return $this->{$method}();
        }

        return $this->entity->{$property};
    }

    public function __isset($property)
    {
        return $this->presentMethodExists($property) || isset($this->entity->{$property});
    }

    /**
     * Allow for methods-style retrieval
     *
     * @param  string $name
     * @param  array  $arguments
     * @return mixed
     */
    public function __call($name, $arguments)
    {
        return call_user_func_array([$this->entity, $name], $arguments);
    }

    protected function presentMethodExists($property)
    {
        return method_exists($this, $this->getPresentMethod($property));
    }

    protected function getPresentMethod($property)
    {
        return 'present'.studly_case($property);
    }
}