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

Ezmigrationbundle Laravel Package

ezsystems/ezmigrationbundle

Kaliop eZ-Migration Bundle makes it easy to programmatically deploy changes to eZPlatform/eZPublish 5 database structure and contents using migrations, inspired by DoctrineMigrationsBundle. Requires PHP 5.6+ and eZPlatform/eZPublish 5.4+. Note: this is an unsupported internal fork.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the honest framing: this is not a Laravel package. ezsystems/ezmigrationbundle is an internal fork of kaliop/ezmigrationbundle, a Symfony bundle for eZ Platform / eZ Publish 5.x. There is no service provider, no Artisan command, no Eloquent, and no database/migrations. It only makes sense if you have inherited an eZ 5.x/1.x application (Symfony 2.8/3.x, app/console, app/config/config.yml). If your app is actually Laravel, stop here — you cannot use this bundle; write an Artisan migration/seeder instead.

Mental model translation for a Laravel dev:

Laravel This bundle
artisan php app/console
Service provider appKernel::registerBundles()
database/migrations/*.php with up()/down() ez_migrations/*.yml, steps only
migrations table bundle-owned Doctrine version table
Eloquent models eZ Repository API (content, content types, locations)

Minimal steps to get a first migration running:

  1. composer require --dev ezsystems/ezmigrationbundle — but verify the package actually published under that name matches the namespace you get. If you also have kaliop/ezmigrationbundle installed, remove it: both ship Kaliop\eZMigrationBundle\eZMigrationBundle, so you get a duplicate-class fatal error.
  2. Register it last-ish in registerBundles():
    new \Kaliop\eZMigrationBundle\eZMigrationBundle(),
    
  3. Confirm the migrations directory exists (default ez_migrations/ at project root; configurable via the bundle config — check the upstream README for the exact key, it has moved between versions).
  4. php app/console list ez:migration to see the real command names for your version. Historically you get status, migrate, generate, execute.
  5. php app/console ez:migration:status — should report an empty/pending state.
  6. php app/console ez:migration:generate against an existing content type to produce a real YAML file. Editing a generated file is the fastest way to learn the schema.
  7. php app/console ez:migration:migrate and re-check status.

First real use case: stand up a demo site — one migration creates the content type(s), a second seeds a small content tree and a demo editor user with a role. That is exactly what eZ built this fork for.

Where to look first (in order): the upstream kaliop/ezmigrationbundle README (authoritative docs; this fork's README is a truncated copy), then the bundle's Command/ directory to confirm command names and options, then the step-handler classes under Core/ to see exactly which YAML keys each type accepts.

Implementation Patterns

Anatomy of a migration. A file is a YAML list of steps; each step has a type and a mode (create / update / delete), plus type-specific keys:

- type: content_type
  mode: create
  content_type: article
  # ...

- type: content
  mode: create
  content_type: article
  parent_location: 2
  attributes:
    title: "Hello from a migration"

- type: role
  mode: create
  name: Editor
  policies: [...]

- type: user
  mode: create
  login: demo_editor
  email: [email protected]
  password: "..."
  groups: [...]

Types you will actually use day to day: content, content_type, role, user, user_group, language, url_alias/url_wildcard, and sql as the escape hatch for anything the content API cannot express.

Generate, then edit — don't hand-write from scratch. ez:migration:generate dumps the current repository state (content types, roles, etc.) into a migration. Treat the output as a scaffold: rename steps, strip fields you don't want, and immediately re-read it before committing. Generated migrations capture a whole object graph and are easy to over-commit.

One migration per logical change, ordered by filename. The bundle sorts files and runs pending ones in order. Use zero-padded sortable names (20240301_001_add_article_type.yml) rather than Version1.yml, so you never get a lexicographic surprise. Put unrelated changes in separate files: since there is no rollback, a small blast radius is your only recovery tool.

Cross-step references instead of hard-coded IDs. Creating a content item and then parenting a child to it should not go through guessed location IDs. The bundle lets a step publish its id under a name and later steps consume it — check the upstream README's reference/lookup section for the exact syntax for your version. Hard-coded parent_location: 2 is fine for the root; anything else should be resolved by remote_id/identifier matching.

Write for re-runs. Failures are not transactional (see Gotchas), so assume any step may execute twice: prefer mode: update with an explicit match, or guard creates with SQL/sql-based existence checks. Where a step cannot be made idempotent, write a compensating migration that cleans up the half-applied state and document the manual recovery procedure in the PR.

Deploy workflow. Migrations live in the repo; on release, run ez:migration:status (must show nothing pending that you didn't intend), then ez:migration:migrate --no-interaction -v. Run as the same OS user as PHP-FPM so var/ and storage permissions stay consistent. For larger sites, run content migrations outside the web request cycle and expect slow runs — every created content item fires domain events and search indexing.

Bulk data: generate the YAML, don't loop in YAML. YAML has no loops or includes here. For seeding hundreds of items, script the YAML from a CSV/JSON source in PHP and commit the generated file, or drop to a type: sql step for raw inserts. Keep the generator script next to the migration for auditability.

Custom step handlers are the extension point. If a recurring operation isn't covered by a type, the bundle supports registering custom step handlers as services (see the upstream "custom migration steps" docs). That is cleaner than a 300-line sql step, and much cleaner than a bespoke Symfony command your team will forget exists.

If you genuinely straddle Laravel and eZ: do not try to invoke this from Laravel. Keep eZ migrations in the eZ repo and trigger them as a discrete deploy step (or a queued job that shells out on the eZ host). Cross-stack coupling here buys nothing and fails in confusing ways.

Gotchas and Tips

  • Package name vs namespace mismatch is the #1 trap. The composer package is ezsystems/ezmigrationbundle; the code namespace is Kaliop\eZMigrationBundle. Installing it alongside the upstream kaliop/ezmigrationbundle is a fatal duplicate class, not a subtle bug.
  • Archived and explicitly unsupported. "Will be completely replaced in the future." No security patches, no PHP 8 support (PHP 5.6 era, Symfony 2.8/3.x APIs). Pin exact versions, keep it dev-only, and budget for migration to the eZ/Ibexa successor bundle. Do not build new production workflows on it.
  • GPL-2.0. Copyleft, unlike most Laravel ecosystem packages (MIT). If you redistribute the application, get this reviewed — it is a licensing decision, not a technical one.
  • No down() / rollback. There is no rollback command. Recovery = write a new forward migration. Plan every destructive step with an inverse in the same PR.
  • No transactionality. A mid-file failure leaves partial DB state while the file stays "not executed", so a naive re-run replays the successful early steps. This is the failure mode that bites teams in production; make steps idempotent or manually clean up before re-running.
  • Re-running an executed migration requires deleting its row from the bundle's version table. Know where that table is before you need it at 2 a.m.; dump it before manual surgery.
  • Stale content type cache. Content type changes may not show up until you clear the eZ cache (and reindex where relevant). A "migration ran but nothing changed" report is usually cache, not a failed step.
  • Rich text attributes are miserable in YAML. Multi-line XML plus YAML block scalars plus quoting is a reliable source of silent corruption. Keep rich text payloads short or load them from files referenced by the migration.
  • Secrets in plaintext. User-creation steps want a password. Do not commit real ones; use environment-specific values or create the user with a random password and force a reset.
  • Debugging playbook: -vvv on migrate for the failing step and file; ez:migration:status to confirm what the bundle thinks is done; ez:migration:execute <file> to run a single migration in isolation while iterating; check the version table when status and reality disagree. git log -p on a generated migration usually explains "why is this field here".
  • Deleting content ≠ deleting locations/trash, and delete steps behave differently depending on what you match on. Verify the resulting state on a DB copy before enabling in a pipeline.
  • Treat generated migrations as diffs, not sources of truth. They capture everything; over-inclusion causes spurious "changes" on other environments and makes reviews meaningless.
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.
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment