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

Pimcore Fixtures Bundle Laravel Package

piszczek/pimcore-fixtures-bundle

A Pimcore bundle that integrates Doctrine Fixtures for reproducible test and development data. It helps seed Pimcore objects, documents, and assets, simplifying local environment setup, demos, and automated testing workflows without manual content entry.

View on GitHub
Deep Wiki
Context7

Getting Started

Read the source before you install it. This package has 0 stars, 0 dependents, and no visible release cadence — you are adopting code, not consuming a dependency. It is small enough to read end to end in an hour, and that hour is the cheapest part of the whole exercise.

  1. Confirm compatibility against your exact stack. Open the repository's composer.json and check its constraints for the Pimcore major, Symfony major, PHP minor, and doctrine/data-fixtures. Pimcore's DataObject save/versioning APIs have shifted across majors, so a mismatch here shows up later as "fixture bugs" that are really API drift.

  2. Install as a dev dependency.

    composer require --dev piszczek/pimcore-fixtures-bundle
    
  3. Register the bundle for dev and test only. On the older Pimcore 5/6 AppKernel.php layout:

    if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
        $bundles[] = new Piszczek\PimcoreFixturesBundle\PimcoreFixturesBundle();
    }
    

    On the newer Symfony 4/5-based Pimcore layout (config/bundles.php):

    return [
        // ...
        Piszczek\PimcoreFixturesBundle\PimcoreFixturesBundle::class => ['dev' => true, 'test' => true],
    ];
    
  4. Where to look first. The bundle is a bridge, not novel machinery. Read, in order: the bundle class (what services it registers and with what tags), the YAML loader/parser (how a YAML node becomes a Pimcore call), and the thin wrapper around Pimcore's DataObject\Service, Element\Service, and Asset\Service. Everything else is Doctrine doctrine/data-fixtures plumbing you probably already know.

  5. Mental model for a Laravel developer. bin/console doctrine:fixtures:load is php artisan db:seed. A Doctrine fixture class is a seeder. The YAML files are your seed data arrays — except they target Pimcore elements (objects, assets, documents) rather than Eloquent rows. getOrder() on a fixture class is your $this->call() ordering. The only genuinely Pimcore-specific part is that you must go through Pimcore's service APIs so versioning, indexing, and relations are handled correctly — never insert rows directly.

  6. First use case: prove the pipeline end to end. In an isolated branch on a disposable database, write one fixture class and one YAML file that produce exactly three things: one instance of one DataObject class, one asset (a small image in a folder), and one document page — with a relation from the object to the asset. Run:

    bin/console doctrine:fixtures:load --group=pimcore -v
    

    If those three elements appear in the admin UI with the relation intact, the bundle works for your stack. If not, you have learned it cheaply and can fall back to ~150 lines of your own doctrine/data-fixtures + Pimcore service calls.

Implementation Patterns

One YAML file per element type, keyed by class. Keep fixtures/assets.yaml, fixtures/documents.yaml, and fixtures/objects/product.yaml separate. When a load fails, the file name tells you which Pimcore service choked. Reviewing seed-data diffs in pull requests is the entire point of the YAML approach — keep the files small and diff-friendly rather than one monolithic fixture.

Custom fixture classes are the primary extension point. Rather than fight the bundle's defaults, write a fixture class per concern that extends Doctrine's Fixture and delegates the Pimcore work to the bundle's loader:

class ProductCatalogFixture extends Fixture
{
    public function getOrder(): int { return 20; } // after assets/documents

    public function load(ObjectManager $manager): void
    {
        // delegate to the bundle's YAML loader service
    }
}

This is the same shape as a Laravel seeder — the class is orchestration, the data lives elsewhere. It also gives you a single seam to swap implementations if you later fork or replace the bundle.

Ordering is a first-class concern. getOrder() is how you guarantee assets exist before the objects that reference them, and parent documents before children. A missing relation target does not always fail loudly — sometimes you get an object with a dangling reference that only breaks in the admin UI. Draw the dependency graph on paper before writing the fixtures.

Make loads idempotent by construction. Use deterministic paths (/fixtures/products/widget-001) and either purge by path prefix before loading, or rely on path-based upsert so a re-run updates rather than duplicates. Every developer machine and every CI job must produce the same element tree. If IDs matter downstream, resolve them by path after load — never hard-code them.

Guard the command behind an environment check. The console command is available wherever the bundle is registered; registering it in dev/test only is necessary but not sufficient if someone flips the environment variable. Add an explicit refusal — check kernel.environment and, ideally, the database name — before any load runs. This is the highest-severity failure mode the package has: a load pointed at a shared database mutates real content.

Wire it into CI as a standard pipeline stage. Fresh database → Pimcore install/migrate → doctrine:fixtures:load → acceptance tests. That is the payoff: data-driven Pimcore features (localized fields, relations, classification stores) become testable, and your release cadence stops being gated on manual content entry.

Tune the load, don't tune the fixtures. Pimcore element saves are heavyweight — versioning, search indexing, cache invalidation. For anything beyond a few dozen elements, disable versioning and search indexing for the duration of the load, batch saves, and cache asset binaries on disk rather than re-importing them per run. Throughput degrades non-linearly as the relation graph grows, so measure on a representative catalog before you promise a fixture-based demo pipeline.

Fork-and-own rather than depend. If the spike passes, vendor the source under your own namespace, pin the Pimcore constraint, and keep an internal wrapper command as the only invocation path. Then replacing the bundle costs one file, not a repository-wide refactor — and you have removed the only significant risk the package carries.

Gotchas and Tips

It is unmaintained, and that is the dominant fact about it. Single maintainer, no dependents, no support channel, no security response process, no evidence of CI. Assume no upstream fixes. Pin an exact version, review every lockfile diff, and budget a maintenance line item for the first Pimcore upgrade that breaks it. If your governance model requires vendor maintenance or SLAs, this package cannot satisfy it — build in-house instead.

Internal-API coupling produces misleading failures. Fixtures necessarily touch Pimcore internals: element save semantics, versioning, indexing, class definitions. These are the most volatile surfaces across Pimcore majors. When an upgrade breaks the bundle, the errors present as fixture problems ("could not save object") rather than dependency problems. Check the Pimcore version first, the fixture definition second.

Partial loads leave orphans. There is no test suite, so correctness is yours. Fixture tooling fails quietly: a load that half-completes leaves orphaned objects, stale relations, and reused IDs that poison subsequent runs. Wrap loads in a transaction where the Pimcore services permit it, verify element counts after each run, and start from a clean database when debugging rather than layering a second load on a broken first one.

Path and ID collisions across environments. Hard-coded element IDs are the classic mistake — they collide across developer machines and CI, and the failure mode is "the fixture silently updated someone else's object." Use path-keyed lookups and generate IDs at load time. Localized-field and classification-store data especially tends to hide hard-coded references that only surface on a second machine.

Localized fields, field collections, classification stores, and asset binaries are where coverage gaps live. The bundle handles the common cases; the complex graphs are likely to need custom fixture code. Evaluate this coverage in the spike, not after you have committed the team to it. For binaries, reference a cached file on disk or a stable URL — do not re-download per load.

Config quirks worth knowing up front. Bundle registration order matters — it must come after Pimcore's own bundles so the Pimcore services it depends on are registered. Registering in dev/test only also means doctrine:fixtures:load is unavailable in production, which is the correct behaviour but surprises people who try to run a fixture command on staging. If staging needs seed data, use Pimcore's importers, not this bundle.

Debugging recipe. Run with -v first; fixture output is terse by default. Then isolate: comment the YAML down to one element and add sections back until it fails. Compare the admin-UI state of a failing element against one created by hand — the difference tells you which Pimcore service call is wrong. Keep the old ad-hoc seed scripts around until the YAML fixtures reach parity, so you always have a known-good reference.

Never repurpose it for production data migration or reference-data seeding. It is a dev/test fixture loader. The operational risk is entirely in misuse: it is safe as a --dev dependency, and unsafe the moment someone points it at a shared environment. Write that constraint into the README and the decision record, next to the upgrade checklist entry for future Pimcore bumps.

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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels