Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
abd174c
improvement: 呼び出し元のない非推奨 public API を削除 (#6933)
ttokoro20240902 Jul 16, 2026
90b3361
improvement: テスト専用の非推奨 public API を削除しテストを整理 (#6933)
ttokoro20240902 Jul 16, 2026
1d13a23
improvement: deprecation ゲートを max[direct]=0 に強制化 (#6933)
ttokoro20240902 Jul 16, 2026
5f969c9
Merge remote-tracking branch 'origin/4.4' into feature/6933-deprecati…
ttokoro20240902 Jul 28, 2026
cb7b6a0
fix: E2E/VAddy のフィクスチャが削除した CustomerStatus 定数を参照する問題を修正 (#6933)
ttokoro20240902 Jul 28, 2026
d6f164a
fix: PHP 8.2 の非推奨警告 11 件を解消する (#6933)
ttokoro20240902 Jul 28, 2026
09c04eb
improvement: deprecation ゲートを PHPUnit 11 ネイティブの failOnDeprecation に置き…
ttokoro20240902 Jul 28, 2026
c93855a
docs: PHPUnit の実行系と非推奨検出の記述を実態に合わせる (#6933)
ttokoro20240902 Jul 28, 2026
42ae808
fix: CI で残っていた非推奨警告 2 件を解消する (#6933)
ttokoro20240902 Jul 28, 2026
bd46b4e
fix: PHP 8.4 / 8.5 固有の非推奨呼び出しを解消しゲート範囲を direct に限定する (#6933)
ttokoro20240902 Jul 28, 2026
9a61ea2
Merge remote-tracking branch 'origin/4.4' into feature/6933-deprecati…
ttokoro20240902 Jul 31, 2026
b5935a4
Merge branch '4.4' into feature/6933-deprecation-gate
ttokoro20240902 Aug 3, 2026
f9b91fb
fix: fputcsv/str_getcsv に $escape を明示して PHP 8.4 の非推奨を解消
ttokoro20240902 Aug 3, 2026
3ee103e
fix(e2e): setup-fixtures の CustomerStatus::ACTIVE 置換漏れを修正
ttokoro20240902 Aug 3, 2026
df658f2
improvement(e2e): フィクスチャ生成の失敗理由をログに残す
ttokoro20240902 Aug 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .claude/skills/eccube-contributing/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ PR では以下が GitHub Actions で走る。**同じものを手元で先に
| コードスタイル(`php-cs-fixer.yml`) | `php vendor/bin/php-cs-fixer fix --diff --dry-run --allow-risky=yes` | `vendor/bin/php-cs-fixer fix`(自動修正) |
| 静的解析(`phpstan.yml`) | `vendor/bin/phpstan analyze src/ --error-format=github` | `vendor/bin/phpstan analyse src`(level 6) |
| リファクタ規約(`rector.yml`) | `vendor/bin/rector process --dry-run --ansi --config=rector.php` | `vendor/bin/rector process`(差分適用) |
| ユニットテスト(`unit-test.yml`) | `vendor/bin/phpunit`(一部グループは分割実行) | 変更に関係するテストを `bin/phpunit <path>` |
| ユニットテスト(`unit-test.yml`) | `vendor/bin/phpunit`(一部グループは分割実行) | 変更に関係するテストを `vendor/bin/phpunit <path>` |

- このほか **E2E(`e2e-test.yml`)・プラグインテスト(`plugin-test.yml`)・セキュリティスキャン(zaproxy/vaddy)** が走る。重いので CI に任せてよいが、落ちたら該当ジョブのログを読む。
- **rector は関門になりやすい**(PHP/Symfony/Doctrine の機械的な現代化を強制)。`--dry-run` で出た差分は基本そのまま適用する。
Expand All @@ -65,6 +65,7 @@ PR では以下が GitHub Actions で走る。**同じものを手元で先に
- ❌ 機能追加なのにテスト無し / 既存テストを壊す → ✅ テストを伴わせ、関連テストを実行
- ❌ マイナー互換を壊す変更(既存シグネチャ・フック・CSV 仕様の変更)を含める → ✅ 互換チェックリストを確認し、壊す場合は別途相談
- ❌ PR テンプレートの節を空のまま提出 → ✅ 概要・方針・テスト範囲・互換性チェックを埋める
- ❌ `@deprecated` な public API・定数の削除を `src/` と PHPUnit の grep だけで「呼び出し元なし」と判定 → ✅ `e2e/`(Playwright の globalSetup が実行する `setup-fixtures.php`)と `codeception/`(VAddy スキャンが `codecept -g vaddy` を実行)も走査対象に含め、全ツリー `git grep` で 0 件を確認する

## 実行・確認方法

Expand All @@ -75,7 +76,7 @@ PR では以下が GitHub Actions で走る。**同じものを手元で先に
vendor/bin/php-cs-fixer fix --dry-run --diff
vendor/bin/phpstan analyse src
vendor/bin/rector process --dry-run --config=rector.php
bin/phpunit <変更に関係するテスト>
vendor/bin/phpunit <変更に関係するテスト>
```

- CI が落ちたら、まず該当ジョブのログで「どのゲート・どのファイル・どのルール」かを特定し、ローカルで同じコマンドを再現して直す。
Expand Down
11 changes: 7 additions & 4 deletions .claude/skills/eccube-phpunit/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: EC-CUBE 4.4 の PHPUnit テストを実装・修正するときの
# PHPUnit テスト規約(EC-CUBE 4.4)

**対象**: `tests/Eccube/Tests/**/*Test.php`
**前提**: PHPUnit 11(`symfony/phpunit-bridge` 経由)/ PHP 8.2+ / Symfony 7.4
**前提**: PHPUnit 11(`vendor/bin/phpunit` を直接実行)/ PHP 8.2+ / Symfony 7.4

## 基本ルール

Expand Down Expand Up @@ -113,16 +113,19 @@ public static function provideStatuses(): array
- ❌ 回帰テストを追加して、修正を外すと落ちることを確認せずに完了とする → ✅ 修正を 1 つずつ外してどのテストが落ちるか実測する(落ちないテストはゲートにならない)。
- ❌ PHP Warning が出ることを回帰の証拠にする → ✅ `phpunit.xml.dist` に `failOnWarning` が無いため Warning では落ちない。戻り値を assert で直接検証する。
- ❌ 型宣言の省略 → ✅ 引数・戻り値に型を付け、PHPStan level 6 を通す。
- ❌ `setUp()` で未宣言のプロパティに代入(`$this->Member = ...`)→ ✅ プロパティを必ず宣言する。PHP 8.2 の動的プロパティ deprecation が `failOnDeprecation`(`phpunit.xml.dist`)で CI red になる。
- ❌ テストのプロパティを非 nullable で宣言(`protected array $Items = [];`)→ ✅ `protected ?array $Items = null;` と nullable にする。`EccubeTestCase::cleanUpProperties()` が tearDown で全プロパティに `null` を代入するため、非 nullable だと `TypeError` で全テストが落ちる(初期値が必要なら `setUp()` で代入する)。
- ❌ HTML パートを持たないメールに `assertEmailHtmlBodyNotContains()` → ✅ `assertNull($Message->getHtmlBody())`。前者は `str_contains(null, …)` の deprecation を出し、かつ「HTML パートが無いので必ず通る」空振りアサーションになる。

## 実行方法

```bash
# 全テスト
bin/phpunit
vendor/bin/phpunit

# 単一ファイル
bin/phpunit tests/Eccube/Tests/Web/ProductControllerTest.php
vendor/bin/phpunit tests/Eccube/Tests/Web/ProductControllerTest.php

# フィルタ
bin/phpunit --filter testRouting
vendor/bin/phpunit --filter testRouting
```
9 changes: 5 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ EC-CUBE は日本で広く使われる OSS の EC プラットフォームです
- **テンプレート**: Twig 3.x
- **データベース**: PostgreSQL 13–18 または MySQL 8.4 LTS
- **フロントエンド**: Sass (SCSS) / webpack / Bootstrap 5.3 / jQuery 4.x
- **テスト**: PHPUnit 11(`symfony/phpunit-bridge` 経由)/ Playwright(E2E、`e2e/`)
- **テスト**: PHPUnit 11(`vendor/bin/phpunit` を直接実行)/ Playwright(E2E、`e2e/`)
- ※ `symfony/phpunit-bridge` は依存にあるが、その `DeprecationErrorHandler`(`SYMFONY_DEPRECATIONS_HELPER`)は **PHPUnit 10 以上では無効**(bridge の `bootstrap.php` が早期 return する)。非推奨の検出は PHPUnit 11 ネイティブの `failOnDeprecation` で行う(`phpunit.xml.dist`)。
- ※ `codeception/` は残置(レガシー)。CI の Codeception ジョブは無効化(`if: false`)されており、E2E は Playwright が正。
- **静的解析**: PHPStan(`phpstan.neon.dist` で level 6)
- **コードスタイル**: PHP-CS-Fixer(PSR-12)
Expand Down Expand Up @@ -108,9 +109,9 @@ bin/console eccube:install
### テスト

```bash
bin/phpunit # 全テスト
bin/phpunit tests/Eccube/Tests/Web/ShoppingControllerTest.php # 単一ファイル
bin/phpunit --filter testCompleteWithLogin # フィルタ
vendor/bin/phpunit # 全テスト
vendor/bin/phpunit tests/Eccube/Tests/Web/ShoppingControllerTest.php # 単一ファイル
vendor/bin/phpunit --filter testCompleteWithLogin # フィルタ
```

E2E(Playwright、`e2e/` 配下で実行):
Expand Down
4 changes: 2 additions & 2 deletions codeception/acceptance/_bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ function createCustomer($container, $email = null, $active = true)

$Customer = $generator->createCustomer($email);
if ($active) {
$Status = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::ACTIVE);
$Status = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::REGULAR);
} else {
$Status = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::NONACTIVE);
$Status = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::PROVISIONAL);
}
$Customer->setStatus($Status);
$entityManager->flush($Customer);
Expand Down
6 changes: 5 additions & 1 deletion e2e/global-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ export default function globalSetup() {
);
console.log(output.toString());
} catch (error: any) {
console.error('Fixture setup failed:', error.stderr?.toString() || error.message);
// PHP CLI は Fatal error を stdout に書くため、stderr だけだと失敗理由が一切残らない
const detail = [error.stdout?.toString(), error.stderr?.toString()]
.filter((s?: string) => s && s.trim() !== '')
.join('\n');
console.error('Fixture setup failed:', detail || error.message);
// フィクスチャ失敗はテスト実行を止めない(基本データは eccube:fixtures:load で入っている)
console.warn('Continuing without additional fixtures...');
}
Expand Down
8 changes: 4 additions & 4 deletions e2e/setup-fixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@
for ($i = 0; $i < $needed; $i++) {
$email = microtime(true).'.'.$faker->safeEmail;
$Customer = $generator->createCustomer($email);
$Status = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::ACTIVE);
$Status = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::REGULAR);
$Customer->setStatus($Status);
$entityManager->flush($Customer);
}
// 仮会員も1名作成
$nonActiveCustomer = $generator->createCustomer(microtime(true).'.'.$faker->safeEmail);
$nonActiveStatus = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::NONACTIVE);
$nonActiveStatus = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::PROVISIONAL);
$nonActiveCustomer->setStatus($nonActiveStatus);
$entityManager->flush($nonActiveCustomer);
echo " Created ".($needed + 1)." customers\n";
Expand Down Expand Up @@ -140,7 +140,7 @@
$existing = $entityManager->getRepository(Customer::class)->findOneBy(['email' => $testEmail]);
if (!$existing) {
$testCustomer = $generator->createCustomer($testEmail);
$Status = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::ACTIVE);
$Status = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::REGULAR);
$testCustomer->setStatus($Status);
$entityManager->flush($testCustomer);
echo " Created test customer: $testEmail\n";
Expand Down Expand Up @@ -220,7 +220,7 @@
$refundCustomer = $entityManager->getRepository(Customer::class)->findOneBy(['email' => $refundTestEmail]);
if (!$refundCustomer) {
$refundCustomer = $generator->createCustomer($refundTestEmail);
$Status = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::ACTIVE);
$Status = $entityManager->getRepository(CustomerStatus::class)->find(CustomerStatus::REGULAR);
$refundCustomer->setStatus($Status);
$entityManager->flush($refundCustomer);
echo " Created refund test customer: $refundTestEmail\n";
Expand Down
13 changes: 11 additions & 2 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
backupGlobals="false"
colors="true"
bootstrap="tests/bootstrap.php"
failOnDeprecation="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
>
<php>
<ini name="memory_limit" value="-1" />
<ini name="display_errors" value="1" />
<ini name="error_reporting" value="-1" />
<server name="KERNEL_CLASS" value="Eccube\Kernel" />
<server name="SYMFONY_DEPRECATIONS_HELPER" value="weak" />
<server name="APP_ENV" value="test" force="true" />
<server name="SHELL_VERBOSITY" value="-1" />
</php>
Expand All @@ -23,7 +24,15 @@
</testsuite>
</testsuites>

<source>
<!--
failOnDeprecation と組み合わせ、Symfony の SYMFONY_DEPRECATIONS_HELPER=max[direct]=0 と
同じ範囲だけを CI ゲートにする。
- direct (自コードが PHP/vendor の非推奨 API を呼ぶ) … ゲート対象。修正すべきもの
- self (自コードが自ら trigger_error する @deprecated 予告) … 対象外
- indirect (vendor 内部で発生し我々が修正できないもの) … 対象外
-->
<source ignoreSelfDeprecations="true"
ignoreIndirectDeprecations="true">
<include>
<directory suffix=".php">src</directory>
</include>
Expand Down
3 changes: 2 additions & 1 deletion src/Eccube/Controller/Admin/Order/OrderController.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ public function index(Request $request, ?int $page_no = null): array

$qb = $this->orderRepository->getQueryBuilderBySearchDataForAdmin($searchData);

$sortKey = $searchData['sortkey'];
// null を配列オフセットに使うのは PHP 8.5 で非推奨。null は '' として扱われるため挙動は変わらない
$sortKey = $searchData['sortkey'] ?? '';
$paginate_options = ['wrap-queries' => true];
if (empty($this->orderRepository::COLUMNS[$sortKey]) || $sortKey == 'order_status') {
$paginate_options = [];
Expand Down
5 changes: 3 additions & 2 deletions src/Eccube/Controller/Admin/Order/RefundRequestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,8 @@ public function export(Request $request): StreamedResponse
trans('admin.order.refund_request.create_date'),
trans('admin.order.refund_request.update_date'),
];
fputcsv($out, $header);
// PHP 8.4 で $escape 省略が非推奨. 既存の出力を変えないようコア既定('\\')を明示する
fputcsv($out, $header, escape: '\\');

$sanitize = static function (mixed $value): string {
$value = (string) ($value ?? '');
Expand All @@ -257,7 +258,7 @@ public function export(Request $request): StreamedResponse
$sanitize($RefundRequest->getCreateDate()?->format('Y-m-d H:i:s')),
$sanitize($RefundRequest->getUpdateDate()?->format('Y-m-d H:i:s')),
];
fputcsv($out, $row);
fputcsv($out, $row, escape: '\\');
$this->entityManager->detach($RefundRequest);
}

Expand Down
3 changes: 2 additions & 1 deletion src/Eccube/Controller/Admin/Product/ProductController.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ public function index(Request $request, $page_no = null): array

$qb = $this->productRepository->getQueryBuilderBySearchDataForAdmin($searchData);

$sortKey = $searchData['sortkey'];
// null を配列オフセットに使うのは PHP 8.5 で非推奨。null は '' として扱われるため挙動は変わらない
$sortKey = $searchData['sortkey'] ?? '';
$paginate_options = ['wrap-queries' => true];
if (empty($this->productRepository::COLUMNS[$sortKey]) || $sortKey == 'code' || $sortKey == 'status') {
$paginate_options = [];
Expand Down
20 changes: 0 additions & 20 deletions src/Eccube/Entity/Cart.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ class Cart extends AbstractEntity implements PurchaseInterface, ItemHolderInterf
#[ORM\JoinColumn(name: 'customer_id', referencedColumnName: 'id')]
private ?Customer $Customer = null;

private bool $lock = false;

/**
* @var Collection<int, CartItem>
*/
Expand Down Expand Up @@ -140,24 +138,6 @@ public function setAgentOwned(bool $agentOwned): Cart
return $this;
}

/**
* @deprecated 使用しないので削除予定
*/
public function getLock(): bool
{
return $this->lock;
}

/**
* @deprecated 使用しないので削除予定
*/
public function setLock(bool $lock): Cart
{
$this->lock = $lock;

return $this;
}

public function getPreOrderId(): ?string
{
return $this->pre_order_id;
Expand Down
14 changes: 0 additions & 14 deletions src/Eccube/Entity/Master/CustomerStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,6 @@
#[ORM\Cache(usage: 'NONSTRICT_READ_WRITE')]
class CustomerStatus extends AbstractMasterEntity
{
/**
* 仮会員.
*
* @deprecated
*/
public const NONACTIVE = 1;

/**
* 本会員.
*
* @deprecated
*/
public const ACTIVE = 2;

/**
* 仮会員.
*/
Expand Down
16 changes: 3 additions & 13 deletions src/Eccube/Entity/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,9 @@ public function getMergedProductOrderItems(): array
$orderItemArray = [];
/** @var OrderItem $ProductOrderItem */
foreach ($ProductOrderItems as $ProductOrderItem) {
$productClassId = $ProductOrderItem->getProductClass()->getId();
// 未永続の明細では ID が null になるため、配列キーとして使えるよう文字列化する
// (null をキーに使うのは PHP 8.5 で非推奨。null は '' として扱われるため挙動は変わらない)
$productClassId = (string) $ProductOrderItem->getProductClass()->getId();
if (array_key_exists($productClassId, $orderItemArray)) {
// 同じ規格の商品がある場合は個数をまとめる
$OrderItem = $orderItemArray[$productClassId];
Expand All @@ -343,18 +345,6 @@ public function getMergedProductOrderItems(): array
return array_values($orderItemArray);
}

/**
* 合計金額を計算
*
* @deprecated
*/
public function getTotalPrice(): string
{
@trigger_error('The '.__METHOD__.' method is deprecated.', E_USER_DEPRECATED);

return $this->getPaymentTotal();
}

#[ORM\Column(name: 'id', type: Types::INTEGER, options: ['unsigned' => true])]
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'IDENTITY')]
Expand Down
22 changes: 0 additions & 22 deletions src/Eccube/Entity/OrderItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -420,28 +420,6 @@ public function getTaxAdjust(): string
return $this->tax_adjust;
}

/**
* Set taxRuleId.
*
* @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

{
$this->tax_rule_id = $taxRuleId;

return $this;
}

/**
* Get taxRuleId.
*
* @deprecated 税率設定は受注作成時に決定するため廃止予定
*/
public function getTaxRuleId(): ?int
{
return $this->tax_rule_id;
}

/**
* Get currencyCode.
*/
Expand Down
10 changes: 0 additions & 10 deletions src/Eccube/Entity/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,16 +149,6 @@ public function _calc(): void
}
}

/**
* Is Enable
*
* @deprecated
*/
public function isEnable(): bool
{
return $this->getStatus()->getId() === ProductStatus::DISPLAY_SHOW ? true : false;
}

/**
* Get ClassName1
*/
Expand Down
10 changes: 0 additions & 10 deletions src/Eccube/Entity/ProductClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,6 @@ public function formattedProductName(): string
return $productName;
}

/**
* Is Enable
*
* @deprecated
*/
public function isEnable(): bool
{
return $this->getProduct()->isEnable();
}

/**
* Set price01 IncTax
*/
Expand Down
11 changes: 0 additions & 11 deletions src/Eccube/Resource/functions/trans.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,3 @@ function trans(string|int $id, array $parameters = [], ?string $domain = null, ?

return $Translator->trans($id, $parameters, $domain, $locale);
}

/**
* @param mixed $number - 不要引数
* @param array<mixed> $parameters
*
* @deprecated transを使用してください。
*/
function transChoice(string|int $id, mixed $number, array $parameters = [], ?string $domain = null, ?string $locale = null): string
{
return trans($id, $parameters, $domain, $locale);
}
6 changes: 0 additions & 6 deletions src/Eccube/Service/CartService.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
use Eccube\Entity\Cart;
use Eccube\Entity\CartItem;
use Eccube\Entity\Customer;
use Eccube\Entity\ItemHolderInterface;
use Eccube\Entity\ProductClass;
use Eccube\Repository\CartRepository;
use Eccube\Repository\OrderRepository;
Expand All @@ -39,11 +38,6 @@ class CartService
*/
protected ?array $carts = null;

/**
* @deprecated
*/
protected ItemHolderInterface $cart;

/**
* CartService constructor.
*/
Expand Down
Loading
Loading