EC-CUBE:最近チェックした商品を表示する

下記書籍をもとに書いています。詳しくは、本をお読みください。

PCでは、jQuery.carouFredSel(http://caroufredsel.frebsite.nl/)を利用して表示する。
また、横スライド用と縦スライド用を用意し、メインブロックへの配置、サイドブロックへの配置に対応する。

3カラムの時(左右にスライド)

2カラムの時(左右にスライド)

サイドに配置した時(上下にスライド)(3カラム、2カラム共通)

1 データベースに登録

(1)会員ユーザーが見た商品を登録するためのdtb_recent_productテーブルを作成する。
——————————————
名前:dtb_recent_product フィールド数:3

フィールド:customer_id
種別:INT
長さ:11
ヌル:チェックしない

フィールド:product_id
種別:INT
長さ:11
ヌル:チェックしない

フィールド:create_date
種別:DATETIME
ヌル:チェックしない
——————————————

(2)最近チェックした商品の表示数を設定する定数をmtb_constantsテーブルに登録する。
——————————————
id:DISP_RECENT_PRODUCT
name:10(←定数)
rank:1241(←適宜)
remarks:最近チェックした商品の表示数
——————————————

★ システム設定>パラメーター設定を開き、「この内容で登録する」をクリックする。

2 最近チェックした商品の登録

■ data/class/pages/products/LC_Page_Products_Detail.php
 // ログイン判定
if ($objCustomer->isLoginSuccess() === true){}内に追加する。

 //最近チェックした商品として登録する
 $this->lfRegistRecentProduct($product_id,$objCustomer->getValue('customer_id'));

 一番下 lfRegistFavoriteProductメソッドの次に追加する。

 function lfRegistRecentProduct($product_id,$customer_id) {
 $objQuery =& SC_Query_Ex::getSingletonInstance();

//既に同じ会員に同じ商品が登録されているか
 $count = $objQuery->count("dtb_recent_product","product_id = ? and customer_id = ?",array($product_id,$customer_id));

//同じ商品が登録されていれば更新
 if($count >0){
 $objQuery->update("dtb_recent_product",array("create_date"=>'now()'),"product_id = ? and customer_id = ?",array($product_id,$customer_id));
 }else{

//登録数を取得
 $maxcount = $objQuery->count("dtb_recent_product","customer_id = ?",array($customer_id,));
 //最大表示数異常であれば一番古い履歴を削除してから登録
 if($maxcount>=DISP_RECENT_PRODUCT){
 $objQuery->delete("dtb_recent_product","customer_id = ? order by create_date limit 1",array($customer_id));
 }
 $objQuery->insert("dtb_recent_product",array("product_id"=>$product_id,"customer_id"=>$customer_id,"create_date"=>"now()"));
 }
 }

3 最近チェックした商品を表示するためにブロックを作成する。

(1)データ取得のための拡張ファイル等を新規作成
 ■html/frontparts/bloc/recent_products.php
 ■data/class_extends/page_extends/frontparts/bloc/LC_Page_FrontParts_Bloc_Recent_Products_Ex.php
 ■data/class/pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Recent_Products.php

【縦スライド用】上記のファイルをコピーして作成。(コードに「_Vertical」を追加すること)
① ■html/frontparts/bloc/recent_products_vertical.php
② ■data/class_extends/page_extends/frontparts/bloc/LC_Page_FrontParts_Bloc_Recent_Products_Vertical_Ex.php
③ ■data/class/pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Recent_Products_Vertical.php

(2)データベースのdtb_blocにPC用(device_type_id=10)、携帯用(device_type_id=1)、スマートフォン用(device_type_id=2)のブロックを登録する。
PC用
——————————————
device_type_id:10
bloc_id:12(環境に応じて)
bloc_name:最近チェックした商品(横スライド)
tpl_path:recent_products.tpl
filename:recent_products
create_date:作成日時
update_date:作成日時
php_path:frontparts/bloc/recent_products.php
deletable_flg:0
——————————————
device_type_id:10
bloc_id:15(環境に応じて)
bloc_name:最近チェックした商品(縦スライド)
tpl_path:recent_products_vertical.tpl
filename:recent_products_vertical
create_date:作成日時
update_date:作成日時
php_path:frontparts/bloc/recent_products_vertical.php
deletable_flg:0
——————————————

携帯用
——————————————
device_type_id:1
bloc_id:7(環境に応じて)
bloc_name:最近チェックした商品
tpl_path:recent_products.tpl
filename:recent_products
create_date:作成日時
update_date:作成日時
php_path:frontparts/bloc/recent_products.php
deletable_flg:0
——————————————

スマートフォン用
——————————————
device_type_id:2
bloc_id:10(環境に応じて)
bloc_name:最近チェックした商品
tpl_path:recent_products.tpl
filename:recent_products
create_date:作成日時
update_date:作成日時
php_path:frontparts/bloc/recent_products.php
deletable_flg:0
——————————————

(3)PC用のテンプレートを作成する
 jQuery.carouFredSel(http://caroufredsel.frebsite.nl/)を適用する。
■html/js/jquery.caroufredsel/jquery.carouFredSel-5.5.0-packed.js
■html/js/jquery.caroufredsel/miscellaneous_sprite.png

■data/Smarty/templates/default/site_frame.tplに追加

 <!--jquery.caroufredsel-->
 <script type="text/javascript" src="<!--{$smarty.const.ROOT_URLPATH}-->js/jquery.caroufredsel/jquery.carouFredSel-5.5.0-packed.js"></script>

テンプレートファイルを作成する

横スライド用 ■data/Smarty/templates/default/frontparts/bloc/recent_products.tpl


<!--{if count($arrRecentProducts) > 0}-->

<script type="text/javascript" language="javascript">

$(function() {

$("#foo1").carouFredSel({

auto : false,

prev : "#foo1_prev",

next : "#foo1_next"

});

});

</script>

<div id="recent_area_main" class="bloc_outer">

<h2>最近チェックした商品</h2>

<div id="carousel">

<div id="foo1">

<!--{section name=cnt loop=$arrRecentProducts}-->

<div class="item">

<div class="image">

<a href="<!--{$smarty.const.P_DETAIL_URLPATH}--><!--{$arrRecentProducts[cnt].product_id|u}-->.html">

<img src="<!--{$smarty.const.ROOT_URLPATH}-->resize_image.php?image=<!--{$arrRecentProducts[cnt].main_list_image|sfNoImageMainList|h}-->&amp;width=110&amp;height=110" alt="<!--{$arrRecentProducts[cnt].name|h}-->" />

</a>

</div>

<div class="content">

<h3>

<a href="<!--{$smarty.const.P_DETAIL_URLPATH}--><!--{$arrRecentProducts[cnt].product_id|u}-->.html"><!--{$arrRecentProducts[cnt].name|h}--></a>

</h3>

<!--{assign var=price01 value=`$arrRecentProducts[cnt].price01_min`}-->

<!--{assign var=price02 value=`$arrRecentProducts[cnt].price02_min`}-->

<p class="sale_price">

<span class="price"><!--{$price02|sfCalcIncTax:$arrInfo.tax:$arrInfo.tax_rule|number_format}--> 円</span>(税込)

</p>

</div>

</div>

<!--{/section}-->

</div>

<div class="clearfix"></div>

<a class="prev" id="foo1_prev" href="#"><span>prev</span></a>

<a class="next" id="foo1_next" href="#"><span>next</span></a>

</div>

</div>

<!--{/if}-->

縦スライド用 ■data/Smarty/templates/default/frontparts/bloc/recent_products_vertical.tpl


<!--{if count($arrRecentProducts) > 0}-->

<script type="text/javascript" language="javascript">

$(function() {

$("#foo2").carouFredSel({

auto : false,

prev : "#foo2_prev",

next : "#foo2_next",

circular : true,

direction : "up",

items : 3

});

});

</script>

<div id="recent_area_main" class="bloc_outer">

<h2>最近チェックした商品</h2>

<div id="carousel">

<div id="foo2">

<!--{section name=cnt loop=$arrRecentProducts}-->

<div class="item">

<div class="image">

<a href="<!--{$smarty.const.P_DETAIL_URLPATH}--><!--{$arrRecentProducts[cnt].product_id|u}-->.html">

<img src="<!--{$smarty.const.ROOT_URLPATH}-->resize_image.php?image=<!--{$arrRecentProducts[cnt].main_list_image|sfNoImageMainList|h}-->&amp;width=70&amp;height=70" alt="<!--{$arrRecentProducts[cnt].name|h}-->" />

</a>

</div>

<div class="content">

<h3>

<a href="<!--{$smarty.const.P_DETAIL_URLPATH}--><!--{$arrRecentProducts[cnt].product_id|u}-->.html"><!--{$arrRecentProducts[cnt].name|h}--></a>

</h3>

<!--{assign var=price01 value=`$arrRecentProducts[cnt].price01_min`}-->

<!--{assign var=price02 value=`$arrRecentProducts[cnt].price02_min`}-->

<p class="sale_price">

<span class="price"><!--{$price02|sfCalcIncTax:$arrInfo.tax:$arrInfo.tax_rule|number_format}--> 円</span>(税込)

</p>

</div>

</div>

<!--{/section}-->

</div>

<div class="clearfix"></div>

<a class="prev" id="foo2_prev" style="cursor:pointer;"><span>prev</span></a>

<a class="next" id="foo2_next" style="cursor:pointer;"><span>next</span></a>

</div>

</div>

<!--{/if}-->

 CSSを適用する
■data/user_data/packages/default/css/bloc.cssに追加

ブロックを配置する場所によっては、レイアウトが崩れる場合もあるので、

#recent_area_mainの部分に、「clear:both;」を追加 (2012/05/30)
 /* ===============================================
 ▼最近チェックした商品
 =============================================== */
 #recent_area_main {
 margin-bottom:20px;
 clear:both;
 }
 #recent_area_main h2 {
 color:#E75019;
 padding:4px 10px;
 border-top:#F90 1px solid;
 border-left:#F90 10px solid;
 background-color:#FEE39E;
 }
 #recent_area_main #carousel {
 padding: 15px 0 15px 40px;
 position: relative;
 }
 #recent_area_main #carousel .item {
 display: block;
 float: left;
 margin: 5px;
 }
 #recent_area_main #carousel .item img {
 border: 1px solid #999;
 background-color: white;
 padding: 3px;
 }
 #recent_area_main a.prev, a.next {
 background: url(../../../../js/jquery.caroufredsel/miscellaneous_sprite.png) no-repeat transparent;
 width: 45px;
 height: 50px;
 display: block;
 position: absolute;
 top: 30px;
 }
 #recent_area_main a.prev {
 left: 0px;
 background-position: 0 0;
 }
 #recent_area_main a.prev:hover {
 background-position: 0 -50px;
 }
 #recent_area_main a.next {
 right: 0px;
 background-position: -50px 0;
 }
 #recent_area_main a.next:hover {
 background-position: -50px -50px;
 }
 #recent_area_main a.prev span, a.next span {
 display: none;
 }
 #recent_area_main .clearfix {
 float: none;
 clear: both;
 }

(4)携帯用のテンプレートを作成する
■data/Smarty/templates/mobile/frontparts/bloc/recent_products.tpl

 <!--{if count($arrRecentProducts) > 0}-->

◆最近チェックした商品<br>
 <!--{foreach from=$arrRecentProducts item=arrProduct name=best_products}-->

<!-- ▼最近チェックした商品コメント ここから -->
 <a href="<!--{$smarty.const.MOBILE_P_DETAIL_URLPATH}--><!--{$arrProduct.product_id|u}-->">
 <!--{$arrProduct.name|h|nl2br}--></a><br>
 <!--{$arrProduct.main_list_comment|h|mb_strimwidth:0:40:"..."}--></a>
 <!-- ▲最近チェックした商品コメント ここまで -->

<!--{if !$smarty.foreach.best_products.last}--><br><!--{/if}-->
 <!--{/foreach}-->

<br>
 <br>
 <hr>

<!--{/if}-->

(5)スマートフォン用のテンプレートを作成する
■data/Smarty/templates/sphone/frontparts/bloc/recent_products.tpl
■html/user_data/packages/sphone/js/jquery.flickslide1.js

■data/Smarty/templates/sphone/site_frame.tplに追加

 <script src="<!--{$TPL_URLPATH}-->js/jquery.flickslide1.js"></script>

■html/user_data/packages/sphone/css/block.css
下記を追加

 /*-----------------------------------------------
 最近チェックした商品
 ----------------------------------------------- */
 #recent_area{
 margin:15px 10px 20px 10px;
 padding-top:10px;
 border:#CCC solid 1px;
 border-radius: 8px;
 -webkit-border-radius: 8px;
 -moz-border-radius: 8px;
 }
 #recent_area h2{
 font-size:12px;
 margin-left:10px;
 }
 #recent_area li{
 width:290px;
 }
 .recentblock{
 width:270px;
 padding:5px 10px 5px 8px;
 margin:0 auto;
 clear:both;
 }
 .recentblock img{
 width:80px;
 float:left;
 }
 .recentblock .productContents{
 width:68%;
 float:right;
 text-align:left;
 }
 .recentblock .productContents p{
 clear:both;
 }
 .recentblock .productContents p.comment{
 width:17em;
 height:3.7em;
 overflow:hidden;
 white-space:nowrap;
 text-overflow: ellipsis;
 -webkit-text-overflow: ellipsis;
 clear:both;
 }
 .recentblock .sale_price{
 clear:both;
 float:right;
 text-align:right;
 }
 #recent_area div.moveWrap {
 width:290px;
 height:auto;
 margin:0 auto;
 position:relative;
 overflow:hidden;
 -webkit-box-sizing:border-box;
 }

#recent_area ul.moveWrapBG {
 margin:0;
 padding:0;
 display:inline-block;
 position:relative;
 width:100%;
 height:auto;
 visibility:hidden;
 -webkit-box-sizing:border-box;
 }
 #recent_area div.slideMask {
 margin:0 auto;
 padding:0;
 margin-right:1px;
 position:absolute;
 top:0;
 left:0;
 border:4px #FFF solid;
 -webkit-box-sizing:border-box;
 }
 #recent_area div.moveWrap>ul.move {
 width:10000px;
 margin:0;
 padding:0;
 position:relative;
 left:0;
 top:0;
 list-style:none;
 -webkit-transition:all 0.6s ease-in-out;
 -webkit-transform:translate3d(0,0,0);
 margin:0;
 padding:0;
 display:none;
 }
 #recent_area div.moveWrap>ul.move li.slideUnit {
 width:290px!important;
 margin:0;
 padding:0;
 float:left;
 list-style:none;
 text-align:center;
 -webkit-box-sizing:border-box;
 }
 #recent_area li.slideUnit>div {
 padding:4px;
 display:inline-block;
 vertical-align:middle;
 text-align:center;
 -webkit-box-sizing:border-box;
 }
 #recent_area div.flickSlide1Bottom {
 width:100%;
 margin-top:5px;
 border-top:#DBDBDB solid 1px;
 background: -moz-linear-gradient(center top, #FFFFFF 0%,#DEE4EA 95%,#FFFFFF 100%);
 background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #FFFFFF),color-stop(0.95, #DEE4EA),color-stop(0, #FFFFFF));
 border-bottom-right-radius:8px;
 -webkit-border-bottom-right-radius: 8px;
 -moz-border-bottom-right-radius: 8px;
 border-bottom-left-radius:8px;
 -webkit-border-bottom-left-radius:8px;
 moz-border-bottom-left-radius:8px;
 }
 #recent_area div.flickSlide1Bottom div.bottomLeft,#recent_area div.flickSlide1Bottom div.bottomRight {
 display:table-cell;
 -webkit-box-sizing:border-box;
 -webkit-box-shadow: rgba(0, 0, 0, 0.0976562) 0px 1px 3px, rgba(255, 255, 255, 1) 0px 0px 0px inset;
 vertical-align:middle;
 padding:0 10px;
 }
 #recent_area div.flickSlide1Bottom div.bottomRight {
 font-size:16px;
 font-weight: bold;
 color:#7F7F7F;
 background-color:transparent;
 border-bottom-right-radius: 8px;
 -webkit-border-bottom-right-radius: 8px;
 -moz-border-bottom-right-radius: 8px;
 border-left:#DBDBDB solid 1px;
 }
 #recent_area div.flickSlide1Bottom div.bottomLeft {
 font-size:16px;
 font-weight: bold;
 color:#7F7F7F;
 background-color:transparent;
 border-bottom-left-radius: 8px;
 -webkit-border-bottom-left-radius: 8px;
 -moz-border-bottom-left-radius:8px;
 border-right:#DBDBDB solid 1px;
 }
 #recent_area div.flickSlide1Bottom div.bottomLeft:after {
 font-size:10px;
 padding:5px;
 text-align:left;
 display:table-cell;
 }
 #recent_area div.flickSlide1Bottom div.bottomLeft:before {
 margin-top:2px;
 padding:5px;
 text-align:left;
 display:table-cell;
 }
 #recent_area div.flickSlide1Bottom div.bottomRight:before {
 font-size:10px;
 padding:5px;
 text-align:right;
 display:table-cell;
 }
 #recent_area div.flickSlide1Bottom div.bottomRight:after {
 margin-top:2px;
 padding:5px;
 text-align:right;
 display:table-cell;
 }
 #recent_area div.flickSlide1Bottom ul.slidePager {
 width:100%;
 margin:0;
 padding:0;
 display:table-cell;
 text-align:center;
 }
 #recent_area div.flickSlide1Bottom ul.slidePager li.slidePagerPointer1 {
 font-size:10px;
 width:6px;
 height:6px;
 margin:12px 6px 6px 6px;
 display:inline-block;
 background-color:#CCC;
 border-radius: 6px;
 -webkit-border-radius: 6px;
 -moz-border-radius: 6px;
 }
 #recent_area div.flickSlide1Bottom ul.slidePager li.slidePagerPointer1.active {
 background-color:#333;
 }

#recent_area_main