Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Fixtures Generator Bundle Laravel Package

xcidar/doctrine-fixtures-generator-bundle

A Symfony bundle that generates Doctrine fixtures from your existing database data. Quickly create realistic, schema-consistent fixture classes for testing and development, reducing manual setup and keeping test data aligned with your current schema. Ideal for bootstrapping test suites and local env...

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install (dev only)

composer require --dev xcidar/doctrine-fixtures-generator-bundle
composer require --dev doctrine/doctrine-fixtures-bundle

The generator writes fixtures that extend Doctrine\Common\DataFixtures\FixtureInterface / AbstractFixture, so the fixtures bundle is a hard runtime dependency of the output, not just of the generator.

2. Register the bundle in dev/test only

Old bundles (last release 2019) still use the *Bundle class convention. Look at the actual class inside vendor/xcidar/doctrine-fixtures-generator-bundle/ before editing config/bundles.php — it may be Webonaute\DoctrineFixturesGeneratorBundle\WebonauteDoctrineFixturesGeneratorBundle or a legacy WebonauteDoctrineFixturesGeneratorBundle class. Register it only for ['dev', 'test'] so it never loads in prod.

3. Where to look first

  • bin/console list — confirm the command is registered (typically webonaute:fixtures:generate or similar; the exact name varies by fork). If it does not appear, the bundle is not loaded in the current env.
  • bin/console <command> --help — this is the authoritative reference for the entity argument format (usually an FQCN like App\Entity\Product) and the IDs syntax.
  • The bundle's DependencyInjection/Configuration.php / services.yml in vendor/ — this tells you the configurable output directory and namespace, which you must align with your PSR-4 autoloading.

4. Minimal config

# config/packages/dev/doctrine_fixtures_generator.yaml
# (key name and node names vary — copy them from the bundle's Configuration.php)
doctrine_fixtures_generator:
    destination: '%kernel.project_dir%/src/DataFixtures/Generated'
    namespace: 'App\DataFixtures\Generated'

Create the directory and make sure the namespace matches the path, or the generated classes will not autoload.

5. First use case

The canonical workflow: point it at a staging database, pick a small set of primary keys for one entity, and turn real rows into a committable fixture.

bin/console doctrine:fixtures:generate 'App\Entity\Product' 12,45,301

Inspect the generated file, fix the obvious problems (see Gotchas), then verify:

bin/console doctrine:fixtures:load --group=generated -e test

That "generate → read → hand-tune → load" loop is the intended day-to-day usage. Treat the output as a scaffold, not a finished fixture.

Implementation Patterns

Generate per aggregate root, wire relations manually. The generator faithfully reproduces scalar columns but is unreliable for associations. The pattern that scales is: generate the leaf/reference entities first (categories, countries, users), load them, then hand-write the root fixture using $this->addReference('product-12', $product) and $this->getReference(...) for associations. Generated files become the "data half"; you own the "relations half."

Reference-based assembly across generated fixtures. Add $this->addReference('entity-'.$entity->getId(), $entity); immediately after each generated persist(). Then any other fixture can getReference() by the original database ID, which keeps the generated code traceable back to the source row — invaluable when a fixture breaks six months later.

Snapshot-to-fixture pipeline. Scrubbed staging dump → import into a disposable test DB → run the generator for the top 3–5 entities with a curated ID list → commit. Script the ID list in a small shell/Makefile target so regeneration is reproducible instead of ad-hoc.

fixtures:
	bin/console doctrine:fixtures:generate 'App\Entity\Category' 1,2,3 --env=dev
	bin/console doctrine:fixtures:generate 'App\Entity\Product' $(PRODUCT_IDS) --env=dev

Parametrize rather than duplicate. If the generator emits 50 near-identical blocks for 50 IDs, refactor once into a foreach over an array of field maps with a private createProduct(array $data) helper. You keep the values (the expensive part) and lose the copy-paste noise.

Bridge to Alice / nelmio/alice. If your team prefers YAML fixtures, use the generator purely as a source of realistic field values: run it against staging, copy the literal strings into Alice YAML, delete the generated PHP. This is often the highest-value use of the tool for teams already invested in Alice.

Load ordering and groups. Give generated fixtures a getGroups() returning ['generated'] so CI can run --group=generated in isolation and skip them in a full fixture load where hand-written seed data must win.

Gotchas and Tips

  • Compatibility is the biggest risk. Last tagged release was 2019. Expect issues on Symfony 5+/6+ (service definitions, Configuration tree changes) and PHP 8.1+ if the code uses deprecated patterns. Before investing, try composer why-not, and check whether the bundle compiles with bin/console cache:warmup -e dev. If it won't boot, a fork or an inline copy of the generator class is usually cheaper than fighting it.
  • Relations are the weak spot. Generated code commonly sets only the owning side, skips cascade handling, and ignores NOT NULL foreign keys. Loading in the wrong order produces integrity-constraint errors that look like generator bugs but are fixture-ordering problems — use DependentFixtureInterface or explicit groups.
  • Type fidelity. DateTime, DateTimeImmutable, JSON/text arrays, decimals and binary/blob columns are the usual casualties: expect new \DateTime('...') to be missing, JSON to arrive as a plain string, and blobs to be garbled. Grep generated files for set.*(array|json|blob) setters and fix them by hand.
  • Value objects and custom DBAL types (money, UUID, enum-backed strings) will likely be emitted as raw scalars into setters that expect an object. This is where the tool quietly produces non-loadable code.
  • Entity inheritance (single-table / class-table) and embeddables are frequently mishandled — the generated file may target the wrong concrete class or flatten embedded fields incorrectly.
  • Explicit IDs. If the generated fixture sets setId() (some forks do), you can collide with auto-increment sequences on --append loads. Prefer letting the ORM assign IDs and rely on addReference for linkage.
  • Lifecycle callbacks still fire. prePersist listeners (Slugifier, Timestampable, password encoders) will mutate your carefully captured values on load. If a generated fixture must preserve production-like timestamps or hashes, be aware they can be overwritten.
  • PDO / driver quirks. The generator reads via the default connection; read replicas or non-default entity managers may return nothing or the wrong schema. Check which EntityManager the command uses.
  • Output directory must pre-exist and be writable, with the configured namespace matching the path exactly. A silent no-op or a class written to the wrong place usually means this mismatch.
  • Check whether files are overwritten. Re-running the generator against an already-tuned file will destroy your edits. Keep generated output in a separate Generated/ subdirectory, or commit before regenerating.
  • Never run this against production for real data you commit. Emails, addresses and hashed passwords are PII. Scrub the source database first; this is the one operational rule that matters most.
  • Debugging: run the command with -vvv and tail var/log/dev.log. "Command not found" is almost always env/bundle registration, not a broken install.
  • Extension point: the generator service is the place to customize. Decorate or subclass it to add formatters for your value objects (money, UUID) so the output is correct out of the box — far better than fixing it by hand every run. This is the one piece of the bundle worth reading the source of.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager