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

/**
 * @file
 * Contains functions which utilize the database and other internal helpers.
 */
7

8
use Drupal\comment\CommentInterface;
9 10 11

/**
 * Get the notification preferences for a specific user.
12
 *
13 14 15
 * @param int $uid
 *   The user id.
 *
16
 * @return mixed
17
 *   StdClass if found, else NULL
18 19 20 21 22 23 24 25 26
 */
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) {
27
      $users[0] = comment_notify_get_default_notification_setting();
28 29
    }
    else {
30
      $setting = db_select('comment_notify_user_settings', 'cnus')
31 32
        ->fields('cnus')
        ->condition('uid', $uid)
33 34 35 36 37
        ->execute()
        ->fetchObject();

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

47 48 49
/**
 * Returns the default values of the notification settings.
 */
50
function comment_notify_get_default_notification_setting() {
51
  return (object) [
52
    'comment_notify' => \Drupal::config('comment_notify.settings')->get('enable_default.watcher'),
53 54
    'node_notify' => \Drupal::config('comment_notify.settings')->get('enable_default.entity_author'),
  ];
55 56
}

57 58
/**
 * Remove comment notification preferences for a user.
59
 *
60 61 62 63 64
 * @param int $uid
 *   The user id.
 *
 * @return bool
 *   TRUE if the preferences were removed correctly, FALSE if weren't removed.
65 66
 */
function comment_notify_delete_user_notification_setting($uid) {
67
  return (bool) db_delete('comment_notify_user_settings')
68 69 70 71 72 73
    ->condition('uid', $uid)
    ->execute();
}

/**
 * Get a user's default preference for comment notification.
74
 *
75 76 77 78 79
 * @param int $uid
 *   The User ID.
 *
 * @return int
 *   Return the comment preference.
80 81 82
 */
function comment_notify_get_user_comment_notify_preference($uid) {
  $setting = comment_notify_get_user_notification_setting($uid);
83 84 85 86
  if (!$setting) {
    $setting = comment_notify_get_default_notification_setting();
  }
  return $setting->comment_notify;
87 88 89 90
}

/**
 * Get a user's default preference for node update notification.
91
 *
92
 * This is notification on nodes where the user is the author.
93
 *
94 95 96 97 98
 * @param int $uid
 *   The User ID.
 *
 * @return int
 *   Return the node_notify value.
99 100 101
 */
function comment_notify_get_user_node_notify_preference($uid) {
  $setting = comment_notify_get_user_notification_setting($uid);
102
  if (!$setting) {
103
    $setting = comment_notify_get_default_notification_setting();
104 105
  }
  return $setting->node_notify;
106 107 108 109
}

/**
 * Sets the notification preferences for a specific user.
110
 *
111 112 113 114 115 116 117 118 119
 * @param int $uid
 *   The User ID.
 * @param int $node_notification
 *   The node notification value.
 * @param int $comment_notification
 *   The comment notification value.
 *
 * @return bool
 *   TRUE if the notification was set correctly.
120 121 122 123 124
 */
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');
  }
125
  $fields = ['uid' => $uid];
126

127 128 129 130
  if (!is_null($node_notification)) {
    $fields['node_notify'] = $node_notification;
  }
  if (!is_null($comment_notification)) {
131
    $fields['comment_notify'] = $comment_notification;
132 133 134 135
  }
  if (comment_notify_get_user_notification_setting($uid)) {
    $query = db_update('comment_notify_user_settings');
    $query->condition('uid', $uid);
136 137
  }
  else {
138 139
    $query = db_insert('comment_notify_user_settings');
  }
140
  return (bool) $query
141 142 143 144 145 146
    ->fields($fields)
    ->execute();
}

/**
 * Add a notification against a comment.
147
 *
148 149 150 151
 * @param int $cid
 *   Comment Id.
 * @param int $notify
 *   The notification type.
152
 * @param string $notify_hash
153 154 155
 *   The comment hash.
 * @param int|null $notified
 *   If the user has been already notified.
156
 *
157 158
 * @return bool
 *   TRUE if the notification was added correctly.
159
 */
160
function comment_notify_add_notification($cid, $notify, $notify_hash, $notified) {
161 162
  // Check if comment already exist.
  $results = db_select('comment_notify', 'cn')
163
    ->fields('cn', ['cid'])
164 165 166 167 168 169
    ->condition('cn.cid', $cid)
    ->execute()
    ->fetchField();

  // Update comment if exist.
  if ($results) {
170 171
    return (bool) db_update('comment_notify')
      ->fields([
172 173
        'notify' => $notify === NULL ? 0 : $notify,
        'notify_hash' => $notify_hash,
174
        'notified' => $notified === NULL ? 0 : $notified,
175
      ])
176 177 178 179 180 181
      ->condition('cid', $cid)
      ->execute();
  }

  // Create new entry.
  else {
182 183
    return (bool) db_insert('comment_notify')
      ->fields([
184 185 186
        'cid' => $cid,
        'notify' => $notify === NULL ? 0 : $notify,
        'notify_hash' => $notify_hash,
187
        'notified' => $notified === NULL ? 0 : $notified,
188
      ])
189 190
      ->execute();
  }
191 192 193
}

/**
194
 * Remove all the notifications linked with a comment.
195
 *
196 197 198 199 200
 * @param int $cid
 *   The comment ID.
 *
 * @return bool
 *   TRUE if all the notifications were removed correctly.
201 202
 */
