Презентеры в 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);
}
}