会員グループ管理::会員グループ価格管理アドオンの EC-CUBE 4.4 対応を進めています。
先に本体の会員グループ管理プラグインを 4.4 に上げた話を書きましたが、あのときは 4.4 上で実際に動かせておらず、構文チェックしか通していませんでした。今回アドオンをやるにあたって EC-CUBE 4.4 を立てて動かしたところ、3つとも構文チェックでは絶対に出ないやつでした。同じところで詰まる人がいそうなので書いておきます。
このアドオンでできること
会員グループごとに商品の価格を変えるアドオンです。本体の会員グループ管理プラグインが土台で、単体では動きません。
| 機能 | 設定単位 | 動作 |
|---|---|---|
| 会員グループ価格 | 商品規格ごと | グループに紐づく固定価格を売価として表示 |
| 卸売価格 | 会員グループの掛け率 | 元価格 × 掛け率% を売価として表示 |
| 割引率 | 会員グループの割引率 | 元価格 × (100 − 割引率)% を売価として表示 |
| ボリュームディスカウント | 商品ごと | 数量条件と割引率で値引き明細を注文に追加 |
同じ会員に複数の設定が当たる場合は、会員グループ価格、割引率、卸売価格の順で評価して、最初に該当したものを採用します。ボリュームディスカウントだけは売価を書き換えるのではなく、値引き明細を足す仕組みなので、上の3つとは独立して効きます。
DiscountProcessor の戻り値型
いちばん最初に踏んだのがこれで、症状は「EC-CUBE のインストール自体が落ちる」でした。
4.4 で DiscountProcessor::addDiscountItem() の戻り値型が void から ?ProcessResult に変わっています。こちらの実装が void のままだったので、シグネチャ不一致の致命的エラーになります。プラグインの画面まで到達しないどころか、EC-CUBE のインストーラーが動かない。
戻り値型を合わせて、途中で抜けている return; を return null; に直しました。値引き明細を足さないケースでは null を返せば、従来どおり何もしません。
型を変えたあとに末尾の return null を1か所取りこぼしていて、これは後の作業で気づいて直しています。戻り値型を変えるときは、抜けているパスがないか全部見たほうがいいです。
Symfony 7 の POST_SUBMIT
次が商品登録と商品規格の保存が500になるやつです。
Form data cannot be changed during "form.post_submit"
Symfony 7 は POST_SUBMIT でのデータ変更を禁止するようになりました。該当箇所を見たら、どれもエンティティを直接いじったあとに $event->setData() を呼んでいて、この呼び出しは元々必要ありませんでした。消して終わりです。
古いコードほど、効いていない行が残っています。Symfony 側が厳しくなったおかげで見つかった、という感じでした。
DBAL 4 と MySQL の暗黙コミット
3つめがいちばん厄介でした。プラグインを有効化すると、こう落ちます。
There is no active transaction.
順を追うと、こうなっています。EC-CUBE 本体はプラグインの有効化をトランザクションで包みます。このアドオンは有効化のたびに外部キーの CASCADE を張り直す処理を持っていて、そこで ALTER TABLE を投げます。ところが MySQL は DDL で暗黙コミットするので、同じ接続で ALTER を投げた時点でトランザクションが終わってしまう。DBAL 4 はこれを検知するようになったため、本体が最後に commit しようとしたところで「トランザクションが無い」と言われて落ちます。
DBAL 3 のときは黙って通っていたので表面化していませんでした。ついでに言うと、有効化のたびに外部キーを張り直す処理を入れたのは 4.3 系での最近の修正で、それと 4.4 の組み合わせで初めて出た問題です。
直し方は、DDL を専用の接続で流すことにしました。本体のトランザクションとは別の接続なので、暗黙コミットが起きても本体には影響しません。外部キーをわざと RESTRICT に戻してから無効化と有効化をやり直して、エラーなく CASCADE に復旧することを 4.4 上で確認しています。
前回の記事で「DBAL 4 の SchemaManager の API 変更には未対応で、4.4 で動作確認が必要」と書いた宿題が、まさにこれでした。
テストの直し
本体のテストクラスが final になった件は本体プラグインと同じで、借りていたシナリオを自前に移しました。それ以外に 4.4 固有で引っかかったのが2つあります。
scenarioCartIn()の第2引数は商品規格の ID です。オブジェクトを渡すとルーティングで文字列変換に失敗します- decimal 列の getter が string を返すようになりました。
assertSameで比較していたテストが軒並み落ちるのでassertEqualsに変えています
あとは PHPUnit 側の作法で、データプロバイダを static にして属性記法に直しました。これで233件が全部通っています。
動作要件
| 項目 | 内容 |
|---|---|
| EC-CUBE | 4.4 系 |
| 会員グループ管理プラグイン | ec-cube/customergroup44 ^4.4 が有効なこと |
| PHP | 8.2 / 8.3 |
| データベース | MySQL 8、PostgreSQL 13 以上 |
パッケージ名は ec-cube/customergroupprice44、プラグインコードは CustomerGroupPrice44 です。本体と同じく、4.2 / 4.3 版とは別プラグイン扱いになります。
いまの状況
2026年7月27日時点で、PHPUnit も PHPStan も 4.4 ブランチで通っています。本体プラグインと違って、こちらは EC-CUBE 4.4 を立てて実際に動かしながら直したので、インストールから有効化、商品登録、購入までは通っている状態です。
ただ EC-CUBE 4.4 本体がまだリリースされていないので、配布はそのあとになります。4.2 / 4.3 版は引き続き更新していて、直近は 4.3.4 です。