Weave Code
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

Phpcr Migrations Laravel Package

phpcr/phpcr-migrations

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

To integrate phpcr/phpcr-migrations into a Laravel project (assuming PHPCR integration via Symfony’s PHPCR Bundle or custom PHPCR setup):

  1. Install the package:

    composer require phpcr/phpcr-migrations
    
  2. Set up PHPCR Session: Ensure you have a PHPCR session available (e.g., via jackalope-doctrine-dbal or another PHPCR adapter). Example:

    use PHPCR\SessionInterface;
    use PHPCR\RepositoryInterface;
    
    $repository = new YourPHPCRAdapter(); // Configure your PHPCR repository
    $session = $repository->login();
    
  3. Create a Migration Factory: Define a factory class to encapsulate initialization logic (e.g., in app/Services/MigrationFactory.php):

    namespace App\Services;
    
    use PHPCR\Migrations\Migrator;
    use PHPCR\Migrations\VersionStorage;
    use PHPCR\Migrations\VersionFinder;
    use PHPCR\SessionInterface;
    
    class MigrationFactory
    {
        public function __construct(
            private SessionInterface $session,
            private string $migrationsPath = database_path('migrations/phpcr')
        ) {}
    
        public function createMigrator(): Migrator
        {
            $storage = new VersionStorage($this->session);
            $finder = new VersionFinder([$this->migrationsPath]);
            $versions = $finder->getVersionCollection();
    
            return new Migrator($this->session, $versions, $storage);
        }
    }
    
  4. Register the Factory: Bind the factory in AppServiceProvider:

    public function register()
    {
        $this->app->singleton(MigrationFactory::class, function ($app) {
            $session = $app['phpcr.session']; // Bind your PHPCR session
            return new MigrationFactory($session);
        });
    }
    
  5. Initialize Migrations: Run initialization during deployment or a post-install script:

    php artisan phpcr:migrate --initialize
    

    Create an Artisan command for this (e.g., app/Console/Commands/PhpcrMigrate.php):

    namespace App\Console\Commands;
    
    use Illuminate\Console\Command;
    use App\Services\MigrationFactory;
    
    class PhpcrMigrate extends Command
    {
        protected $signature = 'phpcr:migrate
            {--initialize : Initialize migrations}
            {--to= : Target version (e.g., 202401010000, up, down, top, bottom)}
            {--output= : Output format (null, console)}';
    
        public function handle(MigrationFactory $factory)
        {
            $migrator = $factory->createMigrator();
            $output = $this->option('output') === 'console'
                ? $this->output
                : new \Symfony\Component\Console\Output\NullOutput();
    
            if ($this->option('initialize')) {
                $migrator->initialize();
                $this->info('Migrations initialized.');
                return;
            }
    
            $target = $this->option('to') ?? 'top';
            $migrator->migrate($target, $output);
            $this->info("Migrated to version {$target}.");
        }
    }
    
  6. Create Your First Migration: Create a migration file at database/migrations/phpcr/Version202401010000.php:

    namespace Database\Migrations\Phpcr;
    
    use PHPCR\Migrations\VersionInterface;
    use PHPCR\SessionInterface;
    
    class Version202401010000 implements VersionInterface
    {
        public function up(SessionInterface $session)
        {
            // Create a node in PHPCR
            $root = $session->getRootNode();
            $node = $root->addNode('example_node');
            $node->setProperty('description', 'Initial migration');
            $session->save();
        }
    
        public function down(SessionInterface $session)
        {
            // Revert the changes
            $root = $session->getRootNode();
            if ($root->hasNode('example_node')) {
                $root->removeItem('example_node');
                $session->save();
            }
        }
    }
    
  7. Run Migrations:

    php artisan phpcr:migrate --to=202401010000
    

First Use Case: Schema Initialization

Use migrations to initialize your PHPCR repository schema during deployment. For example:

php artisan phpcr:migrate --initialize --to=top

This ensures all migrations are registered in the repository’s version storage.


Implementation Patterns

Workflow: Migration Development

  1. Create Migration Files:

    • Place migration classes in a dedicated directory (e.g., database/migrations/phpcr/).
    • Follow the naming convention VersionYYYYMMDDHHMM.php.
    • Example structure:
      database/
      ├── migrations/
      │   ├── phpcr/
      │   │   ├── Version202401010000.php
      │   │   ├── Version202401020000.php
      │   │   └── ...
      
  2. Implement up and down Methods:

    • Use PHPCR’s SessionInterface to interact with the repository.
    • Example: Creating a hierarchical structure:
      public function up(SessionInterface $session)
      {
          $root = $session->getRootNode();
          $config = $root->addNode('config');
          $users = $config->addNode('users');
          $users->setProperty('max_depth', 5);
          $session->save();
      }
      
      public function down(SessionInterface $session)
      {
          $root = $session->getRootNode();
          if ($root->hasNode('config')) {
              $root->removeItem('config');
              $session->save();
          }
      }
      
  3. Order Migrations Chronologically:

    • Ensure filenames reflect chronological order (e.g., Version202401010000 before Version202401020000).
  4. Leverage Transactions:

    • Wrap PHPCR operations in transactions for atomicity:
      public function up(SessionInterface $session)
      {
          $session->begin();
          try {
              // PHPCR operations
              $session->save();
              $session->commit();
          } catch (\Exception $e) {
              $session->rollback();
              throw $e;
          }
      }
      

Integration with Laravel Artisan

  1. Custom Artisan Commands: Extend the basic command to support rollbacks, status checks, and dry runs:

    protected $signature = 'phpcr:migrate
        {action? : [top|bottom|up|down|to] Target action}
        {version? : Target version (e.g., 202401010000)}
        {--dry-run : Simulate migration without executing}
        {--force : Force migration even if not needed}
        {--step= : Number of steps to migrate (default: 1)}';
    
  2. Status Command: Add a command to check migration status:

    protected $signature = 'phpcr:migrate:status';
    
    public function handle(MigrationFactory $factory)
    {
        $migrator = $factory->createMigrator();
        $storage = $migrator->getVersionStorage();
        $current = $storage->getCurrentVersion();
        $versions = $migrator->getVersionCollection()->getAllVersions();
    
        $this->table(['Version', 'Applied'], $versions->mapWithKeys(function ($applied, $version) {
            return [$version => $applied ? '✓' : '✗'];
        }));
    
        $this->info("Current version: {$current}");
    }
    
  3. Event Listeners: Trigger migrations during deployment or after specific events (e.g., deployed):

    namespace App\Listeners;
    
    use App\Services\MigrationFactory;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    
    class RunPhpcrMigrations
    {
        public function __construct(private MigrationFactory $factory) {}
    
        public function handle()
        {
            $migrator = $this->factory->createMigrator();
            $migrator->migrate('top', new \Symfony\Component\Console\Output\ConsoleOutput());
        }
    }
    

Testing Migrations

  1. Unit Tests: Mock the SessionInterface to test migration logic:
    use PHPCR\SessionInterface;
    use PHPUnit\Framework\TestCase;
    
    class MigrationTest extends TestCase
    {
        public function testUpMethod()
        {
            $session = $this->createMock(SessionInterface::class);
            $rootNode = $this->createMock(\PHPCR\NodeInterface::class);
            $session->expects($this->once())
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky