Skip to content

improvement: deprecation ゲート有効化+未使用の非推奨 public API 削除 (#6933) - #6937

Open
ttokoro20240902 wants to merge 11 commits into
4.4from
feature/6933-deprecation-gate
Open

improvement: deprecation ゲート有効化+未使用の非推奨 public API 削除 (#6933)#6937
ttokoro20240902 wants to merge 11 commits into
4.4from
feature/6933-deprecation-gate

Conversation

@ttokoro20240902

@ttokoro20240902 ttokoro20240902 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

概要

Issue #6933 のうち、仕様(実行時の挙動・CSV等の出力・管理/店頭画面・DBスキーマ)を一切変えない範囲で対応する。

  • Part 1: deprecation ゲートの有効化(Symfony 追従の本命)
  • Part 2: 未使用の @deprecated public API の削除(4.4 の BC 破壊に相乗り)

Fixes #6933(の安全に実施できる範囲。据え置き分は後述)

方針

Part 1 — deprecation ゲートを PHPUnit 11 ネイティブの failOnDeprecation で有効化

自コードが非推奨 API を呼んだら CI が失敗するようにし、次期 Symfony(7.4→8)追従を「負債の発掘」から「非推奨を消すだけ」に変えるための早期警告を入れる。

当初は SYMFONY_DEPRECATIONS_HELPERweakmax[direct]=0 に引き上げる方針だったが、この設定は PHPUnit 11 環境では機能しないことがレビュー中の検証で判明したため、PHPUnit 11 が持つネイティブのゲートへ置き換えた。

SYMFONY_DEPRECATIONS_HELPER が効かない理由

  • 値を読んで DeprecationErrorHandler を登録するのは symfony/phpunit-bridgebootstrap.php(composer の autoload.files で常時ロードされる)だが、同ファイルは冒頭で if (class_exists(PHPUnit\Metadata\Metadata::class)) { return; } により PHPUnit 10 以上では早期 return する
  • PHPUnit 10+ 用の SymfonyExtension は ClockMock / DnsMock のみを登録し、DeprecationErrorHandler は登録しない(DeprecationErrorHandler を参照するのは bootstrap.phpbin/simple-phpunit.php だけ)
  • CI(unit-test.yml / coverage.yml)は vendor/bin/phpunit を実行するため、bridge 経由の simple-phpunit も通らない
  • 実測: 非推奨警告を発生させるテストを vendor/bin/phpunit で実行しても bridge のサマリは出力されず、警告も集計されない(SymfonyExtension を登録しても同じ)

置き換え内容(phpunit.xml.dist

設定 内容
SYMFONY_DEPRECATIONS_HELPER 削除(読まれない設定のため)
failOnDeprecation="true" 非推奨 API の呼び出しで CI を失敗させる
displayDetailsOnTestsThatTriggerDeprecations="true" 発生箇所を CI ログに出す
<source ignoreSelfDeprecations="true" ignoreIndirectDeprecations="true"> ゲート範囲を direct のみに限定(下記)

ゲート範囲を direct に限定した理由

PHPUnit 11 の <source> は Symfony の SYMFONY_DEPRECATIONS_HELPER と同じ分類を持ちます(IssueTrigger::isDirect() は「first-party/test コードが third-party/PHP の非推奨を呼ぶ」=Symfony の direct と同義)。当初意図した max[direct]=0 と同じ範囲にするため、次の 2 つを除外しています。

分類 扱い 理由
direct(自コードが PHP / vendor の非推奨 API を呼ぶ) ゲート対象 修正すべきもの。Symfony 追従の早期警告として本来の目的
self(自コードが自ら trigger_error する @deprecated 予告) 対象外 当初 max[self]=0 を併用しなかった判断と同じ
indirect(vendor 内部で発生) 対象外 我々に修正できない(mobiledetect/mobiledetectlib の暗黙 nullable 引数。PHP 8.4 で非推奨)

これを入れないと PHP 8.4 / 8.5 のジョブが vendor 由来の非推奨で必ず落ちます(8.2 / 8.3 では発生しません)。

coverage.yml は base の 4.4 で Codeception カバレッジジョブ自体が削除済み(#6905)のため、本 PR での変更は無くなった。SYMFONY_DEPRECATIONS_HELPER はリポジトリから完全に撤去されている。

前提として既存の非推奨警告 19 件を解消(いずれも挙動不変)

PHP 8.2 で検出できた 11 件に加え、CI で PHP 8.4 / 8.5・除外グループ(plugin-service / cache-clear)で表面化した 8 件も解消している。

分類 件数 内容
src・null の受け方 3 SafeTextmailEscaperExtension(Twig は null の変数もそのまま渡すためエスケーパ引数を ?string に)/ PluginService::deleteDirsinstall()/update() が例外発生時点で未設定の null を渡す仕様のため null をスキップ・phpdoc を string|null に)/ InvalidItemExceptionparent::__construct() へ null を渡さない)
tests・動的プロパティ生成 7 MasterdataTypeTest::$form / LoginHistoryRepository…AdminTest$Member1$LoginHistory1-3 / MailControllerTest$Member$MailHistories を宣言。EccubeTestCase::cleanUpProperties() が tearDown で全プロパティに null を代入するため nullable で宣言
vendor 由来 1 HTML パートを持たないメールへの assertEmailHtmlBodyNotContains()assertNull($Message->getHtmlBody()) に変更(MailServiceTest 3 箇所・WithdrawControllerTest 1 箇所)。元の書き方は symfony/mime 内で str_contains(null, …) の警告を出すうえ、HTML パートが存在しないため常に成立する空振りアサーションだった
plugin-service グループ 1 PluginServiceTest::testCreateEntityAndTrait のダミープラグイン Block に ORM 非マッピングの public $sample を宣言。テストが $Block->sample = true と代入していたため動的プロパティ生成になっていた
doc-comment メタデータ 1 TemplateControllerTest::testChangeTemplateWithEnvOverride()@group cache-clear#[Group] 属性へ(同ファイルの他メソッドは既に属性を使用。PHPUnit 12 で廃止予定)
PHP 8.4 / 8.5 固有の direct 6 Order::getMergedProductOrderItems()(未永続明細で ProductClass の ID が null になり null を配列キー / オフセットに使用 → (string) キャスト)/ ProductController::index()OrderController::index()$searchData['sortkey'] が null のとき COLUMNS[null] 参照 → ?? '')/ PluginApiServicecurl_close() は PHP 8.0 以降なにもせず 8.5 で非推奨 → 削除)/ fgetcsv()$escape 5 箇所を現行既定値 '\\' で明示(PHP 8.4 で明示指定が必須。とくに fgetcsvDoesntOccur5cProblem は SJIS 2 バイト目の 0x5c を escape 文字と誤認しないことの検証なので既定値を変えないことが重要)

