SOY CMSのブロックの機能で、

記事の並べ順をランダムにしたいという質問があった。


SOY CMSのブロック機能で自由に定義を決められるのは、

スクリプトモジュールブロックだけなので、

とりあえずスクリプトモジュールブロックでランダム表示を書いてみた。


スクリプトモジュールブロックはなんぞや?ということもあるだろうから、

スクリプトモジュールブロック関連の記事を貼っておく。

検索フォームと検索結果ページを作ってみた1

検索フォームと検索結果ページを作ってみた2

検索フォームと検索結果ページを作ってみた3




早速ファイルを作成してみる。

ファイルは


/site(サイトID)/script/soycms_random.php

にした。


作成したsoycms_random.phpに下記のコードを記述した。


<?php

function soycms_random(){
	$pageId = (int)$_SERVER["SOYCMS_PAGE_ID"];

	//ブログページか調べる
	$template = "";
	try{
		$blog = SOY2DAOFactory::create("cms.BlogPageDAO")->getById($pageId);
		$uri = str_replace("/" . $_SERVER["SOYCMS_PAGE_URI"] . "/", "", $_SERVER["PATH_INFO"]);

		//トップページ
		if($uri === (string)$blog->getTopPageUri()){
			$template = $blog->getTopTemplate();
		//アーカイブページ		
		}else if(strpos($uri, $blog->getCategoryPageUri()) === 0 || strpos($uri, $blog->getMonthPageUri()) === 0){
			$template = $blog->getArchiveTemplate();
		//記事ごとページ
		}else{
			$template = $blog->getEntryTemplate();
		}
	}catch(Exception $e){
		try{
			$template = SOY2DAOFactory::create("cms.PageDAO")->getById($pageId)->getTemplate();
		}catch(Exception $e){
			return array();
		}
	}

	try{
		$blocks = SOY2DAOFactory::create("cms.BlockDAO")->getByPageId($pageId);
	}catch(Exception $e){
		return array();
	}

	if(!count($blocks)) return array();

	$block = null;
	foreach($blocks as $obj){
		if($obj->getClass() == "ScriptModuleBlockComponent"){
			$block = $obj;
		}
	}

	if(is_null($block)) return array();

	//ラベルIDを取得とデータベースから記事の取得件数指定
	$labelId = null;
	$count = null;
	if(preg_match('/(<[^>]*[^\/]block:id=\"' . $block->getSoyId() . '\"[^>]*>)/', $template, $tmp)){
		if(preg_match('/cms:label=\"(.*?)\"/', $tmp[1], $ltmp)){
			if(isset($ltmp[1]) && is_numeric($ltmp[1])) $labelId = (int)$ltmp[1];
		}
		if(preg_match('/cms:count=\"(.*?)\"/', $tmp[1], $ctmp)){
			if(isset($ctmp[1]) && is_numeric($ctmp[1])) $count = (int)$ctmp[1];
		}
	}else{
		return array();
	}

	$entryDao = SOY2DAOFactory::create("cms.EntryDAO");
	$sql = "SELECT ent.* FROM Entry ent ".
		 "JOIN EntryLabel lab ".
		 "ON ent.id = lab.entry_id ".
		 "WHERE ent.openPeriodStart < " . time() . " ".
		 "AND ent.openPeriodEnd >= " .time() . " ".
		 "AND ent.isPublished = " . Entry::ENTRY_ACTIVE . " ";
	$binds = array();
	
	//ラベルIDを指定する場合
	if(isset($labelId)){
		$sql .= "AND lab.label_id = :labelId ";
		$binds[":labelId"] = $labelId;
	}

	$sql .= "GROUP BY ent.id ";

	if(SOY2DAOConfig::type() == "mysql"){
		$sql .= "ORDER BY Rand() ";
	}else{
		$sql .= "ORDER BY Random() ";
	}

	if(isset($count) && $count > 0) {
		$sql .= "Limit " . $count;
	}
		
	try{
		$res = $entryDao->executeQuery($sql, $binds);
	}catch(Exception $e){
		$res = array();
	}

	if(!count($res)) return array();

	$entries = array();
	foreach($res as $v){
		$entries[] = $entryDao->getObject($v);
	}

	return $entries;
}
?>

なんとこのコード、

ラベル名や記事の取得件数をテンプレートでのブロックの記述の際に指定することができるため、

サイトの至るところで使い回すことが可能です。


使い方は、

テンプレートのブロックの記述の際に、


<!-- block:id="test" cms:label="2" cms:count="5" -->
<h3 cms:id="title">記事タイトル</h3>
<div cms:id="content">記事本文</div>
<!-- /block:id="test" -->

cms:labelはランダム表示したい記事のラベルID、

cms:countはランダム表示したい記事数を指定で、

指定しない場合は片っ端から記事を取得します。


テンプレート周りをもう少し手を加える必要がありますが、

一応動作するのでよろしければご利用ください。


今回のコードはフォーラムにアップロードしました。

SOY CMS フォーラム • トピックの表示 - ラベル毎の記事ランダム並び替え