CakePHP Tips 2015

Most tips are for 2.x and 3.x as they have been applied to both versions.

Complex radio inputs

A while back I posted a tip about deep array options for select input form fields.
With my recent path for 2.6 and 3.0 (>= 3.0.8) this is now also possible for radio() fields:

echo $this->Form->input('Model.field', [
    'type' => 'radio',
    'legend' => false,
    'div' => false,
    'options' => [
        '1' => ['name' => 'Option A', 'title' => 'A Title'],
        '2' => ['name' => 'Option B', 'data-foo' => 'bar']
    ]
]);

Filtering

As of now, there is no way to directly disallow sort fields of pagination views.
There is a hack in 2.x to workaround this, though. Just set the whitelist to a non-existent field:

['foo']

This way the whitelisting is triggered and no valid field can be found. Mission accomplished.

In 3.x (>= 3.0.8), finally, we have an easy way of doing this, by passing an empty array for sortWhiteslist:

'sortWhitelist' => []

Not passing any whitelist will just not trigger the whitelisting at all.

Using the 3.x Migrations plugin for your 2.x app

I have some rather large 2.x apps that will not be migrated any time soon. But I at least want to leverage some of the 3.x stuff already where possible.
So I can include subsplits of the 3.x version via composer.
But for CLI console scripts and the migrations plugin this does not work.
I don’t want to use plain SQL upgrade files, though. And for any other migration solution I would probably also need some third party tool.
Why not going with what CakePHP 3.x seems to be perfectly bundled with? The Migrations plugin 🙂

So inside my 2.x app I create a subfolder upgrade where I put a very basic composer.json:

...
"require": {
    "cakephp/cakephp": "dev-master",
    "cakephp/migrations": "dev-master",
    "cakephp/bake": "dev-master"
},
"require-dev": {
    "cakephp/debug_kit": "2.*"
},
"autoload": {
    "psr-4": {
        "App\\": "src"
    }
},
"autoload-dev": {
    "psr-4": {
        "App\\Test\\": "tests",
        "Cake\\Test\\": "./vendor/cakephp/cakephp/tests"
    }
},
...

I basically check out the 3.x version in a subfolder along with the 2 plugins I need.
I also make sure, the cli folder and the config folder are present and working.

Then I modify the app.php to automatically pull the DB credentials from my root Config/database.php.
Since I don’t want to duplicate the configs.

$file = dirname(dirname(__DIR__)) . DS . 'Config' . DS . 'database.php';
if (!file_exists($file)) {
    throw new \Exception('Cannot find database.php');
}
$content = file_get_contents($file);

preg_match('/\'database\'\s*=\>\s*\'(.*)\'/i', $content, $matches);
$database = !empty($matches[1]) ? $matches[1] : '';

preg_match('/\'login\'\s*=\>\s*\'(.*)\'/i', $content, $matches);
$username = !empty($matches[1]) ? $matches[1] : '';

preg_match('/\'password\'\s*=\>\s*\'(.*)\'/i', $content, $matches);
$password = !empty($matches[1]) ? $matches[1] : '';

preg_match('/\'host\'\s*=\>\s*\'(.*)\'/i', $content, $matches);
$host = !empty($matches[1]) ? $matches[1] : 'localhost';

return [
    ...
    'Datasources' => [
        'default' => [
            'host' => $host,
            'username' => $username,
            'password' => $password,
            'database' => $database,
        ],
    ],
    ...

I can verify if it all works by running bin/cake bake migration_snapshot Init to make a snapshot of the current DB schema in the new migration code.
This will also automatically mark this migration file as migrated.
Now I can simply add more migration files with bin/cake migrations create {Name} and then migrate the DB via bin/cake migrations migrate.

Voila!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.