Part 2 — 削除できるのは「呼び出し元なし/CSV非出力/スキーマ不変」のものだけ

@deprecated public API を「①コアに呼び出し元があるか ②CSV 出力に載る保存カラムのアクセサか ③カラム削除マイグレーションを伴うか」で判定し、すべて No のもののみ削除した。

削除

API 理由
OrderItem::getTaxRuleId() / setTaxRuleId() 呼び出し元皆無・CSV非出力(tax_rule_id カラムは残置)
Product::isEnable()ProductClass::isEnable() 計算メソッド・相互呼び出しのみ
Cart::getLock() / setLock()$lock ORM 非マッピングの一時プロパティ
transChoice() trans() の別名・呼び出し元皆無
TaxProcessor::getTaxDisplayType() デッドな protected メソッド
CartService::$cart 未初期化・未使用プロパティ
Order::getTotalPrice() getPaymentTotal() の別名
CacheUtil::clear() 代替は clearCache()(専用テストごと削除)
CustomerStatus::NONACTIVE / ACTIVE 現役定数 PROVISIONAL / REGULAR と同値の別名

据え置き(削除すると仕様が変わるため本 PR では触らない)

  • Order::getTax/setTaxItemHolderInterface::setTaxOrder::getDiscounttax/discount カラム … CSV 出力「税金」「値引き」列を支える現役@deprecated 予告は残置。
  • BaseInfo::getPhpPath/setPhpPathphp_path カラム … 削除にマイグレーション(スキーマ変更)を伴う。

併せて訂正したドキュメント

SYMFONY_DEPRECATIONS_HELPER が効かない原因調査の過程で、AGENTS.md と Skill の記述に誤りがあることが判明したため訂正した。

  • 「PHPUnit 11(symfony/phpunit-bridge 経由)」→「vendor/bin/phpunit を直接実行」(bridge の非推奨検出が PHPUnit 10 以上で無効である旨も明記)
  • 実在しない bin/phpunitvendor/bin/phpunitbin/ には consoletemplate_jp.php のみ)

テスト

  • 専用テストは削除: CacheUtilTestOrderTest::testGetTotalPrice
  • 道具として使うテストは等価 API へ付け替え:
    • EditControllerTest: getTotalPrice()getPaymentTotal()
    • EntryControllerTest / CustomerRepository(GetQueryBuilderBySearchData)Test / Generator: CustomerStatus::NONACTIVE/ACTIVEPROVISIONAL/REGULAR
  • E2E / VAddy のフィクスチャも同じ置換を適用(レビュー指摘対応):
    • e2e/setup-fixtures.php(Playwright の global-setup.ts が全 E2E 前に実行)
    • codeception/acceptance/_bootstrap.php(VAddy スキャンが codecept run -g vaddy で実行し、@group vaddy の Cest が createCustomer() を使う)
  • ローカル QA(Docker・PHP 8.2): PHPStan(level 6) / PHP-CS-Fixer / Rector すべてクリーン。フルスイート(2905 テスト)で Deprecations 0 / Errors 0。
  • CI 全 115 チェック成功(PHP 8.2 / 8.3 / 8.4 / 8.5 × pgsql / pgsql13 / mysql / sqlite3、Playwright E2E 含む)。
  • 補足: ローカル(PHP 8.2)では 8.4 / 8.5 固有の非推奨は再現しないため、その解消は CI で検証した。
  • 補足: リトライ 2 回目で落ちる RateLimiterListenerTest 3 件は 1 回目が緑で、レートリミッタの状態が試行間に残る既知の flaky。
  • 既知の残件: failOnPhpunitDeprecation は有効化していない(PHPUnit 自身の非推奨は現時点 0 件だが、マトリクス差で表面化するリスクを避けた)。

互換性

  • 本 PR は意図的な BC 破壊(public API の削除)を含む。Issue [4.4] deprecation ゲート有効化+非推奨 public API の削除 #6933 の方針に基づき、4.4 が既に含む Symfony 7 移行の BC 破壊に相乗りさせ、プラグイン作者の移行を 1 回に集約する。
  • CSV 入出力フォーマットは変更していない(税額・値引きの列を支える API は据え置き)。
  • 削除した public API はいずれもコアに呼び出し元がない。プラグインが利用していた場合の移行先は上表のとおり。
  • failOnDeprecation="true" の有効化により、プラグインのテストが非推奨 API を呼んでいる場合は CI が失敗するようになる。

🤖 Generated with Claude Code

Summary by CodeRabbit

  • 破壊的変更

    • 会員ステータスの名称を「仮会員」「本会員」「退会」に対応する新しい定数へ変更しました。
    • 非推奨のカートロック、合計金額、税率、商品有効状態、翻訳、キャッシュ操作用APIを削除しました。
  • バグ修正

    • 未設定の検索条件やディレクトリ、空の例外メッセージを安全に処理できるよう改善しました。
    • メール本文のエスケープ処理とCSV読み込みの互換性を改善しました。
  • テスト

    • 新しい会員ステータスおよび非推奨機能削除に合わせてテストを更新しました。
    • 非推奨事項を検出したテストが失敗する設定を追加しました。

ttokoro20240902 and others added 3 commits July 16, 2026 11:53
コアに呼び出し元がなく、CSV 出力にも載らず、DB スキーマ変更も伴わない
未使用の @deprecated public API を削除する。仕様(挙動・出力・画面)は不変。

- OrderItem::getTaxRuleId() / setTaxRuleId()(呼び出し元皆無・tax_rule_id カラムは残置)
- Product::isEnable() + ProductClass::isEnable()(計算メソッド・相互呼び出しのみ)
- Cart::getLock() / setLock() + ORM 非マッピングの $lock プロパティ
- transChoice()(trans() の別名・呼び出し元皆無)
- TaxProcessor::getTaxDisplayType()(デッドな protected メソッド)
- CartService::$cart(未初期化・未使用プロパティ)+未使用 import

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
呼び出し元がテストのみの @deprecated public API を削除する。
仕様(挙動・出力・画面)は不変。

