トップ  >  趣味の部屋  >  XOOPSサイト構築  >  XSNSのd3pipesジョイントで最新コメント
xoops xsns d3pipes

XSNSモジュールのd3pipesジョイントで新着コメント本文を取得したい anchor.png

XSNSモジュール-1.1.1を使用させていただいています。
本格的に使い始めたところで、ちょっと問題に直面しまして解決させたので、役に立つ場面もあるかと思い、記事にしておきます。

概要 anchor.png

  • XSNSで新着トピブロックを使ったとき、ブロックに表示される新着リンクをクリックしても、トピックの頭の説明にジャンプします。mixiでもトピの頭に飛ぶので同様の仕様と言えますが、これを最新記事にジャンプさせたいと思いました。
  • XSNSのd3pipesブロックジョイントクラス「D3pipおesBlockXsnstopiclist.class.php」で取得するトピックの本文が、最新のコメントではなく、毎回トピ説明が同じように繰り返されます。 ここはやはり、「新着コメント」のほうの本文を通知してほしいものです。

ということで、原因を探してましたが、どうやら「(trust)/modules/blocks/block_functions.php」「function b_xsns_recent_topic_show」の中でDBから取得するSQLに問題がありそう。。 :roll:

問題の箇所 anchor.png

 以下の説明は私も勉強しながら知った身なので言うことが間違っているかもしれません。
 下のSQL文で、GROUP BY tidでトピックIDでグループ化して抽出、MAX(tc.number)、MAX(tc.r_datetime)で各最大値を取得する、までは良いのですが、そこに様々な他のフィールドを検索取得するような指定を並べてます。
 この方法は、結果を保証されない方式であるとの情報もありますし、最新コメントのbodyが得られそうで実際には得られていません。

「(trust)/modules/blocks/block_functions.php」の25行目付近

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
    // 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";

改善案 anchor.png

 そこで、自分なりに見やすいクエリ2つに分割しました。
 また、飛び先のURLのトピ内コメントアンカー番号にジャンプするようにしてあります。 :-)
 (090525修正:リンク先にページ開始番号が抜けていたので追加しました。)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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[] = intval($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');
        }
        
            $comment_index = intval(intval($row['comment_count'])/20)*20;    //naao
            
        $block['topic_list'][] = array(
            'link' => XOOPS_URL.'/modules/'.$mydirname.'/?p=topic&tid='.intval($row['tid']).'&s='.$comment_index.'#'.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;
    }
}

その他 anchor.png

 コメントを編集したときに、トピックの更新日時も更新されてしまいます。 これは考え方の違いだと思うのですが、ユーザーがタイプミスを修正したり追記をしたりした時でも更新と判断されてしまいますので、私は「edit_execAction.php」の当該箇所をコメントアウトしました。 103行目付近と、121行目付近の

//'r_datetime' => $r_datetime, // naao 編集時に、トピ日時を更新しない

ただ、これは現状の仕様のほうが適切なのかもしれず、何とも悩ましいところですね。


実体ページ:inc/xsns_d3pipes
関連ページ:

プリンタ用画面
投票数:83 平均点:5.18
前
d3コメント統合の、元記事閲覧権限連動ハック Plugin版
カテゴリートップ
XOOPSサイト構築

コメント一覧

投稿ツリー


nonn50 サイトURL  投稿日時 2012/2/15 14:53

御無沙汰してます。
本来テーマとは異なることを質問いたします。

Linux PHP 5.3.6 MySQL 5.1.57、XCL 2.21 b2(EUC-JP)の環境に 最新のxoopsモジュール 1.1.1(2008-4-23)をインストールしましたが、以下の症状が発生しています。

「コミュニティ新規作成」または「コミュニティ設定変更」をする場合、必要事項を書き込んでも【コミニュティの説明文が入力されていません】とのメッセージが表示され、コミュニティの新規作成(編集)ができません。
この症状は、パソコンからアクセスした場合に発生し、ガラケーからでは発生せず新規作成することができます。

回避策を御教授いただきたく、よろしくお願いします。

なーお  投稿日時 2012/2/15 17:13 | 最終変更

nonn50さん、こんにちは。

引用:

「コミュニティ新規作成」または「コミュニティ設定変更」をする場合、必要事項を書き込んでも【コミニュティの説明文が入力されていません】とのメッセージが表示され、コミュニティの新規作成(編集)ができません。
この症状は、パソコンからアクセスした場合に発生し、ガラケーからでは発生せず新規作成することができます。

うーん、、ソースを追ってみましたが、なんででしょう?
Pack2011のXCL2.2.1上で、XSNS1.1.2で実サイトでやってみましたが、再現しません。

いくつか疑問点があるのですが、

  • 携帯から書き込みできたとのことですが、MTHの携帯用XSNSテンプレートを書くだけでは、チケットの関係で書き込みできないと思うのですが、 書きこめたということは、MTHのページのソースXSNS本体改編をやっておられるのですね。(確認)
  • PC用テンプレートは何か変更されていませんか? form内では、「info」という名前でtextareaでphpソースに渡されており、「編集」の場合でしたら
    • (trust)/xsns/acl/index/edit_confirmAction.php →
    • (trust)/xsns/userlib/community.class.php
      に渡って、ここの465行目からの、function checkParams($cid, $name, $info, $cat_id, $public_id) に「$info」として渡され、
      1
      2
      3
      4
      
      // 名前が入力されていない
      if(empty($name)){
      	$this->errors[] = _MD_XSNS_INDEX_NAME_NG;
      }
      で判定結果がfalseとなっていると思います。

今回のように、エラーメッセージが表示される場合は、/languages/japanese/  内の各ファイルでそのメーッセージを検索して、言語定数名を調べて、今度はその言語定数名を全スクリプトの中から検索すれば、問題の箇所に行きあたります。 ここまでご自身で一通りソースを追って確認してみてください。

で、この先は、nonn50さんの環境でやらないとわかりませんので、頑張ってください。 先のfunctionの中で、
var_dump($info);
とすれば中身がダンプされますが、リダイレクトされるので結果が見れませんね。。

edit_confirmAction.phpのfunction dispatch 内の、38行目付近の、以下のリダイレクト行の前でダンプ結果をみてください。

1
2
var_dump($info); die;
redirect_header(XSNS_URL_COMMU.'?'.XSNS_ACTION_ARG.'=edit&cid='.$cid, 3, $msg);
nonn50   投稿日時 2012/2/15 19:07

さっそくの回答、ありがとうございます。
ずいぶんと色々ご指導いただきました [worried]

小生は、、諸々の改変をできるスキルが無く、すべてディフォルトのままでインストールしています。

いずれにしても、(白内障 8-) を治療中の為、明日ノンビリとチェックしてみます。
取り急ぎ、御礼まで

nonn50   投稿日時 2012/2/18 12:00

お世話になります。
一度、XSNSをアンインストールしてFTPですべて削除した上、再度アップロードしたところ、症状は発生しなくなりました。
なんだったのか??わかりませんが、お騒がせしました。
ありがとうございました。



新しくコメントをつける

題名
ゲスト名
投稿本文
より詳細なコメント入力フォームへ