Package Data | |
---|---|
Maintainer Username: | deefour |
Maintainer Contact: | jason@deefour.me (Jason Daly) |
Package Create Date: | 2014-11-21 |
Package Last Update: | 2019-04-15 |
Home Page: | |
Language: | PHP |
License: | MIT |
Last Refreshed: | 2024-11-22 03:05:29 |
Package Statistics | |
---|---|
Total Downloads: | 2,445 |
Monthly Downloads: | 2 |
Daily Downloads: | 0 |
Total Stars: | 12 |
Total Watchers: | 2 |
Total Forks: | 1 |
Total Open Issues: | 0 |
Object-oriented presentation logic.
Run the following to add Presenter to your project's composer.json
. See Packagist for specific versions.
composer require deefour/presenter
>=PHP5.5.0
is required.
The Deefour\Presenter\Resolver
determines the FQN of a presenter class associated with an object. The default behavior of the resolver is to append 'Presenter'
to the Article
FQN.
use Deefour\Presenter\Resolver;
(new Resolver)->presenter(new Article); //=> 'ArticlePresenter'
This behavior can be customized by passing a callable to the resolver.
use Deefour\Presenter\Resolver;
$resolver = new Resolver;
$resolver->resolveWith(function ($instance) {
return "App\Presenters\" . get_class($instance) . 'Presenter';
});
$resolver->presenter(new Article); //=> 'App\Presenters\ArticlePresenter'
The resolver will look for a modelClass()
method on an object. If found, the returned FQN will be used instead of the object itself.
class BlogPost
{
static public function modelClass()
{
return Article::class;
}
}
(new Resolver)->presenter(new BlogPost); //=> 'ArticlePresenter'
Instantiating an instance of a presenter is your responsibility.
use Deefour\Presenter\Resolver;
$article = new Article;
$presenterName = (new Resolver)->presenter($article);
$presenter = new $presenterName($article);
use Deefour\Presenter\Resolver;
(new Resolver)->presenter(new Article); //=> 'BlogPresenter'
If the resulting FQN from the resolver does not match an existing, valid class name, null
will be returned or a NotDefinedException
will be thrown.
use Deefour\Presenter\Resolver;
(new Resolver)->presenter(new ObjectWithoutPresenter); //=> null
(new Resolver)->presenterOrFail(new ObjectWithoutPresenter); //=> throws NotDefinedException
The presenters themselves extend Deefour\Presenter\Presenter
.
use Deefour\Presenter\Presenter;
class ArticlePresenter extends Presenter
{
public function isDraft()
{
return $this->_model->isDraft() ? 'Yes' : 'No';
}
}
A quick overview of the API available.
use Deefour\Producer\Factory;
$presenter = (new Factory)->make(new Article, 'presenter'); //=> ArticlePolicy
$presenter->_model; //=> Article
$presenter->_model->isDraft(); //=> false
$presenter->isDraft(); //=> 'No'
$presenter->is_draft; //=> 'No'
$presenter->_model()->published; //=> true
$presenter->published; //=> true
A few things to notice:
$_model
property or model()
method.When a property or method is resolved through the __get()
or __call()
methods on the presenter, an attempt will be made to resolve and wrap the return value in a presenter too.
namespace App;
use Illuminate\Support\Collection;
class Article
{
public function category()
{
return new Category;
}
public function tags()
{
$collection = new Collection;
$collection->push(new Tag);
$collection->push(new Tag);
$collection->push(new Tag);
return $collection;
}
}
Given the existence of ArticlePresenter
, CategoryPresenter
, and TagPresenter
, the following will be returned
use Deefour\Presenter\Resolver;
$presenter = (new Resolver)->presenter(new Article); //=> ArticlePresenter
(new $presenter)->category; //=> CategoryPresenter
(new $presenter)->tags->first(); //=> TagPresenter
Note: The collection resolution works by looking for an instance of
IteratorAggregate
. The iterator is used to loop through the collection and generate presenters for each item. An attempt is then made to instantiate a new instance of the original object implementingIteratorAggregate
. That is the return value.
If you want access to the raw association, simply request it from the underlying object.
$presenter->_model->tags()->first(); //=> Tag
__isset()
implementation on Illuminate\Database\Eloquent\Model
.presenter()
and presenterOrFail()
methods.resolveWith()
method on the resolver accepts a callable to customize resolution.presenterClass()
has been removed from the resolver in favor of the new resolveWith()
method on the resolver. You can pass a callable with your existing presenterClass()
logic to the resolver instead.model()
method. Access to _model
has been disabled.Factory
with new Resolver
class.deefour\producer
Presentable
contractREADME.md
deefour/producer
.Factory
class is available to prevent the need to interact directly with the factory in deefour/producer
.deefour/producer
.'producer'
service in deefour/producer
should be used instead.model()
method on base presenter.$model
property to $_model
to avoid conflicts with an actual model
attribute with the name 'model'
._
on the base presenter to further avoid
conflicts with attribute overrides.$_model
property public.6f33dda
for an explanation.presenter()
helper to present()
helpers.php
from Composer autoload. Developers should be able to choose whether these functions are included.Presentable
trait to ResolvesPresenters
to avoid naming conflict with \Deefour\Presenter\Contracts\Presentable
. $article = new Article;
echo get_class($article->presenter()); //=> 'ArticlePresenter'
echo get_class($article->presenter(FeaturedArticlePresenter::class)); //=> 'FeaturedArticlePresenter'
Illuminate\Support\Collection
instances and native PHP arrays can now be passed directly into the presenter()
helper.presenter()
work with Laravel IoC container if it's available.Copyright (c) 2014 Jason Daly (deefour). Released under the MIT License.