削除:
- Order::getTotalPrice()(getPaymentTotal() の別名。E_USER_DEPRECATED の
  self 発火源)
- CacheUtil::clear()(代替は clearCache()。専用テスト CacheUtilTest ごと削除)
- CustomerStatus::NONACTIVE / ACTIVE(現役定数 PROVISIONAL / REGULAR と同値の別名)

テストの扱い:
- 専用テストは削除: CacheUtilTest、OrderTest::testGetTotalPrice
- 道具として使うテストは等価 API へ付け替え:
  - EditControllerTest: getTotalPrice() → getPaymentTotal()
  - EntryControllerTest / CustomerRepository(GetQueryBuilderBySearchData)Test /
    Generator: CustomerStatus::NONACTIVE/ACTIVE → PROVISIONAL/REGULAR

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Symfony のメジャー追従を楽にするため、自コードが Symfony/Doctrine の
非推奨 API を直接呼んだ場合に CI を落とす。weak(発火してもCIを落とさない)
から max[direct]=0 へ引き上げる。

- phpunit.xml.dist: 実 PHPUnit CI(unit-test.yml / coverage.yml の phpunit
  ジョブ)はこの設定を継承するため、ここが強制化の本体。
- coverage.yml: 無効化済み Codeception ジョブの値も整合のため更新。

max[self]=0 は併用しない(StringUtil の E_USER_DEPRECATED は本 Issue の
対象外で、併用すると CI が落ちるため)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ae03601-707b-4fc8-aaae-a46bbe237fc8

📥 Commits

Reviewing files that changed from the base of the PR and between bd46b4e and 9a61ea2.

📒 Files selected for processing (7)
  • .claude/skills/eccube-contributing/SKILL.md
  • .claude/skills/eccube-phpunit/SKILL.md
  • AGENTS.md
  • e2e/setup-fixtures.php
  • src/Eccube/Entity/Order.php
  • src/Eccube/Entity/Product.php
  • tests/Eccube/Tests/Entity/OrderTest.php
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/Eccube/Entity/Product.php
  • tests/Eccube/Tests/Entity/OrderTest.php
  • AGENTS.md
  • e2e/setup-fixtures.php
  • src/Eccube/Entity/Order.php

📝 Walkthrough

Walkthrough

PHPUnitの非推奨検出を強化し、非推奨APIと顧客ステータス定数を整理しました。PHP 8.4・8.5に対応する入力処理とテスト設定も更新しました。

Changes

非推奨検出ゲートと実行手順

Layer / File(s) Summary
非推奨検出設定とテスト手順
phpunit.xml.dist, AGENTS.md, .claude/skills/*
PHPUnitのdeprecation失敗設定と詳細表示を追加しました。PHPUnitの直接実行コマンドとAPI参照確認手順を更新しました。

エンティティAPIと顧客ステータスの整理

Layer / File(s) Summary
公開APIとステータス定数の整理
src/Eccube/Entity/*, src/Eccube/Entity/Master/CustomerStatus.php
カートロック、税率、商品状態、注文合計などの非推奨APIを削除しました。顧客ステータス定数をPROVISIONALREGULARWITHDRAWINGへ置き換えました。
フィクスチャとテストの定数更新
tests/Eccube/Tests/Fixture/*, tests/Eccube/Tests/Repository/*, tests/Eccube/Tests/Web/*, codeception/acceptance/*, e2e/*
顧客ステータス参照と注文金額参照を新しいAPIおよび定数へ更新しました。

サービス・ユーティリティAPIの削除

Layer / File(s) Summary
サービスとユーティリティの非推奨処理削除
src/Eccube/Resource/functions/trans.php, src/Eccube/Service/*, src/Eccube/Util/CacheUtil.php, src/Eccube/Service/PluginApiService.php
transChoice()、旧カートプロパティ、旧税表示メソッド、旧キャッシュクリアAPIを削除しました。curl_close()の呼び出しも削除しました。

PHP互換性と入力処理の更新

Layer / File(s) Summary
null値と未設定値の処理
src/Eccube/Service/PluginService.php, src/Eccube/Service/PurchaseFlow/InvalidItemException.php, src/Eccube/Twig/Extension/SafeTextmailEscaperExtension.php, src/Eccube/Controller/Admin/*
nullのディレクトリ、例外メッセージ、エスケープ入力、検索ソートキーを明示的に処理するよう更新しました。
CSV処理とテスト生成コード
tests/Eccube/Tests/Service/*, tests/Eccube/Tests/Stream/*
fgetcsv()escape引数を明示しました。生成エンティティに公開プロパティを追加しました。

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

Possibly related PRs

Suggested labels: refactor

Suggested reviewers: dotani1111

Poem

うさぎが跳ねて、deprecationを見つけた
古いAPIを、そっと片づけた
新しい定数が、テストを走らせる
PHPの道を、軽やかに進む
ぴょん、ぴょん、変更完了!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed タイトルは、非推奨検出ゲートの有効化と未使用の非推奨public API削除という、変更の主要目的を明確に示しています。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/6933-deprecation-gate

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/coverage.yml (1)

259-260: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

無効化された Codeception ジョブではなく、実行されるジョブに設定してください。

この設定は if: false の Codeception ジョブ内にあるため、現在のCIでは評価されません。さらに有効化しても continue-on-error: true により非推奨検出がCIゲートになりません。CI全体のゲートを意図する場合は、PHPUnitジョブへ移動するか、この重複設定を削除してください。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/coverage.yml around lines 259 - 260, Move the
SYMFONY_DEPRECATIONS_HELPER setting from the disabled Codeception job to the
active PHPUnit job, and remove continue-on-error there so deprecation failures
gate CI; if the setting is already present in PHPUnit, delete this duplicate
instead.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/Eccube/Tests/Fixture/Generator.php`:
- Line 912:
createCustomers()のDocBlockに記載されたデフォルトステータスをACTIVEからREGULARへ更新し、実装のCustomerStatus::REGULARと説明を一致させてください。

---

Nitpick comments:
In @.github/workflows/coverage.yml:
- Around line 259-260: Move the SYMFONY_DEPRECATIONS_HELPER setting from the
disabled Codeception job to the active PHPUnit job, and remove continue-on-error
there so deprecation failures gate CI; if the setting is already present in
PHPUnit, delete this duplicate instead.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 28c17751-aec3-494b-90c9-37192139dbb3

📥 Commits

Reviewing files that changed from the base of the PR and between b978d3a and 1d13a23.

📒 Files selected for processing (19)
  • .github/workflows/coverage.yml
  • phpunit.xml.dist
  • src/Eccube/Entity/Cart.php
  • src/Eccube/Entity/Master/CustomerStatus.php
  • src/Eccube/Entity/Order.php
  • src/Eccube/Entity/OrderItem.php
  • src/Eccube/Entity/Product.php
  • src/Eccube/Entity/ProductClass.php
  • src/Eccube/Resource/functions/trans.php
  • src/Eccube/Service/CartService.php
  • src/Eccube/Service/PurchaseFlow/Processor/TaxProcessor.php
  • src/Eccube/Util/CacheUtil.php
  • tests/Eccube/Tests/Entity/OrderTest.php
  • tests/Eccube/Tests/Fixture/Generator.php
  • tests/Eccube/Tests/Repository/CustomerRepositoryGetQueryBuilderBySearchDataTest.php
  • tests/Eccube/Tests/Repository/CustomerRepositoryTest.php
  • tests/Eccube/Tests/Util/CacheUtilTest.php
  • tests/Eccube/Tests/Web/Admin/Order/EditControllerTest.php
  • tests/Eccube/Tests/Web/EntryControllerTest.php
💤 Files with no reviewable changes (12)
  • src/Eccube/Entity/ProductClass.php
  • tests/Eccube/Tests/Util/CacheUtilTest.php
  • src/Eccube/Entity/OrderItem.php
  • src/Eccube/Resource/functions/trans.php
  • src/Eccube/Entity/Master/CustomerStatus.php
  • src/Eccube/Entity/Order.php
  • src/Eccube/Entity/Product.php
  • src/Eccube/Entity/Cart.php
  • tests/Eccube/Tests/Entity/OrderTest.php
  • src/Eccube/Service/CartService.php
  • src/Eccube/Util/CacheUtil.php
  • src/Eccube/Service/PurchaseFlow/Processor/TaxProcessor.php

/** @var CustomerStatus $Status */
$Status = $options['status']
?? $this->entityManager->find(CustomerStatus::class, CustomerStatus::ACTIVE);
?? $this->entityManager->find(CustomerStatus::class, CustomerStatus::REGULAR);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

