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

Alice Generator Laravel Package

trappar/alice-generator

A Laravel package that generates Nelmio Alice YAML fixture files from your database, making it easy to capture realistic records for testing and seeding. It bridges Eloquent models with Alice's expressive fixture format and artisan workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat this as a bootstrapping tool, not a runtime dependency. The package's job is simple: take live PHP objects (usually Doctrine entities), walk them recursively, and emit Alice-compatible fixture data — class name, fixture name, properties — so you get a starting YAML file instead of hand-writing one.

Install it as a dev dependency and check the resolver before anything else, because it was last released in early 2019 and pulls in the PHP 7-era stack (nelmio/alice v3, fzaninotto/faker, doctrine/annotations):

composer require --dev trappar/alice-generator -W --dry-run

If that resolves without dragging your app backwards, the first use case is a ten-line script that dumps a slice of a real database:

// bin/dump-fixtures.php
require __DIR__ . '/../vendor/autoload.php';

$em = require __DIR__ . '/../bootstrap/em.php';   // whatever boots Doctrine

$users = $em->getRepository(App\Entity\User::class)->findBy([], null, 10);
foreach ($users as $user) {
    $user->getPosts()->initialize();              // force lazy collections first
}

$generator = new Trappar\AliceGenerator\AliceGenerator();
$fixtureSet = $generator->generateFixtures($users);

// walk the fixtures into the Class: { Name: { prop: value } } shape Alice expects
$rows = [];
foreach ($fixtureSet->getFixtureObjects() as $fixture) {
    $rows[$fixture->getClass()][$fixture->getName()] = $fixture->getProperties();
}
file_put_contents('fixtures/users.yml', Symfony\Component\Yaml\Yaml::dump($rows, 6, 2));

Where to look first, in this order:

  1. src/AliceGenerator.php — the whole entry point is one method.
  2. src/FixtureGenerationContext.php — everything tunable lives here (recursion depth, naming, faker/metadata wiring).
  3. src/Naming/ — the default namer (Class_1, Class_2, …) is what you will almost certainly replace.
  4. src/Annotation/ — @Faker and @Skip are how you make the output safe and stable.

The package is small (a few dozen files) and the README is thin, so read the source once. Verify the fixture-object accessors (getClass()/getName()/getProperties()) against the version you install before wiring them into a command.

The realistic first win: point it at 20–50 rows of a staging database, get a YAML file, load it back with Alice, and confirm your app renders. That's a half-hour job that replaces a day of fixture typing.

Implementation Patterns

Wrap it in a console command, not a script. One command per aggregate root, with --limit, --depth, and an output path. Guard it on APP_ENV=local and give it a read-only database user. This is the difference between "a tool the team uses" and "a file somebody ran once".

Scrub at the source with annotations. Real data contains real PII. Annotate the entity properties you must not commit — names, emails, phone numbers, addresses — with @Faker, and annotate the ones Alice should not care about with @Skip:

/**
 * @Trappar\AliceGenerator\Annotation\Faker("safeEmail")
 * @Trappar\AliceGenerator\Annotation\Skip()   // on $id, $passwordHash, $apiToken
 */
private $email;

Then a generated fixture is email: '<safeEmail()>' instead of a customer's actual address. This is the single most valuable pattern in the package.

Replace the default namer with business keys. User_1, User_2 makes every regeneration a 400-line diff and produces references (@User_3) that nobody can read. Implement NamerInterface so a user becomes user_admin, a category becomes category_electronics. Now references are stable, diffs are reviewable, and hand-written fixtures can reference generated ones.

Dump one side of each bidirectional relation. The generator recurses, so User → posts → author → posts … blows up. Pair a modest maximum recursion depth on the context with @Skip on the inverse-side collection. Let Alice resolve the owning side via @user_admin references instead of trying to print the graph twice.

Load it back through Alice, not by hand. Use nelmio/alice's loader plus doctrine/data-fixtures' Alice loader (or hautelook/alice-bundle if you're on Symfony), and let Alice's persist order the inserts so foreign keys resolve. For tests, commit the YAML next to the test class and load it into a SQLite schema in setUpBeforeClass.

Keep generated and curated fixtures in separate directories. Generated files are a bootstrap artifact; curated files are the ones humans edit to add edge cases, empty collections, nullable fields, and <dateTimeBetween(...)> expressions. Regeneration overwrites the first set and must never touch the second.

Use it to snapshot object graphs you already build in tests. If you have a factory or builder producing a complex graph, feeding it through the generator gives you a readable, diffable YAML representation — genuinely useful when debugging "what does our fixture actually contain".

Gotchas and Tips

  • Maintenance risk is the headline. Last release February 2019, 52 stars, zero dependents, PHP 7-era dependencies. On Symfony 6/7 or PHP 8.2+ you will very likely hit composer conflicts. Fork or vendor the handful of classes you need rather than building a pipeline on it.
  • PHP 8 typed properties will fatal. Reflection on an uninitialized typed property throws Error: must not be accessed before initialization. Initialize defaults or @Skip those properties.
  • Annotations only, no PHP 8 attributes. It uses doctrine/annotations. If you've migrated your entities to attributes, this package won't see @Faker/@Skip and will happily dump raw values.
  • Lazy collections and proxies. Uninitialized PersistentCollections serialise as empty or as __CG__\App\Entity\User class names in the output. Call initialize() (or unwrap()) on every relation before generating.
  • Primary keys come along for the ride. Reloading fixtures with explicit IDs into a non-empty database gives you PK collisions and a broken autoincrement sequence. Strip id with @Skip in the generator, not with a regex on the YAML.
  • DateTime handling is fiddly. DateTime/DateTimeImmutable and binary/blob/resource properties are the usual sources of garbage output or hard failures. Normalise dates in a post-processing pass; @Skip anything stream-like.
  • Duplicate fixture names silently win. YAML maps overwrite duplicate keys without complaint. If two dump runs land in the same file, one class's fixtures disappear. Namespace by file or prefix names in your custom namer.
  • Faker determinism matters. Alice resolves <firstName()> at load time, so every reload produces different data and any assertion baked against it flakes. Seed Faker at bootstrap if you need reproducible databases.
  • Depth settings don't fix bidirectional graphs — they just defer the explosion. Skipping the inverse side is the actual fix.
  • PII leakage is a compliance incident, not a bug. Review the generated diff before the first commit. Add a column blocklist check to CI if you can.
  • Memory. Recursing over a large graph can OOM. Use iterate()/toIterable() on the query and dump per aggregate root with a --limit.
  • Extension points are where the value is. Custom NamerInterface, custom object/faker handlers, metadata, and value filters. The built-in naming and default metadata handling are the parts you will outgrow first — plan to replace them rather than fight them.
  • Debugging order: property missing → check the annotation/metadata reader; property empty → check lazy loading; property wrong type → check recursion depth and whether it's an embeddable the generator tried to recurse into.
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
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect