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 Simple Migration Laravel Package

gal-digital-gmbh/pimcore-simple-migration

A lightweight migration helper for Pimcore that lets you version and apply database or data changes through simple, readable PHP migration files, with a straightforward CLI workflow for running and rolling back migrations across development and production environments.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a small, zero-adoption package, so treat the repository itself as the primary documentation and budget time to read src/ before wiring it into a pipeline. The value proposition is narrow: it removes the boilerplate of setting up Doctrine Migrations inside a Pimcore project (bundle registration, connection wiring, migration directory config) so you can drop a PHP file in a folder and run it.

Minimal steps:

  1. composer require gal-digital-gmbh/pimcore-simple-migration — then immediately open vendor/gal-digital-gmbh/pimcore-simple-migration/composer.json and check the require block. Confirm the Pimcore major version (10 vs 11), the PHP constraint, and whether it expects Doctrine DBAL 2 or 3. A mismatch here is the single most likely reason the package will not work in your project.
  2. Enable the bundle if it ships one. Look for a *Bundle.php class implementing Pimcore\Bundle\... / Symfony\Component\HttpKernel\Bundle\Bundle and register it in config/bundles.php; if it only ships commands, they will be autoconfigured via services.yaml and no registration is needed.
  3. Clear the cache and discover what it actually adds:
    bin/console cache:clear
    bin/console list | grep -i migration
    
    Do this before reading any blog-style instructions — command names and flags are the part most likely to differ from your expectation.
  4. Read the base migration class. It will tell you the method signatures (up() / down() vs migrate() / rollback()), how it exposes the DB connection ($this->db, $this->connection, or a Pimcore\Db helper), and where the tracking table lives.

First real use case: a change that must exist identically on dev, staging, and prod but which the Pimcore admin UI does not version — adding an index to a custom table, backfilling a field on existing objects, or creating the folder tree a feature assumes. Write one migration, run it against a disposable copy of the dev database, and confirm the tracking table recorded it before you trust it on anything shared.

Implementation Patterns

One migration per intent. Keep schema DDL, class-definition changes, and data backfills in separate files. Pimcore's class-definition cache invalidation is a different failure mode from a failed ALTER TABLE, and separating them makes a half-failed deploy diagnosable.

Import class definitions from JSON rather than mutating them in code. The most reliable way to version a data object class in a migration is to export it from the admin UI, commit the JSON, and import it:

// shape only — verify the service and signature against your Pimcore version
$class = \Pimcore\Model\DataObject\ClassDefinition::getByName('Product');
$json  = file_get_contents(__DIR__ . '/../../var/classes/Product.json');
\Pimcore\Model\DataObject\ClassDefinition\Service::importClassDefinitionFromJson($class, $json, true);
$class->save();

The same pattern exists for field collections and object bricks. Doing it this way means the migration is a diff of a committed artifact, not a chain of imperative calls that silently no-ops when a field already exists.

Guard every operation. Migrations get re-run on restored databases and partially-applied environments. Check before you act:

$schema = $this->connection->createSchemaManager();
if (!$schema->tablesExist(['plugin_queue'])) { /* create */ }

Idempotent migrations are the difference between "rerun it" and "restore from backup."

Keep migrations environment-agnostic and non-interactive. They run in CI and in deploy hooks with no TTY. No prompts, no readline, no hardcoded hostnames. If a migration seeds demo content, gate it on an env var rather than on APP_ENV inside the migration file.

Sequence data backfills in batches. A migration that loads 50k objects and calls save() on each will time out and hold locks. Chunk by ID range, and log progress so a killed run is resumable.

Wire it into deploy, not into a human's memory. The package only pays off if bin/console <your-migration-command> is a line in your deployment script (or a CI job with an explicit approve step), running after code deploy and before the cache warmup. Pair it with bin/console pimcore:cache:clear — class-definition and object changes are not visible to the application until the cache is rebuilt.

Rollback is a courtesy, not a strategy. Write down() when it is genuinely reversible (dropping an index you added). For destructive migrations, either leave rollback unimplemented with a comment saying so, or make it a restore instruction. A down() that deletes a column is worse than no down().

Gotchas and Tips

  • Zero stars and zero dependents means you are the QA team. Pin the exact version in composer.json ("gal-digital-gmbh/pimcore-simple-migration": "1.0.0", not ^1.0), and consider reading the source once rather than debugging it in production. There is no community knowledge base to fall back on.
  • Do not mix it with Doctrine Migrations on the same files. If the package keeps its own tracking table (commonly migration_versions or similar), running doctrine:migrations:migrate over the same directory will either re-execute applied migrations or fail on duplicates. Pick one runner per migration directory and note the decision in the README of your project.
  • Pimcore 11 broke a lot of small packages. Symfony 6, PHP 8.1+, Doctrine DBAL 3 (where fetchAll() became fetchAllAssociative() and getSchemaManager() moved to createSchemaManager()). If the package predates that, expect to patch a fork — check whether the maintainer accepts PRs or whether you should vendor it.
  • Class-definition changes need a cache clear, always. The migration will report success while the admin UI and the object runtime keep serving the old definition. After any ClassDefinition::save(), run bin/console pimcore:cache:clear (and, in some setups, restart PHP-FPM) before declaring victory.
  • MySQL DDL is not transactional. A migration that does three ALTER TABLEs and fails on the third leaves you in a partial state. Keep DDL migrations to one statement where possible, and always test against a production-shaped copy.
  • Verify the tracking table directly when things look wrong. Query SELECT * FROM <tracking_table> ORDER BY ... to see what the package thinks has run. "It says applied but nothing changed" and "it keeps re-running" are both diagnosed here in seconds.
  • Debugging a silent failure: run the command with -vvv, and temporarily add fwrite(STDERR, ...) at the top of up() to confirm the method is even reached. If the file is not being picked up, the issue is directory config or filename convention, not your SQL.
  • Extension points are limited by design. You can typically subclass the base migration class and configure the migration path. If you need branching logic, environment targeting, or a dry-run mode, put that in your own command wrapping the package rather than fighting its internals.
  • Sanity-check the licence and the maintainer's activity before this becomes load-bearing. A one-commit repository is fine for a 40-line convenience wrapper and a liability for anything touching production data.
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