Skip to content

Database Migrations

Occasionally certain features or bug fixes require changes to the database — for instance creating new or altering existing tables.

All migrations are managed at the project level. This means all migration scripts are created in the core project plugin under /customizations/plugin, even if the change is required by a custom sub-module or dependency.

Used in: Barberklingen.dk, Barberklingen.se, Barberklingen.nl, Kaffedrengen.dk


Structure

customizations/
└── plugin/
    └── src/
        └── Versions/
            ├── Migrations/
            │   ├── Migration.php        # Base Trait
            │   ├── Migration_1_0_0.php
            │   └── Migration_1_1_0.php
            └── Migrations.php           # Provider

How does it work?

Migrations are checked and executed on CLI requests only. Run them with:

wp {{project}} database migrate

Replace {{project}} with barberklingen or kaffedrengen depending on the project.

The command triggers Migrations::install_available_updates(), which iterates over all scripts in the Migrations folder. For each file found, it compares the current DB version stored in the database against the migration script version. If the script version is higher, it executes — otherwise it is skipped.

The script version is derived from the filename: Migration_1_0_0.php is parsed as version 1.0.0. Migration scripts must have unique version names and must always increment.

The current DB version is stored in the wp_options table under the {{project}}_db_version key (e.g. barberklingen_db_version).


Creating a migration script

  1. Check the Migrations folder for the latest version. If the latest is Migration_1_1_0.php, your new script must be at least 1.1.1 (or 1.2.0, etc.).

  2. Create the new migration class:

    # Location: /customizations/plugin/src/Versions/Migrations/Migration_1_2_0.php
    <?php
    
    class Migration_1_2_0 {
        // Use the Migration trait to inherit abstract methods and logic
        use Migration;
    
        // Contains the actual business logic for this migration
        public function install() {
            global $wpdb;
            $wpdb->query("CREATE TABLE IF NOT EXISTS ...");
            // ...
        }
    }
    
    // Returning a new instance is required.
    // Returning the class only will not work and the migration runner will fail.
    return new Migration_1_2_0();
    
  3. Register the new version in /customizations/plugin/src/Versions/Migrations.php by adding it to the array in get_migrations():

    /**
     * @return array
     */
    private function get_migrations() {
        return [
            '1.0.0',
            '1.1.0',
            '1.2.0', // Our new migration script
        ];
    }
    
  4. Run the migration script locally to verify it works. When deploying, Capistrano will run the migration automatically.

Cross-brand migrations

If a migration needs to run across all projects/brands, the script must be implemented separately in each project.