dennispansegrau/pimcore-content-migration-bundle

A Pimcore bundle that generates Doctrine-like migrations for Documents, Assets, and Data Objects — allowing developers to export Pimcore content structures as executable migration scripts to fully rebuild environments from scratch.

Maintainers

Package info

github.com/dennispansegrau/pimcore-content-migration-bundle

Type:pimcore-bundle

pkg:composer/dennispansegrau/pimcore-content-migration-bundle

Statistics

Installs: 300

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-03-13 18:50 UTC

This package is auto-updated.

Last update: 2026-03-16 10:02:25 UTC


README

Compatibility: Pimcore 11 and above.

Pimcore Content Migrations Bundle

The Pimcore Content Migrations Bundle introduces a migration system — similar to Doctrine Migrations — for Documents, Assets, and Data Objects in Pimcore.
It allows developers to export Pimcore content structures as executable PHP migration scripts and rebuild entire environments from scratch, enabling consistent and reproducible deployments across development, staging, and production systems.
The generated migrations create only dummy dependencies — documents, assets, and data objects are included with their content, but without their dependencies or child elements.

📚 Table of Contents

✨ Features

  • Generates migration scripts for Pimcore Documents, Assets, and Data Objects
  • Rebuilds complete content structures on any environment
  • Integrates with version control and deployment workflows

⚙️ Installation

Install the bundle via Composer:

composer require dennispansegrau/pimcore-content-migration-bundle

Add the bundle to your config/bundles.php:

return [
    // ...
    \PimcoreContentMigration\PimcoreContentMigrationBundle::class => ['all' => true],
];

🧰 Configuration

If you do not use doctrine migrations in your project yet, please add following to your config/config.yaml:

doctrine_migrations:
    migrations_paths:
        'App\Migrations\Content': '%kernel.project_dir%/migrations/content'

This defines where generated content migration files are stored.

You can also set a default namespace to avoid passing it every time:

pimcore_content_migration:
    default_namespace: 'App\Migrations\Content'

When set, content:migration:create uses this namespace if none is provided.

🧩 CLI Command

bin/console content:migration:create [TYPE] [ID] [--namespace=...] [--with-children] [--inline-wysiwyg]
Name Description
TYPE The Pimcore element type (document, asset, or object)
ID The ID of the Pimcore element to export
Option Description
--namespace The namespace for the generated migration class (falls back to pimcore_content_migration.default_namespace if set)
--with-children Include all child elements (e.g., sub-documents or child objects) in the migration file
--inline-wysiwyg Inline WYSIWYG field content directly into the migration instead of saving it in a separate HTML file

💻 Example

bin/console content:migration:create document 1 --namespace=App\\Migrations\\Content

This command creates a migration for the document with ID 1 and stores it in the namespace App\Migrations\Content.

🧩 Custom DataType handlers

If you use custom DataTypes (or hit "Unsupported object of class" errors), you can register your own stringifier handler to control how values are serialized in migrations.

Example handler:

<?php

namespace App\ContentMigration\Stringifier;

use App\Model\DataObject\Data\MyCustomDataType;
use PimcoreContentMigration\Converter\Stringifier\ValueStringifier;
use PimcoreContentMigration\Converter\Stringifier\Handler\Trait\ValueToStringConverterTrait;
use PimcoreContentMigration\Generator\Dependency\DependencyList;

final class MyCustomDataTypeStringifier implements ValueStringifier
{
    use ValueToStringConverterTrait;

    public function supports(mixed $value, array $parameters = []): bool
    {
        return $value instanceof MyCustomDataType;
    }

    public function toString(mixed $value, DependencyList $dependencyList, array $parameters = []): string
    {
        $data = $this->getConverter()->convertValueToString($value->getData(), $dependencyList, $parameters);

        return sprintf(
            'new \\App\\Model\\DataObject\\Data\\MyCustomDataType(%s)',
            $data
        );
    }
}

Register it as a service (priority can be adjusted to run before the default handler):

# config/services.yaml
services:
    App\ContentMigration\Stringifier\MyCustomDataTypeStringifier:
        tags:
            - { name: 'pcmb.stringifier_handler', priority: 100 }

🎨 Custom Twig templates

You can override the bundled Twig templates to adapt the generated migration code to your own style. The bundle reads template paths from configuration, so you can point to your own templates.

Example configuration:

# config/config.yaml
pimcore_content_migration:
    templates:
        migration_template: '@App/content_migration/migration.php.twig'
        document_template: '@App/content_migration/document.php.twig'
        asset_template: '@App/content_migration/asset.php.twig'
        object_template: '@App/content_migration/object.php.twig'

When customizing templates, use the Twig helper pcmb_value_to_string to safely serialize Pimcore objects and complex values into PHP code:

{{ pcmb_value_to_string(myValue, dependencies) }}

🧠 Notes

  • Migrations are executable PHP scripts — they can be committed to your VCS and deployed alongside your code.
  • Each migration is idempotent and can safely be executed multiple times.
  • This bundle does not modify Pimcore’s database schema — it only manages content structures.
  • You can organize different types of migrations (Documents, Assets, Objects) under separate namespaces if needed.
  • Please review and test all generated migrations before committing them or running them in production environments.

🧾 License

This bundle is commercial software.

You may evaluate it free of charge for 28 days for internal testing and evaluation. Continued use after that period requires a paid commercial license.

Licenses can now be purchased at www.content-migration-bundle.com.

See COMMERCIAL-LICENSE.md for the current license terms. For German-speaking customers, see EULA-DE.md. For licensing information, license purchases, or support inquiries, visit www.content-migration-bundle.com.