dantleech/phpcr-migrations-bundle
Archived Symfony bundle integrating PHPCR migrations (renamed to phpcr/phpcr-migrations-bundle). Configure migration paths or auto-discover in bundle Resources, create VersionYYYYMMDDHHSS classes, and run console commands to check status and migrate.
Installation Add the bundle via Composer:
composer require dantleech/phpcr-migrations-bundle
Enable it in config/bundles.php (Symfony):
return [
// ...
Dantleech\PhpcrMigrationsBundle\DantleechPhpcrMigrationsBundle::class => ['all' => true],
];
Configuration Publish the default config:
php bin/console dantleech:phpcr-migrations:init
Edit config/packages/dantleech_phpcr_migrations.yaml to match your PHPCR session (e.g., DoctrinePHPCRBundle).
First Migration
Create a migration file in migrations/ (e.g., 20240101000000_AddRootNode.php):
<?php
namespace App\Migrations;
use Dantleech\PhpcrMigrationsBundle\Migration\Migration;
class AddRootNode extends Migration
{
public function up()
{
$this->createNode('/root', 'nt:unstructured');
}
public function down()
{
$this->removeNode('/root');
}
}
Run the migration:
php bin/console dantleech:phpcr-migrations:migrate
| Command | Description |
|---|---|
phpcr-migrations:migrate |
Run pending migrations. |
phpcr-migrations:status |
Show migration status. |
phpcr-migrations:rollback |
Rollback the last migration. |
phpcr-migrations:init |
Initialize the migrations table. |
phpcr-migrations:create |
Scaffold a new migration file. |
Problem: You need to version-control your PHPCR repository structure (e.g., for a Symfony + DoctrinePHPCR project). Solution:
phpcr-migrations:create to generate a migration for your root node.up()/down() methods to create/remove nodes.phpcr-migrations:migrate to apply changes to your repository.Schema Evolution
/content, /config).public function up()
{
$this->createNode('/content', 'nt:folder');
$this->moveNode('/old-root', '/content');
}
Data Migration
public function up()
{
$session = $this->getSession();
$query = $session->createQuery(
'SELECT [jcr:path] FROM [nt:base] WHERE ISDESCENDANTNODE("/old")',
Query::JCR_SQL2
);
// Process results and migrate to new structure.
}
Environment-Specific Migrations
%kernel.environment% to conditionally apply migrations:
# config/packages/dantleech_phpcr_migrations.yaml
dantleech_phpcr_migrations:
environments:
- dev
- staging
DoctrinePHPCRBundle
doctrine_phpcr config includes the migrations table:
doctrine_phpcr:
session:
workspace: default
repository_class: Doctrine\ODM\PHPCR\DocumentManager\PHPCRDocumentManager
migrations_table: phpcr_migrations
Custom Node Types
public function up()
{
$this->createNodeType('my:custom', [
'mix:title' => 'Title',
'mix:description' => 'Description',
]);
}
Dependency Management
public function up()
{
$this->createNode('/dependencies/base');
$this->createNode('/dependencies/feature', ['parent' => '/dependencies/base']);
}
Testing
public function tearDown(): void
{
$this->container->get('dantleech_phpcr_migrations.migration_service')->rollback();
}
Session Management
doctrine_phpcr is set up before running migrations. Use:
php bin/console doctrine:phpcr:session:list
Transaction Isolation
Node Existence Checks
createNode() fails if the parent doesn’t exist.ensureNodeExists() or check manually:
if (!$this->nodeExists('/parent')) {
$this->createNode('/parent');
}
Down Migration Gaps
down() methods may not cover all up() changes.phpcr-migrations:status to verify.Enable Verbose Output
php bin/console dantleech:phpcr-migrations:migrate --verbose
Check Migration Table
phpcr_migrations in your PHPCR workspace to verify applied migrations:
SELECT * FROM [phpcr_migrations];
PHPCR Logging
config/packages/dev/doctrine.yaml:
doctrine:
phpcr:
logging: true
Custom Migration Service
# config/services.yaml
Dantleech\PhpcrMigrationsBundle\Migration\MigrationService:
arguments:
$preMigrationCallback: [@your_service, 'preMigration']
Dynamic Migration Paths
// src/Migration/MigrationLoader.php
class CustomLoader extends \Dantleech\PhpcrMigrationsBundle\Migration\MigrationLoader
{
public function getMigrationFiles(): array
{
return array_merge(
parent::getMigrationFiles(),
glob(__DIR__ . '/../CustomMigrations/*.php')
);
}
}
PHPCR Event Listeners
nodeAdded) for real-time validation:
$eventManager = $this->getSession()->getWorkspace()->getEventManager();
$eventManager->registerListener(
\PHPCR\Event\NodeAddedEvent::class,
[$this, 'onNodeAdded']
);
Workspace Isolation
default workspace. Specify another in config:
dantleech_phpcr_migrations:
workspace: custom_workspace
Migration Table Location
doctrine_phpcr:
session:
workspace: custom
migrations_table: /var/workspaces/custom/phpcr_migrations
Case Sensitivity
/Root vs /root).How can I help you explore Laravel packages today?