comment_notify.inc 10.3 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 = \Drupal::database()->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
    'entity_notify' => \Drupal::config('comment_notify.settings')->get('enable_default.entity_author'),
54
  ];
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) \Drupal::database()->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 entity update notification.
91
 *
92
 * This is notification on entity 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
function comment_notify_get_user_entity_notify_preference($uid) {
101
  $setting = comment_notify_get_user_notification_setting($uid);
102
  if (!$setting) {
103
    $setting = comment_notify_get_default_notification_setting();
104
  }
105
  return $setting->entity_notify;
106 107 108 109
}

/**
 * Sets the notification preferences for a specific user.
110
 *
111 112
 * @param int $uid
 *   The User ID.
113 114
 * @param int $entity_notification
 *   The entity notification value.
115 116 117 118 119
 * @param int $comment_notification
 *   The comment notification value.
 *
 * @return bool
 *   TRUE if the notification was set correctly.
120
 */
121
function comment_notify_set_user_notification_setting($uid, $entity_notification = NULL, $comment_notification = NULL) {
122 123 124
  if (!$uid) {
    throw new Exception('Cannot set user preference, uid missing');
  }
125
  $fields = ['uid' => $uid];
126

127 128
  if (!is_null($entity_notification)) {
    $fields['entity_notify'] = $entity_notification;
129 130
  }
  if (!is_null($comment_notification)) {
131
    $fields['comment_notify'] = $comment_notification;
132 133
  }
  if (comment_notify_get_user_notification_setting($uid)) {
134
    $query = \Drupal::database()->update('comment_notify_user_settings');
135
    $query->condition('uid', $uid);
136 137
  }
  else {
138
    $query = \Drupal::database()->insert('comment_notify_user_settings');
139
  }
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
  // Check if comment already exist.
162
  $results = \Drupal::database()->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
    return (bool) \Drupal::database()->update('comment_notify')
171
      ->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
    return (bool) \Drupal::database()->insert('comment_notify')
183
      ->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) \Drupal::database()->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
  return (bool) \Drupal::database()->update('comment_notify')
221
    ->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 \Drupal::database()->select('comment_notify', 'cn')
239
    ->fields('cn', ['notify'])
240 241 242 243 244 245
    ->condition('cid', $cid)
    ->execute()
    ->fetchField();
}

/**
246
 * Get a list of mails which need to be contacted for an entity.
247
 *
248 249
 * @param int $entity_id
 *   The entity 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($entity_id, $comment_type) {
257
  $cids = \Drupal::database()->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 = :entity_id AND c.comment_type = :comment_type AND c.status = :status AND cn.notify <> :notify AND (u.uid = 0 OR u.status = 1)", [
258
    ':entity_id' => $entity_id,
259
    ':comment_type' => $comment_type,
260
    ':status' => CommentInterface::PUBLISHED,
261
    ':notify' => COMMENT_NOTIFY_DISABLED,
262
  ])->fetchCol();
263
  return \Drupal::entityTypeManager()->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
  return (bool) \Drupal::database()->update('comment_notify')
281
    ->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
 */
function comment_notify_unsubscribe_by_email($mail) {
301 302 303
  $comment_query = \Drupal::entityQuery('comment');
  if ($user = user_load_by_mail($mail)) {
    $comment_query->condition('uid', $user->id());
304 305
  }
  else {
306 307
    $comment_query->condition('mail', $mail);
  }
308 309 310 311 312 313 314

  $comments = $comment_query->execute();

  if (empty($comments)) {
    return FALSE;
  }

315
  $update_query = \Drupal::database()->update('comment_notify');
316
  $update_query->fields(['notify' => 0]);
317
  $update_query->condition('cid', $comment_query->execute(), 'IN');
318

319
  return (bool) $update_query->execute();
320 321 322
}

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

343 344 345 346
  if (empty($notification)) {
    return FALSE;
  }

347 348 349
  // If this notification is at the entity level and the commenter has a Drupal
  // account, delete all notifications for this entity.
  if (COMMENT_NOTIFY_ENTITY == $notification->notify && $notification->uid) {
350
    $result = \Drupal::database()->query("SELECT cid FROM {comment_field_data} WHERE entity_id = :entity_id AND entity_type = :entity_type AND uid = :uid", [
351 352 353 354
      ':entity_id' => $notification->entity_id,
      ':entity_type' => $notification->entity_type,
      ':uid' => $notification->uid,
    ]);
355 356 357
    $cids = $result->fetchCol();

    // Update all comment notifications to be disabled.
358
    return (bool) \Drupal::database()->update('comment_notify')
359
      ->fields([
360
        'notify' => 0,
361
      ])
362 363 364 365
      ->condition('cid', $cids, 'IN')
      ->execute();
  }
  else {
366
    // Update this notification to be disabled.
367
    return (bool) \Drupal::database()->update('comment_notify')
368 369 370 371 372
      ->fields([
        'notify' => 0,
      ])
      ->condition('notify_hash', $hash)
      ->execute();
373
  }
374
}