webmunkeez / fixture-bundle
Fixture for Symfony.
Package info
github.com/yannissgarra/fixture-bundle
Type:symfony-bundle
pkg:composer/webmunkeez/fixture-bundle
Requires
- php: >=8.2
- doctrine/orm: ^3
- symfony/config: ^7.4
- symfony/console: ^7.4
- symfony/dependency-injection: ^7.4
- symfony/property-access: ^7.4
- symfony/property-info: ^7.4
- webmunkeez/cqrs-bundle: ^3.0
Requires (Dev)
This package is auto-updated.
Last update: 2026-08-19 10:04:24 UTC
README
This bundle brings Doctrine fixtures to Symfony applications.
Installation
Use Composer to install this bundle:
$ composer require webmunkeez/fixture-bundle
Add the bundle in your application kernel, enabled for dev/test only — the extension itself is a no-op in prod, so nothing is wired at all in production:
// config/bundles.php return [ // ... Webmunkeez\FixtureBundle\WebmunkeezFixtureBundle::class => ['dev' => true, 'test' => true], // ... ];
Usage
Writing a fixture
A fixture implements \Webmunkeez\FixtureBundle\Fixture\FixtureInterface — in practice you extend \Webmunkeez\FixtureBundle\Fixture\AbstractFixture, which gives you $this->getReference() and wires the Doctrine ManagerRegistry for you:
final class PostFixture extends AbstractFixture { public const DATA = [ 'title' => 'A post', ]; public function init(): array { return [ 'post_1' => self::DATA, ]; } public function denormalize(array $row): Post { return (new Post()) ->setId(Uuid::v7()) ->setAuthor($this->getReference('author_1')) ->setTitle($row['title']); } public function getDependencies(): array { return [AuthorFixture::class]; } }
Any service implementing FixtureInterface (Symfony's standard App\: resource: '../src/' service auto-registration already covers your own classes) is automatically tagged webmunkeez_fixture.fixture, wired with the Doctrine ManagerRegistry and the fixture reference repository, and collected by AddFixturePass into the Fixture orchestrator service below — no manual wiring needed.
init(): arrayreturns the raw rows to load, keyed by a reference name (e.g.'post_1') other fixtures can look up viagetReference().denormalize(array $row): mixedturns one raw row into a model instance.load()calls it for every row, persists the result, and registers it under its reference name — so a fixture depended upon by another (AuthorFixturehere) must run and be persisted beforedenormalize()on the dependent fixture calls$this->getReference('author_1').getDependencies(): arraylists other fixture classes that must load first;Fixturetopologically sorts all registered fixtures accordingly before runninginit(). A circular dependency between fixtures throws a\LogicExceptionrather than loading in an undefined order.
Assigned identifiers
If a fixture manually assigns an identifier (as above with Uuid::v7()) on an entity whose #[ORM\Id] property is also mapped with #[ORM\GeneratedValue], AbstractFixture::load() detects the pre-populated identifier and forces Doctrine's AssignedGenerator for that entity, so the assigned value is kept as-is on flush instead of being silently overwritten by the configured generator (auto-increment, sequence, etc). The original generator is restored right after Fixture::flush(), so persisting a new instance of that same entity class afterwards — without an assigned id — still relies on auto-generation as normal.
Running fixtures
\Webmunkeez\FixtureBundle\Fixture\Fixture is the orchestrator: init() runs every registered fixture (in dependency order) and flushes; denormalize(string $class, array $row)/load(string $class, array $rows) invoke a single fixture by class name without touching the others; flush() flushes and clears every Doctrine manager and clears all FixtureReferenceRepository references.
The bundle registers a console command that just calls Fixture::init():
$ bin/console webmunkeez:fixture:init