EC-CUBE2.12:売れ筋ランキング(管理画面アクセス時にランキング生成)

ランキングの集計は、管理者が管理画面にログイン後、最初のページを開いた時に、自動的にデータベースに生成される仕組みなので、購入処理が行われてすぐに反映されるものではありません。

▼ここでのカスタマイズファイルをすべてダウンロードできます。
必要な箇所だけコピーしてご利用ください。
他のカスタマイズも含まれている場合がありますので、ファイルの上書きは絶対におやめください。
こちらから(facebookユーザーのみ)

サンプルはこちら

—————-
■■■PC用■■■
—————-

1 データベース dtb_rankingテーブルの作成

CREATE TABLE dtb_ranking(
rank int primary key,
product_id int,
quantity int
);

2 ランキングの表示数を設定する定数をmtb_constantsテーブルに登録する。
ただし、表示数の最大値は「おすすめ商品表示数」となる。おすすめ商品表示数が8に設定されているとき、ランキング表示数を10に設定しても8個までしか表示されない。10個表示したい場合は、おすすめ商品表示数を10に設定する。

INSERT INTO mtb_constants (id, name, rank, remarks) VALUES ('RANKING_LIMIT', '5', 1422, '売れ筋ランキングの表示数');

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

3 ランキングの自動生成(dtb_rankingテーブルへの登録)
システムの負担減を考え、ユーザーがアクセスした時に生成されるのではなく、管理者が管理画面のトップページにアクセスした際に生成されるようにする。
管理画面のトップページにアクセスした時に、最新のランキングが自動的に生成・表示される。

■data/class/pages/admin/LC_Page_Admin_Home.phpのfunction action()メソッド内の最初に追加

//ランキング情報の処理
$objQuery = SC_Query_Ex::getSingletonInstance();
$col = "*";
$from = "(select product_id,sum(quantity) as total from dtb_order_detail group by product_id) as A";
$where = "total >0";

$objQuery->setorder("total DESC");
$objQuery->setlimit(RANKING_LIMIT);

$arrRanking = $objQuery->select($col, $from , $where);
$i = 0;
$objQuery->delete("dtb_ranking");
foreach($arrRanking as $val){
$i++;
$objQuery->insert("dtb_ranking",array("rank"=>$i,"product_id"=>$val['product_id'],"quantity"=>$val['total']));
}

4 ファイル等の作成

(1)下記ファイルを作成する
 ■html/frontparts/bloc/ranking.php

<?php

// {{{ requires
require_once realpath(dirname(__FILE__)) . '/../../require.php';
require_once CLASS_EX_REALDIR . 'page_extends/frontparts/bloc/LC_Page_FrontParts_Bloc_Ranking_Ex.php';

// }}}
// {{{ generate page

$objPage = new LC_Page_FrontParts_BLoc_Ranking_Ex();
$objPage->blocItems = $params['items'];
register_shutdown_function(array($objPage, "destroy"));
$objPage->init();
$objPage->process();
?>

 ■data/class_extends/page_extends/frontparts/bloc/LC_Page_FrontParts_Bloc_Ranking_Ex.php

<?php

// {{{ requires
require_once CLASS_REALDIR . 'pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Ranking.php';

class LC_Page_FrontParts_Bloc_Ranking_Ex extends LC_Page_FrontParts_Bloc_Ranking {

// }}}
// {{{ functions

/**
* Page を初期化する.
*
* @return void
*/
function init() {
parent::init();
}

/**
* Page のプロセス.
*
* @return void
*/
function process() {
parent::process();
}

/**
* デストラクタ.
*
* @return void
*/
function destroy() {
parent::destroy();
}
}
?>

 ■data/class/pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Ranking.php

<?php

// {{{ requires
require_once CLASS_REALDIR . 'pages/frontparts/bloc/LC_Page_FrontParts_Bloc.php';