function comment_notify_remove_all_notifications($cid) {
203
  return (bool) db_delete('comment_notify')
204 205 206 207 208
    ->condition('cid', $cid)
    ->execute();
}

/**
209 210 211 212 213 214
 * Updated a notification with a different notification type.
 *
 * @param int $cid
 *   The comment id.
 * @param int $notify
 *   The value that is going to be updated.
215
 *
216 217
 * @return bool
 *   TRUE if the notification was updated correctly.
218 219
 */
function comment_notify_update_notification($cid, $notify) {
220 221
  return (bool) db_update('comment_notify')
    ->fields([
222
      'notify' => $notify === NULL ? 0 : $notify,
223
    ])
224 225 226 227 228 229
    ->condition('cid', $cid)
    ->execute();
}

/**
 * Get the type of notification for a comment notification record.
230
 *
231 232 233 234 235
 * @param int $cid
 *   The comment id.
 *
 * @return int
 *   Return the notification type.
236 237
 */
function comment_notify_get_notification_type($cid) {
238
  return db_select('comment_notify', 'cn')
239
    ->fields('cn', ['notify'])
240 241 242 243 244 245 246
    ->condition('cid', $cid)
    ->execute()
    ->fetchField();
}

/**
 * Get a list of mails which need to be contacted for a node.
247
 *
248 249
 * @param int $nid
 *   The node id.
250
 * @param string $comment_type
251
 *   The comment type.
252
 *
253 254
 * @return \Drupal\comment\CommentInterface[]
 *   A list of comment entities.
255
 */
256
function comment_notify_get_watchers($nid, $comment_type) {
257
  $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)", [
258
    ':nid' => $nid,
259
    ':comment_type' => $comment_type,
260
    ':status' => CommentInterface::PUBLISHED,
261
    ':notify' => COMMENT_NOTIFY_DISABLED,
262
  ])->fetchCol();
263
  return \Drupal::entityManager()->getStorage('comment')->loadMultiple($cids);
264 265 266
}

/**
267
 * Records that the owner of a comment notification request has been notified.
268
 *
269 270 271 272 273
 * @param int $comment
 *   The comment ID.
 *
 * @return bool
 *   True if it can be updated correctly.
274
 */
275 276 277 278 279
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.
280 281
  return (bool) db_update('comment_notify')
    ->fields([
282
      'notified' => 1,
283
    ])
284
    ->condition('cid', $comment->id())
285 286 287 288 289 290
    ->execute();
}

/**
 * Unsubscribe all comment notification requests associated with an email.
 *
291 292
 * If the email belongs to a user, it will unsubscribe all of their Comment
 * Notify records. If it does not, then it will unsubscribe all anonymous users.
293
 *
294
 * @param string $mail
295 296 297 298
 *   The mail that is going to be unsubscribed.
 *
 * @return bool
 *   TRUE if the comment was unsubscribed correctly.
299 300 301
 */
function comment_notify_unsubscribe_by_email($mail) {
  $update_query = db_update('comment_notify');
302
  $update_query->fields(['notify' => 0]);
303

304
  $comment_query = \Drupal::entityQuery('comment');
305

306 307
  if ($user = user_load_by_mail($mail)) {
    $comment_query->condition('uid', $user->id());
308 309
  }
  else {
310 311
    $comment_query->condition('mail', $mail);
  }
312
  $update_query->condition('cid', $comment_query->execute(), 'IN');
313

314
  return (bool) $update_query->execute();
315 316 317
}

/**
318
 * Unsubscribe comment notification requests associated with a hash.
319
 *
320
 * This is used in the unsubscribe link.
321
 *
322
 * @param string $hash
323 324 325 326
 *   The hash that identified the comment.
 *
 * @return bool
 *   Returns TRUE if the comment was unsubscribed correctly, FALSE otherwise.
327 328
 */
function comment_notify_unsubscribe_by_hash($hash) {
329 330 331
  $query = db_select('comment_notify', 'cn');
  $query->join('comment_field_data', 'cf', 'cn.cid = cf.cid');
  $query->condition('cn.notify_hash', $hash)
332 333 334 335
    ->condition('cn.notify', COMMENT_NOTIFY_DISABLED, '!=')
    ->fields('cn', ['cid', 'notify', 'notified'])
    ->fields('cf', ['entity_id', 'uid'])
    ->execute()->fetchObject();
336
  $notification = $query->execute()->fetchObject();
337

338 339 340 341
  if (empty($notification)) {
    return FALSE;
  }

342 343 344
  // 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) {
345
    $result = db_query("SELECT cid FROM {comment_field_data} WHERE entity_id = :entity_id AND uid = :uid", [':entity_id' => $notification->entity_id, ':uid' => $notification->uid]);
346 347 348
    $cids = $result->fetchCol();

    // Update all comment notifications to be disabled.
349 350
    return (bool) db_update('comment_notify')
      ->fields([
351
        'notify' => 0,
352
      ])
353 354 355 356
      ->condition('cid', $cids, 'IN')
      ->execute();
  }
  else {
357 358 359 360 361 362 363
    // Update this notification to be disabled.
    return (bool) db_update('comment_notify')
      ->fields([
        'notify' => 0,
      ])
      ->condition('notify_hash', $hash)
      ->execute();
364
  }
365
}