comment.admin.inc 9.62 KB
Newer Older
1 2 3 4
<?php

/**
 * @file
5
 * Admin page callbacks for the Comment module.
6 7
 */

8
use Drupal\comment\Comment;
9
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
10

11
/**
12 13 14 15 16 17 18 19
 * Page callback: Presents an administrative comment listing.
 *
 * @param $type
 *   The type of the overview form ('approval' or 'new'). See
 *   comment_admin_overview() for details.
 *
 * @see comment_menu()
 * @see comment_multiple_delete_confirm()
20 21 22 23 24
 */
function comment_admin($type = 'new') {
  $edit = $_POST;

  if (isset($edit['operation']) && ($edit['operation'] == 'delete') && isset($edit['comments']) && $edit['comments']) {
25
    return drupal_get_form('comment_multiple_delete_confirm');
26 27
  }
  else {
28
    return drupal_get_form('comment_admin_overview', $type);
29 30 31 32
  }
}

/**
33
 * Form constructor for the comment overview administration form.
34
 *
35
 * @param $arg
36
 *   The type of overview form ('approval' or 'new').
37
 *
38
 * @ingroup forms
39
 * @see comment_admin()
40 41 42
 * @see comment_admin_overview_validate()
 * @see comment_admin_overview_submit()
 * @see theme_comment_admin_overview()
43
 */
44
function comment_admin_overview($form, &$form_state, $arg) {
45
  // Build an 'Update options' form.
46
  $form['options'] = array(
47 48
    '#type' => 'fieldset',
    '#title' => t('Update options'),
49
    '#attributes' => array('class' => array('container-inline')),
50
  );
51 52 53 54 55 56

  if ($arg == 'approval') {
    $options['publish'] = t('Publish the selected comments');
  }
  else {
    $options['unpublish'] = t('Unpublish the selected comments');
57
  }
58 59
  $options['delete'] = t('Delete the selected comments');

60 61
  $form['options']['operation'] = array(
    '#type' => 'select',
62 63
    '#title' => t('Operation'),
    '#title_display' => 'invisible',
64 65 66 67 68 69 70
    '#options' => $options,
    '#default_value' => 'publish',
  );
  $form['options']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Update'),
  );
71

72
  // Load the comments that need to be displayed.
73
  $status = ($arg == 'approval') ? COMMENT_NOT_PUBLISHED : COMMENT_PUBLISHED;
74 75 76 77
  $header = array(
    'subject' => array('data' => t('Subject'), 'field' => 'subject'),
    'author' => array('data' => t('Author'), 'field' => 'name'),
    'posted_in' => array('data' => t('Posted in'), 'field' => 'node_title'),
78
    'changed' => array('data' => t('Updated'), 'field' => 'c.changed', 'sort' => 'desc'),
79 80 81
    'operations' => array('data' => t('Operations')),
  );

82
  $query = db_select('comment', 'c')->extend('PagerDefault')->extend('TableSort');
83 84
  $query->join('node', 'n', 'n.nid = c.nid');
  $query->addField('n', 'title', 'node_title');
85
  $query->addTag('node_access');
86
  $result = $query
87
    ->fields('c', array('cid', 'subject', 'name', 'changed'))
88 89
    ->condition('c.status', $status)
    ->limit(50)
90 91
    ->orderByHeader($header)
    ->execute();
92

93
  $cids = array();
94

95 96 97 98 99 100 101
  // We collect a sorted list of node_titles during the query to attach to the
  // comments later.
  foreach ($result as $row) {
    $cids[] = $row->cid;
    $node_titles[] = $row->node_title;
  }
  $comments = comment_load_multiple($cids);
102

103
  // Build a table listing the appropriate comments.
104
  $options = array();
105
  $destination = drupal_get_destination();
106

107
  foreach ($comments as $comment) {
108
    // Remove the first node title from the node_titles array and attach to
109 110
    // the comment.
    $comment->node_title = array_shift($node_titles);
111
    $options[$comment->cid] = array(
112 113 114 115 116
      'subject' => array(
        'data' => array(
          '#type' => 'link',
          '#title' => $comment->subject,
          '#href' => 'comment/' . $comment->cid,
117
          '#options' => array('attributes' => array('title' => truncate_utf8($comment->comment_body[LANGUAGE_NOT_SPECIFIED][0]['value'], 128)), 'fragment' => 'comment-' . $comment->cid),
118 119
        ),
      ),
120
      'author' => theme('username', array('account' => $comment)),
121 122 123 124 125 126 127
      'posted_in' => array(
        'data' => array(
          '#type' => 'link',
          '#title' => $comment->node_title,
          '#href' => 'node/' . $comment->nid,
        ),
      ),
128
      'changed' => format_date($comment->changed, 'short'),
129 130 131 132 133 134 135 136
      'operations' => array(
        'data' => array(
          '#type' => 'link',
          '#title' => t('edit'),
          '#href' => 'comment/' . $comment->cid . '/edit',
          '#options' => array('query' => $destination),
        ),
      ),
137
    );
138
  }
139

140
  $form['comments'] = array(
141 142 143 144
    '#type' => 'tableselect',
    '#header' => $header,
    '#options' => $options,
    '#empty' => t('No comments available.'),
145
  );
146

147
  $form['pager'] = array('#theme' => 'pager');
148

149 150 151 152
  return $form;
}

/**
153 154 155
 * Form validation handler for comment_admin_overview().
 *
 * @see comment_admin_overview_submit()
156 157 158
 */
function comment_admin_overview_validate($form, &$form_state) {
  $form_state['values']['comments'] = array_diff($form_state['values']['comments'], array(0));
159
  // We can't execute any 'Update options' if no comments were selected.
160
  if (count($form_state['values']['comments']) == 0) {
161
    form_set_error('', t('Select one or more comments to perform the update on.'));
162 163 164 165
  }
}

