
Cake2 から Cake4 へのシェルの移行は、基本的にコマンドとして移行することになります。
そこで Cake2 の Shell 内に addSubCommand()
が利用されている場合、コマンドでは利用できなくなっているため注意が必要です。
Cake2: addSubcommandを利用した例
class HogeShell extends AppShell {
public $uses = array('Hoge');
public function getOptionParser() {
$parser = parent::getOptionParser();
$parser->addSubcommand('fuga', [
'options' => ['test' => [
print_r($this->Hoge->fugas());
<?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());
}
}
<?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を定義
use Cake\Console\Arguments;
use Cake\Console\Command;
use Cake\Console\ConsoleIo;
use Cake\Console\ConsoleOptionParser;
use Cake\ORM\TableRegistry;
class HogeFugaCommand extends Command
public function initialize(): void
$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', [
* @param \Cake\Console\Arguments $args コマンド引数
* @param \Cake\Console\ConsoleIo $io 対話形式で出力したりファイル作成などを提供
public function execute(Arguments $args, ConsoleIo $io): void
print_r($this->Hoges->fugas());
<?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());
}
}
<?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;
// 以下の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);
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;
}
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
とかで稼働してるコマンド数が多かったらコワ...)