Skip to content
Everett Griffiths edited this page May 21, 2014 · 1 revision

Technically, MODX doesn't use migrations, but Repoman lets you manage your custom database tables via a file-naming convention that approximates migrations.

Special Files

Repoman will look for your migrations inside model/migrations/ (you can configure your "model_path" attribute inside your composer.json)

  • install.php : represents the baseline of your database for a fresh install. This file typically contains calls to MODx's createObjectContainer()
  • uninstall.php : clear out any custom database tables or modifications. This file typically contains calls to removeObjectContainer()

Any other file in the migrations directory should be named using the package version number so that the files may be sorted and executed in a given order, e.g.

  • 1.0.0.php : first public release!
  • 1.0.1.php : patch
  • 1.1.0.php : New feature added
  • ...etc...

Version Numbers

When you name a migration file according to a version number, it is critical that you specify a fully qualified version number with 3 numeric regions, e.g. 2.0.0.php and not 2.php. This is critical to ensure that the files sort in the correct order. Do not include the release string (e.g. "pl" or "beta") in your migration file names!

Migrations typically work something like a play list in iTunes: each file represents changes to the database, and it is critical that they be "played back" in order (which is why you need to name them carefully). However, MODX doesn't really do migrations: it has an ORM, so when you download the PHP code for the latest version of your AddOn, it describes exactly how the database should look -- it has no "memory" of how the ORM PHP classes got to where they are.

When updating a package, PHP's version_compare() function is used to compare the version of the previously installed files to the version of the incoming update. Any migration files that have a version older than incoming version will be ignored.

Development Usage

In order to ensure a fresh copy of the database in its most recent state on a dev machine, you may need to run repoman uninstall followed by repoman install -- this will destroy wall your custom tables and data, so please perform these operations with care. If you need to populate the database using sample data, then specify one or more seed directories in your composer.json in the "seeds_path" attribute. The version-specific migrations are not evaluated during install or uninstall operations.

You can also load up seed data by specifying comma-separated paths in the "seeds_path" command-line argument. This is useful if you want a dev environment to load up different sample data than a production environment.

php repoman install /path/to/mypkg '--seeds_path=model/seeds/base,model/seeds/dev'

Note that if you supply the "seeds_path" attribute via the command line, your values will override the values defined in the composer.json file.

Sample install.php

<?php
/*------------------------------------------------------------------------------
This file is included during package building and during database migration
operations.
------------------------------------------------------------------------------*/
if (!defined('MODX_CORE_PATH')) {return;}

// Follow repoman's conventions here: this code can run in dev mode or in prod mode!
$core_path = $modx->getOption('db_bliss.core_path','',MODX_CORE_PATH.'components/db_bliss/');

$manager = $modx->getManager();
$modx->addPackage('bliss',$core_path.'model/','myprefix_');
$manager->createObjectContainer('Bliss');

/*EOF*/

Sample uninstall.php

Your uninstall.php file is your chance to be polite: remove any custom database tables and clean up after yourself.

<?php
if (!defined('MODX_CORE_PATH')) {return;}

// Follow repoman's conventions here: this code can run in dev mode or in prod mode!
$core_path = $modx->getOption('db_bliss.core_path','',MODX_CORE_PATH.'components/db_bliss/');
$modx->addPackage('bliss',$core_path.'model/','myprefix_');

$manager = $modx->getManager();
$manager->removeObjectContainer('Bliss');

/*EOF*/

Releasing New Versions

WARNING: This can get a bit tricky when you start releasing updates to your package and your database changes over time.

Any time you alter your database schema after you've released your package, you need to increment your package version and create a new migrations file. The file must migrate the state of the database from the old version to the new version, doing things like adding columns or changing table names.

A couple pointers here: your MODX model classes and your install.php will always describe the most current state of the database. When an installed package is updated, the PHP model classes get updated before your migrations are run. That means that for an instant during installation, the PHP model classes are "ahead" of the database, and it is the job of your migration scripts to update the database from its previous state to the state expected by the current PHP model classes.

The installer will execute any migration scripts that are named with a version less than or equal to the new version of the package being upgraded. For example, if you upgrading from version 1.0.0 to version 2.0.0 of a package, then the migration named 2.0.0.php will be run.

See the Tutorial on using Custom Database Tables