Skip to content

Migrations

The schema of your own tables is changed by Phinx migrations: a migration is a PHP class describing a change. No xPDO maps to rebuild.

You do not have to write them by hand — the Migrations tab in the constructor does the same thing and writes both the file and the model for you. This page is for when the change is easier to express in code.

Where they live

Filescore/App/Database/migrations
Configcore/App/phinx.php
Log of what ranpb_app_migrations

This is the site layer — yours. A component update does not touch it.

Plan before you write

status shows what is pending, migrate applies it. Read the plan first and say the expected result out loud: a migration is undone by restoring a dump.

bash
# the plan
php core/components/pageblocks/vendor/bin/phinx status -c core/App/phinx.php

# the write
php core/components/pageblocks/vendor/bin/phinx migrate -c core/App/phinx.php

Never run PHP as root on the server

The site's PHP runs as the site's user. A migration run by root leaves root-owned cache files the site cannot overwrite afterwards — and the manager starts serving a frozen lexicon. Use sudo -u <site user>.

Writing one

php
<?php

declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

final class CreatePbExampleTable extends AbstractMigration
{
    public function change(): void
    {
        $this->table('pb_example', ['id' => true, 'primary_key' => ['id']])
            ->addColumn('name', 'string', ['limit' => 100, 'null' => false, 'default' => ''])
            ->addColumn('data', 'json', ['null' => false, 'default' => '{}'])
            ->addColumn('menuindex', 'integer', ['signed' => false, 'null' => false, 'default' => 0])
            ->addColumn('published_at', 'datetime', ['null' => true, 'default' => null])
            ->addTimestamps()
            ->addColumn('deleted_at', 'datetime', ['null' => true, 'default' => null])
            ->addIndex(['name'], ['name' => 'idx_name'])
            ->create();
    }
}

Phinx adds the table prefix — write pb_example, not modx_pb_example.

A table meant to hold constructor data needs the same tail the built-in ones have: data, menuindex, published_at, timestamps and deleted_at. That tail is what makes publishing, ordering and the recycle bin work without extra code.

© PageBlocks 2019-present