EC-CUBEには、ブロックという便利な機能があります。
EC-CUBE4管理画面から、簡単にブロック追加ができます。しかしそれは動的なブロックではありません。
本記事では、動的ブロックの作成方法をご紹介します!
この記事の対象者
・EC-CUBE4のカスタマイズをしたい人
・PHPについて知識がある方
・データベースについて知識がある方(phpMyAdminを使用します。)
目次
動的ブロックとは
動的とは、状態や構成が状況に応じて変化したり、状況に合わせて選択できたりする柔軟性を持っていること。
つまり、動的なブロックとは、見る状況によって内容が変化するブロックのことです。
また見る状況によって内容が変化しないブロックのことは静的ブロックといいます。
通常EC-CUBEでブロックを作成すると、静的ブロックとして作成されます。
例として、「新着商品ブロック」を見ていきましょう。
動的ブロックであれば、新しい商品が追加された際に新着商品が表示されます。
ブロックを動的にカスタマイズする際には、データベースの編集やプログラムの記述が必要になります。
本記事では例として動的な新着商品ブロックを作成してきます。
それでは実際の作成手順について見ていきましょう。
静的ブロックを作成
まずは通常の静的ブロックを作成します。
管理画面から コンテンツ管理 > ブロック管理 > 新規作成 で作成します。
ブロック名、ファイル名、コードについて下記のように設定します。
※ブロック名やファイル名は任意のものでも構いません。
ファイル名:new_product
コード:下記のコード「new_product.twig」を参照(デフォルトの新着商品ブロックの内容)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | {# 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. #} <div class="ec-role"> <div class="ec-newItemRole"> <div class="ec-newItemRole__list"> <div class="ec-newItemRole__listItem"> <div class="ec-newItemRole__listItemHeading ec-secHeading--tandem"> <span class="ec-secHeading__en">{{ 'NEW ITEM'|trans }}</span> <span class="ec-secHeading__line"></span> <span class="ec-secHeading__ja">{{ '新着商品'|trans }}</span> <a class="ec-inlineBtn--top" href="{{ url('product_list') }}">{{ 'more'|trans }}</a> </div> </div> <div class="ec-newItemRole__listItem"> <a href="{{ url('product_detail', {'id': '1'}) }}"> <img src="{{ asset('cube-1.png', 'save_image') }}"> <p class="ec-newItemRole__listItemTitle">{{ '彩のジェラート"CUBE"'|trans }}</p> <p class="ec-newItemRole__listItemPrice">{{ '¥1,200(税込)'|trans }}</p> </a> </div> <div class="ec-newItemRole__listItem"> <a href="{{ url('product_detail', {'id': '2'}) }}"> <img src="{{ asset('sand-1.png', 'save_image') }}"> <p class="ec-newItemRole__listItemTitle">{{ 'チェリーアイスサンド'|trans }}</p> <p class="ec-newItemRole__listItemPrice">{{ '¥800(税込)'|trans }}</p> </a> </div> <div class="ec-newItemRole__listItem"> <a href="{{ url('product_detail', {'id': '1'}) }}"> <img src="{{ asset(''|no_image_product , 'save_image') }}"> <p class="ec-newItemRole__listItemTitle">{{ '彩のジェラート"CUBE" NEO'|trans }}</p> <p class="ec-newItemRole__listItemPrice">{{ '¥600(税込)'|trans }}</p> </a> </div> </div> </div> </div> |
データベースの内容を編集
次にデータベースの内容を編集し、動的ブロックとして扱えるようにしましょう。
新規追加したブロックを確認
phpMyAdminにてログインし、先ほど追加したブロックを確認しましょう。
EC-CUBEと連携しているデータベースの中の、「dtb_block」テーブルを表示します。
「dtb_block」テーブルは、作成されたブロックの情報を管理するテーブルです。
新規作成したブロックの内容を変更
新規作成したブロックの「user_controller」を「0」から「1」に変更します。
これが「1」になっていることで、EC-CUBEでは動的ブロックとして扱われます。
動的ブロック用のコントローラーを整備
ここからはコントローラーを作成し、動的な処理を書いていきます。
コントローラーで処理したデータを表示側(Twigファイル)に渡すことで、
ブロックの表示内容を動的にすることが可能となります。
コントローラーの作成
下記のフォルダに、動的ブロック用のコントローラーのファイルを作成します。
「プロジェクトディレクトリ/app/Customize/Controller/Block/NewProductController.php」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <?php /* * 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. */ namespace Customize\Controller\Block; use Eccube\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; class NewProductController extends AbstractController { public function __construct( ) { } /** * @Route("/block/new_product", name="block_new_product") * @Template("Block/new_product.twig") */ public function index(Request $request) { //ここに処理を書く return [ ]; } } |
上記のコードは動的ブロック用コントローラーの基本的な形です。
まだメインの処理は書いていない状態です。ここからカスタマイズして、オリジナルの動的ブロック用コントローラーにしていきます。
特に重要な箇所を解説していきます。
クラス名:NewProductController
こちらはクラス名になります。基本的にはファイル名と合わせます。
今回はNewProductControllerとしていますが、クラス名は任意で指定可能です。
ルート設定:@Route(“/block/new_product”, name=”block_new_product”)
こちらはブロックが呼び出される際の設定となります。
ブロック新規作成時のtwigファイルの名前と合わせる必要があります。
テンプレート設定:@Template(“Block/new_product.twig”)
こちらは、ブロックの表示にどのtwigファイルを用いるかの設定となります。
ブロック新規作成時のtwigファイルの名前と合わせる必要があります。
コントローラーの処理を書く
それでは、実際のコントローラーの処理を書きましょう。
コントローラーの処理は下記です。
・取得したデータを表示側(twigファイル)に渡す。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | <?php /* * 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. */ namespace Customize\Controller\Block; use Eccube\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Eccube\Repository\ProductRepository; class NewProductController extends AbstractController { /** * @var ProductRepository */ private $productRepository; public function __construct( ProductRepository $productRepository ) { $this->productRepository = $productRepository; } /** * @Route("/block/new_product", name="block_new_product") * @Template("Block/new_product.twig") */ public function index(Request $request) { $limit = 3;//取得する商品数 $qb = $this->productRepository->getQueryBuilderBySearchData([]); $qb ->orderBy('p.create_date', 'desc') ->setMaxResults($limit); $Products = $qb->getQuery()->getResult(); return [ 'Products' => $Products ]; } } |
コードについて解説します。
$qb
->orderBy(‘p.create_date’, ‘desc’)
->setMaxResults($limit);
$Products = $qb->getQuery()->getResult();
まず「productRepository」クラスを用いて、クエリを作成します。
「getQueryBuilderBySearchData」はもともと「productRepository」クラスに定義されているメソッドです。
最終的に$Products変数に、取得した新着商品のデータが入ります。
今回は簡単な処理なためgetQueryBuilderBySearchDataを流用しましたが、より複雑なカスタマイズしたい場合は自分でクエリを書けば可能です。
EC-CUBE4はSymfonyフレームワークを基に作成されています。また、SymfonyフレームワークではORMとしてDoctrine ORMを採用しています。
Doctorine ORMのQueryBuilderについて学ぶことで、より柔軟化カスタマイズが可能となります。
https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/query-builder.html
returnで、表示側(twigファイル)に渡す変数を定義します。
今回は、「Products」という名前で、「$Products」変数のデータを渡しています。
「Products」という名前は変更しても構いませんが、ここを変更する場合はtwigファイル側で用いる名前も変更する必要がありますので注意してください。
表示側(twigファイル)を整備
ここまでで、コントローラーから新着商品のデータが渡されるようになっています。
しかし、このままではまだ表示が変わりません。
コントローラーから受け取ったデータを表示するようにtwigファイルを編集していきます。
twigファイルを編集
管理画面 > コンテンツ管理 > ブロック管理 > 先ほど作成したブロック から編集画面に行きます。
コントローラーから受け取るデータ「Products」を元に表示するように編集します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | {# 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. #} <div class="ec-role"> <div class="ec-newItemRole"> <div class="ec-newItemRole__list"> <div class="ec-newItemRole__listItem"> <div class="ec-newItemRole__listItemHeading ec-secHeading--tandem"> <span class="ec-secHeading__en">{{ 'NEW ITEM'|trans }}</span> <span class="ec-secHeading__line"></span> <span class="ec-secHeading__ja">{{ '新着商品'|trans }}</span> <a class="ec-inlineBtn--top" href="{{ url('product_list') }}">{{ 'more'|trans }}</a> </div> </div> {% for Product in Products %} <div class="ec-newItemRole__listItem"> <a href="{{ url('product_detail', {'id': Product.id}) }}"> <img src="{{ asset(Product.main_list_image|no_image_product, 'save_image') }}" alt="{{ Product.name }}"> <p class="ec-newItemRole__listItemTitle">{{ Product.name }}</p> <p class="ec-newItemRole__listItemPrice"> {% if Product.hasProductClass %} {% if Product.getPrice02Min == Product.getPrice02Max %} {{ Product.getPrice02IncTaxMin|price }} {% else %} {{ Product.getPrice02IncTaxMin|price }} ~ {{ Product.getPrice02IncTaxMax|price }} {% endif %} {% else %} {{ Product.getPrice02IncTaxMin|price }} {% endif %} </p> </a> </div> {% endfor %} </div> </div> </div> |
簡単に解説していきます。
~
{% endfor %}
Productsには、複数の商品データが入っています。それを表示するために、forタグを使用します。
今回は新着商品のデータが3つ入っているため、forタグの中身が3回表示されるイメージです。
forタグの中では、ひとつひとつの商品データが「Product」として扱うように定義しています。
またProductは、Productエンティティクラスとなります。
そのため、Prouctエンティティクラスで定義されているプロパティやメソッドが使用可能です。
例えば、「Product.id」は商品IDプロパティを指し、「Product.getPrice02Max」は商品の価格の最大値を取得するメソッドを指します。
※Productエンティティの詳細は、「プロジェクトディレクトリ/src/Eccube/Entity/Product.php」を参照
作成した動的ブロックを表示する
作成した動的ブロックを実際に設定して表示してみます。
今回は例としてトップページに表示してみます。
レイアウト管理からブロックを設定
管理画面 > レイアウト管理 > トップページ用レイアウト から設定します。
作成したブロック「新着商品(動的)」を設定して保存します。
表示の確認
表示前に、確認用の商品「テスト新商品」を設定して公開しました。
これで「新着商品(動的)」ブロックに「テスト新商品」が表示されればOKです。
また比較のために今回は「新着商品(動的)」の上に、デフォルトのブロックである「新着商品」を表示しています。
デフォルトのブロックは静的ブロックのため、「テスト新商品」が表示されていないはずです。
まとめ
いかがでしたでしょうか。今回は新着商品という比較的簡単なものを例として挙げました。
これを応用すれば、商品ランキングブロックや、ランダムで表示するブロックなど、いくつもの動的ブロックが作成可能です。
特に難しいのは、やはりコントローラーに動的な処理を書くところでしょうか。
こちらはプログラムの知識やSymfonyフレームワークの理解が必要となります。
Symfonyの公式ドキュメントや、Doctrine ORMのドキュメントなどを参考にするとよいかと思います。
EC-CUBEにはプラグインも多くありますが、要件に合うプラグインというのは無い場合もあります。
そのようなときは、この記事を参考にカスタマイズしてみてはいかがでしょうか。
では!