EC-CUBE4系ではたった3ステップで管理画面の受注一覧へ検索項目を追加するプラグインを開発することが可能です。
※今回は比較的難易度が高い、「発送日の期間」を絞り込み条件に追加します。出荷日ではなく「発送日」という名称を使用していますが、必要に応じて適宜置き換えてください。(EC-CUBE4からは出荷日の呼称がメインになっています)

目標としては画像のようなイメージです。絞り込み条件追加をプラグインだけで実装していきます。
受注一覧に発送日絞り込み

下準備 – プラグインひな形作成

php bin/console eccube:plugin:generateコマンドによりプラグインのひな形を作成します。対話式でプラグインの設定を入力して実行します。

今回はCompanyというコードのプラグインを作成しますが、名前やコードは好きなものに読み替えてください。

EC-CUBE4プラグイン生成コマンド

動作検証にはプラグインをインストール・有効化ください

開発途中で動作確認するにはプラグインをインストール・有効化しておく必要があります。
次のコマンドを実行するとプラグインがインストール・有効化されます。
$ php bin/console eccube:plugin:install –code=Company
$ php bin/console eccube:plugin:enable –code=Company

頭文字だけとってe:p:iとe:p:eでも実行可能です。
検証環境での動作確認は.envの設定をAPP_ENV=dev、APP_DEBUG=1で実行することをおすすめします。(キャッシュの影響を減らすため)

EC-CUBE4プラグイン有効化コマンド

ステップ1. フォーム定義を作成(Form Extension)

既存のフォームを拡張するにはFormTypeExtensionの機構を利用します。(フックポイントで$builderに要素を追加する方法もあるので、ケースバイケースで最適な方法を使い分けます)

ここではSearchOrderTypeを拡張するためのExtensionを作成します。
AbstractTypeExtensionを継承したクラスを作成し、オーバーライドしたbuildFormメソッド内で$builderにshipping_date_start(発送日開始)とshipping_date_end(発送日終了)の要素を日付型で追加し拡張します。

新規作成:app/Plugin/Company/Form/Extension/SearchOrderTypeShippingDateExtension.phpファイルを作成

<?php

namespace Plugin\Company\Form\Extension;

use Eccube\Form\Type\Admin\SearchOrderType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\FormBuilderInterface;

/**
 * Class SearchOrderTypeShippingDateExtension
 * @FormExtension
 */
class SearchOrderTypeShippingDateExtension extends AbstractTypeExtension
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('shipping_date_start', DateType::class, array(
                'label' => '発送日(開始)',
                'required' => false,
                'input' => 'datetime',
                'widget' => 'single_text',
                'format' => 'yyyy-MM-dd',
                'placeholder' => ['year' => '----', 'month' => '--', 'day' => '--'],
                'attr' => [
                    'class' => 'datetimepicker-input',
                    'data-target' => '#admin_search_order_shipping_date_start',
                    'data-toggle' => 'datetimepicker',
                ],

            ))
            ->add('shipping_date_end', DateType::class, array(
                'label' => '発送日(終了)',
                'required' => false,
                'input' => 'datetime',
                'widget' => 'single_text',
                'format' => 'yyyy-MM-dd',
                'placeholder' => ['year' => '----', 'month' => '--', 'day' => '--'],
                'attr' => [
                    'class' => 'datetimepicker-input',
                    'data-target' => '#admin_search_order_shipping_date_start',
                    'data-toggle' => 'datetimepicker',
                ],

            ));
    }

    public function getExtendedType()
    {
        return SearchOrderType::class;
    }
}

作成したFormExtensionは存在するだけで本体のロジックに組み込まれます。ここまででフォームの定義に発送日の要素を追加できましたので、次のステップでは定義した項目を画面上に表示してやります。

ステップ2. テンプレートへフォームを挿しこみ (TemplateEvent::addSnippet)

まず差し込むためのフォームをtwigで出力します。差し込んだフォームはbodyタグを閉じる直前に出力されるので、jQueryを使って検索フォーム内へ移動します。
form_widget関数を利用して、定義したフォームを出力しています。

新規作成:app/Plugin/Company/Resource/template/admin/Order/index_js.twig

<script>
    $(function () {
        $('.searchDetail__append').appendTo($('#searchDetail'));
    })
