Cake2 から Cake4 へのシェルの移行は、基本的にコマンドとして移行することになります。
そこで Cake2 の Shell 内に addSubCommand()
が利用されている場合、コマンドでは利用できなくなっているため注意が必要です。
Cake2: addSubcommandを利用した例
<?php class HogeShell extends AppShell { public $uses = array('Hoge'); public function getOptionParser() { $parser = parent::getOptionParser(); $parser->addSubcommand('fuga', [ 'help' => 'fugaします', 'parser' => [ 'options' => ['test' => [ 'short' => 't', 'help' => 'テスト表示します', ]], ], ]); } public function fuga() { print_r($this->Hoge->fugas()); } }
簡単な例として、コマンド fuga を定義し、モデル Hoge の fugas()
をコールする形です。
もちろん、Hoge モデルには fugas()
というメソッドが定義されていなければエラーとなりますが、そこは話題に触れない部分で「メソッドがある」と仮定し、コードは割愛します。
Cake2のシェルでは addSubcommand()
を用意することで、簡単にサブコマンドを作成できていました。
次は Cake2 で定義した Shell を Cake4 に移行してみます。
Cake4: HogeFugaCommandを定義
<?php declare(strict_types=1); namespace App\Command; use Cake\Console\Arguments; use Cake\Console\Command; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; use Cake\ORM\TableRegistry; class HogeFugaCommand extends Command { /** * インスタンス初期化 * * @return void */ public function initialize(): void { parent::initialize(); $this->Hoges = TableRegistry::getTableLocator()->get('Hoges'); } /** * オプションパーサー * * フックメソッドで引数やオプションを定義する * * @param \Cake\Console\ConsoleOptionParser $parser 引数やオプションを定義 * @return \Cake\Console\ConsoleOptionParser コマンド定義されたオブジェクト */ protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $parser = parent::buildOptionParser($parser); $parser->addOption('test', [ 'short' => 't', 'help' => 'テスト表示します', ]); return $parser; } /** * コマンドが呼び出された時に実行 * * @param \Cake\Console\Arguments $args コマンド引数 * @param \Cake\Console\ConsoleIo $io 対話形式で出力したりファイル作成などを提供 * @return void */ public function execute(Arguments $args, ConsoleIo $io): void { print_r($this->Hoges->fugas()); } }
別にコマンド名はなんでもよいのかもですが、Cake2 からの移行の場合、複数のサブコマンドが存在すると想定すると「親コマンド名 + サブコマンド」のコマンド名がわかりやすいと思います。で、定義したコマンドを Cake2 と同様にサブコマンドとして稼働するように Application.php で定義する必要があります。
Cake4: Application.phpにサブコマンドを登録する
src/Application.php
use App\Command\HogeFugaCommand; use Cake\Console\CommandCollection; // Applicationクラス内 // 以下のconsoleメソッドを追記し、コマンドの別名登録をして、サブコマンドの様に見せる /** * コマンドの登録・別名登録 * * @param \Cake\Console\CommandCollection $commands コマンドコレクション * @return \Cake\Console\CommandCollection 設定済みコマンドコレクション */ public function console(CommandCollection $commands): CommandCollection { // 使用可能なコマンドを検出して登録 $commands->addMany($commands->autoDiscover()); // コマンドの別名登録 $commands->add('Hoge fuga', HogeFugaCommand::class); return $commands; }
上記コードのようにコマンドの別名登録をすることで、./bin/cake Hoge fuga
というコマンドを実行することが可能になります。
注意したい点は、上記コード内の autoDiscover()
を addMany()
しておかないと、既存のコマンドが検出されず、利用できない状態になってしまうことです。
(crontab
とかで稼働してるコマンド数が多かったらコワ...)
■ Cake4: サブコマンドの追加
https://book.cakephp.org/4/ja/console-commands/option-parsers.html#id14
■ Cake4: コマンド名を変更(ネストされたコマンド)
https://book.cakephp.org/4/ja/console-commands.html#renaming-commands