Agent skill

Cakephp Migration

by baserproject in baserproject/basercms

baserCMS の CakePHP バージョンアップ(5.0 → 5.1 → 5.2 ~)対応の非推奨・破壊的変更パターン集と修正レシピ。「Association alias already set」「A validation rule with the name already exists」「Token not found」「headers already sent」「Plugin…

MITAuto-check passed

Install Cakephp Migration

skills CLI
$ npx skills add baserproject/basercms --skill cakephp-migration -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install baserproject/basercms cakephp-migration --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/baserproject/basercms.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/cakephp-migration .claude/skills/cakephp-migration && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
cakephp-migration
GitHub stars
190
Token cost
~4k tokens
SKILL.md length
761 words
Files
1
Skills in repo
15
Repo updated
First seen
Licence
MIT

At a glance

baserCMS の CakePHP バージョンアップ(5.0 → 5.1 → 5.2 ~)対応の非推奨・破壊的変更パターン集と修正レシピ。「Association alias already set」「A validation rule with the name already exists」「Token not found」「headers already sent」「Plugin…

  • Works in 5 steps: 致命的か警告かを logs/debug.log / logs/error.log… → 失敗が多いときは例外メッセージを集計して systemic な原因を特定。 → 各原因についてアプリ src 起因かテスト/環境/fixture/i18n… → …
  • SKILL.md covers 大原則(全バージョン共通), 5.0 → 5.1 の変更, 5.1 → 5.2 の変更 and エコシステム: cakephp/migrations…, plus 1 more section
  • Calls composer, git and npm

What it does

Cakephp Migration is an agent skill from baserproject/basercms. baserCMS の CakePHP バージョンアップ(5.0 → 5.1 → 5.2 ~)対応の非推奨・破壊的変更パターン集と修正レシピ。「Association alias already set」「A validation rule with the name already exists」「Token not found」「headers already sent」「Plugin named X is already loaded」「ResultSet/PaginatedResultSet のエラー」「order()/group() 非推奨」「イベントリスナーの戻り値非推奨」「find('all', $options) 非推奨」「Table::get の配列 options 非推奨/名前付き引数」「配列条件の null 値で例外」「cakecore キャッシュ設定」「pluginBootstrap で後続プラグインの setting.php が読まれず Configure が null(live イテレーション)」「checkFilePath で .. テンプレートが…

Its SKILL.md is about 4k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It works with PHP. The repository describes itself as: baserCMS : Based Website Development Project. The licence is MIT.

Example prompts

  • “Use the cakephp-migration skill to basercm の CakePHP バージョンアップ(5.0 → 5.1 → 5.2 ~)対応の非推奨・破壊的変更パターン集と修正レシピ。「Association alias already set」「A validation…”
  • “/cakephp-migration”

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. 致命的か警告かを logs/debug.log / logs/error.log で判別。
  2. 失敗が多いときは例外メッセージを集計して systemic な原因を特定。
  3. 各原因についてアプリ src 起因かテスト/環境/fixture/i18n 起因かを切り分け(git diff HEAD / Plugin::isLoaded / DIコンテナ登録 / 英語↔日本語メッセージ)。
  4. アプリ src 起因を該当バージョン節のレシピで修正 → php -l で lint → 当該テストを --filter で単体確認。
  5. 仕上げに全テストを再実行して件数の改善と新規回帰の有無を確認。

What it can do on your machine

Read from SKILL.md and the folder at commit 748b4f6. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • composer
    • git
    • npm
    • php

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use git and npm, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Cakephp Migration loads about 4k tokens when it runs. Until then it costs about 235 tokens; SKILL.md has 761 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~235
When it runs · the whole SKILL.md, loaded when a task matches
~4k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from baserproject/basercms at commit 748b4f6, republished under its MIT licence (© baserproject). 761 words, ~3,994 tokens.

