この記事は CakePHP Advent Calendar 2014 の 19日目の記事です。

今年は CakePHP3 のリリースを目前に控えた高揚感もあり、例年にも増して毎日が待ち遠しかったです。まだあと数日楽しめますね。

昨日はkaihiro さんの “CakePHP2 Search PluginのpresetVarsとfilterArgsについて調べてみた” でした。

今日は CakePHP の Shell の我流拡張を晒したいと思います。いわゆる「ぼくのかんがえたさいきょうのShellクラス」です。自己完結環境ならではのワガママ拡張なので悪しからず!

ConsoleOptionParser が邪魔くさい

Shell は日常的によく使っているのですが、未だにどうしても馴染めないのが ConsoleOptionParser を用いた設定です。

自分が作る Shell の多くは、メソッド毎に細かく機能が限定されていて、オプションを渡すとしてもメソッド内の Shell::in() を用いているものが多いのです。すると、 CommentOptionParser を用いた七面倒臭い設定はすっ飛ばして、単純にメソッドにコメント書いて「Shell を呼び出した時にどんなメソッドを実行できるのかという一覧」さえ表示されれば十分と思いました。つまり・・・

「メソッドにコメント書いたらそれで終わりにしたいんだ、僕は」

というわけです。それこそが自分にとっての最強の Shell クラス。で、提供されているものとは全く別の実装をしたのがこちらです。

https://github.com/zuborawka/cakephp-ex-comment-shell

Reflection でメソッドのコメントをパースして Shell::main() から表示しています。

サンプル

プラグインとして ExCommentShell を設置したあと以下の要領で Shell クラスを作成します。

  1. ExCommentShell を継承する。
  2. 次の条件に当てはまるメソッドは選択候補から除外される。
    • public 以外のスコープを持つメソッド
    • アンダースコアから開始される名称のメソッド
    • メンバー変数 $_excluded にセットしたメソッド
    • main, initialize, startup, getCommands
  3. 選択候補になるメソッドには適宜コメントを記述する。
    • コメントは /** で開始し、 */ で終了する
    • アノテーションとして @deprecated を記述すると非推奨になる(→実行前に警告文が表示され、実行の是非の再確認を求められます)

例えばこんな具合・・・

<?php

App::uses('ExCommentShell', 'ExCommentShell.Console/Command');

class MySampleShell extends ExCommentShell {

    /**
     * この配列に含まれたメソッド名は選択肢から除外されます
     *
     * @var array
     */
    protected $_excluded = array('excludedMethod');

    /**
     * 選択可能なメソッド
     * "Hello world" と出力する
     */
    public function helloWorld() {
        $this->out('Hello world');
    }

    /**
     * 選択可能なメソッド
     * "Welcome To Another World" と出力する
     */
    public function anotherWorld() {
        $this->out('Welcome To Another World');
    }

    /**
     * 非推奨ですが実行可能
     *
     * @deprecated
     */
    public function deprecatedMethod() {
        $this->out('だめよ~ダメダメ');
    }

    /**
     * アンダースコアから開始されるメソッド名は無視されます。
     */
    public function _ignoredMethod() {
    }

    /**
     * public 以外のメソッドは無視されます。
     */
    protected function notPublic() {
    }

    /**
     * $_excluded にセットされたメソッドは無視されます。
     */
    public function excludedMethod() {
    }
}

以下のようにシェルを呼び出すと、選択可能なアクションのリストがコメント付きで表示されます。

$ Console/cake MySample

Welcome to CakePHP v2.0.0 Console
---------------------------------------------------------------
App : app
Path: /path/to/cakephp/app/
---------------------------------------------------------------
---------------------------------------------------------------
Choose a command
---------------------------------------------------------------
[1] helloWorld
    : 選択可能なメソッド
    : "Hello world" と出力する

[2] anotherWorld
    : 選択可能なメソッド
    : "Welcome To Another World" と出力する

[3] deprecatedMethod [非推奨]
    : 非推奨ですが実行可能

[Q] Quit

Select (1/2/3/Q)
[Q] >

実行したいコマンドの番号を入力すると実行されます。

これにより、ソースコードのコメントの箇所に内容を書くだけでコンソールの画面からもそれを見ることができるようになるので、作業も少なくてメンテも楽!!!

明日はこの Advent Calendar の発起人でもあり、いつも楽しくためになる記事を書かれている @k1LoW さんの予定です。楽しみ!