DocBlockのデフォルト値もREGULARへ更新してください。

実装はCustomerStatus::REGULARをデフォルトにしていますが、createCustomers()のDocBlock(Line 895)は依然としてACTIVEと記載されています。利用者が誤ったステータスを想定しないよう、コメントも同時に更新してください。

修正例
-     *     `@var` CustomerStatus|null $status         全 Customer に設定する CustomerStatus (デフォルト: ACTIVE)
+     *     `@var` CustomerStatus|null $status         全 Customer に設定する CustomerStatus (デフォルト: REGULAR)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/Eccube/Tests/Fixture/Generator.php` at line 912,
createCustomers()のDocBlockに記載されたデフォルトステータスをACTIVEからREGULARへ更新し、実装のCustomerStatus::REGULARと説明を一致させてください。

@nanasess nanasess left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part 1(deprecation ゲート)と、削除された public API のうち以下は src/app/・PHPUnit に呼び出し元が無いことを確認できました。妥当な削除です。

  • OrderItem::getTaxRuleId/setTaxRuleId / Product::isEnable / ProductClass::isEnable / Cart::getLock/setLock / transChoice() / TaxProcessor::getTaxDisplayType()(protected) / CartService::$cart / Order::getTotalPrice() / CacheUtil::clear()

一方で CustomerStatus::NONACTIVE / ACTIVE の削除は「呼び出し元皆無」ではありません。削除監査が src/ と PHPUnit のみを対象にしており、現行アクティブな Playwright E2E ハーネスを見落としています。修正が必要なため change request とします(詳細はインラインコメント参照)。

🔴 要修正: e2e/setup-fixtures.php が削除された定数を参照

  • e2e/setup-fixtures.php:50, 56, 140CustomerStatus::ACTIVE / NONACTIVE を使用。
  • このファイルは e2e/global-setup.ts:16php e2e/setup-fixtures.php として 全 E2E 実行前の globalSetup で必ず実行します(e2e-test.yml / e2e-test-throttling.yml)。

影響:

  • 定数削除後、line 50 で Error: Undefined constant Eccube\Entity\Master\CustomerStatus::ACTIVE が fatal になり、フィクスチャ生成が中断。
  • global-setup.ts の try/catch が例外を握り潰すため E2E setup は即死しませんが、line 50 以降のテスト会員・仮会員・商品・受注が生成されず、これらに依存する spec(例: front-throttling.spec.ts は globalSetup 生成のテスト用顧客に依存)が失敗します。

修正案(本 PR の Generator.php で既に適用済みの置換と同一):

-        $Status = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::ACTIVE);
+        $Status = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::REGULAR);
...
-    $nonActiveStatus = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::NONACTIVE);
+    $nonActiveStatus = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::PROVISIONAL);

ACTIVE=2=REGULARNONACTIVE=1=PROVISIONAL で同値です)

補足: codeception/acceptance/_bootstrap.php:158,160 も同定数を参照

CI 無効(coverage.yml if: false)のレガシーですが、削除後は壊れた dead reference として残ります。ついでに同置換するか、少なくとも本 PR の削除判定の対象外である旨を明記すると安全です。

補足: CI(PHPUnit / Playwright)が本 PR で未実行

本 PR は base 4.4CONFLICTING 状態のため、main.ymlpull_request トリガ)が一時マージコミットを生成できず起動していません。結果、max[direct]=0 ゲート・E2E ともに CI 上で未検証です。4.4 へ rebase してコンフリクト解消 → main.yml 起動 → 上記 E2E 修正込みで緑を確認する流れを推奨します。

@@ -28,20 +28,6 @@
#[ORM\Cache(usage: 'NONSTRICT_READ_WRITE')]
class CustomerStatus extends AbstractMasterEntity

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この定数削除(NONACTIVE/ACTIVE)は e2e/setup-fixtures.php:50,56,140 で参照されており、現行の Playwright E2E globalSetup(e2e/global-setup.ts:16 が実行)が Undefined constant で fatal になります。e2e/setup-fixtures.phpACTIVEREGULAR / NONACTIVEPROVISIONAL に修正してください(Generator.php と同一の置換)。レガシーの codeception/acceptance/_bootstrap.php:158,160 も同定数を参照しています。

ttokoro20240902 and others added 5 commits July 28, 2026 14:12
…on-gate

# Conflicts:
#	.github/workflows/coverage.yml
#	src/Eccube/Entity/Cart.php
#	src/Eccube/Entity/Master/CustomerStatus.php
#	src/Eccube/Entity/Order.php
#	src/Eccube/Entity/OrderItem.php
#	src/Eccube/Entity/Product.php
#	src/Eccube/Entity/ProductClass.php
#	src/Eccube/Util/CacheUtil.php
レビュー指摘対応。CustomerStatus::NONACTIVE/ACTIVE の削除監査が src/ と
PHPUnit のみを対象にしており、以下の現役 E2E ハーネスを見落としていた。

- e2e/setup-fixtures.php … Playwright の globalSetup (e2e/global-setup.ts) が
  全 E2E 実行前に必ず実行する。定数削除後は Undefined constant で
  フィクスチャ生成が中断し、テスト会員・商品・受注が生成されない。
- codeception/acceptance/_bootstrap.php … VAddy スキャン
  (.github/workflows/vaddy/scan/action.yml) が codecept run -g vaddy を
  実行し、@group vaddy の Cest が本ファイルの createCustomer() を使う。

いずれも同値の現行定数へ置換する (ACTIVE=2=REGULAR / NONACTIVE=1=PROVISIONAL)
ため挙動は変わらない。あわせて Generator::createCustomers() の DocBlock の
デフォルト値表記を実装 (REGULAR) と一致させる。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
deprecation ゲートを有効化する前提として、テスト実行時に発生していた
非推奨警告 11 件を解消する。いずれも挙動は変えない。

src (3 件・null の受け方):
- SafeTextmailEscaperExtension: Twig は null の変数もそのまま渡すため
  エスケーパの引数を ?string で受け、str_replace へ '' を渡す
- PluginService::deleteDirs: install()/update() は例外発生時点で未設定の
  null を渡す仕様のため、null をスキップし phpdoc を string|null に修正
- InvalidItemException: parent::__construct() へ null を渡さない

tests (7 件・動的プロパティ生成):
- MasterdataTypeTest::$form / LoginHistoryRepository…AdminTest の
  $Member1・$LoginHistory1-3 / MailControllerTest の $Member・$MailHistories
  を宣言する。EccubeTestCase::cleanUpProperties() が tearDown で全プロパティに
  null を代入するため、いずれも nullable で宣言する

vendor 由来 (1 件):
- HTML パートを持たないメールに対する assertEmailHtmlBodyNotContains() を
  assertNull($Message->getHtmlBody()) へ変更(MailServiceTest 3 箇所・
  WithdrawControllerTest 1 箇所)。元の書き方は symfony/mime 内で
  str_contains(null, …) の非推奨警告を出すうえ、HTML パートが存在しないため
  常に成立する空振りアサーションだった

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…換える (#6933)

当初 SYMFONY_DEPRECATIONS_HELPER を weak から max[direct]=0 に引き上げたが、
この設定は PHPUnit 11 環境では機能しないことが判明したため、PHPUnit 11 が
持つネイティブのゲートへ置き換える。

SYMFONY_DEPRECATIONS_HELPER が効かない理由:
- 値を読んで DeprecationErrorHandler を登録するのは symfony/phpunit-bridge の
  bootstrap.php だが、同ファイルは冒頭で
  `if (class_exists(PHPUnit\Metadata\Metadata::class)) { return; }` により
  PHPUnit 10 以上では早期 return する
- PHPUnit 10+ 用の SymfonyExtension は ClockMock / DnsMock のみを登録し、
  DeprecationErrorHandler は登録しない
- CI (unit-test.yml / coverage.yml) は vendor/bin/phpunit を実行するため、
  bridge 経由の simple-phpunit も通らない
- 実測: 非推奨警告を発生させるテストを vendor/bin/phpunit で実行しても
  bridge のサマリは出力されず、警告も集計されない

置き換え内容:
- SYMFONY_DEPRECATIONS_HELPER を削除(読まれない設定のため)
- failOnDeprecation="true" … 非推奨 API の呼び出しで CI を失敗させる
- displayDetailsOnTestsThatTriggerDeprecations="true" … 発生箇所を CI ログに出す

前提となる既存の非推奨警告 11 件は先行コミットで解消済みで、フルスイート
(2905 テスト) で Deprecations 0 を確認している。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- AGENTS.md / phpunit Skill: 「PHPUnit 11(symfony/phpunit-bridge 経由)」を
  「vendor/bin/phpunit を直接実行」に訂正し、bridge の
  SYMFONY_DEPRECATIONS_HELPER が PHPUnit 10 以上で無効である旨を明記
- AGENTS.md / phpunit Skill / contributing Skill: 実在しない `bin/phpunit` を
  `vendor/bin/phpunit` に訂正(bin/ には console と template_jp.php のみ)
- phpunit Skill「よくある間違い」に 3 項追記
  - 未宣言プロパティへの代入は failOnDeprecation で CI red になる
  - テストのプロパティは nullable 必須(cleanUpProperties が null を代入する)
  - HTML パートを持たないメールへの assertEmailHtmlBodyNotContains は空振り
- contributing Skill「よくある間違い」に 1 項追記
  - 非推奨 public API の削除監査は e2e/ と codeception/ も対象に含める

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ttokoro20240902

Copy link
Copy Markdown
Contributor Author

@nanasess レビューありがとうございます。指摘はすべて実コードで裏取りし対応しました。あわせて Part 1(deprecation ゲート)が実は無効だったことが判明したため、方式を差し替えています。

① 🔴 e2e/setup-fixtures.php の定数参照 — 修正しました

ご指摘のとおりで、削除監査の対象を src/ と PHPUnit に限っていたのが漏れの原因です。ご提案の置換をそのまま適用しました(ACTIVE=2=REGULAR / NONACTIVE=1=PROVISIONAL で同値、挙動不変)。

codeception/acceptance/_bootstrap.php — 「レガシーだから放置」ではなく修正しました

補足として挙げていただいた箇所ですが、確認したところ dead reference ではなく現役でした。

  • .github/workflows/vaddy/scan/action.ymlvendor/bin/codecept run -g vaddy acceptance を実行している
  • @group vaddy の Cest(EA04OrderCest / EA05CustomerCest / EF04CustomerCest 等)が _bootstrap.phpcreateCustomer() を使う

coverage.yml の Codeception ジョブが無効なだけで VAddy スキャン経路は生きているため、同じ置換を適用しました。

③ CI 未実行 — 4.4 を取り込んで解消しました

origin/4.4 をマージし、コンフリクト 8 ファイルを解消しました(CONFLICTINGMERGEABLEmain.yml 起動済み)。原因は 4.4 側の以下 2 件でした。

いずれも 4.4 側を採用してから削除対象メンバーを再削除する形で解消し、4.4 との src 差分が**削除のみ(追加行 0)**であることを確認しています。

④ 🔴 Part 1 が機能していませんでした(方式を差し替え)

CI で検証できる状態にしたうえでゲートの実効性を確認したところ、SYMFONY_DEPRECATIONS_HELPER は PHPUnit 11 では読まれないことが判明しました。つまり weakmax[direct]=0 の変更は no-op で、当初の PR 本文にあった「max[direct]=0 実適用で direct 発火 0 を確認」も実質的に何も検証していませんでした。失礼しました。

  • 値を読んで DeprecationErrorHandler を登録するのは symfony/phpunit-bridgebootstrap.php(composer の autoload.files で常時ロード)ですが、冒頭の if (class_exists(PHPUnit\Metadata\Metadata::class)) { return; }PHPUnit 10 以上では早期 return します
  • PHPUnit 10+ 用の SymfonyExtension は ClockMock / DnsMock のみ登録し、DeprecationErrorHandler は登録しません(参照元は bootstrap.phpbin/simple-phpunit.php だけ)
  • CI は vendor/bin/phpunit を実行するため simple-phpunit 経路も通りません(そもそも simple-phpunit は PHPUnit 9.6 を取得して fatal になります)
  • 実測: 非推奨警告を出す probe テストを vendor/bin/phpunit で実行しても bridge のサマリは出力されず、警告も集計されませんでした(SymfonyExtension を登録しても同じ)

差し替え後(phpunit.xml.dist: SYMFONY_DEPRECATIONS_HELPER を撤去し、PHPUnit 11 ネイティブの failOnDeprecation="true"displayDetailsOnTestsThatTriggerDeprecations="true" を設定しました。

その前提として既存の非推奨警告 11 件を解消しています(挙動不変)。内訳は src 3 件(null の受け方)/tests 7 件(動的プロパティ生成)/vendor 由来 1 件です。vendor 由来の 1 件は HTML パートを持たないメールへの assertEmailHtmlBodyNotContains() で、HTML パートが無いので常に成立する空振りアサーションでもあったため assertNull($Message->getHtmlBody()) に変更しました。

なお failOnDeprecation は Symfony の max[direct]=0 と対象範囲が異なります(PHP 言語レベルの非推奨も拾い、direct/indirect の区別はしない)。ゲートとしてはより広く、Symfony 追従の早期警告という目的は満たします。

⑤ CodeRabbit 指摘(coverage.ymlSYMFONY_DEPRECATIONS_HELPER)— 4.4 取り込みで解消

「無効化された Codeception ジョブに設定していて効かない」という指摘は事実でしたが、4.4 側でジョブ自体が削除済みだったためマージで当該 hunk が消滅しました。あわせて提案されていた「PHPUnit ジョブへ移す」は、上記④のとおり SYMFONY_DEPRECATIONS_HELPER 自体が機能しないため採用していません。

⑥ CodeRabbit 指摘(Generator.php の DocBlock)— 修正しました

createCustomers() の DocBlock のデフォルト値表記を実装(REGULAR)と一致させました。

⑦ CodeRabbit pre-merge(UPGRADE ノート / CHANGELOG)— 対応なし

リポジトリに UPGRADE.md / CHANGELOG.md が存在せず、先行の BC 破壊 PR も追加していないため本 PR では新設しません。削除した public API と移行先は PR 本文の互換性節に記載しています。

併せて訂正したドキュメント

④の調査過程で AGENTS.md と Skill の記述に誤りが見つかったため訂正しました。

  • 「PHPUnit 11(symfony/phpunit-bridge 経由)」→「vendor/bin/phpunit を直接実行」
  • 実在しない bin/phpunitvendor/bin/phpunitbin/ には consoletemplate_jp.php のみ)

自主確認した点

  • Order::getTotalPrice() の間接参照: Twig の total_price は全て OrderItem / CartItem 由来で Order.total_price の使用はなし。dtb_csv にも total_price / tax_rule_id の行がないため CSV 出力に影響しません
  • 現行 4.4 に対して削除対象 API の呼び出し元を再監査 → _bootstrap.php / setup-fixtures.php 以外の残存なし

ローカル QA(Docker)

  • PHPStan(level 6) / PHP-CS-Fixer / Rector すべてクリーン
  • フルスイート(2905 テスト)で Deprecations 0 / Errors 0(差し替え前は Deprecations 11)
  • 残る Failures 16 件は本 PR と無関係。13 件は dtb_login_history にローカル環境の残留 13 行があるための件数不一致、3 件はローカル環境依存で、削除 API への参照は該当テスト・SUT ともに 0 件です。CI(fresh DB)での結果を確認します

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
e2e/setup-fixtures.php (1)

20-26: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

boot_env() で読み込んだ APP_ENV$_SERVER / $_ENV から取得してください。

boot_env() は Symfony Dotenv のままでは putenv() を使用せず $_SERVER / $_ENV に値を書き込むため、.envAPP_ENVgetenv() だけで参照すると反映されず、Kernel が e2e で起動します。

-$appEnv = getenv('APP_ENV') ?: 'e2e';
+$appEnv = $_SERVER['APP_ENV']
+    ?? $_ENV['APP_ENV']
+    ?? (getenv('APP_ENV') ?: 'e2e');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/setup-fixtures.php` around lines 20 - 26, Update the APP_ENV assignment
after boot_env() to read from $_SERVER or $_ENV before falling back to 'e2e',
rather than relying only on getenv(). Preserve the existing fallback when
neither environment array contains APP_ENV.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@e2e/setup-fixtures.php`:
- Around line 20-26: Update the APP_ENV assignment after boot_env() to read from
$_SERVER or $_ENV before falling back to 'e2e', rather than relying only on
getenv(). Preserve the existing fallback when neither environment array contains
APP_ENV.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a4ff616f-8a1a-493c-a098-576332df8de3

📥 Commits

Reviewing files that changed from the base of the PR and between 1d13a23 and c93855a.

📒 Files selected for processing (16)
  • .claude/skills/contributing/SKILL.md
  • .claude/skills/phpunit/SKILL.md
  • AGENTS.md
  • codeception/acceptance/_bootstrap.php
  • e2e/setup-fixtures.php
  • phpunit.xml.dist
  • src/Eccube/Entity/Cart.php
  • src/Eccube/Entity/Master/CustomerStatus.php
  • src/Eccube/Entity/Order.php
  • src/Eccube/Entity/OrderItem.php
  • src/Eccube/Entity/Product.php
  • src/Eccube/Entity/ProductClass.php
  • src/Eccube/Service/PluginService.php
  • src/Eccube/Service/PurchaseFlow/InvalidItemException.php
  • src/Eccube/Twig/Extension/SafeTextmailEscaperExtension.php
  • src/Eccube/Util/CacheUtil.php
💤 Files with no reviewable changes (6)
  • src/Eccube/Entity/OrderItem.php
  • src/Eccube/Entity/Product.php
  • src/Eccube/Entity/ProductClass.php
  • src/Eccube/Entity/Order.php
  • src/Eccube/Util/CacheUtil.php
  • src/Eccube/Entity/Master/CustomerStatus.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Eccube/Entity/Cart.php

ttokoro20240902 and others added 2 commits July 28, 2026 15:14
ローカルで除外していたグループ (plugin-service / cache-clear) に
残っていた非推奨警告を解消する。

- PluginServiceTest::testCreateEntityAndTrait: ダミープラグインの Block
  エンティティに ORM 非マッピングの public $sample を宣言する。
  テストが $Block->sample = true と代入していたため PHP 8.2 の
  動的プロパティ生成 (deprecated) になっており、failOnDeprecation で
  CI が失敗していた(12 マトリクス全滅の唯一の原因)
- TemplateControllerTest::testChangeTemplateWithEnvOverride: doc-comment の
  @group cache-clear を #[Group(name: 'cache-clear')] 属性に統一する。
  同ファイルの他メソッドは既に属性を使っており取り残しだった。
  doc-comment メタデータは PHPUnit 12 で廃止予定

これによりスイート全体の Deprecations / PHPUnit Deprecations がいずれも
0 になった(cache-clear グループは 21 テストのまま変化なし)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CI で PHP 8.4 / 8.5 のジョブのみ失敗していた(8.2 / 8.3 は緑)。原因は
failOnDeprecation が PHP 8.4 / 8.5 で新たに非推奨となった呼び出しを検出した
ためで、うち 1 件は vendor 内で我々には修正できないものだった。

ゲート範囲を direct のみに限定 (phpunit.xml.dist):
PHPUnit 11 の <source> は Symfony の SYMFONY_DEPRECATIONS_HELPER と同じ
分類 (self / direct / indirect) を持つため、当初意図した max[direct]=0 と
同じ範囲になるよう設定する。
- ignoreSelfDeprecations="true"     … 自コードの @deprecated 予告 (trigger_error) は対象外
- ignoreIndirectDeprecations="true" … vendor 内部で発生し修正できないものは対象外
  (mobiledetect/mobiledetectlib の暗黙 nullable。PHP 8.4 で非推奨)

direct な非推奨呼び出しの解消(いずれも挙動不変):
- Order::getMergedProductOrderItems(): 未永続明細では ProductClass の ID が
  null になり、null を配列キー / オフセットに使っていた(PHP 8.5 で非推奨)。
  (string) にキャストする。null は '' として扱われるため挙動は同じ
- ProductController::index() / OrderController::index(): $searchData['sortkey']
  が null のとき COLUMNS[null] を参照していたため ?? '' で受ける
- PluginApiService: curl_close() は PHP 8.0 以降なにもせず 8.5 で非推奨に
  なったため呼び出しを削除する
- CsvExportServiceTest / SjisToUtf8EncodingFilterTest: fgetcsv() の $escape を
  現行の既定値 '\\' で明示する(PHP 8.4 で明示指定が必須)。とくに
  fgetcsvDoesntOccur5cProblem は SJIS 2 バイト目の 0x5c を escape 文字として
  誤認しないことの確認なので、既定値を変えずに明示することが重要

なお同ジョブのリトライ 2 回目で失敗する RateLimiterListenerTest 3 件は
1 回目が緑であり、レートリミッタの状態が試行間で残る既知の flaky で本変更とは無関係。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.27%. Comparing base (89dec55) to head (bd46b4e).

Additional details and impacted files
@@            Coverage Diff             @@
##              4.4    #6937      +/-   ##
==========================================
+ Coverage   77.25%   77.27%   +0.02%     
==========================================
  Files         547      547              
  Lines       27163    27122      -41     
==========================================
- Hits        20985    20959      -26     
+ Misses       6178     6163      -15     
Flag Coverage Δ
Unit 77.27% <100.00%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ttokoro20240902

Copy link
Copy Markdown
Contributor Author

CI が全 115 チェック成功しました(PHP 8.2 / 8.3 / 8.4 / 8.5 × pgsql / pgsql13 / mysql / sqlite3、Playwright E2E 含む)。前回コメント以降の追加対応を報告します。

CI 1 回目: PHPUnit 全 12 マトリクス失敗 → 原因は 1 件

本体スイート(2905 テスト)自体は Failures / Errors 0 で緑でした。ローカルで出ていた 16 件の Failures は dtb_login_history の残留行によるローカル環境要因だったと確定しています。

失敗の真因は、ローカルで除外していた plugin-service グループの 1 件だけでした。

Creation of dynamic property Plugin\dummyvoluptatum\Entity\Block::$sample is deprecated

PluginServiceTest::testCreateEntityAndTrait$Block->sample = true と代入していたためです。ダミープラグインの Block に ORM 非マッピングの public $sample を宣言して解消しました。

別途ご確認いただきたい点: このテストは Entity/BlockTrait.phpエンティティ本体と同じ内容を書き込んでいます($tar->addFromString('Entity/BlockTrait.php', $dummyEntity);)。$sample を宣言するトレイトではないため、$Block->sample = truefind($clazz, 1)->sample は同一インスタンスを読み直すだけで、テスト名が謳うトレイト適用の検証は成立していません。本 PR ではゲート通過に必要な最小修正に留めています。真のトレイト検証を入れるかは設計判断が必要なため、別 Issue が妥当と考えます。

あわせて、スイート唯一の残件だった PHPUnit Deprecations: 1 も解消しました。TemplateControllerTest::testChangeTemplateWithEnvOverride()@group cache-clear(doc-comment メタデータ、PHPUnit 12 で廃止予定)で、同ファイルの他メソッドは既に #[Group] 属性を使っており取り残しでした。cache-clear グループは 21 テストのまま変化していません。

CI 2 回目: PHP 8.4 / 8.5 のみ失敗 → ゲート範囲を direct に限定

8.2 / 8.3 は全て緑で、8.4 / 8.5 の 9 ジョブだけが落ちました。failOnDeprecationPHP 8.4 / 8.5 で新たに非推奨になった呼び出しを検出したためです(8.5/mysql で 12 件、8.4/pgsql13 で 6 件)。うち 1 件は vendor/mobiledetect/mobiledetectlib の暗黙 nullable 引数で、我々には修正できません

PHPUnit 11 の <source> が Symfony の SYMFONY_DEPRECATIONS_HELPER と同じ分類を持つことを実装で確認しました(IssueTrigger::isDirect() は「first-party/test コードが third-party/PHP の非推奨を呼ぶ」で Symfony の direct と同義。isIndirect() は vendor → vendor)。当初意図した max[direct]=0 と同じ範囲になるよう設定しました。

分類 扱い 理由
direct ゲート対象 修正すべきもの。Symfony 追従の早期警告として本来の目的
self(自コードの trigger_error による @deprecated 予告) 対象外 当初 max[self]=0 を併用しなかった判断と同じ
indirect(vendor 内部) 対象外 我々に修正できない

そのうえで direct な非推奨呼び出しを解消しました(いずれも挙動不変)。

箇所 内容
Order::getMergedProductOrderItems() 未永続明細では ProductClass の ID が null になり、null を配列キー / オフセットに使っていた(PHP 8.5 で非推奨)→ (string) キャスト。null は '' として扱われるため挙動は同じ
ProductController::index() / OrderController::index() $searchData['sortkey'] が null のとき COLUMNS[null] を参照 → ?? ''
PluginApiService curl_close() は PHP 8.0 以降なにもせず 8.5 で非推奨 → 呼び出しを削除
CsvExportServiceTest / SjisToUtf8EncodingFilterTest fgetcsv()$escape 5 箇所を現行既定値 '\\' で明示(PHP 8.4 で明示指定が必須)。とくに fgetcsvDoesntOccur5cProblem は SJIS 2 バイト目の 0x5c を escape 文字と誤認しないことの検証なので、既定値を変えずに明示することが重要でした

切り分けた flaky

リトライ 2 回目で落ちていた RateLimiterListenerTest::testOnController 3 件は、1 回目が緑でレートリミッタの状態が試行間に残る既知の flaky です。本変更とは無関係で、最新の実行では発生していません。

補足

  • ローカルは PHP 8.2 のため 8.4 / 8.5 固有の非推奨は再現せず、その解消は CI で検証しました
  • failOnPhpunitDeprecation は有効化していません(現時点 0 件ですが、マトリクス差で表面化するリスクを避けました)
  • PR 本文も上記の内容に更新済みです

@ttokoro20240902 ttokoro20240902 added this to the 4.4.0 milestone Jul 29, 2026

@nanasess nanasess left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

先の change request で指摘した e2e/setup-fixtures.php(および補足の codeception/acceptance/_bootstrap.php)の CustomerStatus::ACTIVE/NONACTIVE 参照が REGULAR/PROVISIONAL へ修正されたことを確認しました。

  • ゲートが PHPUnit 11 ネイティブの failOnDeprecation + ignoreSelfDeprecations/ignoreIndirectDeprecations に置き換わり、当初意図(direct のみで落とす)を標準機能で表現できています。
  • 追加された本体コードの非推奨解消(OrderController/ProductController?? curl_close() 削除、PluginService の null ガード、InvalidItemExceptionSafeTextmailEscaperExtension の null 対策)はいずれも最小・挙動不変。
  • コンフリクト解消により main.yml がフル実行され、PHPUnit・dockerbuild(8.2–8.5)・e2e-test 全 suite・e2e-test-throttling が全て pass。ゲートと E2E フィクスチャの両方が実 CI で裏取りされています。

LGTM 👍

*
* @deprecated 税率設定は受注作成時に決定するため廃止予定
*/
public function setTaxRuleId(?int $taxRuleId = null): OrderItem

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この関数は、クーポンプラグインで使用しているようです。
削除する場合は、先にプラグインの修正PRをお願いします。
https://github.com/EC-CUBE/coupon-plugin/blob/112ab3ebc461cf77e2d63af3f59f33273251d392/Service/PurchaseFlow/Processor/CouponProcessor.php#L298

@dotani1111

dotani1111 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

追加で見たところ、定期購入プラグインも影響があるかと思います。
4.4へ対応の際は修正が必要になります。

  • Service/PeriodicBatchHelper.php:176 — $Product->isEnable()(削除)
  • Service/PurchaseFlow/CreatePeriodicPurchaseProcessor.php:252 — core $OrderItem->getTaxRuleId()(削除)

…on-gate

# Conflicts:
#	tests/Eccube/Tests/Web/Admin/Store/TemplateControllerTest.php
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[4.4] deprecation ゲート有効化+非推奨 public API の削除

3 participants