EC-CUBE4で商品項目等の追加(フォーム拡張も)

はじめに

EC-CUBE4で商品・受注・会員情報などに新しく項目を追加する方法やフォームを拡張する方法が公式ドキュメントだけだと最初はよくわからなかったのでメモという意味もこめて解説します。

今回は商品項目に“重量”という項目を新しく追加する例です。
プログラム中では“weight”と表現することとします。

項目の追加だけではあまり意味がないので管理画面の商品登録フォームの拡張を軽く行っていきます。
また、おまけ要素として商品の検索結果などに表示される商品詳細画面のテンプレート編集も行います

前提

Windows10でXamppを使用

EC-CUBE 4.0.2
PHP 7.3.2
※パスを通しておく必要があります
Apache 2.4.38
MariaDB 10.1.38

DBから商品名などを引っ張ってくる際は、(商品IDなどを基に)商品テーブルへアクセスして商品名のデータを取得するのが一般的だと思います。


ですが、EC-CUBEではEntity(エンティティ)という概念があり、商品・受注・会員情報などは各々が一つのエンティティで、エンティティを管理して組み合わせることによってシステムが成り立ってます。

なので、あくまで項目の追加(拡張)は商品テーブルに対してではなく、“商品エンティティ”に対して行います。

商品エンティティの拡張(下準備)

エンティティの拡張を定義するファイルは /app/Customize/Entityの中に置きます。ファイル名はなんでもいいです。
今回はファイル名を”ProductTrait.php“としました。

/app/Customize/Entity/ProductTrait.phpを以下のようにします。


namespace Customize\Entity;

#DBにアクセスするためのライブラリなどを読み込み
use Doctrine\ORM\Mapping as ORM;
use Eccube\Annotation as Eccube;

#拡張をする対象エンティティの指定
/**
* @Eccube\EntityExtension("Eccube\Entity\Product")
*/


trait ProductTrait //ファイル名と合わせる
{
  //ココに実際の拡張内容などを記述していきます
}

記述が終わったらこのProductTrait.phpを拡張ファイルとしてProxyを通すコマンドを実行します。


php bin\console eccube:generate:proxies

実行結果がこんな感じの内容が出力されていれば成功です。

gen -> C:\DocumentRoot\eccube-4.0.2/app/proxy/entity/Product.php

拡張の下準備は終了したので実際に新規項目を追加していきます。

新規項目(重量)を定義

カラムの制約などを記述

/app/Customize/Entity/ProductTrait.phpを編集して下記のようにします


namespace Customize\Entity;

#DBにアクセスするためのライブラリなどを読み込み
use Doctrine\ORM\Mapping as ORM;
use Eccube\Annotation as Eccube;

#拡張をする対象エンティティの指定
/**
* @Eccube\EntityExtension("Eccube\Entity\Product")
*/


trait ProductTrait //ファイル名と合わせる
{
    /**
    * @ORM/Column(name="weight", type="text", nullable=true)
    */
    public $weight;
}

追加部分に関して


/**
* @ORM/Column(name="weight", type="text", nullable=true)
*/
public $weight;

name:カラム名
type:データ型
nullable:null制約の有無

MySQLでカラムを追加する時と同じように、他にも色々な制約を定義することができます。

weightプロパティの宣言も忘れずに。

ここまで出来たら一応キャッシュを削除します

php bin\console cache:clear --no-warmup

新規カラムの追加

新規カラムを追加していきますが、その前に実行されるクエリを確認しておく

php bin\console doctrine:schema:update --dump-sql

出力結果(例)

The following SQL statements will be executed:

     ALTER TABLE dtb_product ADD weight VARCHAR(255) DEFAULT NULL;

問題無ければDBに変更を適用します
(--dump-sqlはクエリを確認するためのオプションなので、無くてもいいです)

php bin\console doctrine:schema:update --dump-sql --force

出力結果(例)

 The following SQL statements will be executed:

     ALTER TABLE dtb_product ADD weight VARCHAR(255) DEFAULT NULL;

 Updating database schema...

     1 query was executed

 [OK] Database schema updated successfully!


コレでdtb_productというテーブルにweightというカラムが追加されていると思います。

項目追加に伴うフォームの拡張

項目を追加しただけでは何も変わらないので「商品登録フォーム」や「商品編集フォーム」などから商品の重量を設定・変更できるようにエンティティに対してフォームの拡張を行っていきます。

/app/Customize/Entity/ProductTrait.phpを以下のように編集します


namespace Customize\Entity;

use Doctrine\ORM\Mapping as ORM;
use Eccube\Annotation as Eccube;

/**
* @Eccube\EntityExtension("Eccube\Entity\Product")
*/

trait ProductTrait
{
    /**
    * @var string
    * @ORM\Column(name="weight", type="string", nullable=true)
    * @Eccube\FormAppend(
    *  auto_render=true,
    *  options={
    *   "required": false,
    *   "label":"重量"
    *  }
    * )
    */
    public $weight;
}

追加した内容がコチラ


 * @Eccube\FormAppend(
 *  auto_render=true,
 *  options={
 *   "required": false,
 *   "label":"重量"
 *  }
 * )

FormAppendでinput要素の追加・設定を行っていきます。


公式ドキュメントでは「auto_render=falseにしなさいみたいな記載がありますがアレは多分ミスです。いくらここで色々な設定をしてもauto_render=trueにしないと何も反映されません。


細かい設定はoptions={}の中で行っていきます。

requiredtrueにすると入力必須項目となります。

labelに設定した値は単純にinput要素のラベル(名称)となります。

上記の二つ以外にもセレクトボックス・ラジオボタンにするなど記述次第で細かい設定が色々できますが、ココでは割愛します。

管理画面から商品登録画面を開いてフォームの確認をしてみましょう

labelが「重量」のテキストフィールドが生成されていれば成功です。
実際に値を入力して商品の新規登録などを行ってみてください。

ここまでで新規項目の追加&フォームの拡張が完了しました。

※うまく反映されなかったりしたらキャッシュを削除してみてください。

php bin\console cache:clear --no-warmup

おまけ

せっかくなので、商品詳細画面(商品情報ページ?)で重量の値を表示してみましょう。また、重量は必須項目としていないので値が設定されていなかったら表示しないこととします。

ではブラウザ(eccubeの管理画面)からテンプレートの編集を行っていきます。
管理画面→コンテンツ管理→ページ管理→商品詳細ページ
そしたら、画像のようなページが表示されるかと思います。

エディタ内で下方向にスクロールして375行目周辺に手を加えていきます。


そして以下のようにします。

....... 
</div>
        {% if Product.freearea %}
         <div class="ec-productRole__description">
           {{ include(template_from_string(Product.freearea)) }}
         </div>
        {% endif %}

    {% if Product.weight %}
          重量:{{ include(template_from_string(Product.weight))}}kg
    {% endif %}

{% endblock %}

Product.freeareaに関する記述は既存のもので、それをほぼコピーしただけです。

記述が終わったら、ブラウザ画面右下の「登録」ボタンを押下して新しいテンプレートを適用させます。

商品を新しく登録(重量に何かしら値を入れるのを忘れずに)して追加した商品の詳細ページへ飛びます。

下のほうに小さくですが表示されてます。

特にスタイルなども適用させてなくてこの状態で表示させる意味はないですが、一応「重量」という項目の値を表示させることはできました。

応用していくと色々できそうです。

ご覧いただきありがとうございました。