You are here

function flag_comment::get_flagging_record in Flag 7.3

Overrides flag_flag::get_flagging_record().

This queries for flagging records for all comments on the node for the current comment, and prefills the flag_get_user_flags() static cache with the result for a performance gain.

Overrides flag_flag::get_flagging_record

File

includes/flag/flag_comment.inc, line 79
Contains the flag_comment class.

Class

flag_comment
Implements a comment flag.

Code

function get_flagging_record($entity_id, $uid = NULL, $sid = NULL) {
  static $seen_comment_nids = array();
  $comment = $this
    ->fetch_entity($entity_id);

  // Figure out if this is the first comment we've seen for its parent node.
  if (!isset($seen_comment_nids[$comment->nid])) {

    // Preload the flag_get_user_flags() static cache with flagging records
    // for all the comments on the node. This means that if multiple comments
    // on this node are being viewed, only one query is run for all their
    // flagging records, rather than one for each comment. This is because
    // flag_get_user_flags() can only optimized across flags on one entity.
    $flag_get_user_flags_cache =& drupal_static('flag_get_user_flags');

    // We need to get a row for each comment, including empty ones if there is
    // no flagging, so that the cache is warmed up for all comments. Therefore
    // the query has to have the {comment} table as its base, and include the
    // comment cid field.
    $query = db_select('comment', 'c');
    $query
      ->leftJoin('flagging', 'f', "c.cid = f.entity_id AND f.entity_type = 'comment'");
    $query
      ->fields('f')
      ->fields('c', array(
      'cid',
    ))
      ->condition('c.nid', $comment->nid)
      ->condition(db_or()
      ->isNull('f.flagging_id')
      ->condition(db_and()
      ->condition(db_or()
      ->condition('f.uid', $uid)
      ->condition('f.uid', 0))
      ->condition('f.sid', $sid)));

    // The result set can have multiple rows for a single comment, and rows
    // which have no flagging ID, so there's nothing useful to index it by.
    $result = $query
      ->execute()
      ->fetchAll();
    $flag_names = _flag_get_flag_names();
    foreach ($result as $flagging_data) {
      $cid = $flagging_data->cid;

      // At the very least, we need an empty array for the entity ID key in
      // the cache array, so it counts as present.
      if (!isset($flag_get_user_flags_cache[$uid][$sid]['comment'][$cid])) {
        $flag_get_user_flags_cache[$uid][$sid]['comment'][$cid] = array();
      }

      // If the flagging table gave us no data, we're done with this row.
      if (is_null($flagging_data->flagging_id)) {
        continue;
      }

      // Remove the comment ID field from the row, so it's just the flagging
      // table row.
      unset($flagging_data->cid);
      $flag_get_user_flags_cache[$uid][$sid]['comment'][$cid][$flag_names[$flagging_data->fid]] = $flagging_data;
    }

    // Mark that we've seen this node so we don't process it again.
    $seen_comment_nids[$comment->nid] = TRUE;
  }

  // Return data for the comment we were asked about.
  $user_flags = flag_get_user_flags($this->entity_type, $entity_id, $uid, $sid);
  return isset($user_flags[$this->name]) ? $user_flags[$this->name] : NULL;
}