class LC_Page_FrontParts_Bloc_Ranking extends LC_Page_FrontParts_Bloc {

// }}}
// {{{ functions

/**
* Page を初期化する.
*
* @return void
*/
function init() {
parent::init();
}

/**
* Page のプロセス.
*
* @return void
*/
function process() {
$this->action();
$this->sendResponse();
}

/**
* Page のアクション.
*
* @return void
*/
function action() {

// 基本情報を渡す
$objSiteInfo = SC_Helper_DB_Ex::sfGetBasisData();
$this->arrInfo = $objSiteInfo->data;

//ランキング商品表示
$this->arrBestProducts = $this->lfGetRanking();


}

/**
* デストラクタ.
*
* @return void
*/
function destroy() {
parent::destroy();
}

/**
* ランキング商品検索.
*
* @return array $arrBestProducts 検索結果配列
*/
function lfGetRanking(){
$objQuery =& SC_Query_Ex::getSingletonInstance();
$objProduct = new SC_Product_Ex();

// ランキング商品取得
$col = '*';
$table = 'dtb_ranking';
$objQuery->setOrder('rank');
$objQuery->setLimit(RECOMMEND_NUM);
$arrBestProducts = $objQuery->select($col, $table, $where);

$objQuery =& SC_Query_Ex::getSingletonInstance();
if (count($arrBestProducts) > 0) {
// 商品一覧を取得
// where条件生成&セット
$arrBestProductIds = array();
$where = 'product_id IN (';
foreach ($arrBestProducts as $key => $val) {
$arrBestProductIds[] = $val['product_id'];
}
$where .= implode(', ', $arrBestProductIds);
$where .= ')';
$objQuery->setWhere($where);
// 取得
$arrTmp = $objProduct->lists($objQuery);
foreach ($arrTmp as $key => $arrRow) {
$arrProductList[$arrRow['product_id']] = $arrRow;
}
// ランキング商品情報にマージ
foreach (array_keys($arrBestProducts) as $key) {
$arrRow =& $arrBestProducts[$key];
if (isset($arrProductList[$arrRow['product_id']])) {
$arrRow = array_merge($arrRow, $arrProductList[$arrRow['product_id']]);
} else {
// 削除済み商品は除外
unset($arrBestProducts[$key]);
}
}
}
return $arrBestProducts;
}
}
?>

 ■data/Smarty/templates/default/frontparts/bloc/ranking.tpl

<!--{if count($arrBestProducts) > 0}-->
<!--▼ランキング-->
<div class="block_outer">
<div id="ranking_area">

<h2>売れ筋ランキング</h2>

<div>
<ul>
<!--{section name=cnt loop=$arrBestProducts}-->
<li>
<div class="rank"><div id="rank_<!--{$arrBestProducts[cnt].rank|h}-->">第<!--{$arrBestProducts[cnt].rank|h}-->位</div></div>
<div class="left">
<div class="image">
<a href="<!--{$smarty.const.P_DETAIL_URLPATH}--><!--{$arrBestProducts[cnt].product_id|u}--><!--{if $smarty.const.STATIC_URL == true}-->.html<!--{/if}-->">
<img src="<!--{$smarty.const.ROOT_URLPATH}-->resize_image.php?image=<!--{$arrBestProducts[cnt].main_list_image|sfNoImageMainList|h}-->&amp;width=80&amp;height=80" alt="<!--{$arrBestProducts[cnt].name|h}-->" /></a>
</div>
</div>
<div class="right">
<p><a href="<!--{$smarty.const.P_DETAIL_URLPATH}--><!--{$arrBestProducts[cnt].product_id|u}--><!--{if $smarty.const.STATIC_URL == true}-->.html<!--{/if}-->"><!--{$arrBestProducts[cnt].name|h}--></a></p>
<!--{assign var=price01 value=`$arrBestProducts[cnt].price01_min`}-->
<!--{assign var=price02 value=`$arrBestProducts[cnt].price02_min`}-->
<p style="white-space:nowrap;"><!--{$price02|sfCalcIncTax:$arrInfo.tax:$arrInfo.tax_rule|number_format}-->円</p>
<!--<p style="white-space:nowrap;">はIE7対応-->
</div>
</li>
<!--{/section}-->
</ul>
<div class="clear"></div>
</div>
</div>
</div>
<!--{/if}-->

(2)データベースにブロックを登録

INSERT INTO dtb_bloc (device_type_id, bloc_id, bloc_name, tpl_path, filename, create_date, update_date, php_path, deletable_flg) VALUES (10, 12, 'ランキング', 'ranking.tpl', 'ranking', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'frontparts/bloc/ranking.php', 0)