Download SKILL.mdSave it as .claude/skills/cakephp-migration/SKILL.md (or your agent's skills folder).
name
cakephp-migration
description
baserCMS の CakePHP バージョンアップ(5.0 → 5.1 → 5.2 ~)対応の非推奨・破壊的変更パターン集と修正レシピ。「Association alias already set」「A validation rule with the name already exists」「_Token not found」「headers already sent」「Plugin named X is already loaded」「ResultSet/PaginatedResultSet のエラー」「order()/group() 非推奨」「イベントリスナーの戻り値非推奨」「find('all', $options) 非推奨」「Table::get の配列 options 非推奨/名前付き引数」「配列条件の null 値で例外」「_cake_core_ キャッシュ設定」「pluginBootstrap で後続プラグインの setting.php が読まれず Configure が null(live イテレーション)」「_checkFilePath で .. テンプレートが MissingPluginException/500」「TreeBehavior でルートに parent_id=null を入れて lft/rght 破損」「Entity::set 配列一括の非推奨」「AbstractMigration/AbstractSeed 非推奨 → BaseMigration/BaseSeed(cakephp/migrations 4.5+)」「config/routes.php の fallbacks() でテストのみ 404」「ヘルパの実メソッドがマジックメソッド委譲化し method_exists が false(TextHelper::truncate→is_callable 判定)」等、CakePHP本体・関連パッケージ起因の問題の調査・修正時に参照する。新しい CakePHP バージョン対応時は本書にバージョン別追記する。PHP本体起因の問題は php-migration スキルを参照。
license
MIT

CakePHP バージョン移行ガイド(baserCMS)

CakePHP のアップグレードで遭遇した破壊的変更・非推奨と修正レシピ集。バージョン別に整理して育てる。PHP 本体起因(暗黙nullable・動的プロパティ等)は別スキル php-migration を参照。

収録: 5.0 → 5.1、5.1 → 5.2。バージョンの帰属は移行作業時の実観測ベース(厳密な導入版と差異がありうる)。新バージョン対応時は新しい「## X.Y → X.Z の変更」節を追記する。


大原則(全バージョン共通)

  • アップグレードは composer require を使う。composer update は使わない(依存全体が動くのを避ける)。 例: composer require cakephp/cakephp:"5.2.*" --update-with-dependencies
  • 「致命的エラー」と「非推奨警告」を区別する。デバッグモードでは非推奨警告が画面下部に表示され「エラー」に見えるが、logs/debug.log の debug: は警告(動作継続)。logs/error.log や Fatal/Exception が本当のエラー。
  • テスト大量失敗時は根本原因単位で分類する。数百件の失敗でも原因は十数種。フルログから例外を集計して systemic な原因を先に潰す(集計コマンド・切り分け手順は basercms-unittest スキル参照)。
  • regression と既存/環境failを切り分ける。git diff HEAD -- <file> で自分の変更対象か確認。未変更ファイルかつ fixture/プラグインロード依存(Plugin::isLoaded('X') が false/DIコンテナ未登録/英語↔日本語メッセージ不一致)なら移行起因ではなく環境要因。vendor が既に新版に入れ替わっているため単純な git stash ではクリーンな baseline は作れない。

ユニットテストの実行方法・失敗の集計と切り分け手順は basercms-unittest スキルを参照。


5.0 → 5.1 の変更

5.1 では E_USER_DEPRECATED 系の非推奨が増える。Error.errorLevel で抑制可能だが、本対応として潰す。

1-1. Query::order() / group() の非推奨

order()→orderBy()、group()→groupBy()(SelectQuery::group() も)。

php
// Before
$query->order(['Contents.id'])->group('site_id');
// After
$query->orderBy(['Contents.id'])->groupBy('site_id');
1-2. find('all', $options)(options 配列)の非推奨(Since 5.0.0)

options 配列渡しが非推奨。名前付き引数 or スプレッドにする。

php
// Before
$this->Table->find('all', ['limit' => $n, 'conditions' => $c]);
// After(いずれか)
$query = $this->Table->find()->where($c); if ($n) $query->limit($n);
$this->Table->find('all', ...$options);   // $options のキーが finder の名前付き引数に一致する場合
$this->Table->find('all', conditions: $c, order: $o);
  • 既に ...$options / conditions: 等になっているものは対象外(誤検出注意)。
  • 警告: Calling 'findAll' finder with options array is deprecated. Use named arguments instead.
1-3. ページネーション結果が PaginatedResultSet に

paginate() の戻り値が PaginatedInterface(PaginatedResultSet)になり、isEmpty() 等の ResultSet メソッドを直接持たない。先に ->items() を呼ぶ。

php
// Before(テンプレート等)
if (!$sites->isEmpty()) { ... }
// After
if (!$sites->items()->isEmpty()) { ... }
1-4. 翻訳キャッシュ設定のリネーム

_cake_core_ → _cake_translations_。config/app.php・config/bootstrap.php・BcUtil 等の参照を更新。

  • config/plugins.php で 'BaserCore' => null のような値は 'BaserCore' => [] にする。

5.1 → 5.2 の変更

5.2 は「これまでサイレントに上書き/許容していた操作を例外化」する変更が多い。

2-1. イベントリスナーの戻り値返却が非推奨(5.3 でエラー化)

リスナーから値を return せず、$event->setResult() / $event->stopPropagation() を使う。戻り型は : void にできる。

php
// Before
public function beforeSave(EventInterface $event) { return false; }
// After
public function beforeSave(EventInterface $event): void { $event->setResult(false); }
  • Table/Marshaller コールバックの戻り値は元々無視されるので単に return を削除すればよい(beforeMarshal は ArrayObject $data を参照で書き換える。返り値は使われない)。
  • コントローラ beforeFilter の定番修正:
    php
    // Before
    $response = parent::beforeFilter($event);
    if ($response) return $response;
    ...
    return $this->redirect(...);
    // After
    parent::beforeFilter($event);
    if ($event->getResult()) return;
    ...
    $event->setResult($this->redirect(...));
    return;
  • クロージャ内の return(SEO等)は対象外(誤検出注意)。
2-2. AssociationCollection::add() が重複エイリアスで例外化

5.1までサイレント上書き → 5.2は Association alias 'X' is already set. を throw。 initialize() で定義済みの関連を、別メソッド/Service/Controller で hasMany/belongsTo 等で再設定すると発生(finder 差し替え等)。

php
// 再設定の前に既存を削除してガードする
if ($table->associations()->has('CustomLinks')) {
    $table->associations()->remove('CustomLinks');
}
$table->hasMany('CustomLinks')->setFinder('all')->...;
  • inline hasMany('X') は、ガード済みの専用メソッド(例: setHasManyLinksByAll())に集約すると安全。
  • 検出: grep -rnE "\->(hasMany|belongsTo|belongsToMany|hasOne)\(" --include="*.php" で Service/Controller 内の関連設定を洗う(Table の initialize 以外は要注意)。
2-3. 重複バリデーションルール名で例外化

同一フィールドに同名ルールを2回 add すると A validation rule with the name 'X' already exists。5.1は上書き。

  • 同名ブロックが重複していれば統合(後勝ちの意図を保つ)。例: alias に対する複数の検証定義をまとめる、minLength を一度だけ追加する等。
  • コールバックの名前付き引数 $context の衝突に注意(独自メソッドの第2引数を $context にしない)。
  • 注意: テストが「同じ validator に同メソッドを2回呼んで上書きを確認」している場合はテスト側の事情で、本番フロー(1フィールド1回)では起きない=アプリ修正対象外のことがある。
2-4. ResultSet の型・clone 不可
  • Query::all() の戻り値が Cake\ORM\ResultSet(旧 ResultSetDecorator)。型宣言は ResultSetInterface か iterable に緩める。
  • ResultSet は clone 不可・イテレータ共有。clone $resultSet や、ライブな ResultSet への二重イテレートで要素が消える。->toArray() で早期に materialize してから使う(フォームの項目が消える等の不具合の原因)。
  • ヘルパ/サービスの引数型は ResultSetInterface/iterable にし、is_array($x) ? $x : $x->toArray() で吸収。
2-5. 配列条件の null 値が例外化

where(['field' => null]) は Expression 'field' has invalid 'null' value. ... operator (IS, IS NOT) is missing. を throw。null安全な IS 演算子を使う。

php
// Before
$conditions = ['Contents.entity_id' => $entityId];   // $entityId が null だと例外
// After
$conditions = ['Contents.entity_id IS' => $entityId]; // 非nullなら =、nullなら IS NULL
2-6. エンティティの文字列キャスト非推奨

テンプレ等で (string)$entity 相当(HTML 属性へ直挿し等)が非推奨。json_encode($entity) を使う。

php
$this->BcBaser->js('...', false, ['data-current' => json_encode($content)]);
2-7. PluginCollection::add() が既ロードで例外化

Plugin named 'X' is already loaded。addPlugin の前にガードする。

php
if (!$application->getPlugins()->has($name)) {
    $application->addPlugin($name);
}
  • テーマ(coreFrontTheme 等)と $themes 配列で同名が二重追加されるケースに注意(addTheme())。
  • Migrations / Authentication / CakephpFixtureFactories 等の追加箇所も同様にガードする。

baserCMS は postLink のフォームを独自JS(plugins/bc-admin-third/src/js/admin/common/lib/jquery.bcToken.js)で再構成して送信する。 CakePHP 5.2 で postLink の onclick が document.{form}.submit() → document.{form}.requestSubmit()(CSP対応)に変わり、抽出用正規表現が一致せず _Token が送られなくなる。

js
// jquery.bcToken.js: 両対応にする
var regex = /document\.(post_.+?)\.(?:request)?[Ss]ubmit\(\)/;
  • 修正後は管理テーマの JS を再ビルド: cd plugins/bc-admin-third && npm run build(bcToken は common/startup バンドルに含まれる。webpack が src/**/*.js を自動エントリー化)。
  • 個別アクションを unlockedActions で除外するより、この正規表現修正の方が全 postLink を一括で直せる(CSRF保護も維持)。プラグイン無効化・テーマ切替/コピー/削除・キャッシュクリア等が一斉に復旧する。
2-9. PluginCollection の live イテレーション中の変更で後続プラグインの bootstrap がスキップ

5.2 の BaseApplication::pluginBootstrap() は PluginCollection::with('bootstrap') の live なジェネレータを走査する。あるプラグインの bootstrap() がイテレーション中に addPlugin()/remove()(テーマ追加・DebugKit 削除等)でコレクションを変更すると、直後に並ぶプラグインの bootstrap() がスキップされ、setting.php 等が読み込まれず Configure::read('BcXxx....') が null になる。

  • 本番では問題のプラグイン(baserCMS では BaserCorePlugin)がコンテンツプラグインを「後から」追加するため直後に要素が無く顕在化しないが、テストで事前ロード(appPluginsToLoad 相当)すると顕在化する。
  • 修正: live イテレーションをやめ、未 bootstrap が無くなるまでスナップショット単位で bootstrap する(テスト基盤 BcTestCase::setUp 等)。
    php
    $booted = [];
    do {
        $pending = [];
        foreach ($app->getPlugins() as $plugin) {
            if ($plugin->isEnabled('bootstrap') && !in_array($plugin->getName(), $booted, true)) $pending[] = $plugin;
        }
        foreach ($pending as $plugin) { $booted[] = $plugin->getName(); $plugin->bootstrap($app); }
    } while ($pending);
2-10. View::_checkFilePath() の第2引数がプラグイン名に(.. を含むテンプレートで MissingPluginException)

5.2 で View::_checkFilePath(string $file, ?string $plugin) が第2引数 $plugin を _paths($plugin) に渡すようになった。_getTemplateFileName()/_getLayoutFileName() をオーバーライドしてファイルシステムパスを第2引数に渡していると、パスをプラグイン名と誤解して .. を含むテンプレート(render('../element/...') 等)が 500 になる。

  • 修正: 第2引数にはパスではなくプラグイン名を渡す。_checkFilePath($path . $name, $path) → _checkFilePath($path . $name, $plugin)。
  • .. を含まない通常テンプレートは早期 return のため影響なし(顕在化するのは .. 経由のみ)。
2-11. TreeBehavior: ルートに parent_id=null をセットして保存するとツリー破損

5.2 の TreeBehavior は、ルート(parent_id=0)のエンティティに parent_id=null をセットして保存すると「ルートへの移動」とみなして lft/rght を再計算する。結果ツリーが壊れ、配下の URL 生成等が失敗する。

  • 修正: ルート更新時は parent_id をデータに含めない(変更しない)。
    php
    $data = ['id' => $id, 'name' => $name, ...];
    if (!is_null($rootContentId)) $data['parent_id'] = $rootContentId; // ルート(null)では parent_id を触らない
2-12. Table::get() の第2引数も名前付き引数に(配列 options は非推奨)

find() と同様、5.2 で Table::get($id, mixed ...$args) となり options 配列は非推奨。

php
// Before → After
$table->get($id, ['contain' => ['Users']]);   →  $table->get($id, contain: ['Users']);
// 動的に options を組む場合はスプレッドで名前付き引数展開(PHP 8.1+)
$query->find($finder, array_merge(['prefix' => $prefix], $options));
  → $query->find($finder, ...array_merge(['prefix' => $prefix], $options));
  • スプレッド展開は文字列キーの連想配列前提(finder/get の名前付き引数名に一致)。
2-13. Entity::set([...])(配列一括セット)の非推奨

エンティティへの配列一括セットは patchEntity() を使う。

php
// Before(テスト等)
$entity->set(['field' => $v, ...]);
// After
$table->patchEntity($entity, ['field' => $v, ...]);
Show full SKILL.md (346 more words)Show less
2-14. ヘルパの実メソッドがマジックメソッド委譲化 → method_exists() が false(TextHelper::truncate 等)

CakePHP のアップデートで、これまで実宣言だったヘルパのメソッドが __call による委譲に置き換わることがある。代表例: TextHelper::truncate/tail/highlight/excerpt/toList は実メソッドを持たず、TextHelper::__call() が Cake\Utility\Text::{$method}() へ委譲する。

  • 影響: 呼び出し前に method_exists($helper, 'truncate') で存在確認しているコードは、method_exists() が実宣言メソッドしか true にしないため false になり、当該機能が静かに動かなくなる(例外も出ず null 等を返す)。
  • baserCMS 実例: BcBaserHelper::__call() が PluginBaserHelper::methods() のマッピング('truncateText' => ['Text','truncate'])を呼ぶ前のガードで method_exists() を使っており、truncateText() が無反応化した。
  • 修正: ガードを is_callable() に変える。is_callable([$obj, $method]) は実メソッドだけでなく __call を持つオブジェクトでも true を返す(マッピングが呼び出し対象の正本なので判定を緩めても設計上の安全性は保てる)。
    php
    // Before
    if (method_exists($pluginBaser->{$helper}, $target)) { ... }
    // After
    if (is_callable([$pluginBaser->{$helper}, $target])) { ... }
  • 検出: grep -rn "method_exists(" --include="*.php" で、対象がヘルパ/ユーティリティの委譲メソッドになり得る箇所を洗う。method_exists と is_callable の非対称性(後者だけが __call を true にする)が要点。
  • テスト: BcBaserHelper 経由の委譲メソッドは、有効プラグインが無いと _initPluginBasers() が早期 return して BaserCore baser が登録されない(PluginFactory::make(['name'=>'BcBlog'])->persist() してから検証する)。

エコシステム: cakephp/migrations 4.5+(CakePHP 5.2 期に同梱更新)

M-1. AbstractMigration / AbstractSeed の非推奨 → BaseMigration / BaseSeed

migrations 4.5 以降、Migrations\AbstractMigration / Migrations\AbstractSeed が非推奨化。マイグレーションを走らせるテストで Migrations\AbstractMigration is deprecated が大量に出る(xdebug のスタックダンプも相まって大量エラーに見える)。

  • 修正: 基底クラスを BaseMigration / BaseSeed に変更。use Migrations\Table; → use Migrations\Db\Table;(table() の戻り型 Migrations\Db\Table に合わせる)。
  • BaseMigration::__construct(int $version)(引数は version の int 1つ。旧 AbstractMigration の多引数から変更)。$this->input は無い。
  • baserCMS のように table() をオーバーライドしてプレフィックスを付与している場合、$this->input が使えないため実行中アダプターの接続設定から取得する:
    php
    public function table(string $tableName, array $options = []): \Migrations\Db\Table {
        $prefix = $this->getAdapter()->getConnection()->config()['prefix'] ?? '';
        return parent::table($prefix . $tableName, $options);
    }
  • インラインのテスト用マイグレーション(テスト内で $file->write('<?php class X extends AbstractMigration ...'))も忘れず BaseMigration に変更する。
M-2. Migration テストの新アダプタ API(Phinx\Db\Adapter\AdapterFactory 廃止)

旧 Phinx\Db\Adapter\AdapterFactory + Symfony Console の setInput() は新基底と非互換。新 Migrations\Db\Adapter\AdapterFactory を使い、アダプタ種別は接続のドライバ名から導出する(migrations 本体 Environment::getAdapter() と同じ)。MySQL 決め打ちを避けると PostgreSQL/SQLite でもテストが通る。

php
$connection = ConnectionManager::get('test');
$driverClass = get_class($connection->getDriver());
$adapterType = strtolower(substr($driverClass, (int)strrpos($driverClass, '\\') + 1)); // mysql / postgres / sqlite
$options = ['adapter' => $adapterType, 'connection' => $connection] + (array)$connection->config();
$adapter = \Migrations\Db\Adapter\AdapterFactory::instance()->getAdapter($adapterType, $options);

バージョン非依存(CakePHP 5.x 全般 / baserCMS 固有)

3-1. コントローラは Response を返す(出力直書き禁止)

header() + echo readfile() 等の直接出力は headers already sent の原因。Response を返す。

php
$content = file_get_contents($distPath);
// 後始末(unlink / emptyFolder)を先に実施
return $this->getResponse()
    ->withType('zip')
    ->withHeader('Cache-Control', 'no-store')
    ->withHeader('Content-Disposition', 'attachment; filename="' . basename($distPath) . '"')
    ->withStringBody($content);
  • KCAPTCHA 等の出力は ob_start()/ob_get_clean() で文字列化し withStringBody() で返す。
  • 戻り型 : void を付けている場合は : \Cake\Http\Response に変える。
  • ダウンロード系(テーマDL・バックアップDL・ログDL)に多い。
3-2. クラスのオーバーライドと自動検出ツール(baserCMS固有)

baserCMS は一部 CakePHP クラスを plugins/baser-core/src/Routing/(namespace Cake\Routing)でオーバーライドしている(Asset・RouteCollection 等)。 AnalyseController がソースを走査し ReflectionClass でロードする際、パス由来のクラス名(\BaserCore\Routing\Asset)でロードすると、別名前空間の既ロードクラス(Cake\Routing\Asset)を再宣言して Cannot redeclare class で Fatal になり、全テストが途中停止する。 → AnalyseController::CONVERT_CLASS_NAME に '\BaserCore\Routing\Asset' => '\Cake\Routing\Asset' のように補正を追加(オーバーライドを増やしたら必ず登録)。

3-3. グローバル env() 依存の検出器は統合テストで再現不可 → $request->getEnv()

リバースプロキシ判定等で 'https' detector を上書きする際にグローバル env() を見ていると、統合テスト($this->configRequest() で environment を差し込む)では再現できず分岐が効かない。$request->getEnv() を使うと本番同等かつテストでも再現可能。

php
// Before: $request->addDetector('https', fn() => env('HTTPS') === 'on' || ...);
// After:  $request->addDetector('https', fn($r) => $r->getEnv('HTTPS') === 'on' || ...);
3-4. 全テスト実行(長時間)で時刻比較がズレる → 実 time() を使わない

time()(実時刻)と DB の modified 等(テストでは Chronos 固定の bootstrap 時刻)を比較する許容時間チェックは、全テストが数十分かかると範囲外になり長時間実行時だけ失敗する。\Cake\I18n\DateTime::now()->getTimestamp() を使うと Chronos の固定/移動に追随し、本番では実時刻と同一。

3-5. config/routes.php の fallbacks() がコンテンツルーティングを隠す(テストで 404)

baserCMS はコンテンツルーティング(BcContentsRoute = /*)で URL を解決し、BaserCorePlugin::disableRootRoutes() が config/routes.php の fallbacks()(/{controller}/{action}/*)を無効化している。だが disableRootRoutes() は BcUtil::isConsole() でコンソール(ユニットテスト)ではスキップされるため、テストでのみ fallbacks が残り /{controller}/{action}/* が BcContentsRoute より先にマッチしてブログのアーカイブ等が 404 になる。

  • 安全策(現行): config/routes.php の $builder->fallbacks(); を無効化(コメントアウト)して本番挙動に合わせる。baserCMS はコンテンツルーティング主体で汎用 controller fallback を使わないため、これが最も堅牢。
  • ⚠️ アンチパターン: 「テストでも disableRootRoutes() を走らせる(isTest() で許可)」案は避ける。disableRootRoutes() はリフレクションでルートコレクションを破壊的に空にするが、テスト環境ではルートコレクションがリクエストを跨いで蓄積されるため、2回目以降のビルドで API ルート等まで巻き込んで wipe し、全 API 統合テストが 404 になる(実測で確認済み)。fallbacks を消すだけの surgical な除去でも、wipe の副作用と相殺せず破綻しやすい。

調査の進め方(チェックリスト)

  1. 致命的か警告かを logs/debug.log / logs/error.log で判別。
  2. 失敗が多いときは例外メッセージを集計して systemic な原因を特定。
  3. 各原因についてアプリ src 起因かテスト/環境/fixture/i18n 起因かを切り分け(git diff HEAD / Plugin::isLoaded / DIコンテナ登録 / 英語↔日本語メッセージ)。
  4. アプリ src 起因を該当バージョン節のレシピで修正 → php -l で lint → 当該テストを --filter で単体確認。
  5. 仕上げに全テストを再実行して件数の改善と新規回帰の有無を確認。

関連: PHP本体起因(暗黙nullable・動的プロパティ・fgetcsv・Reflection)は php-migration スキルへ。

© baserproject, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/cakephp-migration of baserproject/basercms.

Open the folder on GitHubat commit 748b4f6

Compare with similar skills

Cakephp Migration next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Cakephp Migration compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Cakephp Migration this skillbaserproject/basercms190—~4kAutomated safety check: PassMIT
Configuring Horizoncoollabsio/coolify63k4 repos~898Automated safety check: PassMIT
Tailwindcss Developmentanonaddy/anonaddy4.9k10 repos~865Automated safety check: PassMIT
Fortify Developmentcoollabsio/coolify63k4 repos~1.9kAutomated safety check: PassMIT
MCP Developmentcoollabsio/coolify63k1 repos~949Automated safety check: PassMIT
WooCommerce Code Reviewwoocommerce/woocommerce11k3 repos~1.1kAutomated safety check: PassCustom licence

Similar skills

  • Configuring Horizon

    coollabsio/coolify

    A skill your agent uses whenever the user mentions Horizon by name in a Laravel context.

    63k GitHub starsUsed in 4 repos~898 tokens
    Backend & APIsAuto-check passed
  • Tailwindcss Development

    anonaddy/anonaddy

    Always invoke when the user's message includes 'tailwind' in any form.

    4.9k GitHub starsUsed in 10 repos~865 tokens
    Frontend & DesignAuto-check passed
  • Fortify Development

    coollabsio/coolify

    ACTIVATE when the user works on authentication in Laravel. An agent skill from coollabsio/coolify.

    63k GitHub starsUsed in 4 repos~1.9k tokens
    Backend & APIsAuto-check passed
  • MCP Development

    coollabsio/coolify

    A skill your agent uses for Laravel MCP development. An agent skill from coollabsio/coolify.

    63k GitHub starsUsed in 1 repo~949 tokens
    Frontend & DesignAuto-check passed
  • WooCommerce Code Review

    woocommerce/woocommerce

    Reviews WooCommerce code changes against the project's standards, flagging backend PHP architecture, naming, documentation, data integrity and testing violations.

    11k GitHub starsUsed in 3 repos~1.1k tokens
    DevelopmentAuto-check passed
  • Sync Translations

    symfony/symfony

    Synchronize translation catalogs across maintained Symfony branches: find messages that newer branches added to the English catalogs but that are still missing from the oldest maintained branch…

    31k GitHub stars~1.9k tokensUpdated today
    Writing & ContentAuto-check passed

More from baserproject/basercms

All 15 skills in this repo
  • Basercms Security Advisory

    baserproject/basercms

    baserCMS のリポジトリセキュリティアドバイザリ(GHSA・triage含む)対応を、一覧取得→指摘検証→課題別の修正→プライベートフォーク/ブランチ/PR作成→ローカル検証まで一気通貫で扱う手順とスクリプト。「セキュリティアドバイザリを確認」「triageの脆弱性を検証」「アドバイザリごとにフォークとPRを作って」「脆弱性修正をプルリクにまとめて」等のときに使う。Copilot/GHAは…

    190 GitHub stars~1.4k tokensUpdated 3 days ago
    Auto-check passed
  • Basercms Core Plugin Convert

    baserproject/basercms

    baserCMS の「通常プラグイン(サードパーティ/単体配布)」を monorepo の「コアプラグイン」に昇格させる手順。「コアプラグインに変更」「コアプラグイン化」「通常プラグインをコアに昇格」「monorepo に取り込む」等のときに参照する。プラグイン名の規約変更(bc- プレフィックス付与・CamelCase→ハイフン区切り)、.git/シンボリックリンク/standalone…

    190 GitHub stars~3.1k tokensUpdated 3 days ago
    Auto-check passed
  • Basercms Plugin 5x Update

    baserproject/basercms

    baserCMS プラグインを 5.2系 から 5.3系(PHP 8.5 / CakePHP 5.2.x ベース、開発中)へ移行する際の baserCMS 固有の破壊的変更・非推奨・テスト基盤対応のレシピ集。「プラグインを5.3に対応」「baserCMS 5.3 マイグレーション」「PluginCollection::create(): $config null given」「Plugin…

    190 GitHub stars~2.3k tokensUpdated 3 days ago
    Auto-check passed
  • Basercms Release Note

    baserproject/basercms

    baserCMS の plugins/baser-core/VERSION.txt に、リリース分の変更履歴(NEW/CHG/BUG)をコミットログから生成して追記する手順。「VERSION.txt を更新して」「リリースノートを作って」「変更履歴をまとめて」「今回のリリース分の変更点を書き出して」「前回リリースからの差分を VERSION.txt…

    190 GitHub stars~1.6k tokensUpdated 3 days ago
    Auto-check passed
  • Basercms Unittest

    baserproject/basercms

    baserCMS(CakePHP5 / PHPUnit)のユニットテストをローカル Docker 環境で実行・調査する手順。「ユニットテストを実行して」「全テストを走らせて」「このテストだけ流して」「テスト失敗を調べて」「プラグイン単体でテストを動かしたい」「プラグインにテスト環境を導入したい」等のときに参照する。コンテナ名・実行コマンド・権限自動承認のためのコマンド整形・失敗の集計と切り分け方…

    190 GitHub stars~4.9k tokensUpdated 3 days ago
    Auto-check passed
  • Basercms4 Development

    baserproject/basercms

    baserCMS 4系(CakePHP 2.10ベース)+ jQuery プロジェクトの開発ルール集。「baserCMS 4 で開発」「4系のプラグインを修正」「CakePHP 2系のコードを書く」「app/Plugin 配下の Controller/Model/View」「テーマの…

    190 GitHub stars~877 tokensUpdated 3 days ago
    Auto-check passed

Works with

Questions about Cakephp Migration

What does Cakephp Migration do?

baserCMS の CakePHP バージョンアップ(5.0 → 5.1 → 5.2 ~)対応の非推奨・破壊的変更パターン集と修正レシピ。「Association alias already set」「A validation rule with the name already exists」「Token not found」「headers already sent」「Plugin…. Cakephp Migration is an agent skill from baserproject/basercms.php が読まれず Configure が null(live イテレーション)」「checkFilePath で ..

How do I install Cakephp Migration in Claude Code?

Run `npx skills add baserproject/basercms --skill cakephp-migration -a claude-code`. Or copy the skill folder (.agents/skills/cakephp-migration in baserproject/basercms) into .claude/skills/cakephp-migration in your project. Claude Code loads it when a task matches its description.

How do I install Cakephp Migration in Codex?

Run `npx skills add baserproject/basercms --skill cakephp-migration -a codex`. Or copy the skill folder (.agents/skills/cakephp-migration in baserproject/basercms) into .agents/skills/cakephp-migration in your project. Codex loads it when a task matches its description.

Can I use Cakephp Migration in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add baserproject/basercms --skill cakephp-migration -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/cakephp-migration, .gemini/skills/cakephp-migration, .github/skills/cakephp-migration and .opencode/skills/cakephp-migration in your project.

What does Cakephp Migration need to run?

Going by SKILL.md and its folder, Cakephp Migration needs the command-line tools its instructions call (composer, git, npm and php).

Does Cakephp Migration access the network?

SKILL.md contains no URLs. Its commands use git and npm, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Cakephp Migration safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Cakephp Migration use?

Cakephp Migration is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Cakephp Migration use?

About 4k tokens (SKILL.md is roughly 16k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Cakephp Migration?

Skills that share tags, products or a category with Cakephp Migration: Configuring Horizon (coollabsio/coolify, 63k stars), Tailwindcss Development (anonaddy/anonaddy, 4.9k stars), Fortify Development (coollabsio/coolify, 63k stars) and MCP Development (coollabsio/coolify, 63k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Cakephp Migration?

baserproject (a GitHub organization) maintains it in baserproject/basercms, which has 190 GitHub stars. The repository holds 15 skills in this directory. The repository was last updated on October 5, 2026.

Source: baserproject/basercms on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.