EC-CUBE:売れ筋ランキング(MySQL・PostgreSQL両対応)

ここで紹介している内容は、「EC-CUBEで売れ筋ランキングを表示する」とは異なるもので、MySQL・PostgreSQLの両方に対応しています。


ランキングの自動生成(dtb_rankingテーブルへの登録)は、システムの負担減を考え、ユーザーがアクセスした時に生成されるのではなく、管理者が管理画面にアクセスした際に生成されるように作成してあります。


1 データベース dtb_rankingテーブルの作成
———————————————
CREATE TABLE dtb_ranking(
rank int primary key,
product_id int,
quantity int
);
———————————————

2 ランキングの表示数を設定する定数をmtb_constantsテーブルに登録する。

ただし、表示数の最大値は「おすすめ商品表示数」となる。おすすめ商品表示数が8に設定されているとき、ランキング表示数を10に設定しても8個までしか表示されない。10個表示したい場合は、おすすめ商品表示数を10に設定する。
——————————————
id:RANKING_LIMIT
name:5(←定数)
rank:1246(←適宜)
remarks:売れ筋ランキングの表示数
——————————————

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

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 ファイル等の作成 下記の①~④のファイルとCSSファイルをダウンロードする

(1)下記ファイルを作成する(おすすめ商品[recommend]をもとに作成してある)
 ■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/rontparts/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="bloc_outer">

<div id="ranking_area">

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

<div class="bloc_body">

<ul>

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

<li>

<table>

<tr><td colspan="2" class="rank"><div id="rank_<!--{$arrBestProducts[cnt].rank|h}-->">第<!--{$arrBestProducts[cnt].rank|h}-->位</div></td></tr>

<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">

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

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

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

<p><!--{$price02|sfCalcIncTax:$arrInfo.tax:$arrInfo.tax_rule|number_format}-->円<br />(税込み)</p>

</td></tr></table>

</li>

<!--{/section}-->

</ul>

</div>

</div>

</div>

<!--{/if}-->

(2)データベースにブロックを登録
テーブル:dtb_bloc
device_type_id:10
bloc_id:11
bloc_name:ランキング
tpl_path:ranking.tpl
filename:ranking
create_date:作成日
update_date:作成日
php_path:frontparts/bloc/ranking.php
deletable_flg:0

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

 /* ===============================================
 ▼ランキング
 =============================================== */
 #ranking_area .bloc_body{
 border:none;
 }
 #ranking_area table {
 margin-bottom:0;
 border:none;
 }
 #ranking_area table td {
 padding:0px;
 border:none;
 vertical-align:top;
 }
 #ranking_area li {
 list-style:none;
 margin-bottom:0;
 padding-bottom:5px;
 background:url(../img/background/line_dot_01.gif) repeat-x bottom;
 }
 #ranking_area .rank {
 font-size:130%;
 font-weight:bold;
 padding-bottom:5px;
 }
 #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 .left {
 width:97px;
 }
 #ranking_area .image {
 border:#999 1px solid;
 background-color:#FFF;
 padding:3px;
 width:80px;
 }

(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位以降も表示させたいのであれば、同じように作成する。