</script>
<div class="row searchDetail__append">
    <div class="col">
        <label class="col-form-label">発送日</label>
        <div class="form-row align-items-center">
            <div class="col">
                {{ form_widget(searchForm.shipping_date_start) }}
                {{ form_errors(searchForm.shipping_date_start) }}
            </div>
            <div class="col-auto text-center">{{ 'admin.common.separator__range'|trans }}</div>
            <div class="col">
                {{ form_widget(searchForm.shipping_date_end) }}
                {{ form_errors(searchForm.shipping_date_end) }}
            </div>
        </div>
    </div>

    <div class="col">

    </div>
</div>

プラグインのEvent.phpを書き換え、今作成したフォームを受注一覧のテンプレートへ挿しこみます。
受注一覧のテンプレートファイルはadmin/Order/index.twigなので、’@admin/Order/index.twig’ というキーでイベントがコールされます。このイベントに対して追加したメソッドadminOrderIndexTwigをフックしてやります。

このメソッド内でTemplateEventのインスタンスに対してaddSnippetを実行し、上で作成したフォーム出力用テンプレートファイルを受注一覧画面へ挿入します。

プラグインのResource/templateディレクトリにはプラグインコードの名前空間が与えられますので、’@Company/admin/Order/index_js.twig’で呼び出すことができます。

編集: app/Plugin/Company/Event.php

<?php

namespace Plugin\Company;

use Eccube\Event\TemplateEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Class Event
 * @package Plugin\Company
 * @see https://umebius.com/eccube/v4-plugin-order_list_filter_shipping_date/
 */
class Event implements EventSubscriberInterface
{
    /**
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return [
            '@admin/Order/index.twig' => 'adminOrderIndexTwig'
        ];
    }

    public function adminOrderIndexTwig(TemplateEvent $event)
    {
        $event->addSnippet('@Company/admin/Order/index_js.twig');
    }
}

ステップ2までで画面上にフォームが表示されますが、絞り込みロジックはまだ実装していません。次のステップでは実際にフォームから送信した日付で受注情報を絞り込むクラスを作成します。

受注一覧に発送日フォーム表示

ステップ3. 絞り込みロジックを追加(QueryCustomizer)

受注マスタの絞り込みなのでgetQueryKeyにはQueryKey::ORDER_SEARCH_ADMINを指定します。
WhereClauseのgteとltメソッドで作ったインスタンスを配列形式で返却することにより、複数条件の絞り込みに対応させています。
新規作成:app/Plugin/Company/Repository/Query/AdminOrderShippingDateCustomizer.php

<?php


namespace Plugin\Company\Repository\Query;

use Eccube\Doctrine\Query\WhereClause;
use Eccube\Doctrine\Query\WhereCustomizer;
use Eccube\Repository\QueryKey;

class AdminOrderShippingDateCustomizer extends WhereCustomizer
{
    /**
     * 出荷日で絞り込み
     * @see https://umebius.com/eccube/v4-plugin-order_list_filter_shipping_date/
     * @param array $params
     * @param $queryKey
     *
     * @return WhereClause[]
     */
    protected function createStatements($params, $queryKey)
    {
        $rtn = [];
        if (!empty($params['shipping_date_start']) && $params['shipping_date_start']) {
            $rtn[] = WhereClause::gte('s.shipping_date', ':shipping_date_start', ['shipping_date_start' => $params['shipping_date_start']]);
        }

        if (!empty($params['shipping_date_end']) && $params['shipping_date_end']) {
            $shippingDateEnd = clone $params['shipping_date_end'];
            $shippingDateEnd = $shippingDateEnd->modify('+1 days');
            $rtn[] = WhereClause::lt('s.shipping_date', ':shipping_date_end', ['shipping_date_end' => $shippingDateEnd]);
        }

        return $rtn;
    }

    /**
     * カスタマイズ対象のキーを返します。
     *
     * @return string
     */
    public function getQueryKey()
    {
        return QueryKey::ORDER_SEARCH_ADMIN;
    }
}

ステップ3まで完了すると本体を何も修正しなくてもQueryCustomizer(WhereCustomizer)がロジックに組み込まれ、添付画像のように発送日で絞り込みができるようになっています。EC-CUBE4系では非常に簡潔に記述することができて素晴らしいです。

受注一覧に発送日絞り込み

EC-CUBEプラグイン開発まとめ

EC-CUBE4では仕組みを理解するとプラグインの開発が高速で実現可能です。ぜひプラグインを作って様々なカスタマイズを実現してみてください。


EC-CUBE4系プラグイン