In this post I reveal one of my tricks on how to leverage 3.x power in a legacy 2.x project.
You might have already read on how to use some of the splits, like the ORM, in 2.x projects.
Today I want to talk about migration as a topic.
Status Quo
I do have to maintain two remaining CakePHP 2.x apps that have been too large to just upgrade yet.
And time and budget was not on my side so far.
In 2.x there was also not a real powerful database migration tool available so far.
Let’s use the 3.x Migrations plugin
We can use the Migrations plugin quite easily in all 2.x apps do all database modification this way.
First we create a subfolder in your 2.x root folder, let’s call it /upgrade
.
This will contain a standalone 3.x app including the Migrations plugin as dependency.
In my case the composer.json looks like this:
"require": {
"cakephp/cakephp": "^3.3",
"cakephp/migrations": "^1.6",
"dereuromark/cakephp-setup": "^1.0",
"dereuromark/cakephp-tools": "^1.1"
},
"require-dev": {
"cakephp/bake": "^1.2",
"cakephp/debug_kit": "^3.2"
},
Since I include cakephp/bake
, I can also leverage the Bake plugin to generate the necessary migration file.
Any time I need a new migration file I simply go to the subfolder and use the 3.x shell:
cd upgrade
bin/cake bake migration CreateArticles ...
Of course you can now modify it further and once complete commit this file into version control.
On the server your deployment script just also needs to contain the following lines then to fully automate it:
cd upgrade
composer install --prefer-dist --no-dev --optimize-autoloader --no-interaction
chmod +x bin/cake
bin/cake Migrations migrate
cd ..
Once you upgrade to 3.x you can move all migration files to the actual place in your app, remove the subfolder and simplify the deployment lines to just the single command 🙂
At least I now have to only remember one way to do migrations, for all 3.x and the old 2.x apps. And I can benefit from all recent improvements in those plugins even in those old apps.
Upgrading from existing 2.x migration tool?
You might be using a 2.x tool like this already, but upgrading to the state of the art 3.x Migrations plugin hotness is not a problem here, either.
Just create a dump of the current schema, put it into an SQL file and include that in your first Migrations file:
public function change() {
$sql = file_get_contents('dump.sql');
$this->query($sql);
}
Make sure you mark it as migrated, so it is not accidentally executed again.
As alternative you could build in a switch to auto-detect if one of the tables already exists:
$exists = $this->hasTable('users');
if ($exists) {
return;
}
...
Tips
Deploy admin user along with the schema
In some cases it can make sense to provide a basic admin login along with the first initial migration:
$data = [
[
'username' => 'admin',
'email' => '[email protected]',
'password' => '...' // Must be changed right afterwards
]
];
$table = $this->table('users');
$table->insert($data)->save();
For more, it is advised to leverage the seed functionality the Migrations plugin ships with.
Further goodies
As you can see, I also included my Setup and Tools plugin, which in v3 also contain very useful and powerful tools for database maintenance and alike. I can now also leverage them and do not have to backport everything to 2.x anymore.
The same would be true for any such plugin and will help you save time for other things if you can focus on development for the 3.x branch only.
Bottom line
Every pre-3.x project should definitly have a subfolder which runs an up-to-date CakePHP 3.x shell including all useful and required plugin shells.
Feel free to share your ideas and experiences on advancing slowly towards 3.x as comments.
See my old post about it for some more details on how to share the credentials, so you can keep them DRY in your main app config.