LOGIN ID Password Auto Login Register Now! Lost Password?
Xoops Q&A

d3forum側で統合コメントのツリー全表示

  • このフォーラムに新しいトピックを立てることはできません
  • このフォーラムではゲスト投稿が禁止されています

投稿ツリー


前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 .2 | 投稿日時 2009/3/20 21:45 | 最終変更
naao  Commander 居住地: 2006年10月頃~  投稿数: 509
こんにちは。

コメント統合に関連するd3forumの質問になります。
GIJOEさんに直撃になっちゃいます。 いつものように前置きが長くてすみません。 (お忙しいと思いますので、後回しで結構です)

【背景】
 コメント統合で付いたコメント。 質問内容が変わったりしてトピック分けしたりすると、d3forum側で「このトピックの投稿一覧へ」で閲覧してもトピック内の投稿しか表示されないため、 同じ元記事に紐付いた他のトピックの投稿に気づかない場合があります。 

 現状では、元記事にジャンプして初めてその存在に気づくことになっていて、最大表示記事数を超えている場合は元記事側でも他のトピの投稿が流れてしまって表示されない場合もあります。 こういう時は、仕方なく「トピック表示」にしたりしますが、訪問者から見るとコメントし辛い感じ。

 色々な案を考えてやってみたのですが、一番しっくりきたのはd3forum側で「このトピックの投稿一覧へ」を表示したときに、他のトピも含めてツリーを表示するというものです。

【方法】
 (d3forum)_main_listposts.html を編集するのですが、「(d3forum)_main_viewpost.html」から引っ張ってきたツリー部分を貼るだけでは、当該トピ分のツリーしか表示されません。
 そこで、まずはsmartyプラグインを書いてみました。
  (この投稿のお尻に記載したソースです)
 ツリーのリンクをクリックすると、同トピ内記事はアンカーへジャンプし、他トピ内記事にはページ遷移、としています。

【質問事項】
 ツリー構造自体はこれでうまく作れたのですが、一つ問題が残りました。「ツリー構造順で表示」「投稿の新しいものから」「投稿の古いものから」をクリックした時の、昇順/降順の切り替えをツリー順に反映する方法を求めてソースを見て回りましたが、探しきれずに行き詰ってしまいました。
(trust)/modules/d3forum/include/listposts.php の103行目付近、
$posts = d3forum_make_treeinformations( $posts ) ;
 から、「main_functions.php」に行き着きました。 が、同listposts.phpの 106行目付近