(3)CSSに追加する。
■html/user_data/packages/default/css/bloc.css

/* ===============================================
▼ランキング
=============================================== */
#ranking_area h2 {
color: #E65D19;
font-size:120%;
padding:3px 8px;
border-left:10px #E65D19 solid;
border-bottom:#999 3px double;
border-right:#CCC 1px solid;
border-top:#F60 1px solid;
background-color: #FCE3A0;
background: -moz-linear-gradient(top, #FEF2DA, #F7E17E); /* Firefox用 */
background: -webkit-gradient(linear, left top, left bottom, from(#FEF2DA), to(#F7E17E)); /* Safari,Google Chrome用 */
}
#ranking_area .block_body{
padding:10px;
}
#ranking_area .block_body ul {
}
#ranking_area li {
display:inline;
float:left;
list-style:none;
width:135px;
margin-right:10px;
}
#ranking_area .rank {
font-size:130%;
margin-bottom:3px;
}
#ranking_area .rank div {
padding-left:35px;
padding-top:10px;
height:20px;
}
#ranking_area #rank_1 {
background:url(../img/ranking/rank_1.png) no-repeat left bottom;
}
#ranking_area #rank_2 {
background:url(../img/ranking/rank_2.png) no-repeat left bottom;
}
#ranking_area #rank_3 {
background:url(../img/ranking/rank_3.png) no-repeat left bottom;
}
#ranking_area #rank_4 {
background:url(../img/ranking/rank_4.png) no-repeat left bottom;
}
#ranking_area #rank_5 {
background:url(../img/ranking/rank_5.png) no-repeat left bottom;
}
#ranking_area .image img {
border:#ccc 1px solid;
background-color:#FFF;
padding:3px;
}

/* メインカラム用 3カラムに配置した時 */
#three_maincolumn #ranking_area li {
width:101px;
}

/* サイドカラムに配置した時 */
.side_column #ranking_area .block_body{
padding:5px;
}
.side_column #ranking_area li {
background:url(../img/background/line_dot_01.gif) repeat-x bottom;
margin-bottom:5px;
padding-bottom:10px;
width:100%;
}
.side_column #ranking_area .left {
width:50%;
float:left;
}
.side_column #ranking_area .right {
width:40%;
float:right;
}

(4)下記の順位の画像を「ranking」フォルダに作成し、フォルダごとアップロードする。
■html/user_data/packages/default/img/ranking
画像名は、プログラムに関係しているので変更しない。
左から、rank_1.png rank_2.png rank_3.png rank_4.png rank_5.png

6位以降も表示させたいのであれば、同じように作成する。

—————————-
■■■スマートフォン用■■■
—————————-

1 ランキングを表示するための専用のページを新規作成する。

(1)下記の4つを作成

 ■html/sphone_ranking.php

<?php
// {{{ requires
require_once './require.php';
require_once CLASS_EX_REALDIR . 'page_extends/LC_Page_Sphone_ranking_Ex.php';

// }}}
// {{{ generate page

$objPage = new LC_Page_Sphone_ranking_Ex();
register_shutdown_function(array($objPage, "destroy"));
$objPage->init();
$objPage->process();
?>

 ■data/class_extends/page_extends/LC_Page_Sphone_ranking_Ex.php

<?php

// {{{ requires
require_once CLASS_REALDIR . 'pages/LC_Page_Sphone_ranking.php';

class LC_Page_Sphone_ranking_Ex extends LC_Page_Sphone_ranking {

// }}}
// {{{ functions

/**
* Page を初期化する.
*
* @return void
*/
function init() {
parent::init();
}

/**
* Page のプロセス.
*
* @return void
*/
function process() {
parent::process();
}

/**
* デストラクタ.
*
* @return void
*/
function destroy() {
parent::destroy();
}
}
?>

 ■data/class/pages/LC_Page_Sphone_ranking.php

<?php

// {{{ requires
require_once CLASS_EX_REALDIR . 'page_extends/LC_Page_Ex.php';

class LC_Page_Sphone_ranking extends LC_Page_Ex {

// }}}
// {{{ functions

/**
* Page を初期化する.
*
* @return void
*/
function init() {
parent::init();
}

/**
* Page のプロセス.
*
* @return void
*/
function process() {
parent::process();
$this->action();
$this->sendResponse();
}

/**
* Page のアクション.
*
* @return void
*/
function action() {
$this->tpl_title = '';
$objCustomer = new SC_Customer_Ex();
$this->isLogin = $objCustomer->isLoginSuccess(true);
}

/**
* デストラクタ.
*
* @return void
*/
function destroy() {
parent::destroy();
}
}
?>

 ■data/Smarty/templates/sphone/sphone_ranking.tpl

<!--▼検索バー -->
<section id="search_area">
<form method="get" action="<!--{$smarty.const.ROOT_URLPATH}-->products/list.php">
<input type="hidden" name="<!--{$smarty.const.TRANSACTION_ID_NAME}-->" value="<!--{$transactionid}-->" />
<input type="hidden" name="mode" value="search" />
<input type="search" name="name" id="search" value="" placeholder="キーワードを入力" class="searchbox" />
</form>
</section>
<!--▲検索バー -->

(2) データベースにページを登録

INSERT INTO dtb_pagelayout (device_type_id, page_id, page_name, url, filename, header_chk, footer_chk, edit_flg, author, description, keyword, update_url, create_date, update_date) VALUES (2, 30, 'ランキングページ', 'sphone_ranking.php', 'sphone_ranking', 1, 1, 2, NULL, NULL, NULL, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)

2 ブロックを作成する

(1) ■data/Smarty/templates/sphone/frontparts/bloc/ranking.tpl

<!-- ▼ランキング -->
<!--{if count($arrBestProducts) > 0}-->
<section id="recommend_area" class="mainImageInit">
<h2>売れ筋ランキング</h2>
<ul>
<!--{section name=cnt loop=$arrBestProducts}-->
<li id="mainImage<!--{$smarty.section.cnt.index}-->">
<div class="recommendblock clearfix">
<div class="rank">第<!--{$arrBestProducts[cnt].rank|h}-->位</div>
<table>
<tr>
<td class="left">
<div class="image">
<a href="<!--{$smarty.const.P_DETAIL_URLPATH}--><!--{$arrBestProducts[cnt].product_id|u}-->.html">
<img src="<!--{$smarty.const.ROOT_URLPATH}-->resize_image.php?image=<!--{$arrBestProducts[cnt].main_list_image|sfNoImageMainList|h}-->&amp;width=80&amp;height=80" alt="<!--{$arrBestProducts[cnt].name|h}-->" /></a>
</div>
</td>
<td class="right">
<a href="<!--{$smarty.const.P_DETAIL_URLPATH}--><!--{$arrBestProducts[cnt].product_id|u}-->.html"><!--{$arrBestProducts[cnt].name|h}--></a>
<p class="mini comment"><!--{$arrBestProducts[cnt].main_list_comment|h|nl2br}--></p>
<!--{assign var=price01 value=`$arrBestProducts[cnt].price01_min`}-->
<!--{assign var=price02 value=`$arrBestProducts[cnt].price02_min`}-->
<p class="sale_price"><span class="mini">販売価格(税込):</span><span class="price"><!--{$price02|sfCalcIncTax:$arrInfo.tax:$arrInfo.tax_rule|number_format}-->円</span></p>
</td>
</tr>
</table>
</div>
</li>
<!--{/section}-->
</ul>
</section>
<!--{else}-->
現在、売れ筋ランキングのデータがありません。
<!--{/if}-->
<!-- ▲ランキング -->


<script type="application/javascript">
<!--//
$(function(){
$('#recommend_area ul li').flickSlide({target:'#recommend_area>ul', duration:5000});
});
//-->
</script>

(2) データベースにブロックを登録

INSERT INTO dtb_bloc (device_type_id, bloc_id, bloc_name, tpl_path, filename, create_date, update_date, php_path, deletable_flg) VALUES (2, 10, 'ランキング', 'ranking.tpl', 'ranking', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'frontparts/bloc/ranking.php', 0)

3  管理画面「デザイン管理>スマートフォン>レイアウト設定」でランキングページを選択し、ブロックを配置する。

TOPページと同じに配置にした後、「おすすめ商品」ブロックをはずし、「ランキング」ブロックを置く。