/**
166
 * Form submission handler for comment_admin_overview().
167
 *
168
 * Executes the chosen 'Update option' on the selected comments, such as
169
 * publishing, unpublishing or deleting.
170 171
 *
 * @see comment_admin_overview_validate()
172 173
 */
function comment_admin_overview_submit($form, &$form_state) {
174 175 176 177 178 179 180 181 182 183 184 185 186
  $operation = $form_state['values']['operation'];
  $cids = $form_state['values']['comments'];

  if ($operation == 'delete') {
    comment_delete_multiple($cids);
  }
  else {
    foreach ($cids as $cid => $value) {
      $comment = comment_load($value);

      if ($operation == 'unpublish') {
        $comment->status = COMMENT_NOT_PUBLISHED;
      }
187
      elseif ($operation == 'publish') {
188
        $comment->status = COMMENT_PUBLISHED;
189
      }
190
      comment_save($comment);
191 192
    }
  }
193 194
  drupal_set_message(t('The update has been performed.'));
  $form_state['redirect'] = 'admin/content/comment';
195
  cache_clear_all();
196 197 198
}

/**
199
 * Form constructor for the confirmation form for bulk comment deletion.
200 201
 *
 * @ingroup forms
202
 * @see comment_admin()
203
 * @see comment_multiple_delete_confirm_submit()
204
 */
205
function comment_multiple_delete_confirm($form, &$form_state) {
206
  $edit = $form_state['input'];
207

208 209 210 211 212 213
  $form['comments'] = array(
    '#prefix' => '<ul>',
    '#suffix' => '</ul>',
    '#tree' => TRUE,
  );
  // array_filter() returns only elements with actual values.
214 215
  $comment_counter = 0;
  foreach (array_filter($edit['comments']) as $cid => $value) {
216
    $comment = comment_load($cid);
217
    if (is_object($comment) && is_numeric($comment->cid)) {
218
      $subject = db_query('SELECT subject FROM {comment} WHERE cid = :cid', array(':cid' => $cid))->fetchField();
219
      $form['comments'][$cid] = array('#type' => 'hidden', '#value' => $cid, '#prefix' => '<li>', '#suffix' => check_plain($subject) . '</li>');
220 221 222 223 224 225
      $comment_counter++;
    }
  }
  $form['operation'] = array('#type' => 'hidden', '#value' => 'delete');

  if (!$comment_counter) {
226
    drupal_set_message(t('There do not appear to be any comments to delete, or your selected comment was deleted by another administrator.'));
227
    drupal_goto('admin/content/comment');
228 229 230 231
  }
  else {
    return confirm_form($form,
                        t('Are you sure you want to delete these comments and all their children?'),
232
                        'admin/content/comment', t('This action cannot be undone.'),
233 234 235 236 237
                        t('Delete comments'), t('Cancel'));
  }
}

/**
238
 * Form submission handler for comment_multiple_delete_confirm().
239 240 241
 */
function comment_multiple_delete_confirm_submit($form, &$form_state) {
  if ($form_state['values']['confirm']) {
242
    comment_delete_multiple(array_keys($form_state['values']['comments']));
243
    cache_clear_all();
244 245
    $count = count($form_state['values']['comments']);
    watchdog('content', 'Deleted @count comments.', array('@count' => $count));
246
    drupal_set_message(format_plural($count, 'Deleted 1 comment.', 'Deleted @count comments.'));
247
  }
248
  $form_state['redirect'] = 'admin/content/comment';
249 250
}

251
/**
252 253 254 255 256 257 258
 * Page callback: Shows a confirmation page for comment deletions.
 *
 * @param $cid
 *   The ID of the comment that is about to be deleted.
 *
 * @see comment_menu()
 * @see comment_confirm_delete()
259 260 261 262 263
 */
function comment_confirm_delete_page($cid) {
  if ($comment = comment_load($cid)) {
    return drupal_get_form('comment_confirm_delete', $comment);
  }
264
  throw new NotFoundHttpException();
265 266
}

267
/**
268 269
 * Form constructor for the confirmation form for comment deletion.
 *
270
 * @param Drupal\comment\Comment $comment
271
 *   The comment that is about to be deleted.
272 273
 *
 * @ingroup forms
274
 * @see comment_confirm_delete_page()
275
 * @see comment_confirm_delete_submit()
276
 * @see confirm_form()
277
 */
278
function comment_confirm_delete($form, &$form_state, Comment $comment) {
279
  $form['#comment'] = $comment;
280 281
  // Always provide entity id in the same form key as in the entity edit form.
  $form['cid'] = array('#type' => 'value', '#value' => $comment->cid);
282 283 284
  return confirm_form(
    $form,
    t('Are you sure you want to delete the comment %title?', array('%title' => $comment->subject)),
285
    'node/' . $comment->nid,
286 287 288 289 290 291
    t('Any replies to this comment will be lost. This action cannot be undone.'),
    t('Delete'),
    t('Cancel'),
    'comment_confirm_delete');
}

292
/**
293
 * Form submission handler for comment_confirm_delete().
294
 */
295 296
function comment_confirm_delete_submit($form, &$form_state) {
  $comment = $form['#comment'];
297
  // Delete the comment and its replies.
298 299
  comment_delete($comment->cid);
  drupal_set_message(t('The comment and all its replies have been deleted.'));
300
  watchdog('content', 'Deleted comment @cid and its replies.', array('@cid' => $comment->cid));
301 302 303 304 305
  // Clear the cache so an anonymous user sees that his comment was deleted.
  cache_clear_all();

  $form_state['redirect'] = "node/$comment->nid";
}