【问题标题】:SQL to sort nested comments in wordpress by likesSQL按喜欢对wordpress中的嵌套评论进行排序
【发布时间】:2018-03-15 21:20:28
【问题描述】:

希望有好心人能帮帮我。

我想按喜欢对 wordpress 中的嵌套 cmets 进行排序。我只找到了一个可以做到这一点的插件,但它不能满足我的需求,所以我正在尝试编写自己的插件。大部分其实很简单,但是 sql 让我望而却步(不是我的强项)。

我需要一个 SQL 查询来按喜欢对 cme​​ts 进行排序,回复紧随其父级,并且对每个父级的回复也按喜欢排序。顶级 cmets 和回复由“层”区分。只有一级回复。我的桌子是这样的:

ID(整数)

Comment_Name (VarChar)

Layer (Int)... 1 用于顶级评论,2 用于回复

ID_of_Parent_Comment (Int)...回复必须分组在具有此 ID 的顶级评论下

喜欢(内部)

例如,如果顶级 cmets 用数字表示,回复用字母,它看起来像这样:

1、2、3、3a、3b、4、5、5a...等

有人有什么想法吗?

【问题讨论】:

  • mmccabe,感谢您抽出宝贵时间回复。但是,恐怕这不适用于我的情况。我的“顶级 cmets”和“回复”都只是由 layer 列区分的“cmets”,都包含在同一个表中。如果我的描述有误导性,我很抱歉。
  • mmccabe,等等...在您的 FROM 子句中,您是否将 MYTABLE 别名为两个单独的表,然后有效地将同一个表加入到自身中?我不知道你能做到这一点。如果是这样,我想这正是我所需要的!
  • mmccabe,我终于完成了测试。我不得不删除 WHERE 子句,但除此之外它工作得很好。太感谢了!一旦我弄清楚系统是如何工作的,我会立即标记你。 :) 再次感谢!
  • 这是一个棘手的问题....很高兴我能帮忙:)

标签: sql wordpress comments


【解决方案1】:

事实证明,另一个答案毕竟没有奏效。它看起来确实是对的。回复很好地分组在适当的父评论下方,所有内容都按喜欢排序。但如果仔细观察,sqlfiddle 测试返回了 14 条记录,其中只有 12 条可用。

在我的网站上花了太多时间摆弄它之后,我无法进一步解决它。一组或另一组(顶级 cmets 或回复)总是被遗漏或重复。

我终于放弃了,假设用SQL做不到,所以我又回到了我熟悉的东西:php。这是我的解决方案。希望有人会发现它有用。如果不出意外,这是一个有趣的项目。

myComments.php

<?php

global $wpdb;

$post_ID = get_the_ID();

// Get Comment Table
$sql =
 " SELECT *"
." FROM wp_comments"
." WHERE comment_post_ID = " . $post_ID     // only retrieve comments for this post
." AND comment_parent = '0'"                // only retrieve top level comments
." ORDER BY likes DESC"
.";";
$tlc = $wpdb->get_results($sql, ARRAY_A);   // Retrieve all records into $tlc
                                            // this should never be
                                            // large enough to be a problem.
$commentCount = count( $tlc );              // Number of TopLevelComments

// Adjust Comments
for ( $i = 0; $i <= $commentCount-1; $i++ ) {
    $tlc[$i]['layer'] = 0;                  // Layer 0 indicates top level comment
    $tlc[$i]['index'] = $i;                 // index is used to group parents 
                                            // with children
}

// Get Reply Table
$sql =
 " SELECT *"
." FROM wp_comments"
." WHERE comment_post_ID = " . $post_ID
." AND comment_parent > '0'"                        // only retrieve replies
." ORDER BY likes DESC"
.";";
$replies = $wpdb->get_results($sql, ARRAY_A);
$replyCount = count( $replies );

// Adjust Replies
for ( $i = 0; $i <= $commentCount-1; $i++ ) {
    $replies[$i]['layer'] = 1;                      // Layer 1 indicates replies
}

// Set child index to that of parent
// then add child record to parent array
for ( $i = 0; $i <= $replyCount-1; $i++ ) {
    $x = $replies[$i]['comment_parent'];            // Get ID of parent
    for ( $j = 0; $j <= $commentCount-1; $j++ ) {
        if ( $tlc[$j]['comment_ID'] == $x ) {       // If parent found
            $value = $tlc[$j]['index'];             // Get parent's index
            $replies[$i]['index'] = $value;         // Give child parent's index
            array_push ( $tlc, $replies[$i]);
        }
    }
}

// Sort comments
// Note that $tlc was sorted by select
// and index was assigned while in that order
$tlc = array_orderby($tlc,  'index', SORT_ASC, 
                            'layer', SORT_ASC,
                            'likes', SORT_DESC);

// Display comments
$commentCount = count($tlc);
if ( $commentCount ) {
    echo "<ol class='commentNumbering'>";
    // Used to determine if we have opened a second <ol> for nested comments
    // and ensure we close it before we are done.
    $inReplyList = false;
    // We don't want to close the <ol> before we've opened it.
    $firstComment = true;
    for ( $i = 0; $i <= $commentCount-1; $i++ ) {
        $myComment = $tlc[$i];
        // Set $depth (needed by reply-link on myCommentTemplate page)
        $depth = 0;
        $comment_ID = $myComment['comment_ID'];
        while( $comment_ID > 0  ) {
            $tempComment = get_comment( $comment_ID );
            $comment_ID = $tempComment->comment_parent;
            $depth++;
        }
        // Treat each group of nested comments as a separate ordered group
        if ( $depth == 2 ) {
            if ( ! $inReplyList ) {
                echo "<ol>";
                $inReplyList = true;
            }
        } else {
            if ( ! $firstComment ) {
                if ( $inReplyList ) {
                    echo "</ol>";
                    $inReplyList = false;
                }
            }
        }
        $firstComment = false;
        // Display each comment
        include ('myCommentTemplate.php');
    }
    if ( $inReplyList ) {
        echo "</ol>";
    }
    echo "</ol>";
} else {
    echo 'No comments found.';
}
// Where comments are made
include('myCommentForm.php');

$wpdb->flush();

?>

函数array_orderby()(位于functions.php中)

/* SORT PHP ARRAYS OF RECORDS */

// PHP function 'array_multisort' requires columns //
// This function handles the conversion from row to col and back again //

// Example:
// $sorted = array_orderby($data, 'volume', SORT_DESC, 'edition', SORT_ASC);

function array_orderby()
{
    $args = func_get_args();
    $data = array_shift($args);
    foreach ($args as $n => $field) {
        if (is_string($field)) {
            $tmp = array();
            foreach ($data as $key => $row)
                $tmp[$key] = $row[$field];
            $args[$n] = $tmp;
            }
    }
    $args[] = &$data;
    call_user_func_array('array_multisort', $args);
    return array_pop($args);
}

【讨论】:

    【解决方案2】:

    看起来应该很接近了:

    select 
      post.ID,
      post.likes as postLikes,
      reply.ID,
      reply.likes as replyLikes
    from MyTable post
      left join MyTable reply
        on post.ID = reply.ID_of_Parent_Comment
    where post.ID_of_Parent_Comment is  null
    order by post.likes desc, reply.likes desc
    ;
    

    它将为您提供按父喜欢排序的父 ID,以及按最喜欢的孩子排序的每个父母(如果有)的相关子 ID

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    • 2016-03-24
    相关资源
    最近更新 更多