switch( $postorder ) {
 の$postorder の元を追いかけるところで、自分の実力より深追いしすぎた気がして止まっています。

 このまま追っていけば、下記コードに追記する形で実装できそうでしょうか? あるいは、もっと簡単な実装が可能かどうかも含めてどうぞご指導お願いします。

【コード】
(追記:コメント統合でないforumでも、topic_idを渡してトピック内ツリーを表示するように変更しました)
(再追記:コメント統合元のmodule_configの「表示数」「昇順/降順」設定を反映するように変更しました) → この中で拾っても、d3forumのだから元記事モジュールのは入ってこないので駄目でした。 それに$xoopsConfigじゃあないし。

・html/class/smarty/plugins/function.d3comment_tree.php として新規作成。
<?php
/*
 * Smarty plugin
 * -------------------------------------------------------------
 * Type:     function
 * Name:     d3comment_tree
 * Version:  0.1.1
 * Date:     March 21, 2009
 * Author:   naao
 * Purpose:  Shows comment trees in a external link id
 * Input:    
 * 
 * Examples: <{d3comment_tree forum_dirname=$mydirname forum_id=$forum.id external_link_id=$topic.external_link_id order="ASC" limit=10 item="tree"}>
 *
 */
function smarty_function_d3comment_tree($params, &$smarty)
{
	global $xoopsUser , $xoopsConfig , $xoopsModule ;

	// transitional from 'dirname' -> 'forum_dirname'
	$params['forum_dirname'] = @$params['forum_dirname'] . @$params['dirname'] ;

	$forum_dirname = ! empty( $params['forum_dirname'] ) ? $params['forum_dirname'] : 1 ;
	$forum_id = ! empty( $params['forum_id'] ) ? intval( $params['forum_id'] ) : 1 ;
	$topic_id = ! empty( $params['topic_id'] ) ? intval( $params['topic_id'] ) : 0 ;
	$external_link_id = ! empty( $params['external_link_id'] ) ? intval( $params['external_link_id'] ) : 1 ;

	$sql_order =  strtolower($xoopsConfig['comment_order']) == 'asc' ? 'ASC'  : (strtolower(@$params['order']) == 'asc' ? 'ASC' : 'DESC') ;
	$limit = ! empty( $xoopsConfig['comment_posts_num'] ) ? intval( $xoopsConfig['comment_posts_num'] ) : ! empty( $params['limit'] ) ? intval( $params['limit'] ) : 100 ;
	
	
	if( ! preg_match( '/^[0-9a-zA-Z_-]+$/' , $forum_dirname ) || $forum_id <= 0 || $external_link_id <= 0 ) {
		echo "<p>d3comment_tree function does not set properly.</p>" ;
	} else {


		$db =& Database::getInstance() ;
		$myts =& MyTextSanitizer::getInstance() ;

		// main query
		$sql = "SELECT p.*,t.topic_locked,t.topic_id,t.forum_id FROM ".$db->prefix($forum_dirname."_posts")." p LEFT JOIN ".$db->prefix($forum_dirname."_topics")." t ON p.topic_id=t.topic_id WHERE t.forum_id='".$forum_id."' AND (topic_external_link_id='".addslashes($external_link_id)."' OR t.topic_id='".addslashes($topic_id)."') ORDER BY post_time DESC LIMIT $limit" ;

		if( ! $trs = $db->query( $sql ) ) die( _MD_D3FORUM_ERR_SQL.__LINE__ ) ;
		$user_handler =& xoops_gethandler( 'user' ) ;
		
		while( $post_row = $db->fetchArray( $trs ) ) {

			// get this poster's object
			$poster_obj =& $user_handler->get( intval( $post_row['uid'] ) ) ;
			if( is_object( $poster_obj ) ) {
				$poster_uname4disp = $poster_obj->getVar( 'uname' ) ;
			} else {
				$poster_uname4disp = "" ;
			}

			$poster_uname4disp = $poster_uname4disp ? $poster_uname4disp : $myts->makeTboxData4Show( $post_row['guest_name'] ) ;

			// posts array
			$posts[] = array(
				'id' => intval( $post_row['post_id'] ) ,
				'subject' => $myts->makeTboxData4Show( $post_row['subject'] , $post_row['number_entity'] , $post_row['special_entity'] ) ,
				'post_time_formatted' => formatTimestamp( $post_row['post_time'] , 'm' ) ,
				'poster_uid' => intval( $post_row['uid'] ) ,
				'poster_uname' => $poster_uname4disp ,
				'icon' => intval( $post_row['icon'] ) ,
				'depth_in_tree' => intval( $post_row['depth_in_tree'] ) ,
				'order_in_tree' => intval( $post_row['order_in_tree'] ) ,
				'topic_id' => intval( $post_row['topic_id'] ) ,
				'ul_in' => '<ul><li>' ,
				'ul_out' => '</li></ul>' ,
			) ;
		}
		
		// reverse array if order is "ASC"
		if ($sql_order == 'ASC') {$posts = array_reverse($posts);}
		
		$assign_name = @$params['item'] . @$params['assign'] ;
		$smarty->assign( $assign_name , $posts ) ;
	}
}

?>

・テンプレート d3forum_main_listposts.html に以下を追記
<{d3comment_tree forum_dirname=$mydirname forum_id=$forum.id topic_id=$topic.id external_link_id=$topic.external_link_id order="asc" item="tree"}>

<!-- start post tree  -->
<h2 class="head d3f_tree d3f_head"><{$smarty.const._MD_D3FORUM_POSTSTREE}></h2>

<{foreach from=$tree item=eachpost}>
	<{$eachpost.ul_in|replace:"<ul>":"<ul class='d3f_eachbranch'>\n\t"|replace:"<li>":"<li class='d3f_eachbranchitem'><span style='padding-left:`$eachpost.depth_in_tree`0px;'>"}>
	<a href="<{$mod_url}>/index.php?topic_id=<{$eachpost.topic_id}>#post_id<{$eachpost.id}>" id="post_path<{$eachpost.unique_path}>" name="post_path<{$eachpost.unique_path}>"><img src="<{$mod_imageurl}>/posticon<{$eachpost.icon}>.gif" alt="<{$icon_meanings[$eachpost.icon]}>" /> <{$eachpost.subject}></a>
	(<{$eachpost.poster_uname}>, <{$eachpost.post_time_formatted}>)
	<{if $forum.isadminormod}><a href="<{$mod_url}>/index.php?page=cutpasteposts&amp;post_id=<{$eachpost.id}>"><img src="<{$mod_imageurl}>/adminicon_cutpaste.gif" alt="<{$smarty.const._MD_D3FORUM_CUTPASTEPOSTS}>" /></a><{/if}></span>
<{$eachpost.ul_out}>
<{/foreach}>
<!-- end post tree  -->

・テンプレート d3forum_comment_listposts_flat.html
(コメント元での表示でも使用する場合)
<{d3comment_tree forum_dirname=$mydirname forum_id=$forum.id external_link_id=$external_link_id|escape:"url" order="asc" limit="10" item="tree"}>

<!-- start post tree  -->
<h2 class="head d3f_tree d3f_head"><{$smarty.const._MD_D3FORUM_POSTSTREE}></h2>
<{foreach from=$tree item=eachpost}>
	<ul class='d3f_eachbranch'><{"<span style='padding-left:`$eachpost.depth_in_tree`0px; padding-top: 0;'>"}>
	<a href="<{$mod_url}>/index.php?topic_id=<{$eachpost.topic_id}>#post_id<{$eachpost.id}>" id="post_path<{$eachpost.unique_path}>" name="post_path<{$eachpost.unique_path}>"><img src="<{$mod_imageurl}>/posticon<{$eachpost.icon}>.gif" alt="<{$icon_meanings[$eachpost.icon]}>" /> <{$eachpost.subject}></a>
	(<{$eachpost.poster_uname}>, <{$eachpost.post_time_formatted}>)
	<{if $forum.isadminormod}><a href="<{$mod_url}>/index.php?page=cutpasteposts&amp;post_id=<{$eachpost.id}>"><img src="<{$mod_imageurl}>/adminicon_cutpaste.gif" alt="<{$smarty.const._MD_D3FORUM_CUTPASTEPOSTS}>" /></a><{/if}></span>
<{$eachpost.ul_out}>
<{/foreach}>
<!-- end post tree  -->

【実装済サイト】
 こんな感じ(d3forum側)
投票数:0 平均点:0.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2009/3/22 5:01
GIJOE  Admiral 居住地: 2003年4月くらい  投稿数: 3708
naaoさん、こんにちは。

引用:

 現状では、元記事にジャンプして初めてその存在に気づくことになっていて、最大表示記事数を超えている場合は元記事側でも他のトピの投稿が流れてしまって表示されない場合もあります。 こういう時は、仕方なく「トピック表示」にしたりしますが、訪問者から見るとコメントし辛い感じ。

 色々な案を考えてやってみたのですが、一番しっくりきたのはd3forum側で「このトピックの投稿一覧へ」を表示したときに、他のトピも含めてツリーを表示するというものです。
なるほど。
このあたりはなかなか悩ましいですね。

別の話題でも同一トピックにして、トピックツリーの最初を2番3番…とする、なんて手はあるかな、とか思ってました。

他のトピックを表示、というのは確かに良い手ですね。

引用:
 このまま追っていけば、下記コードに追記する形で実装できそうでしょうか? あるいは、もっと簡単な実装が可能かどうかも含めてどうぞご指導お願いします。
現在リンク先が死んでいるので良く判らないのですが、おそらく実装できているんですよね。
それはそれでアリだと思います。

個人的には、そうやってコントローラを独自に増やしてしまうと、結果的に仕様変更に追いつけなくなるので、自分自身が面倒になるかな、という気がします。

この手の情報を、あるモジュールから取得しようとするなら、独自のコントローラを作るより、該当モジュールのブロック表示関数を流用する方がお勧めです。それなら、モジュール作者が仕様を変更したとしても、ブロック表示関数側も修正するでしょうから、手を入れる必要がありません。一種のAPIであるブロックオプション(=引数)さえ大きく変わらなければ、という前提ですが。

もっとも、d3forumには、external_link_idでの絞り込み機能のあるトピック/投稿一覧ブロックなんてないので、d3forum側で対応しないといけないですね。
投票数:0 平均点:0.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2009/3/22 9:14 | 最終変更
naao  Commander 居住地: 2006年10月頃~  投稿数: 509
GIJOEさん、こんにちは。

お返事ありがとうございます。

引用:
なるほど。
このあたりはなかなか悩ましいですね。

別の話題でも同一トピックにして、トピックツリーの最初を2番3番…とする、なんて手はあるかな、とか思ってました。

他のトピックを表示、というのは確かに良い手ですね。

クイック投稿を新規トピにするかどうか、というあたりの話でしたっけ? 

その話でしたら、質問系のようにクイック投稿を新規トピにしたい使用例もあれば、単純なブログのコメントのように1つの投稿に繋げる現状の仕様のほうが良い場合もあって、まさに悩ましいですね。

希望としては、これもユーザーが統合コメント元のテンプレートなどで選択できると嬉しいです。(デフォは現状仕様で。。あ、要望になってしまった。) 

今回の「他のトピックも合わせてツリー表示」にしても、サイト管理者がどう考えるかで全く変わってくるので、オプション的に実装できるようになっていれば十分だと思っています。

引用:
もっとも、d3forumには、external_link_idでの絞り込み機能のあるトピック/投稿一覧ブロックなんてないので、d3forum側で対応しないといけないですね。
本体のブロックで引数で受けて$block[]内に格納してくださるのでしたら、xugj-blockでテンプレート内で指定することで表示できますね。 いつか採用いただきたく、お願い致します。

ついでといってはなんですが、例えばブログや日記モジュールなどで、「○○さんの記事へのコメント」を統合コメントから絞り込んでブロック表示させたい、という要望があります。 ブログ等のモジュールでマルチユーザーでコメント統合する場合に必要ですよね。
以前の投稿で、minidiaryでこれを実現するために、「block_functions.php」を拡張して別関数を定義し、これをxugj_blockで表示させた実装があります。(昨日更新)
 ここにて掲載・配布してあります
(追記:実装はこちら右側の「最近のコメント」。minidiaryは元々メインページ内にブロック分割表示の仕様です。)

その「(trust)/modules/d3forum/blocks/block_functions_bcomment.php」の一部を下記します。
受けたOPTIONから、ブログ側DBテーブルにクエリを発行してブログ執筆者の投稿bidをArrayで取得した後で、d3forumのクエリにtopic_external_link_idがそれに合致するよう絞り込む、という流れです。
function b_d3forum_list_posts_show( $options )
{
	global $xoopsUser ;

	$mydirname = empty( $options[0] ) ? 'd3forum' : $options[0] ;
	$max_posts = empty( $options[1] ) ? 10 : intval( $options[1] ) ;
	$now_order = empty( $options[2] ) ? 'time' : trim( $options[2] ) ;
	$categories = empty( $options[3] ) ? array() : explode(',',$options[3]) ;
	$this_template = empty( $options[4] ) ? 'db:'.$mydirname.'_block_list_posts.html' : trim( $options[4] ) ;
	$forums = empty( $options[5] ) ? array() : explode(',',$options[5]) ;
	$blogger_uid = empty( $options[6] ) ? 0 : intval( $options[6] ) ; //naao added
	$blog_prefix = empty( $options[7] ) ? "d3blog_entry" : $options[7] ; //naao added
こんなのももっとうまい仕組みでコメント元モジュールとの連携が何とかなるといいなあ、、なんて妄想してます。

** 以下、雑談
引用:
現在リンク先が死んでいるので良く判らないのですが、おそらく実装できているんですよね。
あぁ、バックアップのために毎週日曜日の早朝に仮想ゲストのスリープ/丸ごとコピー/リジュームを行っているので、止まってました。

と思って調べたら、DDNSのdicedが調子悪くて1週間更新されていませんでした。(1年前くらいに同様の症状があったような。。)
固定IPなんですが、とある事情でDDNSを通してるんです。
今は正常に表示されていると思います。
投票数:1 平均点:10.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2009/3/26 21:55 | 最終変更
naao  Commander 居住地: 2006年10月頃~  投稿数: 509
こんばんは。

自己レスです。

引用:
 ツリー構造自体はこれでうまく作れたのですが、一つ問題が残りました。「ツリー構造順で表示」「投稿の新しいものから」「投稿の古いものから」をクリックした時の、昇順/降順の切り替えをツリー順に反映する方法

この件、自己解決しました。 smarty変数に$postorder がアサインされていたので、これを使用することに致しました。 (但し、「ツリー構造順」は追いきれなかったので反映できていません。)(「ツリー構造順」も反映しました。)

変更後のソース等は、こちらのページにまとめました。 細かな修正と、プラグイン内ソースも整理しました。
(追記)コメント元ページにツリー表示とトピック一覧を表示するように再修正しました。

以上にて、当初の質問は解決済みです。よろしくお願いします。
投票数:0 平均点:0.00
  条件検索へ

Back to Page Top
MainMenu
Manuals
Search
XOOPS Official & Dev.
XOOPS Communities