tonicforhealth / model-transformer
Simple abstraction for object transformations
Installs: 16 889
Dependents: 1
Suggesters: 0
Security: 0
Stars: 1
Watchers: 4
Forks: 0
Open Issues: 0
Requires (Dev)
- phpspec/phpspec: ~2.3
This package is not auto-updated.
Last update: 2024-11-09 19:30:19 UTC
README
Simple abstraction for object transformations.
Installation
Require dependencies via composer:
$ composer require tonicforhealth/model-transformer
Usage
Possible use cases:
- Separate domain model layer from view or presentation layer, but still keep objects.
- Separate domain model from resource representations (in RESTful applications).
Suppose, there are two domain objects:
<?php class Product { /** * @var string */ private $name; /** * @var Category */ private $category; // ... /** * @return string */ public function getName() { return $this->name; } /** * @return Category */ public function getCategory() { return $this->category; } } class Category { /** * @var string */ private $name; // ... /** * @return string */ public function getName() { return $this->name; } }
And one presentation object which can be used in presentation layer:
<?php class ProductPresentation { /** * @var string */ private $name; /** * @var string */ private $categoryName; /** * @var int */ private $purchasedCount; // ... /** * @return string */ public function getName() { return $this->name; } /** * @return string */ public function getCategoryName() { return $this->categoryName; } /** * @return string */ public function getPurchasedCount() { return $this->purchased; } }
There are lot of solutions for transforming Product
and Category
objects to ProductRepresentation
:
- just create
ProductRepresentation
basedProduct
andCategory
on at the needed place; - create factory for
ProductRepresentation
; - and so on.
This library provides simple and concise solution for this problem:
- Create transformer for objects.
- Register it in transformer manager or use it separately.
Possible transformer for ProductRepresentation
:
<?php class ProductToProductRepresentationModelTransformer implements ModelTransformerInterface { /** * @var ProductRepository */ private $productRepository; // ... /** * {@inheritdoc} */ public function supports($object, $targetClass) { return ($object instanceof Product) && is_a($targetClass, ProductRepresentation::class, true); } /** * {@inheritdoc} */ public function transform($object, $targetClass) { /** @var Product $product */ $product = $object; $purchasedCount = $this->productRepository->computePurchasedCount($product); return new ProductRepresentation( $product->getName(), $product->getCategory()->getName(), $purchasedCount ); } }
Register it:
<?php $priority = 0; $modelTransformer->addTransformer($productToProductRepresentationModelTransformer, $priority = 0);
With an optional priority integer (higher equals more important and therefore that the transformer will be triggered earlier) that determines when a transformer is triggered versus other transformers (defaults to 0).
Use it anywhere:
<?php $productRepresentation = $modelTransformer->transform($product, ProductRepresentation::class);
If you have simple rules of transformation, you can use ObjectTransformerInterface instead. As bonus transformation will work much faster.
Specifications
All actual documentation is runnable library specifications at /spec
directory.
And to ensure library is not broken, run (under library directory):
bin/phpspec run