記述元参照ファイル
/src/Eccube/Service/OrderStateMachine.php
OrderStateMachine
クラスで、注文の状態(OrderStatus
)の変更に関するビジネスロジックが実装されています。
以下に、このコードの主な内容を解説します。
1. ステータス変更ルールが適用される箇所
1.1. apply
メソッド
phpコードをコピーするpublic function apply(Order $Order, OrderStatus $OrderStatus)
{
$context = $this->newContext($Order);
$transition = $this->getTransition($context, $OrderStatus);
if ($transition) {
$this->machine->apply($context, $transition->getName());
} else {
throw new \InvalidArgumentException();
}
}
- このメソッドは、指定された
OrderStatus
(注文ステータス)への遷移を試みるメインの処理です。 - ステータス変更が可能かどうかを判断するのは、
getTransition
メソッドです。- ルールの詳細:
getTransition
内で、現在のステータスから遷移可能な状態が存在するかをチェックします。
- ルールの詳細:
1.2. can
メソッド
phpコードをコピーするpublic function can(Order $Order, OrderStatus $OrderStatus)
{
return !is_null($this->getTransition($this->newContext($Order), $OrderStatus));
}
- このメソッドは、ステータス遷移が可能かどうかを事前に確認するための処理です。
getTransition
メソッドを利用して、現在の状態から遷移先が許可されているかどうかを判定します。
1.3. getTransition
メソッド
phpコードをコピーするprivate function getTransition(OrderStateMachineContext $context, OrderStatus $OrderStatus)
{
$transitions = $this->machine->getEnabledTransitions($context);
foreach ($transitions as $t) {
if (in_array($OrderStatus->getId(), $t->getTos())) {
return $t;
}
}
return null;
}
- ここでは、現在の状態(
OrderStateMachineContext
)から遷移可能な状態を取得します。 - 状態遷移を決定するロジック:
StateMachine::getEnabledTransitions
が、現在のステータスに基づいて利用可能な遷移(transition
)をリストアップします。- 指定された
OrderStatus
が、これらの遷移先($t->getTos()
)のいずれかに含まれている場合、その遷移を適用可能とします。
2. イベントによるステータス変更のトリガー
コードの下部では、イベントを介した注文ステータスの変更や関連処理が記述されています。
2.1 イベントハンドラーの登録
phpコードをコピーするpublic static function getSubscribedEvents()
{
return [
'workflow.order.completed' => ['onCompleted'],
'workflow.order.transition.pay' => ['updatePaymentDate'],
'workflow.order.transition.cancel' => [['rollbackStock'], ['rollbackUsePoint']],
'workflow.order.transition.back_to_in_progress' => [['commitStock'], ['commitUsePoint']],
'workflow.order.transition.ship' => [['commitAddPoint']],
'workflow.order.transition.return' => [['rollbackUsePoint'], ['rollbackAddPoint']],
'workflow.order.transition.cancel_return' => [['commitUsePoint'], ['commitAddPoint']],
];
}
workflow.order.completed
: ステータス遷移完了後の処理。workflow.order.transition.[遷移名]
: 特定の遷移(例: 支払い済み、キャンセル)に応じた処理をトリガー。- イベント名に対応するハンドラーで、例えば在庫調整やポイント処理などを行います。
2.2 状態遷移完了後の処理(例: onCompleted
)
phpコードをコピーするpublic function onCompleted(Event $event)
{
$context = $event->getSubject();
$Order = $context->getOrder();
$CompletedOrderStatus = $this->orderStatusRepository->find($context->getStatus());
$Order->setOrderStatus($CompletedOrderStatus);
}
- 遷移が完了した後に、注文エンティティの
OrderStatus
を更新する処理です。
3. 変更方法
このクラスには、EC-CUBEの標準的なステータス遷移ルールが含まれています。
もし遷移ルールを変更したい場合、以下のように対応できます。
3.1. 状態遷移ルールの確認
- 遷移ルールは
state_machine
の設定に基づいています。 app/config/eccube/packages/workflow.yaml
で定義されています。
3.2. ルール変更例
以下は、workflow.yaml
で遷移ルールを変更する例です。
yamlコードをコピーするframework:
workflows:
order:
type: 'state_machine'
initial_marking: 'new'
places:
- new
- paid
- shipped
- canceled
transitions:
pay:
from: new
to: paid
ship:
from: paid
to: shipped
cancel:
from: [new, paid]
to: canceled
- この設定では、
new
(新規)からpaid
(支払い済み)への遷移を許可しています。 - 必要に応じて
transitions
のfrom
やto
を編集して、独自のルールを作成します。
3.3. イベントでのカスタマイズ
- 特定の遷移時の処理をカスタマイズしたい場合、イベントハンドラーを拡張するか、独自のリスナーを追加します。
まとめ
- このコードには、注文ステータス変更のロジックと、関連するイベント処理が含まれています。
- ルールは主に
getTransition
メソッドやstate_machine
設定に基づいています。 - カスタマイズするには、
OrderStateMachine
クラスやworkflow.yaml
を編集し、新しい遷移ルールを定義するのが適切です。