codixis/fixtures-mapper-bundle
Installation
Add the bundle to your composer.json:
composer require codixis/fixtures-mapper-bundle
Enable it in config/bundles.php:
Codixis\FixturesMapperBundle\CodixisFixturesMapperBundle::class => ['all' => true],
Basic Configuration
Update config/packages/codixis_fixtures_mapper.yaml (create if missing):
codixis_fixtures_mapper:
fixtures_dir: '%kernel.project_dir%/data/fixtures'
formats: ['csv', 'yaml']
First Fixture File
Create a CSV file at data/fixtures/users.csv:
id,name,email
1,John Doe,john@example.com
2,Jane Smith,jane@example.com
Load Fixtures via CLI
Use the fixtures:load command:
php bin/console fixtures:load
Define a Mapper Class
Create a mapper for your User entity in src/DataFixtures/Mapper/UserMapper.php:
namespace App\DataFixtures\Mapper;
use Codixis\FixturesMapperBundle\Mapper\FixturesMapperInterface;
use Doctrine\Common\Persistence\ObjectManager;
class UserMapper implements FixturesMapperInterface
{
public function map(array $data, ObjectManager $manager)
{
$user = new \App\Entity\User();
$user->setId($data['id']);
$user->setName($data['name']);
$user->setEmail($data['email']);
$manager->persist($user);
}
}
Register the Mapper
Update config/packages/codixis_fixtures_mapper.yaml:
codixis_fixtures_mapper:
mappers:
user:
class: App\DataFixtures\Mapper\UserMapper
file: users.csv
Load Specific Fixtures
php bin/console fixtures:load user
File Structure Organize fixtures by entity/module:
data/fixtures/
├── users/
│ ├── users.csv
│ └── users.yaml
└── products/
├── products.csv
└── products.yaml
YAML Fixtures
Example products.yaml:
products:
product_1:
name: "Laptop"
price: 999.99
stock: 10
product_2:
name: "Phone"
price: 699.99
stock: 20
Mapper for YAML
namespace App\DataFixtures\Mapper;
use Codixis\FixturesMapperBundle\Mapper\FixturesMapperInterface;
use Doctrine\Common\Persistence\ObjectManager;
class ProductMapper implements FixturesMapperInterface
{
public function map(array $data, ObjectManager $manager)
{
foreach ($data['products'] as $productData) {
$product = new \App\Entity\Product();
$product->setName($productData['name']);
$product->setPrice($productData['price']);
$product->setStock($productData['stock']);
$manager->persist($product);
}
}
}
Dependency Injection
Inject the FixturesMapper service in controllers/services:
use Codixis\FixturesMapperBundle\Service\FixturesMapper;
class SomeService
{
public function __construct(private FixturesMapper $fixturesMapper) {}
public function loadTestData()
{
$this->fixturesMapper->load('user');
}
}
Custom Fixture Directories
Override fixtures_dir per environment:
# config/packages/dev/codixis_fixtures_mapper.yaml
codixis_fixtures_mapper:
fixtures_dir: '%kernel.project_dir%/data/fixtures/dev'
Partial Loads
Use --filter to load specific records (CSV only):
php bin/console fixtures:load user --filter="name=John"
Post-Load Actions
Extend the FixturesMapper to run logic after loading:
$this->fixturesMapper->load('user', function() {
// Run post-load logic (e.g., send welcome emails)
});
Unmaintained Package
CSV Parsing Quirks
,). Use --delimiter for custom delimiters:
php bin/console fixtures:load user --delimiter=";"
"New York, NY") must be quoted. Test edge cases.YAML Anchors & References
&) and references (*) as they may not map cleanly to arrays.Doctrine Events
prePersist) for critical logic.Overwriting Data
--delete to truncate tables first:
php bin/console fixtures:load user --delete
Dry Run Mode Enable verbose output to see what would be loaded:
php bin/console fixtures:load user --dry-run
Logging Configure Monolog to log fixture loading:
# config/packages/monolog.yaml
handlers:
fixtures:
type: stream
path: "%kernel.logs_dir%/fixtures.log"
level: debug
Mapper Errors
Custom Format Support
Extend the bundle to support JSON or XML by implementing Codixis\FixturesMapperBundle\Loader\LoaderInterface:
namespace App\Fixtures\Loader;
use Codixis\FixturesMapperBundle\Loader\LoaderInterface;
class JsonLoader implements LoaderInterface
{
public function load(string $file): array
{
return json_decode(file_get_contents($file), true);
}
}
Register in config:
codixis_fixtures_mapper:
loaders:
json: App\Fixtures\Loader\JsonLoader
Pre/Post Load Hooks
Subscribe to the fixtures_mapper.load event:
namespace App\EventListener;
use Codixis\FixturesMapperBundle\Event\FixturesLoadEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class FixturesSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
'fixtures_mapper.load' => 'onFixturesLoad',
];
}
public function onFixturesLoad(FixturesLoadEvent $event)
{
// Run before/after loading
}
}
Dynamic Fixtures
Generate fixtures dynamically by implementing FixturesMapperInterface with runtime logic:
class DynamicUserMapper implements FixturesMapperInterface
{
public function map(array $data, ObjectManager $manager)
{
for ($i = 1; $i <= 100; $i++) {
$user = new User();
$user->setName("User $i");
$user->setEmail("user$i@example.com");
$manager->persist($user);
}
}
}
Case Sensitivity
Default Values
null. Handle in your mapper:
$user->setEmail($data['email'] ?? 'default@example.com');
Environment Variables
%env() in config for dynamic paths:
codixis_fixtures_mapper:
fixtures_dir: '%env(FIxtures_DIR)%/data'
Caching
How can I help you explore Laravel packages today?