定制 logaretm/transformers 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

logaretm/transformers

Composer 安装命令:

composer require logaretm/transformers

包简介

Simple laravel eloquent models transformers.

README 文档

README

Codacy Badge Build Status

This a package that provides transformer (reducer/serializer) classes and traits for the Laravel eloquent models.

Install

Via Composer

composer require logaretm/transformers
Transformer:

A class responsible for transforming or reducing an object from one form to another then consumed.

Why would you use them?

Transformers are useful in API responses, where you want the ajax results to be in a specific form, by hiding attributes, exposing additional ones, or convert attribute types.

Also by delegating the responsibility of transforming models to a separate class make it easier to handle and maintain down the line.

Inspiration

Having seenJeffery Way's Laracasts video and reading the book Building APIs You Won't Hate, I wanted to create a simple package specific to laravel apps and because I needed this functionality in almost every project.

Usage

First you need to a transformer for your model. the transformer should extend the Transformer abstract class. And provide an implementation for the getTransformation() method.

class UserTransformer extends Transformer
{
    /**
     * @param $user
     * @return mixed
     */
    public function getTransformation($user)
    {
        return [
            'name' => $user->name,
            'email' => $user->email,
            'memberSince' => $user->created_at->timestamp
        ];
    }
}

Now you can use the transformer in multiple ways, inject it in your controller method and laravel IoC should instantiate it.

class UsersController extends Controller
{
    public function index(UserTransformer $transformer)
    {
        $users = User::get();

        return response()->json([
            'users' => [
                'data' => $transformer->transform($users)
            ]
        ]);
    }
}

You can also instantiate it manually if you don't think DI is your thing.

$transformer = new UserTransformer;

Dynamic Transformation

You can also use the TransformableTrait on your model and define a $transformer property to be able to use the getTransformer() method.

class User extends Model implements Transform
{
    use TransformableTrait;

    /**
     * Defines the appropiate transformer for this model.
     *
     * @var
     */
    protected $transformer = UserTransformer::class;
}

then you can get the transformer instance using:

$user = User::first();
$transformer = $user->getTransformer(); // returns instance of UserTransformer.

which can be helpful if you want to dynamically transform models. but note that it will throw a TransformerException if the returned instance isn't an instance of Transformer.

Service Provider

You may find retrieving the transformer over and over isn't intuitive, you can use the TransformerServiceProvider and a config file to define an array mapping each model or any class to a transformer class.

  • Add this line to config/app.php in the service providers array.

Logaretm\Transformers\Providers\TransformerServiceProvider::class

  • Run this artisan command:

php artisan vendor:publish --provider="Logaretm\Transformers\Providers\TransformerServiceProvider" --tags="config"

  • Head over to config/transformers.php and populate the array with your model/transformer pairs.
    'transformers' => [
        User::class => UserTransformerClass
    ]
  • Now you don't need to provide the $transformer property anymore on your model, nor implement the interface.

Note that the transformer resolution for the related model will prioritize the registered transformers.

Furthermore you can now use the static methods Transformer::make and Transformer::canMake to instantiate transformers for the models, using the trait is still helpful, but not required anymore.

if(Transformer::canMake(User::class); // returns true if the transformer is registered.
$transformer = Transformer::make(User::class); // creates a transformer for the model.

Relations

It is also possible to transform a model along with their related models using the fluent method with().

The related model transformer is resolved when:

  • If the service provider is registered, then it will be resolved from the config array.

  • If the model implements the Transformable contract which is automated by the TransformableTrait. it also needs to define the $transformer property.

otherwise the model will be transformed using a simple toArray() call.

$transformer = new UserTransformer();
$users = User::with('posts')->get();
$data = $transformer->with('posts')->transform($users);

you can also transform nested relations with the same syntax.

$transformer = new UserTransformer();
$users = User::with('posts.tags')->get();
$data = $transformer->with('posts.tags')->transform($users);

you can reset the transformer relations using $transformer->resetRelations() which will remove the related models from the transformation. also note that any call to with will reset the transformer automatically.

aside from collections you can transform a paginator, or a single object.

$users = User::get();
$transformer->transform($users); // returns an array of arrays.

$paginator = User::paginate(15);
$transformer->transform($paginator); // returns an array(15).

$user = User::first();
$transformedUser =  $transformer->transform($user); // returns a single array.

Alternate Transformations

You don't have to use only one transformation per transformer, for example you may need specific transformations for specific scenarios for the same model.

using the method setTransformation you can override the transformation method to use another one you have defined on the transformer.

class UserTransformer extends Transformer
{
    /**
     * @param $user
     * @return mixed
     */
    public function getTransformation($user)
    {
        return [
            'name' => $user->name,
            'email' => $user->email,
            'memberSince' => $user->created_at->timestamp
        ];
    }

    // Custom/Alternate transformation.
    public function adminTransformation($user)
    {
        return [
            'name' => $user->name,
            'email' => $user->email,
            'memberSince' => $user->created_at->timestamp,
            'isAdmin' => $user->isAdmin()
        ];
    }
}

To use the alternate transformation:

$transformer->setTransformation('admin');

or you can pass a closure as an alternate transformation method.

$transformer->setTransformation(function ($user) {
    return [
        'name' => $user->name,
        'email' => $user->email,
        'memberSince' => $user->created_at->timestamp,
        'isAdmin' => $user->isAdmin()
    ];
});

Note that the naming convention for the transformation method is {transformation_name}Transformation.

any subsequent calls to transform method will use that transformation instead.

Note that it will throw a TransformerException if the requested transformation does not exist.

to reset the transformation method use the resetTransformation method.

$transformer->resetTransformation(); //resets the transformation method.

or if you want to reset both relations and transformation method:

$transformer->reset(); //resets the transformation method and the relations.

Generating Transformers

You can easily generate a transformer class using this artisan command:

php artisan make:transformer {transformer name}

which will create a basic transformer class in app/Transformers directory, don't forget to put your transformations there.

Testing

Use php unit for testing.

phpunit

TODO

  • Improve the API and method names.
  • Maybe a console command to generate a transformer for a model.
  • Use closures to override transformation.
  • Write more todos.

Contributing

All contributes will be fully credited.

Issues

If you discover any issues, email me at logaretm1@gmail.com or use the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

logaretm/transformers 适用场景与选型建议

logaretm/transformers 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 28.27k 次下载、GitHub Stars 达 18, 最近一次更新时间为 2016 年 02 月 20 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「laravel」 「transformers」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 logaretm/transformers 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 logaretm/transformers 我们能提供哪些服务?
定制开发 / 二次开发

基于 logaretm/transformers 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 28.27k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 20
  • 点击次数: 9
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 18
  • Watchers: 4
  • Forks: 3
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2016-02-20