LoginSignup
4
4

More than 3 years have passed since last update.

EC-CUBEのPurchaseFlowを極力自然にカスタマイズ

Last updated at Posted at 2020-09-07

PurchaseFlowをカスタマイズしたい。
でも競合はできるだけ避けたい。

結論

app/Customize/Common/Collections/DecorativeArrayCollection.php
<?php

namespace Customize\Common\Collections;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

class DecorativeArrayCollection extends ArrayCollection
{
    public function __construct($elements = [])
    {
        $elements = ($elements instanceof Collection)
            ? $elements->toArray()
            : $elements;

        parent::__construct($elements);
    }
}
app/config/eccube/packages/purchaseflow_customize.yaml
services:
    eccube.purchase.flow.shopping.item_validators_decorate:
        class: Customize\Common\Collections\DecorativeArrayCollection
        decorates: eccube.purchase.flow.shopping.item_validators
        arguments: ['@eccube.purchase.flow.shopping.item_validators_decorate.inner']
        calls:
            - [add, ['@Customize\Service\PurchaseFlow\Processor\CustomizeItemValidator']]

解説

本体ファイルの変更を避ける

  • 本体ファイル(app/config/eccube/packages/purchaseflow.yaml)を変更するのは簡単だが、本体アップデートの追従の手間が増える。別ファイル(今回はapp/config/eccube/packages/purchaseflow_customize.yaml)に記述する。
  • 読み込み順は恐らくファイル名の昇順であるため、ファイル名に気をつける。(なんならz_purchaseflow.yamlとかでもいい)

ServiceをDecorateする

  • Decorateの説明はこちら https://symfony.com/doc/3.4/service_container/service_decoration.html
  • 要は、元となるサービスをコンストラクタに渡して別のサービスに置き換える機能。
  • しかしDoctrineのCollectionのコンストラクタにはarrayしか渡せない。そのためCollectionを受け取れる独自のCollection(今回はDecorativeArrayCollection)が必要。
  • callsにて追加したい機能をaddする。

おしまい。

追記

ある程度任意の順番にProcessorを挿入したい

こんな感じでいいんじゃないですか。しらんけど。

app/Customize/Common/Collections/DecorativeArrayCollection.php
<?php

namespace Customize\Common\Collections;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Eccube\Service\PurchaseFlow\Processor\PriceChangeValidator;

class DecorativeArrayCollection extends ArrayCollection
{
    public function __construct($processor, $elements = [])
    {
        $elements = ($elements instanceof Collection)
            ? $elements->toArray()
            : $elements;

        /* 最初に挿入する
        array_unshift($elements, $processor);
        */

        /* 任意のクラスの後に挿入する
        $newElements = [];
        $inserted = false;
        foreach ($elements as $element) {
            $newElements[] = $element;
            if ($element instanceof PriceChangeValidator) {
                $newElements[] = $processor;
            }
        }

        if (!$inserted) {
            // 任意のクラスが存在しなかった場合の処理
        }
        */

        parent::__construct($elements);
    }
}
app/config/eccube/packages/purchaseflow_customize.yaml
services:
    eccube.purchase.flow.shopping.item_validators_decorate:
        class: Customize\Common\Collections\DecorativeArrayCollection
        decorates: eccube.purchase.flow.shopping.item_validators
        arguments:
            - '@Customize\Service\PurchaseFlow\Processor\CustomizeItemValidator'
            - '@eccube.purchase.flow.shopping.item_validators_decorate.inner'

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4