4  ランキングページへのリンクを作成

■data/Smarty/templates/sphone/frontparts/bloc/recommend.tpl(最下部に追加)
(ランキングページを開くためには、「おすすめ商品」ブロックを配置しなければならない)

<div>
<ul class="navBox">
<li><a href="<!--{$smarty.const.ROOT_URLPATH}-->sphone_ranking.php">売れ筋ランキング</a></li>
</ul>
</div>

5 CSSに追加

■html/user_data/packages/sphone/css/block.css

/*-----------------------------------------------
ランキング
----------------------------------------------- */
#recommend_area .rank {
background-color:#C00;
padding:1px;
margin-bottom:5px;
color:#FFF;
font-weight:bold;
text-align:center;
}
#recommend_area table td {
text-align:left;
vertical-align:top;
}
#recommend_area table td.right {
padding-left:5px;
}

——————
■■■携帯用■■■
——————

1 データベースに携帯用のページを登録

INSERT INTO dtb_pagelayout (device_type_id, page_id, page_name, url, filename, header_chk, footer_chk, edit_flg, author, description, keyword, update_url, create_date, update_date) VALUES (1, 39, 'ランキングページ', 'sphone_ranking.php', 'sphone_ranking', 1, 1, 2, NULL, NULL, NULL, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)

2 ブロックを作成する(PC用のranking.tplが作成済みであることが前提)

(1) ■data/Smarty/templates/mobile/frontparts/bloc/ranking.tpl

<!-- ▼ランキング -->
<!--{if count($arrBestProducts) > 0}-->
<h3>売れ筋ランキング</h3><br>
<!--{section name=cnt loop=$arrBestProducts}-->
第<!--{$arrBestProducts[cnt].rank|h}-->位:<a href="<!--{$smarty.const.P_DETAIL_URLPATH}--><!--{$arrBestProducts[cnt].product_id|u}-->.html"><!--{$arrBestProducts[cnt].name|h}--></a><br>
<center><a href="<!--{$smarty.const.P_DETAIL_URLPATH}--><!--{$arrBestProducts[cnt].product_id|u}-->.html"><img src="<!--{$smarty.const.IMAGE_SAVE_URLPATH}--><!--{$arrBestProducts[cnt].main_list_image|h}-->"></a></center>
<!--{$arrarrBestProducts[cnt].main_list_comment|h|nl2br}--><br>
<!--{assign var=price01 value=`$arrBestProducts[cnt].price01_min`}-->
<!--{assign var=price02 value=`$arrBestProducts[cnt].price02_min`}-->
販売価格(税込):<!--{$price02|sfCalcIncTax:$arrInfo.tax:$arrInfo.tax_rule|number_format}-->円
<hr>
<!--{/section}-->
<!--{else}-->
<h3>売れ筋ランキング</h3><br>
現在、売れ筋ランキングのデータがありません。<br><br>
<!--{/if}-->
<!-- ▲ランキング -->

(2) データベースにブロックを登録

INSERT INTO dtb_bloc (device_type_id, bloc_id, bloc_name, tpl_path, filename, create_date, update_date, php_path, deletable_flg) VALUES (1, 7, 'ランキング', 'ranking.tpl', 'ranking', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'frontparts/bloc/ranking.php', 0)

3 ランキングページへのリンクを作成

(1)■data/Smarty/templates/mobile/frontparts/bloc/category.tpl(最上部の前に追加)
(ランキングページを開くためには、「カテゴリ」ブロックを配置しておかなければならない)

<!--▼ランキングここから-->
<!--{assign var=sphone_ranking  value="`$smarty.const.ROOT_URLPATH`sphone_ranking.php"}-->
<!--{if $smarty.server.PHP_SELF==$sphone_ranking}-->
<!--{else}-->
<hr>
<br>
<center><a href="<!--{$smarty.const.MOBILE_TOP_URLPATH}-->sphone_ranking.php">売れ筋ランキングを見る</a></center>
<br>
<hr>
<!--{/if}-->
<!--▲kランキングここまで-->

(2)デザイン管理>モバイル>レイアウト設定
ランキングページに、ブロックを配置する。ランキングブロックを必ず置く。
ランキングページでは、カテゴリブロックを置いてもランキングへのリンクは表示されない。