【EC-CUBE 4】管理画面 / 商品管理のカスタマイズ(2) ~ データ追加 ~

前回、管理画面の商品登録に新メニュー【メーカー管理】を追加しました。
今回は、メーカー管理メニューから実際にメーカーを新規追加・保存できるようにする方法を紹介します。

カスタマイズ(前回)
EC-CUBEの管理画面の商品管理に新メニューを登録した状態の画面
メニューの追加まで実装
カスタマイズ(今回)
メーカー管理メニューの新規登録画面
「dtb_maker」に保存されているメーカーを一覧表示。
また、新しいメーカーを追加するためのフォームを設置。
メーカー管理メニューの保存完了画面
フォームを入力して「新規作成」をクリックすると、新しいメーカーが登録されて一覧も更新される。
カスタマイズ(次回)
編集ボタンと削除ボタンを実装したときの画面
一覧の右端に編集ボタンと削除ボタンを設置。
編集ボタンをクリックしたときの画面
編集をクリックすると、メーカー名とコードを変更するフォームが表示される。
削除ボタンをクリックしたときの画面
削除をクリックすると、削除のためのモーダルウィンドウが表示される。

【動作環境】
EC CUBEのバージョン:4.2.1
サーバー:Xserver

開発前にデバッグモードの設定をお薦めします

デバッグモードを設定しておくと、エラーが起きたときに詳細情報が表示されるようになります。
エラー箇所を探しやすくなるので、開発前に設定しておくのをオススメします。
デバッグモードの設定方法については 以下記事 で解説しています。

カスタマイズ後は、デバッグモードの解除を忘れないように。

目次

カスタマイズの流れ

  • Repositoryの作成(保存&メーカー一覧作成)
  • FormTypeの作成(保存のための登録フォーム作成)
  • Controllerの修正(RepositoryとFormTypeを利用)
  • Twigテンプレートの修正(登録フォームとメーカー一覧を作成)
STEP

Repositoryを用意する

新規メーカーを保存するため、MakerRepositoryを作成してsave()メソッドを定義します。
作成したファイルは「app/Customize/Repository」にアップします。

<?php

namespace Customize\Repository;

use Doctrine\Persistence\ManagerRegistry as RegistryInterface;
use Customize\Entity\Maker;
use Eccube\Repository\AbstractRepository;

/**
 * MakerRepository
 */
class MakerRepository extends AbstractRepository
{
    /**
     * MakerRepository constructor.
     *
     * @param RegistryInterface $registry
     */
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Maker::class);
    }

     /**
     * メーカーを保存する.
     *
     * @param Maker $maker
     */
    public function save($maker)
    {
        $em = $this->getEntityManager();
        $em->persist($maker);
        $em->flush();
    }
}
STEP

FormTypeを用意する

次に、メーカーを新規登録するためのフォームを用意します。
以下のMakerTypeを作成し、「app/Customize/Form/Type/Admin」にアップします。

<?php

namespace Customize\Form\Type\Admin;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints as Assert;
use Customize\Entity\Maker;

class MakerType extends AbstractType
{
      public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class, [
                'constraints' => [
                    new Assert\NotBlank(),
                ],
                ])
                ->add('code', TextType::class, [
                  'required' => false,
                  'constraints' => [
                      new Assert\NotBlank(),
                  ],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Maker::class,
        ]);
    }

    public function getBlockPrefix()
    {
        return 'admin_maker';
    }
}
STEP

Controllerを修正する

続いて、前回作成したMakerControllerを修正します。

  • STEP 1で作成したMakerRepostioryを使ってメーカー一覧を取得し、save()メソッドで保存機能を実装します。
  • STEP 2で作成したMakerTypeを使い、メーカー名とメーカーコードを入力するフォームを取得します。

修正したファイルは「app/Customize/Controller/Admin/Product」にアップします。

<?php

namespace Customize\Controller\Admin\Product;

use Eccube\Controller\AbstractController;
use Customize\Entity\Maker;
use Customize\Form\Type\Admin\MakerType;
use Customize\Repository\MakerRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;

class MakerController extends AbstractController
{
    /**
     * @var MakerRepository
     */
    protected $makerRepository;

    /**
     * MakerController constructor.
     *
     * @param MakerRepository $makerRepository
     */
    public function __construct(MakerRepository $makerRepository)
    {
        $this->makerRepository = $makerRepository;
    }

    /**
     * @Route("/%eccube_admin_route%/product/maker", name="admin_product_maker")
     * @Template("@admin/Product/maker.twig")
     */
    public function index(Request $request)
    {
        $makers = $this->makerRepository->findAll();

        $newMaker = new Maker();

        $builder = $this->formFactory
            ->createBuilder(MakerType::class, $newMaker);

        $form = $builder->getForm();

        if ($request->getMethod() === 'POST') {
            $form->handleRequest($request);
            if ($form->isSubmitted() && $form->isValid()) {
                $this->makerRepository->save($newMaker);
                $this->addSuccess('admin.common.save_complete', 'admin');
                return $this->redirectToRoute('admin_product_maker');
            }
        }

        return [
            'form' => $form->createView(),
            'makers' => $makers,
            'newMaker' => $newMaker,
        ];
    }
}
STEP

Twigテンプレートを修正する

最後にTwigテンプレートを修正します。

0から作るのは大変なので、今回はデフォルトで用意されている「規格管理」のTwigテンプレート(class_name.twig)を複製して作成しました。
元のテンプレートは「src/Eccube/Resource/template/admin/Product」

{#
This file is part of EC-CUBE

Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.

http://www.ec-cube.co.jp/

For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% extends '@admin/default_frame.twig' %}

{% set menus = ['product', 'maker'] %}

{% block title %}{{ 'admin.product.maker_management'|trans }}{% endblock %}
{% block sub_title %}{{ 'admin.product.product_management'|trans }}{% endblock %}

{% form_theme form '@admin/Form/bootstrap_4_horizontal_layout.html.twig' %}
{% block stylesheet %}
    <style type="text/css">
        .list-group-item:hover {
            z-index: inherit;
        }
    </style>
{% endblock stylesheet %}

{% block javascript %}
{% endblock %}

{% block main %}
    <div class="c-contentsArea__cols">
        <div class="c-contentsArea__primaryCol">
            <div class="c-primaryCol">
                <div class="card rounded border-0 mb-4">
                    <div class="card-body p-0">
                        <div class="card rounded border-0">
                            <ul class="list-group list-group-flush sortable-container">
                                <li class="list-group-item">
                                    <form role="form" class="row" name="form1" id="form1" method="post" action="{{ url('admin_product_maker') }}">
                                        <div class="col-auto align-self-center"><span>{{ 'admin.product.maker.name'|trans }}</span></div>
                                        <div class="col-3 me-2">
                                            {{ form_widget(form._token) }}
                                            {{ form_widget(form.name) }}
                                            {{ form_errors(form.name) }}
                                        </div>
                                        <div class="col-auto align-self-center" data-bs-toggle="tooltip" data-bs-placement="top" title="{{ 'tooltip.product.backend_name'|trans }}">
                                            <span>{{ 'admin.product.maker.code'|trans }}</span>
                                        </div>
                                        <div class="col-3">
                                            {{ form_widget(form.code) }}
                                            {{ form_errors(form.code) }}
                                        </div>
                                        <div class="col-auto">
                                            <button class="btn btn-ec-regular" type="submit">{{ 'admin.common.create__new'|trans }}</button>
                                        </div>
                                    </form>
                                </li>
                                <li class="list-group-item">
                                    <div class="row">
                                        <div class="col-auto"><strong> </strong></div>
                                        <div class="col-auto"><strong>{{ 'admin.common.id'|trans }}</strong></div>
                                        <div class="col-1"><strong>{{ 'admin.product.maker_management'|trans }}</strong></div>
                                    </div>
                                </li>
                                {% for maker in makers %}
                                    <li id="ex-class_name-{{ maker.id }}" class="list-group-item sortable-item" data-class-name-id="{{ maker.id }}">
                                        <div class="row justify-content-around mode-view">
                                            <div class="col-auto d-flex align-items-center"><i class="fa fa-bars text-ec-gray"></i></div>
                                            <div class="col-auto d-flex align-items-center">{{ maker.id }}</div>
                                            <div class="col d-flex align-items-center">{{ maker.name }}</div>
                                        </div>
                                    </li>
                                {% endfor %}
                            </ul>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

admin.product.maker.nameadmin.product.maker.codeは、前回作成した「messages.ja.yaml」で定義しています。

STEP

キャッシュを削除

ここまでで準備完了です。
管理画面からキャッシュを削除して、商品管理メニューのメーカー管理を確認しましょう。

キャッシュの削除方法
管理画面のキャッシュ管理からキャッシュを削除できます。

【メーカー管理】が以下のような表示になり、実際にメーカーの追加ができるようになっています。

メーカー管理メニューの新規登録画面
【メーカー管理】メニューを開くと、フォームとメーカー一覧が表示される。
メーカー管理メニューの保存完了画面
フォームに値を入力して「新規作成」をクリックすると、新しいメーカーが保存されて一覧が更新される。

まとめ&次のステップ

以上、新メニューからデータを新しく追加できるようにするカスタマイズ方法を紹介しました。

次の記事では、新規追加だけでなく、保存済のメーカー情報を修正したり削除したりする方法を紹介します。
本記事と合わせてご覧ください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次