CakePHP5への移行

先日、2023年4月19日に、CakePHP４系に対応した baserCMS５というバージョンをリリースしたのですが、その後、９月にCakePHP５系がリリースされてしまいましたので、、、
現在、鋭意移行作業を進めています。

CakePHP３系４系への移行の時ほど大変ではないのですが、なかなか引っかかりポイントがありましたので軽くまとめてみます。

## 全般

### File / Folderクラスがなくなった

baserCMS４系ではかなり多くの場所で使っていたので、これはかなり大変でした。

PHP標準の `SplFileInfo` などを使えとのことでしたが、結構使いにくいので、ラッパークラスを使って移行をしやすくしました。

[BcFile](https://github.com/baserproject/basercms/blob/dev-cake5-adjust/plugins/baser-core/src/Utility/BcFile.php) / [BcFolder](https://github.com/baserproject/basercms/blob/dev-cake5-adjust/plugins/baser-core/src/Utility/BcFolder.php)

### FrozenTimeがDateTimeへ

これはアップグレードツールである程度やってくれます。

```php
// Cake4系
\Cake\I18n\FrozenTime
// Cake5系
\Cake\I18n\DateTime
```

### プラグインのロードが設定ファイルでできるようになった

プラグインのロードは、 `config/plugins.php` でできるようになったようです。

デバッグ時のみロード、CLIの場合のみロードなどと指定もできます。

### callable の設定が Closure に

こちらは全てではないかもしれませんが、コールバック処理として指定する callable な 関数が、Closureでないと怒られる場合があるようです。

```php
// 例）ServerRequestにおける管理画面判定
// 4系
$this->getRequest()->addDetector('admin', [$this, 'isAdmin']);
// 5系
$this->getRequest()->addDetector('admin', $this->isAdmin(...));
```

最近、ドット３つの省略記法が増えましたね。

スッキリしていい感じですが、理解してないと読めないなこれ。

## リクエスト

### SSLの判定方法が変わった

```php
// Cake4系
$this->getRequest()->is('ssl')
// Cake5系
$this->getRequest()->is('https')
```

### アップロードファイルのデータオブジェクトに

CakePHP4までは、配列とオブジェクトを選択できるようになっていたのですが、その設定がなくなり、`UploadedFile`のインスタンスで取得するようになっています。

## コントローラー

### ページネーションの結果セットがPaginatedResultSetに

以前は、ページネーションの結果について、 `ResultSet` で戻ってきていたのですが、`PaginatedResultSet` で戻るようになりました。

## コンポーネント

### SecurityComponent がなくなった

HTTPSを強制するには、`HttpsEnforcerMiddleware` を利用することになり、POSTデータのバリデーションは、 `FormProtectionComponent` を利用することになりました。

### RequestHandlerComponent がなくなった

API開発で利用していたのですが、これもなくなっちゃいました。
`JsonView` を自動的に利用するためには、コントローラーで `viewClasses` メソッドを実装し、明示的に指定する必要があります。

```php
public function viewClasses(): array
{
    return [JsonView::class];
}
```

RSSファイルへのリクエスト判定でも利用していたのですが、こちらは ServerRequest クラスにまとめました。

```php
// RSS判定
$this->RequestHandler->prefers('rss');
// ServerRequest にまとめた
$this->getRequest()->addDetector('rss', ['accept' => ['application/xml'], 'param' => '_ext', 'value' => 'rss'])
$this->getRequest()->is('rss')
```

## テーブル

### allowEmptyの指定方法が変わった

型の種類を指定する必要があるようです。

```php
// Table内にて
// Cake4系
$validator->allowEmpty()
// Cake5系
$validator->allowEmptyString()
```

### orderの名称変更

こちらはアップグレードツールである程度やってくれます。

```php
// Cake4系
$query->order();
// Cake5系
$query->orderBy();
```

### Table::get()の第２引き数が名前付き引き数に

これもアップグレードツールである程度やってくれます。

PHPもこんな書き方ができるようになったんですね

```php
// Table内で
// Cake4系
$this->get(1, ['contain' => [$tableName], 'conditions' => $conditions]);
// Cake5系
$this->get(1, contain: [$tableName], conditions: $conditions);
```

## データベース

### SQLの発行メソッドが変わった

```php
$db = ConnectionManager::get('default');
// Cake4系
$db->query($sql);
// Cake5系
$db->execute($sql);
```

## ビュー

### ヘルパーの追加方法が変わった

```php
// View内にて
// Cake4系
$this->loadHelper($helper);
// Cake5系
$this->addHelper($helper);
```

## テスト

### ユニットテストのDataProviderが静的メソッドに

`static` を付けないと怒られます。

### FixtureManagerが利用できなくなった

これはめっちゃ大変。今まで資産がちょっと間違えると負債に転換してしまう。

`FixtureFactory` と `FixtureScenario` に移行します。

といった感じでしょうか。





---
2023年12月24日現在、まだ完了しておらず、これまでに頑張って作った3000のユニットテストがだいぶ死んでしまったので、[dev-cake5-adjust](https://github.com/baserproject/basercms/tree/dev-cake5-adjust) ブランチで調整中です。

ユニットテストの調整ができたら、全体的な手動テストを実施して、2024年の3月頃に、baserCMS 5.1.0 としてリリースする予定です。

Laravelもよいですが、CakePHPも良い方向に進歩していますね。baserCMSの開発にご興味ある方は、[GitHubのレポジトリ](https://github.com/baserproject/basercms)を覗いてみてください。