SOY Shopの商品詳細ページで、関連商品を登録されている全商品もしくは指定したカテゴリから指定した件数だけランダムで取得して表示したいという要望がありましたので、対応方法を記載します。


上記の要望に対してのモジュールはありませんので、

PHPモジュールとSOY2DAOを駆使して自作してみます。

SOY CMSでどのページでも使えるブログのサイドバーを作ってみた

SOY2DAOでSQLを実行して、オブジェクトで返す


PHPモジュールは使用制限を設けていますので、

今回の内容を試す前にPHPモジュールの使用制限を外してください。

SOY CMS/ShopでPHPモジュールに使用の制限を設けました




管理画面のテンプレート管理で



モジュールの追加ボタンをクリックし、



モジュールIDをitem.randomで作成してみた。

※モジュール名は何でも良いです。


モジュール作成後、編集画面を開き、下記のコードを登録する。


<?php
//ここにモジュールとして読み込むHTML・PHPを記述してください。
//使用可能な変数
//     $html	テンプレートに記述されたHTML
//     $htmlObj	ページオブジェクト($htmlObj->createAdd()が使えます)

$itemDao = SOY2DAOFactory::create("shop.SOYShop_ItemDAO");

$categoryId = null;		//カテゴリを指定する nullの場合はすべての商品から
$limit = 5;			//表示件数を指定する

//カテゴリを指定した場合
if(isset($categoryId)){

	$sql = "SELECT * FROM soyshop_item ".
			"WHERE item_type IN ('single','group','download') ".
			"AND item_category = :categoryId ".
			"AND is_disabled != 1 ".
			"AND item_is_open = 1 ".
			"AND open_period_start < " . time() . " ".
			"AND open_period_end > " . time() . " ".
			"ORDER BY Rand() ".		//MySQL版。SQLite版の時はRand()の代わりにRandom()を使用する
			"LIMIT " . $limit;
			
	try{
		$res = $itemDao->executeQuery($sql, array(":categoryId" => $categoryId));
	}catch(Exception $e){
		$res = array();
	}

//カテゴリを指定しなかった場合
}else{

	$sql = "SELECT * FROM soyshop_item ".
			"WHERE item_type IN ('single','group','download') ".
			"AND is_disabled != 1 ".
			"AND item_is_open = 1 ".
			"AND open_period_start < " . time() . " ".
			"AND open_period_end > " . time() . " ".
			"ORDER BY Rand() ".		//MySQL版。SQLite版の時はRand()の代わりにRandom()を使用する
			"LIMIT " . $limit;
			
	try{
		$res = $itemDao->executeQuery($sql);
	}catch(Exception $e){
		$res = array();
	}
}

$items = array();

if(count($res)) {
	foreach($res as $v){
		if(!isset($v["id"])) continue;	//データが取得できているか念のために調べておく
		$items[] = $itemDao->getObject($v);
	}
}

//ここから先はcms:idを生成するためのお約束 2行目にあるfunctionの後ろにある文字列を指定する
$obj = $htmlObj->create("soyshop_random","HTMLTemplatePage", array(
	"arguments" => array("soyshop_random",$html)
));

$obj->createAdd("random_item_list","SOYShop_ItemListComponent", array(
	"list" => $items,
	"soy2prefix" => "block",
));

//商品があるときだけ表示
if(count($items) > 0){
	$obj->display();
}
?>

これで、<!-- shop:module="item.random" -->と

その中で<!-- block:id="random_item_list" -->が使用できるようになった。


商品詳細ページのテンプレートを開き、


<!-- shop:module="item.random" -->
<section class="items">
	<h1>ランダム関連商品</h1>
	<div class="item_list">
		<!-- block:id="random_item_list" -->
		<article>
			<a href="detail2.html" cms:id="item_link"><img cms:id="item_small_image" src="/shop2/themes/photos/list_sample2.jpg" width="150" height="113" alt="ナノブロック">
			<h1 cms:id="item_name">ナノブロック</h1></a>
			<p class="tag"><!-- cms:id="custom_icon_field" /--></p>
			<p class="price">¥<!-- cms:id="item_price" -->2,100<!-- /cms:id="item_price" --></p>
			<p class="text" cms:id="item_copy1">ナノブロックのセット。犬シリーズです。ぜひ組み立てて遊んでみてください。</p>
			<p class="new" cms:id="this_is_new"><img src="/shop2/themes/common/images/new_icon.png" alt="NEW!"></p>
			<p class="more"><a href="" cms:id="item_link*">>>詳細を見る</a></p>
		</article>
		<!-- /block:id="random_item_list" -->
	</div>
</section>
<!-- /shop:module="item.random" -->

このようなHTMLを記述して表示してみたところ、



こんな感じで表示された。

試しにページの再読み込みをしてみると、



表示順が変わった。

これで意図した動作になったわけだ。


現時点でのコードは公開している商品全てで、

指定したカテゴリというわけではないので、

最後にカテゴリの指定を行います。


カテゴリ1というカテゴリに紐付いた商品をランダムで表示するとして、



カテゴリ1の詳細画面を開いて、アドレスバーを確認し、

https://example.com/cms/soyshop/index.php/Item/Category/Detail/1

だった時、末尾の1を先ほど作成したモジュールのコードの

$categoryId = null;

の箇所を

$categoryId = 1;

に変更すれば終了です。