deefour / presenter
PHP 对象的 Presenters/Decorators
3.0.1
2017-11-07 15:03 UTC
Requires
- php: >=5.5.0
- illuminate/support: ^5.0
Requires (Dev)
- friendsofphp/php-cs-fixer: 2.1.0
- illuminate/container: ^5.0
- illuminate/support: ^5.0
- phpspec/phpspec: ^2.4.0
README
面向对象的展示逻辑。
入门
运行以下命令将 Presenter 添加到项目的 composer.json
中。有关特定版本,请参阅 Packagist。
composer require deefour/presenter
需要 >=PHP5.5.0
。
解析器
Deefour\Presenter\Resolver
决定与对象关联的展示类类的完全限定名 (FQN)。解析器的默认行为是在 Article
FQN 后追加 'Presenter'
。
use Deefour\Presenter\Resolver; (new Resolver)->presenter(new Article); //=> 'ArticlePresenter'
可以通过向解析器传递一个可调用来自定义此行为。
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'
解析器将在对象上查找 modelClass()
方法。如果找到,将使用返回的 FQN 而不是对象本身。
class BlogPost { static public function modelClass() { return Article::class; } } (new Resolver)->presenter(new BlogPost); //=> 'ArticlePresenter'
实例化
实例化展示类实例是您的责任。
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'
如果从解析器返回的 FQN 与现有的有效类名不匹配,将返回 null
或抛出 NotDefinedException
。
use Deefour\Presenter\Resolver; (new Resolver)->presenter(new ObjectWithoutPresenter); //=> null (new Resolver)->presenterOrFail(new ObjectWithoutPresenter); //=> throws NotDefinedException
展示者
展示者本身扩展 Deefour\Presenter\Presenter
。
use Deefour\Presenter\Presenter; class ArticlePresenter extends Presenter { public function isDraft() { return $this->_model->isDraft() ? 'Yes' : 'No'; } }
API
API 快速概述。
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
一些需要注意的事项
- 可以通过
$_model
属性或model()
方法访问被展示者装饰的底层对象。 - 底层对象上公开的任何属性或方法也可以通过展示者直接访问。
- 展示者或底层模型上的任何公开的、驼峰式的公共方法都可以通过蛇形属性访问来访问。
自动展示者解析
当通过展示者的 __get()
或 __call()
方法解析属性或方法时,将尝试解析并将返回值包装在展示者中。
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; } }
给定存在 ArticlePresenter
、CategoryPresenter
和 TagPresenter
,将返回以下内容
use Deefour\Presenter\Resolver; $presenter = (new Resolver)->presenter(new Article); //=> ArticlePresenter (new $presenter)->category; //=> CategoryPresenter (new $presenter)->tags->first(); //=> TagPresenter
注意: 集合解析通过查找
IteratorAggregate
的实例来工作。迭代器用于遍历集合并为每个项目生成展示者。然后尝试实例化一个实现IteratorAggregate
的原始对象的新的实例。这是返回值。
如果您想访问原始关联,只需从底层对象请求它。
$presenter->_model->tags()->first(); //=> Tag
贡献
变更日志
3.0.1 - 2017年11月7日
- 在检查是否存在底层模型上的方法之前,先检查它是否是一个属性。修复了与 Laravel 的
__isset()
实现在Illuminate\Database\Eloquent\Model
上的冲突。
3.0.0 - 2017年7月20日
- 解析器不再接受对象进行实例化。相反,对象直接传递到
presenter()
和presenterOrFail()
方法。 - 解析器上新增了
resolveWith()
方法,接受一个可调用来自定义解析。 - 解析器中已删除对
presenterClass()
的支持,转而使用解析器上的新resolveWith()
方法。您可以将包含现有presenterClass()
逻辑的可调用传递给解析器。 - 应仅通过新的
model()
方法进行模型访问。已禁用对_model
的访问。
2.0.0 - 2017年2月12日
- 将
Factory
替换为新的Resolver
类。 - 移除了对
deefour\producer
的依赖。 - 移除了
Presentable
合约。 - 简化了
README.md
。
1.0.0 - 2015年10月7日
- 发布 1.0.0 版本。
0.8.0 - 2015年8月8日
- 为
deefour/producer
的更新进行兼容性更改。 - 新的
Factory
类可用于防止在deefour/producer
中直接与工厂交互。 - 将呈现器解析抽象到新的
deefour/producer
。 - 移除了 Laravel 服务提供者和外观。应使用
deefour/producer
中的'producer'
服务。
0.6.2 - 2015年6月5日
- 现在遵循 PSR-2。
0.6.0 - 2015年5月24日
- 移除了基呈现器上的
model()
方法。 - 将
$model
属性重命名为$_model
以避免与名为'model'
的实际模型属性冲突。 - 呈现器现在只为呈现器上的 公共 属性提供属性访问。
- 在基呈现器上对 API 方法/属性使用
_
前缀以进一步避免与属性覆盖冲突。 - 使
$_model
属性公开。 - 更新代码格式。
0.5.0 - 2015年4月27日
- 蛇形到驼峰式方法转换现在被缓存以提高性能。
- 对于缺少的属性/方法不再抛出异常。有关说明,请参阅
6f33dda
。
0.4.0 - 2015年3月19日
- 将
presenter()
辅助函数重命名为present()
。 - 从 Composer 自动加载中移除
helpers.php
。开发者应能够选择是否包含这些函数。 - 清理文档块。
- 对呈现器工厂进行类型提示。
- 将
Presentable
特性重命名为ResolvesPresenters
以避免与\Deefour\Presenter\Contracts\Presentable
命名冲突。
0.3.0 - 2015年3月16日
- 允许显式请求呈现器,绕过模型默认值。例如
$article = new Article; echo get_class($article->presenter()); //=> 'ArticlePresenter' echo get_class($article->presenter(FeaturedArticlePresenter::class)); //=> 'FeaturedArticlePresenter'
0.2.3 - 2015年2月27日
- 现在可以直接将
Illuminate\Support\Collection
实例和原生 PHP 数组传递给presenter()
辅助函数。
0.2.2 - 2015年2月20日
- 更新了对 Laravel Eloquent 关系的支持。现在在请求时,关系会被检索并转换为包裹在呈现器中的对象或集合。
0.2.0 - 2015年2月5日
- 修复服务提供者。
- 如果可用,全局
presenter()
将与 Laravel IoC 容器一起工作。 - 移动特性。
0.1.0 - 2014年11月21日
- 初始发布。
许可
版权所有 (c) 2014 Jason Daly (deefour)。在 MIT 许可证 下发布。