comment_notify.inc 8.72 KB
Newer Older
1 2 3 4 5 6 7
<?php

/**
 * @file
 *
 * Contains functions which utilize the database and other internal helpers.
 */
8
use Drupal\comment\CommentInterface;
9 10 11

/**
 * Get the notification preferences for a specific user.
12
 *
13
 * @param integer $uid
14 15
 * @return mixed
 *  StdClass if found, else NULL
16 17 18 19 20 21 22 23 24
 */
function comment_notify_get_user_notification_setting($uid) {
  $users = &drupal_static(__FUNCTION__);
  if (!isset($users[$uid])) {
    if (is_null($uid)) {
      throw new Exception('Cannot get user preference, uid missing');
    }
    // Handle anonymous users with defaults.
    if ($uid == 0) {
25
      $users[0] = comment_notify_get_default_notification_setting();
26 27
    }
    else {
28
      $setting = db_select('comment_notify_user_settings', 'cnus')
29 30
        ->fields('cnus')
        ->condition('uid', $uid)
31 32 33 34 35
        ->execute()
        ->fetchObject();

      if (!$setting) {
        return NULL;
36 37
      }
      else {
38
        $users[$uid] = $setting;
39
      }
40 41 42 43 44
    }
  }
  return $users[$uid];
}

45 46
function comment_notify_get_default_notification_setting() {
  return (object) array(
47 48
    'comment_notify' => \Drupal::config('comment_notify.settings')->get('enable_default.watcher'),
    'node_notify' => \Drupal::config('comment_notify.settings')->get('enable_default.entity_author')
49 50 51
  );
}

52 53
/**
 * Remove comment notification preferences for a user.
54
 *
55 56 57 58 59 60 61 62 63 64 65
 * @param integer $uid
 * @return boolean
 */
function comment_notify_delete_user_notification_setting($uid) {
  return (bool)db_delete('comment_notify_user_settings')
    ->condition('uid', $uid)
    ->execute();
}

/**
 * Get a user's default preference for comment notification.
66
 *
67 68 69 70 71
 * @param integer $uid
 * @return integer
 */
function comment_notify_get_user_comment_notify_preference($uid) {
  $setting = comment_notify_get_user_notification_setting($uid);
72 73 74 75
  if (!$setting) {
    $setting = comment_notify_get_default_notification_setting();
  }
  return $setting->comment_notify;
76 77 78 79
}

/**
 * Get a user's default preference for node update notification.
80
 *
81
 * This is notification on nodes where the user is the author.
82
 *
83 84 85 86 87
 * @param integer $uid
 * @return integer
 */
function comment_notify_get_user_node_notify_preference($uid) {
  $setting = comment_notify_get_user_notification_setting($uid);
88
  if (!$setting) {
89
    $setting = comment_notify_get_default_notification_setting();
90 91
  }
  return $setting->node_notify;
92 93 94 95
}

/**
 * Sets the notification preferences for a specific user.
96
 *
97 98 99 100 101 102 103 104 105 106
 * @param integer $uid
 * @param integer $node_notification
 * @param integer $comment_notification
 * @return boolean
 */
function comment_notify_set_user_notification_setting($uid, $node_notification = NULL, $comment_notification = NULL) {
  if (!$uid) {
    throw new Exception('Cannot set user preference, uid missing');
  }
  $fields = array('uid' => $uid);
107

108 109 110 111
  if (!is_null($node_notification)) {
    $fields['node_notify'] = $node_notification;
  }
  if (!is_null($comment_notification)) {
112
    $fields['comment_notify'] = $comment_notification;
113 114 115 116
  }
  if (comment_notify_get_user_notification_setting($uid)) {
    $query = db_update('comment_notify_user_settings');
    $query->condition('uid', $uid);
117 118
  }
  else {
119 120 121 122 123 124 125 126 127
    $query = db_insert('comment_notify_user_settings');
  }
  return (bool)$query
    ->fields($fields)
    ->execute();
}

/**
 * Add a notification against a comment.
128
 *
129 130 131
 * @param integer $cid
 * @param integer $notify
 * @param string $notify_hash
132
 * @param integer|NULL $notified
133
 *
134 135
 * @return boolean
 */
136
function comment_notify_add_notification($cid, $notify, $notify_hash, $notified) {
137 138 139 140 141 142 143 144 145 146 147 148 149
  // Check if comment already exist.
  $results = db_select('comment_notify', 'cn')
    ->fields('cn', array('cid'))
    ->condition('cn.cid', $cid)
    ->execute()
    ->fetchField();

  // Update comment if exist.
  if ($results) {
    return (bool)db_update('comment_notify')
      ->fields(array(
        'notify' => $notify === NULL ? 0 : $notify,
        'notify_hash' => $notify_hash,
150
        'notified' => $notified === NULL ? 0 : $notified,
151 152 153 154 155 156 157 158 159 160 161 162
      ))
      ->condition('cid', $cid)
      ->execute();
  }

  // Create new entry.
  else {
    return (bool)db_insert('comment_notify')
      ->fields(array(
        'cid' => $cid,
        'notify' => $notify === NULL ? 0 : $notify,
        'notify_hash' => $notify_hash,
163
        'notified' => $notified === NULL ? 0 : $notified,
164 165 166
      ))
      ->execute();
  }
167 168 169 170
}

/**
 * Remove all the notifications linked with a comment
171
 *
172 173 174 175 176 177 178 179 180 181 182
 * @param integer $cid
 * @return boolean
 */
