会員グループ管理::会員グループ価格管理アドオンの 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-CUBE4.4 系
会員グループ管理プラグインec-cube/customergroup44 ^4.4 が有効なこと
PHP8.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 です。