[EC-CUBE3] 商品総数を表示したかった。[メモ]

EC-CUBE2時代はテンプレートにサクッとphpを書けば表示できてたものが、EC-CUBE3になってsymfonyベースになったせいで非常にデザイナー泣かせのシステムになってしまいました。

何が辛いって、「変数一つ表示するのにそんなに手間をかけないといけないの?」ってレベルの話で、データベースの値を変更しないとそもそもcontrollerが動かないという正直なところ、symfonyはもう二度と触りたくないと思いました。
全然仕組みがわからないので、かれこれ数十時間を無駄に費やしたと思います。
本も数冊買ったけど全然やくに立たなかった。

愚痴っても仕方ないので、登録されている商品の総商品点数の表示の仕方をメモしておきます。

1. ブロックを作る

全ページのヘッダーに商品数を表示したかったので、全ページに表示するための、ブロックを管理画面から作成します。
(既存のブロックに追加する場合は、ここは飛ばしてok)
スクリーンショット 2018-04-10 19.34.40

2. ページレイアウトにブロックを追加

レイアウト管理で、作成したブロックをページレイアウトに追加します。
スクリーンショット 2018-04-10 19.35.42

3. [重要]DBでdtb_blockのlogic_flgを1にする

これをしないと、上に書いたように、そもそもControllerが動かないという謎の仕様。
管理画面のブロック追加のページに書いといてほしいと思いました。
スクリーンショット 2018-04-10 19.39.22

4. Controllerを作る

/src/Eccube/Controller/Block/に、任意の名前のファイルを作ります。
ProductCountController.phpとかでいいと思います。

中身は、以下。

<?php 
namespace Eccube\Controller\Block;
use Eccube\Application;
class ProductCountController
{
    public function index(Application $app)
    {
        $products = $app['eccube.repository.product']->findAll();
        $num = count($products);
        
        return $app->render('Block/product_count.twig', array(
            'count' => $num,
        ));
    }
}

これはもうどうしようもなくてフォーラムに質問したら教えてくれました。
やはり本読んだりググるより、直接知ってる人に聞くのが一番だと思いました。

5. ControllerProviderに追記をする

/src/Eccube/ControllerProvider/FrontControllerProvider.php
の、
75行目付近にブロック関連のプロバイダーが書いてあるので、そこに追記します。

$c->match('/block/product_count', '\Eccube\Controller\Block\ProductCountController::index')->bind('block_product_count');

6. ブロックに変数を記述

ここで、ようやくビューに変数を書きます。

<dl>
<dt>商品点数</dt>
<dd>{{ count }}</dd>
</dl>

以上です。

EC-CUBE2だったら、/data/Smarty/templates/default/header.tpl に以下を書くだけだったのに、本当めんどくさくなりましたね。

<!--{php}-->
    $objQuery = new SC_Query();
    $table = 'dtb_products';
    $where = 'del_flg = 0 AND status = 1';
    $count = $objQuery->count($table, $where);
        echo $count;
    <!--{/php}-->

[EC-CUBE + Concrete5] ECキューブの商品情報をConcrete5で利用する

タイトル通りですが、もうちょっと詳しく説明しますと、
「ECキューブに商品登録されている商品情報をxmlで取得してきて、Concrete5の編集でブロックに個別の商品IDを入力すると表示する」といった感じでしょうか。
ECキューブのページ作成機能がお客さんには使いづらいという感想だったので、Concrete5で編集・商品リストの作成は任意で行ってもらうようにしました。

バージョン:
ECキューブ 2.13.3
Concrete5 5.6.3.1

ECキューブAPIの取得方法については、下記のサイトを参考にさせていただきました。
EC-CUBEのAjax APIを使う(2) −−− 商品情報取得

なお、今回は同一サーバー、同一ドメイン内にECキューブとConcrete5をインストールしています。

ECキューブのAPIを使う

ECキューブには最近のバージョンでAPI機能が追加されたので、APIを利用して商品情報を取得できるようにします。

管理画面の「システム設定>パラメーター設定」にある「API_ENABLE_FLAG」を「true」にします。

xml.php

ECキューブのAPIは以下のURLでリクエストが送れます。

https://ドメイン/api/出力フォーマット.php

出力フォーマットは、JSONとxmlとphpの三種類あります。
今回はxmlを使用しました。

https://ドメイン/api/xml.php

これだけだと、下記のようにFalseが返ってきてなにも表示することができませんので、パラメータを設定する必要があります。

パラメータを含めたリクエストURL

https://ドメイン/api/xml.php?Operation=ItemLookup&Service=abc&ItemId=商品ID

Operation オペレーションの種類を指定します
Service 指定しないとエラーになります。ただし何も使われていないので適当な値を入力すれば大丈夫

Operationの種類は多数あるのですが、今回は「ItemLookup」を使用しました。
ItemLookupは、商品IDをキーに、商品詳細情報を取得します。商品IDは「ItemId」へ入力します。

これで商品情報の取得が可能です

Concrete5での設定 Desginer content

Concrete5側では、お客さんに商品IDを入れてもらうだけにするために、「Designer content」アドオンを利用します。
インストール方法などは省きます。

Designer contentで、新しいブロックを作成します。

Block Handleとブロック名は任意で、Add Fieldから「Text Box」を選択し、「Editor Label」に「商品ID」と入力。ダッシュボードでのDesigner contentで行う作業はこれだけです。

作成したブロックをカスタマイズ

Designer contentで作成したブロックのフロントテンプレートは、コンクリインストールフォルダの「/blocks/」ディレクトリ内に作成されます。
上記の例だと「/blocks/product_item」というディレクトリができているかと思います。
この中にあるview.phpがフロントテンプレートになります。

view.phpには以下のphpが書かれていますので、これをどうにかして商品情報を表示するように設定します

<?php  defined('C5_EXECUTE') or die("Access Denied.");
?>

<?php  if (!empty($field_1_textbox_text)): ?>
	<?php  echo htmlentities($field_1_textbox_text, ENT_QUOTES, APP_CHARSET); ?>
<?php  endif; ?>

「echo htmlentities($field_1_textbox_text, ENT_QUOTES, APP_CHARSET);」が、ブロックに入力された文字を表示するので、ここに商品IDを入力してもらっていれば、phpからxmlへリクエストを送る際の必要な商品IDをそのまま利用できるということになります。

<?php
$productID = htmlentities($field_1_textbox_text, ENT_QUOTES, APP_CHARSET); //編集画面で入力された商品ID
$xml = simplexml_load_file('/api/xml.php?Operation=ItemLookup&Service=abc&ItemId=' . $productID); //APIへのリクエスト


xmlから必要な情報を取り出して変数に入れる

<?php
$productURL = $xml->Item->DetailPageURL;
$productName = $xml->Item->Title;
$productThumb = $xml->Item->ItemAttributes->main_list_image;
$productPrice = $xml->Item->ItemAttributes->price02_max;
?>


htmlのマークアップはお好みでどうぞ。

<p class="item_image"><a href="<?php echo $productURL;?>"><img src="/upload/save_image/<?php echo $productThumb;?>" alt="<?php echo $productName;?>"></a></p>
<p class="checkItemname"><a href="<?php echo $productURL;?>"><?php echo $productName;?></a></p>
<p class="price"><em><?php echo $productPrice;?></em>円</p>

補足

ちなみに、同一ドメインでも、apiへのリクエストが「/api〜〜」になっていると「I/O warning : failed to load external entity」が出る事があったので、apiリクエストを「http〜〜」になるようにしました。

<?php
$domain = (empty($_SERVER["HTTPS"]) ? "https://" : "https://") . $_SERVER["HTTP_HOST"] ; //ドメイン取得
$productID = htmlentities($field_1_textbox_text, ENT_QUOTES, APP_CHARSET); //編集画面で入力された商品ID

$xml = simplexml_load_file($domain . '/api/xml.php?Operation=ItemLookup&Service=abc&ItemId=' . $productID); //APIへのリクエスト

[ECキューブ 2.13.3]タイトルタグの表示を変えたい[メモ]

ECキューブのタイトルタグは、デフォルトだと「サイト名 / ページ名」という形で表示されます。
昔だとそれでも問題なかったんですが、最近のブラウザはタブ表示でサイト名が先に表示されるとタブを見てもどこのページを開いているかわかりませんので、特別な理由(宗教上の理由とか)がない限り、ページ名を先に表示させた方が明らかにユーザビリティに優れていますよね。

バージョン:2.13.3

ECキューブのタイトルタグは基本、テンプレートのsite_frame.tplに書かれています。
/data/Smarty/templates/default/site_frame.tpl

その中の27行目あたりにタイトルタグがありますので、中身をちょちょいといじれば大丈夫
※一行だとみづらいので改行しています

「サイト名 / ページ名」

<title>
<!--{$arrSiteInfo.shop_name|h}-->
<!--{if $tpl_subtitle|strlen >= 1}--> / <!--{$tpl_subtitle|h}-->
<!--{elseif $tpl_title|strlen >= 1}--> / <!--{$tpl_title|h}-->
<!--{/if}-->
</title>

「ページ名|サイト名」にしました。

<title>
<!--{if $tpl_subtitle|strlen >= 1}-->
<!--{$tpl_subtitle|h}-->|
<!--{elseif $tpl_title|strlen >= 1}-->
<!--{$tpl_title|h}-->|
<!--{/if}--><!--{$arrSiteInfo.shop_name|h}-->
</title>

中身のif文は管理画面でサブタイトルが設定されているときにページ名の代わりに表示するものです。
<!–{$arrSiteInfo.shop_name|h}–>がサイト名です。

[EC-CUBE]プラグインが競合したときは。

今ECCUBEでサイト構築の案件をやっているのですが、デフォルトだと必要だと思う機能がなくて、プラグインを入れざるを得ない状況になります。
で、あれもこれもってプラグインを追加していくと上記のスクリーンショットのように競合のアラートが出まくります。競合すると動作もフロントに表示すらしなくなるので非常に困ります。

競合したら、まず優先度の数値を変えてみると問題が解消されることがあります。
それでもダメだったら自分でなんとかする前に、プラグインの開発者に問い合わせましょう。
それでもダメだったら、諦めましょう。