dmytrof/import-fractal-bundle
Install Dependencies Run:
composer require dmytrof/import-fractal-bundle league/fractal
Ensure dmytrof/import-bundle is also installed (this package extends its functionality).
Enable the Bundle
Add to config/bundles.php:
Dmytrof\ImportFractalBundle\DmytrofImportFractalBundle::class => ['all' => true],
First Use Case: Transform Import Results Configure a transformer for your import job’s output. Example:
// src/Import/Transformers/UserTransformer.php
namespace App\Import\Transformers;
use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
public function transform($userData)
{
return [
'id' => $userData['id'],
'name' => $userData['name'],
'email' => $userData['email'],
];
}
}
Apply Transformer to Import Job In your import job class, inject the transformer:
// src/Import/Jobs/UserImportJob.php
use Dmytrof\ImportBundle\Import\Job\JobInterface;
use Dmytrof\ImportFractalBundle\Import\Job\FractalAwareJobInterface;
class UserImportJob implements JobInterface, FractalAwareJobInterface
{
private $transformer;
public function __construct(UserTransformer $transformer)
{
$this->transformer = $transformer;
}
public function getTransformer(): TransformerAbstract
{
return $this->transformer;
}
}
Define Transformer
Extend TransformerAbstract to shape raw import data into API-friendly structures.
Example for nested data:
public function transform($data)
{
return [
'user' => $this->transformUser($data['user']),
'metadata' => $data['metadata'],
];
}
protected function transformUser($userData)
{
return [
'id' => $userData['id'],
'roles' => array_map(fn($role) => ['name' => $role], $userData['roles']),
];
}
Leverage Fractal’s Serializer
Use Data::create() to format responses:
use League\Fractal\Manager;
use League\Fractal\Resource\Collection;
use League\Fractal\Resource\Item;
// In your controller/service
$manager = new Manager();
$manager->setSerializer(new JsonSerializer());
$resource = new Collection($importedData, new UserTransformer());
$result = $manager->createData($resource)->toArray();
Integrate with ImportBundle
Use FractalAwareJobInterface to auto-apply transformers:
$importJob = new UserImportJob($transformer);
$importManager = $this->get('dmytrof_import.manager');
$importManager->import($importJob);
// Fetch transformed results
$results = $importManager->getResults();
$serialized = $manager->createData(new Collection($results, $transformer))->toArray();
Batch Processing For large imports, process in chunks and serialize incrementally:
$batchSize = 100;
$manager = new Manager();
foreach ($importedData as $i => $chunk) {
$resource = new Collection(array_slice($chunk, 0, $batchSize), $transformer);
yield $manager->createData($resource)->toArray();
}
Transformer Injection
FractalAwareJobInterface or its getTransformer() method.ClassNotFoundException or MethodNotFoundException in logs.Circular References
RuntimeException for circular references in nested data.includeRelationships() or manually handle cycles:
$resource = new Item($data, $transformer);
$resource->setIncluded($this->getIncludedResources($data));
Performance with Large Datasets
JsonStreamSerializer:
$manager->setSerializer(new JsonStreamSerializer());
Bundle Compatibility
dmytrof/import-bundle may have breaking changes.composer.json:
"require": {
"dmytrof/import-bundle": "^1.0",
"dmytrof/import-fractal-bundle": "^1.0"
}
Reuse Transformers Extend a base transformer for shared fields:
abstract class BaseEntityTransformer extends TransformerAbstract
{
abstract public function getDefaultIncludes();
public function transform($data)
{
return [
'id' => $data['id'],
'created_at' => $data['created_at'],
// ... common fields
];
}
}
Custom Serialization Override Fractal’s serializer for custom formatting (e.g., snake_case keys):
use League\Fractal\Serializer\ArraySerializer;
class SnakeCaseSerializer extends ArraySerializer
{
protected function transformKey($key)
{
return strtolower(preg_replace('/(.)(?=[A-Z])/', '$1_', $key));
}
}
Testing Transformers Use PHPUnit to test transformers in isolation:
public function testUserTransformer()
{
$transformer = new UserTransformer();
$data = ['id' => 1, 'name' => 'John', 'email' => 'john@example.com'];
$result = $transformer->transform($data);
$this->assertEquals('John', $result['name']);
}
Debugging
$manager->parseIncludes(true); // For debugging included resources
error_log('Raw: ' . print_r($rawData, true));
error_log('Transformed: ' . print_r($transformer->transform($rawData), true));
Extension Points
getDefaultIncludes() in transformers.$transformer = new UserTransformer($currentUser);
How can I help you explore Laravel packages today?