CakePHP3の焼き方

この記事はの CakePHP3 Advent Calendar 2016 の14日目として投稿したものです。

毎週水曜日Junkinsの日2日目でございます。 本日のテーマはCakePHP3 Advent Calendar 2016 初日や9日目の記事にも取り上げられた、Bakeです。

Bakeは便利

CakePHP3のBakeはカスタマイズが楽で重宝しています。

Bakeで生成したコードはPluginに比べ気軽に柔軟に修正することでき、 Pluginとはまた違った形で開発効率の向上に寄与してくれます。

Bakeのカスタマイズ

bakeをカスタマイズする場合は、TaskとTemplateをカスタマイズします。

例として、ModelTaskを拡張してみます。

Task

src/Shell/Task/JunkinsModelTask.php

<?php
namespace App\Shell\Task;

use Bake\Shell\Task\ModelTask;

class JunkinsModelTask extends ModelTask
{}

この時点でbakeコマンドを実行してみます。

bin/cake bake
Welcome to CakePHP v3.3.10 Console
---------------------------------------------------------------
App : src
Path: /var/www/html/htdocs/bake/src/
PHP : 5.6.22
---------------------------------------------------------------
The following commands can be used to generate skeleton code for your application.

Available bake commands:

- all
- behavior
- cell
- component
- controller
- fixture
- form
- helper
- junkins_model
- mailer
- migration
- migration_diff
- migration_snapshot
- model
- plugin
- seed
- shell
- shell_helper
- task
- template
- test

JunkinsModelのタスクが実行できるようになっています。

- junkins_model

下記のコマンドで通常のModelTaskと同じ処理が可能です。

bin/cake bake junkins_model
Welcome to CakePHP v3.3.10 Console
---------------------------------------------------------------
App : src
Path: /var/www/html/htdocs/bake/src/
PHP : 5.6.22
---------------------------------------------------------------
Choose a model to bake from the following:
- Accounts
- Admins
- Attachments

※ 同じ名前のクラス名で定義するとBakePluginのタスクが優先されてしまいます。

<?php
namespace App\Shell\Task;

use Bake\Shell\Task\ModelTask as BakeModelTask;

class ModelTask extends BakeModelTask
{}

Taskの拡張例

<?php
namespace App\Shell\Task;

use Bake\Shell\Task\ModelTask;

class JunkinsModelTask extends ModelTask
{
    public $skipTables = ['i18n', 'cake_sessions', 'phinxlog', 'users_phinxlog', 'admins'];
}
bin/cake bake junkins_model
Welcome to CakePHP v3.3.10 Console
---------------------------------------------------------------
App : src
Path: /var/www/html/htdocs/bake/src/
PHP : 5.6.22
---------------------------------------------------------------
Choose a model to bake from the following:
- Accounts
- Attachments

admins tableを無視してくれます。allオプションを指定する際などに便利ですね。

bin/cake bake junkins_model all --force
Template

src/Template/Bake/Model/table.ctp

継承元のクラスを変える変更をしています。

<?php
namespace <%= $namespace %>\Model\Table;

<%
$uses = [
    'use App\Model\Table\AppTable;',
];
sort($uses);
echo implode("\n", $uses);
%>

<%= $this->DocBlock->classDescription($name, 'Model', $annotations) %>
class <%= $name %>Table extends AppTable
{
}
bin/cake bake junkins_model Accounts

src/Model/Table/AccountsTable.php

継承元のクラスが変更されました。

<?php
namespace App\Model\Table;

use App\Model\Table\AppTable;
class AccountsTable extends AppTable
{
}
別のディレクトリへのファイル作成

src/Shell/Task/JunkinsModelTask.php

<?php
namespace App\Shell\Task;

use Bake\Shell\Task\ModelTask;

class JunkinsModelTask extends ModelTask
{
    public $pathFragment = 'JunkinsModel/';
}

このように拡張するとBakeで作成するファイルを設置する場所を変更することができます。

bin/cake bake junkins_model Clips

ClipsTable.phpとClip.phpがJunkinsModel以下に作成されていることがわかります。

Welcome to CakePHP v3.3.10 Console
---------------------------------------------------------------
App : src
Path: /var/www/html/htdocs/bake/src/
PHP : 5.6.22
---------------------------------------------------------------
One moment while associations are detected.

Baking table class for Clips...

Creating file /var/www/html/htdocs/bake/src/JunkinsModel/Table/ClipsTable.php
Wrote `/var/www/html/htdocs/bake/src/JunkinsModel/Table/ClipsTable.php`

Baking entity class for Clip...

Creating file /var/www/html/htdocs/bake/src/JunkinsModel/Entity/Clip.php
Wrote `/var/www/html/htdocs/bake/src/JunkinsModel/Entity/Clip.php`
テンプレートを変更する場合

先ほどの例では、下記のファイルパスにテンプレートをファイルを設置してテンプレートを作成しました。

src/Template/Bake/Model/table.ctp

ただ、このままだと複数のテンプレートを使い分けることができません。 その際に用いられるのが「テーマ」機能です。

下記のパスでテンプレートを作成すると、下記のコマンドで作成することができます。

// テンプレートパス
plugins/Simple/src/Template/Bake/Model/table.ctp
// コマンド
bin/cake bake junkins_model Clips --theme Simple

注意:SimplePluginはPluginとして使用出来る状態に設定する必要がある。

Bakeのイベント

Bake イベントを設定することで、bake対象のtableごとに処理を分けることが可能です。

config/bootstrap_cli.php
use Cake\Event\Event;
use Cake\Event\EventManager;
use Cake\Utility\Hash;

EventManager::instance()->on(
    'Bake.beforeRender.Model.table',
    function (Event $event) {
        $view = $event->subject();
    }
);
おまけ 1

もっとも自由にカスタマイズできるクラスは「SimpleBakeTask」です。

デフォルトで下記のクラスが準備されていますが、それ以外をBakeしたい場合はSimpleBakeTaskを使うと良いと思います。

BehaviorTask
CellTask
ComponentTask
ControllerTask
FixtureTask
FormTask
HelperTask
MailerTask
PluginTask
ShellHelperTask
ShellTask
TaskTask
TemplateTask
TestTask
おまけ 2

bakeの便利コマンド

// Model、Controller、Templateなど全てbakeするコマンド
cake bake all everything --force
参考URL

http://book.cakephp.org/3.0/ja/bake/usage.html

http://book.cakephp.org/3.0/ja/bake/development.html

http://book.cakephp.org/3.0/ja/bake/development.html#creating-a-bake-theme

http://book.cakephp.org/3.0/ja/views/themes.html