1: 2009-05-24 (日) 10:25:27 なーお |
現: - no date - |
- | * XSNSモジュールの新着トピックで新着コメントを取得したい [#t844a559] | |
- | XSNSモジュールを使用させていただいています。 | |
- | 本格的に使い始めたところで、ちょっと問題に直面しまして解決させたので、役に立つ場面もあるかと思い、記事にしておきます。 | |
| | | |
- | ** 概要 [#if89ed49] | |
- | - XSNSで新着トピブロックを使ったとき、ブロックに表示される新着リンクをクリックしても、トピックの頭の説明にジャンプします。mixiでもトピの頭に飛ぶので同様の仕様と言えなくもありませんが、これを最新記事にジャンプさせたいと思いました。 | |
- | - XSNSのd3pipesブロックジョイントクラス「D3pipおesBlockXsnstopiclist.class.php」で取得するトピックの本文が、最新のコメントではなく、毎回トピ説明が同じように繰り返されます。 ここはやはり、「新着コメント」のほうの本文を通知してほしいものです。 | |
- | | |
- | ということで、原因を探してましたが、どうやら「(trust)/modules/blocks/block_functions.php」「function b_xsns_recent_topic_show」の中でDBから取得するSQLに問題がありそう。。 :roll: | |
- | | |
- | ** 問題の箇所 [#p67a389b] | |
- | 「(trust)/modules/blocks/block_functions.php」の25行目付近 | |
- | #code(php,25-){{ | |
- | // topic search | |
- | $sql = "SELECT ". | |
- | "c.c_commu_id AS cid,". | |
- | "c.name AS cname,". | |
- | "c.uid_admin AS cadmin,". | |
- | "c.uid_sub_admin AS csubadmin,". | |
- | "c.public_flag AS cflag,". | |
- | "t.c_commu_topic_id AS tid,". | |
- | "t.name AS tname,". | |
- | "tc.body AS tcbody,". | |
- | "tc.uid AS tcuid,". | |
- | "MAX(tc.number) AS comment_count,". | |
- | "MAX(tc.r_datetime) AS max_r_datetime". | |
- | " FROM (". $db->prefix($mydirname.'_c_commu'). " c". | |
- | " INNER JOIN ". $db->prefix($mydirname.'_c_commu_topic_comment'). " tc". | |
- | " USING(c_commu_id))". | |
- | " INNER JOIN ". $db->prefix($mydirname.'_c_commu_topic'). " t". | |
- | " USING(c_commu_topic_id)". | |
- | " GROUP BY tid". | |
- | " ORDER BY max_r_datetime DESC"; | |
- | }} | |
- | | |
- | なお、以下の説明は私も勉強しながら知った身なので言うことが間違っているかもしれません。 | |
- | | |
- | 上のSQL文で、GROUP BY tidでトピックIDでグループ化して抽出、MAX(tc.number)、MAX(tc.r_datetime)で各最大値を取得する、までは良いのですが、そこに様々な他のフィールドを検索取得するような指定を並べてます。 | |
- | この方法は、[[結果を保証されない方式であるとの情報:http://q.hatena.ne.jp/1213899211#a836594]]もありますし、最新のsubjectが得られそうで実際には得られていません。 | |
- | | |
- | そこで、自分なりに見やすいクエリ2つに分割しました。 | |
- | | |
- | #code(php,1-){{ | |
- | function b_xsns_recent_topic_show($options) | |
- | { | |
- | global $xoopsUser, $xoopsUserIsAdmin; | |
- | | |
- | require_once dirname(dirname(__FILE__)).'/include/common_functions.php'; | |
- | | |
- | $db =& Database::getInstance(); | |
- | $myts =& MyTextSanitizer::getInstance(); | |
- | | |
- | $mydirname = empty($options[0]) ? 'xsns' : $options[0]; | |
- | $item_limit = empty($options[1]) ? 5 : intval($options[1]); | |
- | | |
- | if( preg_match( '/[^0-9a-zA-Z_-]/' , $mydirname ) ) die( 'Invalid dirname' ) ; | |
- | | |
- | $constpref = '_MB_'.strtoupper($mydirname); | |
- | | |
- | $block = array(); | |
- | $perm_arr = array(); | |
- | | |
- | $own_uid = is_object($xoopsUser) ? $xoopsUser->getVar('uid') : -1; | |
- | | |
- | // naao from | |
- | //各トピの最新コメントIDを取得 | |
- | $sql = "SELECT c_commu_topic_id AS tid, MAX(c_commu_topic_comment_id) AS com_id FROM ". $db->prefix($mydirname.'_c_commu_topic_comment')." GROUP BY tid;"; | |
- | | |
- | $result = $db->query($sql); | |
- | if(!$result || $db->getRowsNum($result) < 1){ | |
- | return array(); | |
- | } | |
- | | |
- | while ( $dbdat = $db->fetchArray($result)){ | |
- | $com_num[] = $dbdat['com_id']; | |
- | } | |
- | | |
- | $whr_num = "tc.c_commu_topic_comment_id IN (" .implode( "," , $com_num ). ") "; | |
- | | |
- | // topic search | |
- | $sql = "SELECT ". | |
- | "c.c_commu_id AS cid,". | |
- | "c.name AS cname,". | |
- | "c.uid_admin AS cadmin,". | |
- | "c.uid_sub_admin AS csubadmin,". | |
- | "c.public_flag AS cflag,". | |
- | "t.c_commu_topic_id AS tid,". | |
- | "t.name AS tname,". | |
- | "tc.body AS tcbody,". | |
- | "tc.uid AS tcuid,". | |
- | "tc.number AS comment_count,". | |
- | "tc.r_datetime AS r_datetime,". | |
- | "tc.c_commu_topic_comment_id ". | |
- | " FROM (". $db->prefix($mydirname.'_c_commu'). " c". | |
- | " INNER JOIN ". $db->prefix($mydirname.'_c_commu_topic_comment'). " tc". | |
- | " USING(c_commu_id))". | |
- | " INNER JOIN ". $db->prefix($mydirname.'_c_commu_topic'). " t". | |
- | " USING(c_commu_topic_id)". | |
- | " WHERE ".$whr_num. | |
- | " ORDER BY r_datetime DESC"; | |
- | // naao to | |
- | | |
- | $rs = $db->query($sql); | |
- | if(!$rs || $db->getRowsNum($rs) < 1){ | |
- | return array(); | |
- | } | |
- | | |
- | $today = date('Y-m-d'); | |
- | $item_count = 0; | |
- | require_once dirname(dirname(__FILE__)).'/userlib/utils.php'; | |
- | | |
- | while($row = $db->fetchArray($rs)) { | |
- | | |
- | if($item_limit <= $item_count){ | |
- | break; | |
- | } | |
- | | |
- | // check community permission | |
- | if($row['cflag']==3 && !$xoopsUserIsAdmin && $row['cadmin']!=$own_uid && $row['csubadmin']!=$own_uid){ | |
- | if($own_uid < 0){ | |
- | continue; | |
- | } | |
- | $cid = intval($row['cid']); | |
- | if(!isset($perm_arr[$cid])){ | |
- | $perm_arr[$cid] = xsns_is_community_member($mydirname, $cid, $own_uid); | |
- | } | |
- | if(!$perm_arr[$cid]){ | |
- | continue; | |
- | } | |
- | } | |
- | | |
- | //$date_arr = explode(' ', XsnsUtils::getUserDatetime($row['max_r_datetime']), 2); | |
- | $date_arr = explode(' ', XsnsUtils::getUserDatetime($row['r_datetime']), 2); //naao | |
- | if(!is_array($date_arr)){ | |
- | continue; | |
- | } | |
- | if($today==$date_arr[0]){ | |
- | $r_time_arr = explode(':', $date_arr[1], 3); | |
- | if(!is_array($r_time_arr)){ | |
- | continue; | |
- | } | |
- | $r_time = $r_time_arr[0].':'.$r_time_arr[1]; | |
- | } | |
- | else{ | |
- | $r_time_arr = explode('-', $date_arr[0], 3); | |
- | if(!is_array($r_time_arr)){ | |
- | continue; | |
- | } | |
- | $r_time = $r_time_arr[1]. constant($constpref.'_MONTH'). $r_time_arr[2]. constant($constpref.'_DAY'); | |
- | } | |
- | | |
- | $block['topic_list'][] = array( | |
- | 'link' => XOOPS_URL.'/modules/'.$mydirname.'/?p=topic&tid='.intval($row['tid']).'#'.intval($row['comment_count']), //naao | |
- | 'title' => $myts->htmlSpecialChars($row['tname']), | |
- | 'body' => $myts->htmlSpecialChars($row['tcbody']), | |
- | 'comment_count' => intval($row['comment_count']), | |
- | 'datetime' => $r_time, | |
- | // 'time' => XsnsUtils::getUserTimestamp($row['max_r_datetime']), //naao | |
- | 'time' => XsnsUtils::getUserTimestamp($row['r_datetime']), //naao | |
- | 'uid' => intval($row['tcuid']), | |
- | 'community' => array( | |
- | 'link' => XOOPS_URL.'/modules/'.$mydirname.'/?cid='.intval($row['cid']), | |
- | 'title' => $myts->htmlSpecialChars($row['cname']), | |
- | ), | |
- | ); | |
- | | |
- | $item_count++; | |
- | } | |
- | | |
- | if(empty($options['disable_renderer'])){ | |
- | require_once XOOPS_ROOT_PATH.'/class/template.php' ; | |
- | $tpl =& new XoopsTpl(); | |
- | $tpl->assign('block', $block); | |
- | $ret['content'] = $tpl->fetch('db:'.$mydirname.'_block_recent_topic.html'); | |
- | return $ret; | |
- | } | |
- | else{ | |
- | return $block; | |
- | } | |
- | } | |
- | }} | |