bfg / transformer
Installs: 30 875
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 1
Open Issues: 0
Type:bfg-app
Requires
- php: >=8.0.0
- illuminate/contracts: ^8.0|^9.0|^10.0|^11.0
- dev-master
- 1.4.4
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.6
- 1.3.5
- 1.3.4
- 1.3.3
- 1.3.2
- 1.3.1
- 1.3.0
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.5
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.16
- 1.0.15
- 1.0.14
- 1.0.13
- 1.0.12
- 1.0.11
- 1.0.10
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- 0.2.7
- 0.2.6
- 0.2.5
- 0.2.4
- 0.2.3
- 0.2.2
- 0.2.1
- 0.2.0
- 0.1.2
- 0.1.1
- 0.1.0
This package is auto-updated.
Last update: 2024-12-07 18:40:31 UTC
README
Install
composer require bfg/transformer
Description
The package is designed to transform data for
the model (on the example obtained by the data from the API). And data from
the model (for example, when you need to send data back on the API).
Usage
Create new transformer
php artisan make:transformer UserTransformer -m User
Describe all the fields that you will fill in the new class App\Transformers\UserTransformer
in the $toModel
variable:
use Bfg\Transformer\Transformer; ... class UserTransformer extends Transformer { /** * If your data that you received from * a third-party source have an Identifier, * then you need to specify this field. * @var string|null */ protected ?string $remoteId = "ID"; /** * An alternative source indicate the model * if it is not sent to the transformer. * @var string|null */ protected ?string $modelClass = User::class; /** * Mapping to send data generation into the model. * @var string[] */ protected array $toModel = [ 'FullName' => 'name', 'Email' => 'email', // or if you identical key names: 'name', 'email', // for related iteration ContactsTransformer::class // The transformer of contacts => 'contacts', // The relation name in the model ]; /** * Mapping for the direction of data generation * from the model, back to third-party service. * @var string[] */ protected array $fromModel = [ 'name' => ['FirstName', 'LastName'], 'address' => 'Address', 'email' => 'Email', 'phone' => 'Phone', ]; /** * To implement the data unloading mechanism * on third-party service. * @return void */ public function upload() { } }
Mutators
For fully transformation, it is often necessary to process a little more accurately, for this there are mutators in different directions:
use Bfg\Transformer\Transformer; ... class UserTransformer extends Transformer { ... protected array $toModel = [ 'FullName' => 'name', 'Email' => 'email', ]; protected array $fromModel = [ 'name' => ['FirstName', 'LastName'], 'email' => 'Email', ]; protected function toNameAttribute($dataValue) { $this->data; // All data is available on this property. $this->model; // The model is available on this property. return $dataValue; } protected function fromNameAttribute($modelValue) { return $modelValue; } protected function forFirstNameDataAttribute($modelValue) { return $modelValue; } protected function forLastNameDataAttribute($modelValue) { return $modelValue; } protected function forEmailDataAttribute($modelValue) { return $modelValue; } }
Casting
All transformation casting rules are completely copied from the
casting of Laravel Attributes
and their functionality is absolutely identical (except for the set
of custom casts):
... protected $casts = [ 'views' => 'int' ]; ...
Applies to data, not to the model.
Model catch
In order to catch a model definition for a transformer (based on data), you can use the getModel
method:
use Bfg\Transformer\Transformer; use App\Models\User; ... class UserTransformer extends Transformer { ... protected function getModel() { return User::where('remote_id', $this->data['ID'])->first() ?: parent::getModel(); } }
Data catch
For a transformer, you can determine the value for processing directly inside,
this mechanism allows you to generate built-in dependent nesting.
According to the rules, if a collection Illuminate\Support\Collection
is returned,
then the selection of a transformer instance will be created for each entry.
use Bfg\Transformer\Transformer; use App\Models\User; ... /** * @property-read ApiService $api For example some "ApiService" class */ class UserTransformer extends Transformer { ... protected function getData() { return $this->api->findUser($this->model->remote_id); } }
Data to model
use App\Transformers\UserTransformer; ... $data = [ 'userName' => 'Thomas', 'userEmail' => 'thomas@example.com', ]; // for example, any data $model = UserTransformer::make() ->withData($data) ->toModel(); // Instance of User model // Or from any model $model = UserTransformer::make() ->withData($data) ->withModel(User::find(1)) ->toModel(); // With my instance of User model $model->save();
Data from model
use App\Models\User; use App\Transformers\UserTransformer; ... $model = User::find(1); $data = UserTransformer::make()->withModel($model)->toData()->data; // => ['userName' => 'Thomas','userEmail' => 'thomas@example.com'] // Or with you data filling $fillData = (object) ['userName' => null, 'userEmail' => null, 'otherData' => 'test'] UserTransformer::make()->withModel($model)->withData($fillData)->toData()->upload();
Next, the collection perceives all the methods of the model to the entire collection:
use App\Transformers\TransformerCollection; ... /** @var TransformerCollection $collection */ $collection->save();
To start the entire chain in the transaction:
use App\Transformers\TransformerCollection; ... /** @var TransformerCollection $collection */ $collection->transaction()->save(); // For additional updating $collection->transaction()->save()->update([ 'api_updated_at' => now() ]);