comment_render

Versions
4.6 – 6
comment_render($node, $cid = 0)

▾ 1 function calls comment_render()

node_show in modules/node.module
Generate a page displaying a single node, along with its comments.

Code

modules/comment.module, line 694

<?php
function comment_render($node, $cid = 0) {
  global $user;

  $output = '';

  if (user_access('access comments')) {
    // Pre-process variables.
    $nid = $node->nid;
    if (empty($nid)) {
      $nid = 0;
    }

    $mode = _comment_get_display_setting('mode');
    $order = _comment_get_display_setting('sort');
    $comments_per_page = _comment_get_display_setting('comments_per_page');

    $output .= "<a id=\"comment\"></a>\n";

    if ($cid) {
      // Single comment view.
      $query = 'SELECT c.cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name, c.mail, c.homepage, u.uid, u.name AS registered_name, u.picture, u.data, c.score, c.users, c.status FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d';
      $query_args = array($cid);
      if (!user_access('administer comments')) {
        $query .= ' AND c.status = %d';
        $query_args[] = COMMENT_PUBLISHED;
      }

      $result = db_query($query, $query_args);

      if ($comment = db_fetch_object($result)) {
        $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
        $output .= theme('comment_view', $comment, module_invoke_all('link', 'comment', $comment, 1));
      }
    }
    else {
      // Multiple comment view
      $query_count = 'SELECT COUNT(*) FROM {comments} WHERE nid = %d';
      $query = 'SELECT c.cid as cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name, c.mail, c.homepage, u.uid, u.name AS registered_name, u.picture, u.data, c.score, c.users, c.thread, c.status FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.nid = %d';

      $query_args = array($nid);
      if (!user_access('administer comments')) {
        $query .= ' AND c.status = %d';
        $query_count .= ' AND status = %d';
        $query_args[] = COMMENT_PUBLISHED;
      }

      /*
      ** We want to use the standard pager, but threads would need every
      ** comment to build the thread structure, so we need to store some
      ** extra info.
      **
      ** We use a "thread" field to store this extra info. The basic idea
      ** is to store a value and to order by that value. The "thread" field
      ** keeps this data in a way which is easy to update and convenient
      ** to use.
      **
      ** A "thread" value starts at "1". If we add a child (A) to this
      ** comment, we assign it a "thread" = "1.1". A child of (A) will have
      ** "1.1.1". Next brother of (A) will get "1.2". Next brother of the
      ** parent of (A) will get "2" and so on.
      **
      ** First of all note that the thread field stores the depth of the
      ** comment: depth 0 will be "X", depth 1 "X.X", depth 2 "X.X.X", etc.
      **
      ** Now to get the ordering right, consider this example:
      **
      ** 1
      ** 1.1
      ** 1.1.1
      ** 1.2
      ** 2
      **
      ** If we "ORDER BY thread ASC" we get the above result, and this is
      ** the natural order sorted by time.  However, if we "ORDER BY thread
      ** DESC" we get:
      **
      ** 2
      ** 1.2
      ** 1.1.1
      ** 1.1
      ** 1
      **
      ** Clearly, this is not a natural way to see a thread, and users
      ** will get confused. The natural order to show a thread by time
      ** desc would be:
      **
      ** 2
      ** 1
      ** 1.2
      ** 1.1
      ** 1.1.1
      **
      ** which is what we already did before the standard pager patch. To
      ** achieve this we simply add a "/" at the end of each "thread" value.
      ** This way out thread fields will look like depicted below:
      **
      ** 1/
      ** 1.1/
      ** 1.1.1/
      ** 1.2/
      ** 2/
      **
      ** we add "/" since this char is, in ASCII, higher than every number,
      ** so if now we "ORDER BY thread DESC" we get the correct order.  Try
      ** it, it works ;).  However this would spoil the "ORDER BY thread ASC"
      ** Here, we do not need to consider the trailing "/" so we use a
      ** substring only.
      */

      if ($order == COMMENT_ORDER_NEWEST_FIRST) {
        if ($mode == COMMENT_MODE_FLAT_COLLAPSED || $mode == COMMENT_MODE_FLAT_EXPANDED) {
          $query .= ' ORDER BY c.timestamp DESC';
        }
        else {
          $query .= ' ORDER BY c.thread DESC';
        }
      }
      else if ($order == COMMENT_ORDER_OLDEST_FIRST) {
        if ($mode == COMMENT_MODE_FLAT_COLLAPSED || $mode == COMMENT_MODE_FLAT_EXPANDED) {
          $query .= ' ORDER BY c.timestamp';
        }
        else {

          /*
          ** See comment above.  Analysis learns that this doesn't cost
          ** too much.  It scales much much better than having the whole
          ** comment structure.
          */

          $query .= ' ORDER BY SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))';
        }
      }

      // Start a form, for use with comment control.
      $result = pager_query($query, $comments_per_page, 0, $query_count, $query_args);
      if (db_num_rows($result) && (variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_ABOVE || variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_ABOVE_BELOW)) {
        $output .= comment_controls($mode, $order, $comments_per_page);
      }

      while ($comment = db_fetch_object($result)) {
        $comment = drupal_unpack($comment);
        $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
        $comment->depth = count(explode('.', $comment->thread)) - 1;

        if ($mode == COMMENT_MODE_FLAT_COLLAPSED) {
          $output .= theme('comment_flat_collapsed', $comment);
        }
        else if ($mode == COMMENT_MODE_FLAT_EXPANDED) {
          $output .= theme('comment_flat_expanded', $comment);
        }
        else if ($mode == COMMENT_MODE_THREADED_COLLAPSED) {
          $output .= theme('comment_thread_collapsed', $comment);
        }
        else if ($mode == COMMENT_MODE_THREADED_EXPANDED) {
          $output .= theme('comment_thread_expanded', $comment);
        }
      }

      $output .= theme('pager', NULL, $comments_per_page, 0);

      if (db_num_rows($result) && (variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_BELOW || variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_ABOVE_BELOW)) {
        $output .= comment_controls($mode, $order, $comments_per_page);
      }
    }

    // If enabled, show new comment form.
    if (user_access('post comments') && node_comment_mode($nid) == COMMENT_NODE_READ_WRITE && (variable_get('comment_form_location', COMMENT_FORM_SEPARATE_PAGE) == COMMENT_FORM_BELOW)) {
      $output .= comment_form(array('nid' => $nid), t('Post new comment'));
    }
  }
  return $output;
}
?>
Login or register to post comments
 
 

All source code and documentation on this site is released under the terms of the GNU General Public License, version 2 and later. Drupal is a registered trademark of Dries Buytaert.