function comment_notify_remove_all_notifications($cid) {
  return (bool)db_delete('comment_notify')
    ->condition('cid', $cid)
    ->execute();
}

/**
 * Updated a notification with a different notification type
183
 *
184 185 186 187 188 189 190
 * @param integer $cid
 * @param integer $notify
 * @return boolean
 */
function comment_notify_update_notification($cid, $notify) {
  return (bool)db_update('comment_notify')
    ->fields(array(
191
      'notify' => $notify === NULL ? 0 : $notify,
192 193 194 195 196 197 198
    ))
    ->condition('cid', $cid)
    ->execute();
}

/**
 * Get the type of notification for a comment notification record.
199
 *
200 201 202 203
 * @param integer $cid
 * @return integer
 */
function comment_notify_get_notification_type($cid) {
204
  return db_select('comment_notify', 'cn')
205 206 207 208 209 210 211 212
    ->fields('cn', array('notify'))
    ->condition('cid', $cid)
    ->execute()
    ->fetchField();
}

/**
 * Get a list of mails which need to be contacted for a node.
213
 *
214
 * @param integer $nid
215 216
 * @param string $comment_type
 *
217 218
 * @return \Drupal\comment\CommentInterface[]
 *   A list of comment entities.
219
 */
220 221
function comment_notify_get_watchers($nid, $comment_type) {
  $cids = db_query("SELECT c.cid FROM {comment_field_data} c INNER JOIN {comment_notify} cn ON c.cid = cn.cid LEFT JOIN {users_field_data} u ON c.uid = u.uid WHERE c.entity_id = :nid AND c.comment_type = :comment_type AND c.status = :status AND cn.notify <> :notify AND (u.uid = 0 OR u.status = 1)", array(
222
    ':nid' => $nid,
223
    ':comment_type' => $comment_type,
224
    ':status' => CommentInterface::PUBLISHED,
225 226
    ':notify' => COMMENT_NOTIFY_DISABLED,
  ))->fetchCol();
227
  return \Drupal::entityManager()->getStorage('comment')->loadMultiple($cids);
228 229 230 231
}

/**
 * Record that the owner of a comment notification request has already been notified.
232
 *
233 234 235
 * @param integer $cid
 * @return boolean
 */
236 237 238 239 240
function comment_notify_mark_comment_as_notified($comment) {
  // First, mark the passed comment (an object, so passed by reference).
  $comment->notified = 1;

  // Next, store this fact in the DB as well.
241 242
  return (bool)db_update('comment_notify')
    ->fields(array(
243
      'notified' => 1,
244
    ))
245
    ->condition('cid', $comment->id())
246 247 248 249 250 251
    ->execute();
}

/**
 * Unsubscribe all comment notification requests associated with an email.
 *
252
 * If the email belongs to a user, it will unsubscribe all of their Comment Notify records.
253
 * If it does not, then it will unsubscribe all anonymous users.
254
 *
255 256 257 258 259 260
 * @param string $mail
 * @return boolean
 */
function comment_notify_unsubscribe_by_email($mail) {
  $update_query = db_update('comment_notify');
  $update_query->fields(array('notify' => 0));
261

262
  $comment_query = \Drupal::entityQuery('comment');
263

264 265
  if ($user = user_load_by_mail($mail)) {
    $comment_query->condition('uid', $user->id());
266 267
  }
  else {
268 269
    $comment_query->condition('mail', $mail);
  }
270
  $update_query->condition('cid', $comment_query->execute(), 'IN');
271

272 273 274 275
  return (bool)$update_query->execute();
}

/**
276
 * Unsubscribe comment notification requests associated with a hash.
277
 *
278
 * This is used in the unsubscribe link.
279
 *
280 281 282 283
 * @param string $hash
 * @return boolean
 */
function comment_notify_unsubscribe_by_hash($hash) {
284 285 286 287 288 289 290 291
  $query = db_select('comment_notify', 'cn');
  $query->join('comment_field_data', 'cf', 'cn.cid = cf.cid');
  $query->condition('cn.notify_hash', $hash)
      ->condition('cn.notify', COMMENT_NOTIFY_DISABLED, '!=')
      ->fields('cn', array('cid', 'notify', 'notified'))
      ->fields('cf', array('entity_id', 'uid'))
      ->execute()->fetchObject();
  $notification = $query->execute()->fetchObject();
292

293 294 295 296
  if (empty($notification)) {
    return FALSE;
  }

297 298 299 300
  // If this notification is at the node level and the commenter has a Drupal
  // account, delete all notifications for this node.
  if (COMMENT_NOTIFY_NODE == $notification->notify && $notification->uid) {
    $result = db_query("SELECT cid FROM {comment_field_data} WHERE entity_id = :entity_id AND uid = :uid", array(':entity_id' => $notification->entity_id, ':uid' => $notification->uid));
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
    $cids = $result->fetchCol();

    // Update all comment notifications to be disabled.
    return (bool)db_update('comment_notify')
      ->fields(array(
        'notify' => 0,
      ))
      ->condition('cid', $cids, 'IN')
      ->execute();
  }
  else {
   // Update this notification to be disabled.
   return (bool)db_update('comment_notify')
     ->fields(array(
       'notify' => 0,
     ))
317 318
    ->condition('notify_hash', $hash)
    ->execute();
319
  }
320
}