11 | | * Comments List Table class. |
12 | | * |
13 | | * @package WordPress |
14 | | * @subpackage List_Table |
15 | | * @since 3.1.0 |
16 | | * @access private |
17 | | */ |
18 | | class WP_Comments_List_Table extends WP_List_Table { |
19 | | |
20 | | public $checkbox = true; |
21 | | |
22 | | public $pending_count = array(); |
23 | | |
24 | | public $extra_items; |
25 | | |
26 | | private $user_can; |
27 | | |
28 | | /** |
29 | | * Constructor. |
30 | | * |
31 | | * @since 3.1.0 |
32 | | * @access public |
33 | | * |
34 | | * @see WP_List_Table::__construct() for more information on default arguments. |
35 | | * |
36 | | * @global int $post_id |
37 | | * |
38 | | * @param array $args An associative array of arguments. |
39 | | */ |
40 | | public function __construct( $args = array() ) { |
41 | | global $post_id; |
42 | | |
43 | | $post_id = isset( $_REQUEST['p'] ) ? absint( $_REQUEST['p'] ) : 0; |
44 | | |
45 | | if ( get_option( 'show_avatars' ) ) { |
46 | | add_filter( 'comment_author', array( $this, 'floated_admin_avatar' ), 10, 2 ); |
47 | | } |
48 | | |
49 | | parent::__construct( array( |
50 | | 'plural' => 'comments', |
51 | | 'singular' => 'comment', |
52 | | 'ajax' => true, |
53 | | 'screen' => isset( $args['screen'] ) ? $args['screen'] : null, |
54 | | ) ); |
55 | | } |
56 | | |
57 | | public function floated_admin_avatar( $name, $comment_ID ) { |
58 | | $comment = get_comment( $comment_ID ); |
59 | | $avatar = get_avatar( $comment, 32, 'mystery' ); |
60 | | return "$avatar $name"; |
61 | | } |
62 | | |
63 | | /** |
64 | | * @return bool |
65 | | */ |
66 | | public function ajax_user_can() { |
67 | | return current_user_can('edit_posts'); |
68 | | } |
69 | | |
70 | | /** |
71 | | * |
72 | | * @global int $post_id |
73 | | * @global string $comment_status |
74 | | * @global string $search |
75 | | * @global string $comment_type |
76 | | */ |
77 | | public function prepare_items() { |
78 | | global $post_id, $comment_status, $search, $comment_type; |
79 | | |
80 | | $comment_status = isset( $_REQUEST['comment_status'] ) ? $_REQUEST['comment_status'] : 'all'; |
81 | | if ( !in_array( $comment_status, array( 'all', 'moderated', 'approved', 'spam', 'trash' ) ) ) |
82 | | $comment_status = 'all'; |
83 | | |
84 | | $comment_type = !empty( $_REQUEST['comment_type'] ) ? $_REQUEST['comment_type'] : ''; |
85 | | |
86 | | $search = ( isset( $_REQUEST['s'] ) ) ? $_REQUEST['s'] : ''; |
87 | | |
88 | | $post_type = ( isset( $_REQUEST['post_type'] ) ) ? sanitize_key( $_REQUEST['post_type'] ) : ''; |
89 | | |
90 | | $user_id = ( isset( $_REQUEST['user_id'] ) ) ? $_REQUEST['user_id'] : ''; |
91 | | |
92 | | $orderby = ( isset( $_REQUEST['orderby'] ) ) ? $_REQUEST['orderby'] : ''; |
93 | | $order = ( isset( $_REQUEST['order'] ) ) ? $_REQUEST['order'] : ''; |
94 | | |
95 | | $comments_per_page = $this->get_per_page( $comment_status ); |
96 | | |
97 | | $doing_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX; |
98 | | |
99 | | if ( isset( $_REQUEST['number'] ) ) { |
100 | | $number = (int) $_REQUEST['number']; |
101 | | } |
102 | | else { |
103 | | $number = $comments_per_page + min( 8, $comments_per_page ); // Grab a few extra |
104 | | } |
105 | | |
106 | | $page = $this->get_pagenum(); |
107 | | |
108 | | if ( isset( $_REQUEST['start'] ) ) { |
109 | | $start = $_REQUEST['start']; |
110 | | } else { |
111 | | $start = ( $page - 1 ) * $comments_per_page; |
112 | | } |
113 | | |
114 | | if ( $doing_ajax && isset( $_REQUEST['offset'] ) ) { |
115 | | $start += $_REQUEST['offset']; |
116 | | } |
117 | | |
118 | | $status_map = array( |
119 | | 'moderated' => 'hold', |
120 | | 'approved' => 'approve', |
121 | | 'all' => '', |
122 | | ); |
123 | | |
124 | | $args = array( |
125 | | 'status' => isset( $status_map[$comment_status] ) ? $status_map[$comment_status] : $comment_status, |
126 | | 'search' => $search, |
127 | | 'user_id' => $user_id, |
128 | | 'offset' => $start, |
129 | | 'number' => $number, |
130 | | 'post_id' => $post_id, |
131 | | 'type' => $comment_type, |
132 | | 'orderby' => $orderby, |
133 | | 'order' => $order, |
134 | | 'post_type' => $post_type, |
135 | | ); |
136 | | |
137 | | $_comments = get_comments( $args ); |
138 | | if ( is_array( $_comments ) ) { |
139 | | update_comment_cache( $_comments ); |
140 | | |
141 | | $this->items = array_slice( $_comments, 0, $comments_per_page ); |
142 | | $this->extra_items = array_slice( $_comments, $comments_per_page ); |
143 | | |
144 | | $_comment_post_ids = array_unique( wp_list_pluck( $_comments, 'comment_post_ID' ) ); |
145 | | |
146 | | $this->pending_count = get_pending_comments_num( $_comment_post_ids ); |
147 | | } |
148 | | |
149 | | $total_comments = get_comments( array_merge( $args, array( |
150 | | 'count' => true, |
151 | | 'offset' => 0, |
152 | | 'number' => 0 |
153 | | ) ) ); |
154 | | |
155 | | $this->set_pagination_args( array( |
156 | | 'total_items' => $total_comments, |
157 | | 'per_page' => $comments_per_page, |
158 | | ) ); |
159 | | } |
160 | | |
161 | | /** |
162 | | * |
163 | | * @param string $comment_status |
164 | | * @return int |
165 | | */ |
166 | | public function get_per_page( $comment_status = 'all' ) { |
167 | | $comments_per_page = $this->get_items_per_page( 'edit_comments_per_page' ); |
168 | | /** |
169 | | * Filter the number of comments listed per page in the comments list table. |
170 | | * |
171 | | * @since 2.6.0 |
172 | | * |
173 | | * @param int $comments_per_page The number of comments to list per page. |
174 | | * @param string $comment_status The comment status name. Default 'All'. |
175 | | */ |
176 | | return apply_filters( 'comments_per_page', $comments_per_page, $comment_status ); |
177 | | } |
178 | | |
179 | | /** |
180 | | * |
181 | | * @global string $comment_status |
182 | | */ |
183 | | public function no_items() { |
184 | | global $comment_status; |
185 | | |
186 | | if ( 'moderated' == $comment_status ) |
187 | | _e( 'No comments awaiting moderation.' ); |
188 | | else |
189 | | _e( 'No comments found.' ); |
190 | | } |
191 | | |
192 | | /** |
193 | | * |
194 | | * @global int $post_id |
195 | | * @global string $comment_status |
196 | | * @global string $comment_type |
197 | | */ |
198 | | protected function get_views() { |
199 | | global $post_id, $comment_status, $comment_type; |
200 | | |
201 | | $status_links = array(); |
202 | | $num_comments = ( $post_id ) ? wp_count_comments( $post_id ) : wp_count_comments(); |
203 | | //, number_format_i18n($num_comments->moderated) ), "<span class='comment-count'>" . number_format_i18n($num_comments->moderated) . "</span>"), |
204 | | //, number_format_i18n($num_comments->spam) ), "<span class='spam-comment-count'>" . number_format_i18n($num_comments->spam) . "</span>") |
205 | | $stati = array( |
206 | | 'all' => _nx_noop('All', 'All', 'comments'), // singular not used |
207 | | 'moderated' => _n_noop('Pending <span class="count">(<span class="pending-count">%s</span>)</span>', 'Pending <span class="count">(<span class="pending-count">%s</span>)</span>'), |
208 | | 'approved' => _n_noop('Approved <span class="count">(<span class="approved-count">%s</span>)</span>', 'Approved <span class="count">(<span class="approved-count">%s</span>)</span>'), |
209 | | 'spam' => _n_noop('Spam <span class="count">(<span class="spam-count">%s</span>)</span>', 'Spam <span class="count">(<span class="spam-count">%s</span>)</span>'), |
210 | | 'trash' => _n_noop('Trash <span class="count">(<span class="trash-count">%s</span>)</span>', 'Trash <span class="count">(<span class="trash-count">%s</span>)</span>') |
211 | | ); |
212 | | |
213 | | if ( !EMPTY_TRASH_DAYS ) |
214 | | unset($stati['trash']); |
215 | | |
216 | | $link = 'edit-comments.php'; |
217 | | if ( !empty($comment_type) && 'all' != $comment_type ) |
218 | | $link = add_query_arg( 'comment_type', $comment_type, $link ); |
219 | | |
220 | | foreach ( $stati as $status => $label ) { |
221 | | $class = ( $status == $comment_status ) ? ' class="current"' : ''; |
222 | | |
223 | | if ( !isset( $num_comments->$status ) ) |
224 | | $num_comments->$status = 10; |
225 | | $link = add_query_arg( 'comment_status', $status, $link ); |
226 | | if ( $post_id ) |
227 | | $link = add_query_arg( 'p', absint( $post_id ), $link ); |
228 | | /* |
229 | | // I toyed with this, but decided against it. Leaving it in here in case anyone thinks it is a good idea. ~ Mark |
230 | | if ( !empty( $_REQUEST['s'] ) ) |
231 | | $link = add_query_arg( 's', esc_attr( wp_unslash( $_REQUEST['s'] ) ), $link ); |
232 | | */ |
233 | | $status_links[$status] = "<a href='$link'$class>" . sprintf( |
234 | | translate_nooped_plural( $label, $num_comments->$status ), |
235 | | number_format_i18n( $num_comments->$status ) |
236 | | ) . '</a>'; |
237 | | } |
238 | | |
239 | | /** |
240 | | * Filter the comment status links. |
241 | | * |
242 | | * @since 2.5.0 |
243 | | * |
244 | | * @param array $status_links An array of fully-formed status links. Default 'All'. |
245 | | * Accepts 'All', 'Pending', 'Approved', 'Spam', and 'Trash'. |
246 | | */ |
247 | | return apply_filters( 'comment_status_links', $status_links ); |
248 | | } |
249 | | |
250 | | /** |
251 | | * |
252 | | * @global string $comment_status |
253 | | * |
254 | | * @return array |
255 | | */ |
256 | | protected function get_bulk_actions() { |
257 | | global $comment_status; |
258 | | |
259 | | $actions = array(); |
260 | | if ( in_array( $comment_status, array( 'all', 'approved' ) ) ) |
261 | | $actions['unapprove'] = __( 'Unapprove' ); |
262 | | if ( in_array( $comment_status, array( 'all', 'moderated' ) ) ) |
263 | | $actions['approve'] = __( 'Approve' ); |
264 | | if ( in_array( $comment_status, array( 'all', 'moderated', 'approved', 'trash' ) ) ) |
265 | | $actions['spam'] = _x( 'Mark as Spam', 'comment' ); |
266 | | |
267 | | if ( 'trash' == $comment_status ) |
268 | | $actions['untrash'] = __( 'Restore' ); |
269 | | elseif ( 'spam' == $comment_status ) |
270 | | $actions['unspam'] = _x( 'Not Spam', 'comment' ); |
271 | | |
272 | | if ( in_array( $comment_status, array( 'trash', 'spam' ) ) || !EMPTY_TRASH_DAYS ) |
273 | | $actions['delete'] = __( 'Delete Permanently' ); |
274 | | else |
275 | | $actions['trash'] = __( 'Move to Trash' ); |
276 | | |
277 | | return $actions; |
278 | | } |
279 | | |
280 | | /** |
281 | | * |
282 | | * @global string $comment_status |
283 | | * @global string $comment_type |
284 | | * |
285 | | * @param string $which |
286 | | */ |
287 | | protected function extra_tablenav( $which ) { |
288 | | global $comment_status, $comment_type; |
289 | | ?> |
290 | | <div class="alignleft actions"> |
291 | | <?php |
292 | | if ( 'top' == $which ) { |
293 | | ?> |
294 | | <label class="screen-reader-text" for="filter-by-comment-type"><?php _e( 'Filter by comment type' ); ?></label> |
295 | | <select id="filter-by-comment-type" name="comment_type"> |
296 | | <option value=""><?php _e( 'All comment types' ); ?></option> |
297 | | <?php |
298 | | /** |
299 | | * Filter the comment types dropdown menu. |
300 | | * |
301 | | * @since 2.7.0 |
302 | | * |
303 | | * @param array $comment_types An array of comment types. Accepts 'Comments', 'Pings'. |
304 | | */ |
305 | | $comment_types = apply_filters( 'admin_comment_types_dropdown', array( |
306 | | 'comment' => __( 'Comments' ), |
307 | | 'pings' => __( 'Pings' ), |
308 | | ) ); |
309 | | |
310 | | foreach ( $comment_types as $type => $label ) |
311 | | echo "\t" . '<option value="' . esc_attr( $type ) . '"' . selected( $comment_type, $type, false ) . ">$label</option>\n"; |
312 | | ?> |
313 | | </select> |
314 | | <?php |
315 | | /** |
316 | | * Fires just before the Filter submit button for comment types. |
317 | | * |
318 | | * @since 3.5.0 |
319 | | */ |
320 | | do_action( 'restrict_manage_comments' ); |
321 | | submit_button( __( 'Filter' ), 'button', 'filter_action', false, array( 'id' => 'post-query-submit' ) ); |
322 | | } |
323 | | |
324 | | if ( ( 'spam' == $comment_status || 'trash' == $comment_status ) && current_user_can( 'moderate_comments' ) ) { |
325 | | wp_nonce_field( 'bulk-destroy', '_destroy_nonce' ); |
326 | | $title = ( 'spam' == $comment_status ) ? esc_attr__( 'Empty Spam' ) : esc_attr__( 'Empty Trash' ); |
327 | | submit_button( $title, 'apply', 'delete_all', false ); |
328 | | } |
329 | | /** |
330 | | * Fires after the Filter submit button for comment types. |
331 | | * |
332 | | * @since 2.5.0 |
333 | | * |
334 | | * @param string $comment_status The comment status name. Default 'All'. |
335 | | */ |
336 | | do_action( 'manage_comments_nav', $comment_status ); |
337 | | echo '</div>'; |
338 | | } |
339 | | |
340 | | /** |
341 | | * @return string|false |
342 | | */ |
343 | | public function current_action() { |
344 | | if ( isset( $_REQUEST['delete_all'] ) || isset( $_REQUEST['delete_all2'] ) ) |
345 | | return 'delete_all'; |
346 | | |
347 | | return parent::current_action(); |
348 | | } |
349 | | |
350 | | /** |
351 | | * |
352 | | * @global int $post_id |
353 | | * |
354 | | * @return array |
355 | | */ |
356 | | public function get_columns() { |
357 | | global $post_id; |
358 | | |
359 | | $columns = array(); |
360 | | |
361 | | if ( $this->checkbox ) |
362 | | $columns['cb'] = '<input type="checkbox" />'; |
363 | | |
364 | | $columns['author'] = __( 'Author' ); |
365 | | $columns['comment'] = _x( 'Comment', 'column name' ); |
366 | | |
367 | | if ( ! $post_id ) { |
368 | | /* translators: column name or table row header */ |
369 | | $columns['response'] = __( 'In Response To' ); |
370 | | } |
371 | | |
372 | | return $columns; |
373 | | } |
374 | | |
375 | | /** |
376 | | * |
377 | | * @return array |
378 | | */ |
379 | | protected function get_sortable_columns() { |
380 | | return array( |
381 | | 'author' => 'comment_author', |
382 | | 'response' => 'comment_post_ID' |
383 | | ); |
384 | | } |
385 | | |
386 | | /** |
387 | | * Get the name of the default primary column. |
388 | | * |
389 | | * @since 4.3.0 |
390 | | * @access protected |
391 | | * |
392 | | * @return string Name of the default primary column, in this case, 'comment'. |
393 | | */ |
394 | | protected function get_default_primary_column_name() { |
395 | | return 'comment'; |
396 | | } |
397 | | |
398 | | /** |
399 | | * @access public |
400 | | */ |
401 | | public function display() { |
402 | | wp_nonce_field( "fetch-list-" . get_class( $this ), '_ajax_fetch_list_nonce' ); |
403 | | |
404 | | $this->display_tablenav( 'top' ); |
405 | | |
406 | | ?> |
407 | | <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>"> |
408 | | <thead> |
409 | | <tr> |
410 | | <?php $this->print_column_headers(); ?> |
411 | | </tr> |
412 | | </thead> |
413 | | |
414 | | <tbody id="the-comment-list" data-wp-lists="list:comment"> |
415 | | <?php $this->display_rows_or_placeholder(); ?> |
416 | | </tbody> |
417 | | |
418 | | <tbody id="the-extra-comment-list" data-wp-lists="list:comment" style="display: none;"> |
419 | | <?php |
420 | | $this->items = $this->extra_items; |
421 | | $this->display_rows_or_placeholder(); |
422 | | ?> |
423 | | </tbody> |
424 | | |
425 | | <tfoot> |
426 | | <tr> |
427 | | <?php $this->print_column_headers( false ); ?> |
428 | | </tr> |
429 | | </tfoot> |
430 | | |
431 | | </table> |
432 | | <?php |
433 | | |
434 | | $this->display_tablenav( 'bottom' ); |
435 | | } |
436 | | |
437 | | /** |
438 | | * @global WP_Post $post |
439 | | * |
440 | | * @param object $comment |
441 | | */ |
442 | | public function single_row( $comment ) { |
443 | | global $post; |
444 | | |
445 | | $the_comment_class = wp_get_comment_status( $comment ); |
446 | | if ( ! $the_comment_class ) { |
447 | | $the_comment_class = ''; |
448 | | } |
449 | | $the_comment_class = join( ' ', get_comment_class( $the_comment_class, $comment, $comment->comment_post_ID ) ); |
450 | | |
451 | | if ( $comment->comment_post_ID > 0 ) { |
452 | | $post = get_post( $comment->comment_post_ID ); |
453 | | } |
454 | | $this->user_can = current_user_can( 'edit_comment', $comment->comment_ID ); |
455 | | |
456 | | echo "<tr id='comment-$comment->comment_ID' class='$the_comment_class'>"; |
457 | | $this->single_row_columns( $comment ); |
458 | | echo "</tr>\n"; |
459 | | |
460 | | $post = null; |
461 | | } |
462 | | |
463 | | /** |
464 | | * Generate and display row actions links. |
465 | | * |
466 | | * @since 4.3.0 |
467 | | * @access protected |
468 | | * |
469 | | * @param object $comment Comment being acted upon. |
470 | | * @param string $column_name Current column name. |
471 | | * @param string $primary Primary column name. |
472 | | * @return string|void Comment row actions output. |
473 | | */ |
474 | | protected function handle_row_actions( $comment, $column_name, $primary ) { |
475 | | global $comment_status; |
476 | | |
477 | | if ( $primary !== $column_name ) { |
478 | | return ''; |
479 | | } |
480 | | |
481 | | if ( ! $this->user_can ) { |
482 | | return; |
483 | | } |
484 | | |
485 | | $the_comment_status = wp_get_comment_status( $comment ); |
486 | | |
487 | | $out = ''; |
488 | | |
489 | | $del_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "delete-comment_$comment->comment_ID" ) ); |
490 | | $approve_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "approve-comment_$comment->comment_ID" ) ); |
491 | | |
492 | | $url = "comment.php?c=$comment->comment_ID"; |
493 | | |
494 | | $approve_url = esc_url( $url . "&action=approvecomment&$approve_nonce" ); |
495 | | $unapprove_url = esc_url( $url . "&action=unapprovecomment&$approve_nonce" ); |
496 | | $spam_url = esc_url( $url . "&action=spamcomment&$del_nonce" ); |
497 | | $unspam_url = esc_url( $url . "&action=unspamcomment&$del_nonce" ); |
498 | | $trash_url = esc_url( $url . "&action=trashcomment&$del_nonce" ); |
499 | | $untrash_url = esc_url( $url . "&action=untrashcomment&$del_nonce" ); |
500 | | $delete_url = esc_url( $url . "&action=deletecomment&$del_nonce" ); |
501 | | |
502 | | // Preorder it: Approve | Reply | Quick Edit | Edit | Spam | Trash. |
503 | | $actions = array( |
504 | | 'approve' => '', 'unapprove' => '', |
505 | | 'reply' => '', |
506 | | 'quickedit' => '', |
507 | | 'edit' => '', |
508 | | 'spam' => '', 'unspam' => '', |
509 | | 'trash' => '', 'untrash' => '', 'delete' => '' |
510 | | ); |
511 | | |
512 | | // Not looking at all comments. |
513 | | if ( $comment_status && 'all' != $comment_status ) { |
514 | | if ( 'approved' == $the_comment_status ) { |
515 | | $actions['unapprove'] = "<a href='$unapprove_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID:e7e7d3:action=dim-comment&new=unapproved' class='vim-u vim-destructive' title='" . esc_attr__( 'Unapprove this comment' ) . "'>" . __( 'Unapprove' ) . '</a>'; |
516 | | } elseif ( 'unapproved' == $the_comment_status ) { |
517 | | $actions['approve'] = "<a href='$approve_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID:e7e7d3:action=dim-comment&new=approved' class='vim-a vim-destructive' title='" . esc_attr__( 'Approve this comment' ) . "'>" . __( 'Approve' ) . '</a>'; |
518 | | } |
519 | | } else { |
520 | | $actions['approve'] = "<a href='$approve_url' data-wp-lists='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=approved' class='vim-a' title='" . esc_attr__( 'Approve this comment' ) . "'>" . __( 'Approve' ) . '</a>'; |
521 | | $actions['unapprove'] = "<a href='$unapprove_url' data-wp-lists='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=unapproved' class='vim-u' title='" . esc_attr__( 'Unapprove this comment' ) . "'>" . __( 'Unapprove' ) . '</a>'; |
522 | | } |
523 | | |
524 | | if ( 'spam' != $the_comment_status ) { |
525 | | $actions['spam'] = "<a href='$spam_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::spam=1' class='vim-s vim-destructive' title='" . esc_attr__( 'Mark this comment as spam' ) . "'>" . /* translators: mark as spam link */ _x( 'Spam', 'verb' ) . '</a>'; |
526 | | } elseif ( 'spam' == $the_comment_status ) { |
527 | | $actions['unspam'] = "<a href='$unspam_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID:66cc66:unspam=1' class='vim-z vim-destructive'>" . _x( 'Not Spam', 'comment' ) . '</a>'; |
528 | | } |
529 | | |
530 | | if ( 'trash' == $the_comment_status ) { |
531 | | $actions['untrash'] = "<a href='$untrash_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID:66cc66:untrash=1' class='vim-z vim-destructive'>" . __( 'Restore' ) . '</a>'; |
532 | | } |
533 | | |
534 | | if ( 'spam' == $the_comment_status || 'trash' == $the_comment_status || !EMPTY_TRASH_DAYS ) { |
535 | | $actions['delete'] = "<a href='$delete_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::delete=1' class='delete vim-d vim-destructive'>" . __( 'Delete Permanently' ) . '</a>'; |
536 | | } else { |
537 | | $actions['trash'] = "<a href='$trash_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::trash=1' class='delete vim-d vim-destructive' title='" . esc_attr__( 'Move this comment to the trash' ) . "'>" . _x( 'Trash', 'verb' ) . '</a>'; |
538 | | } |
539 | | |
540 | | if ( 'spam' != $the_comment_status && 'trash' != $the_comment_status ) { |
541 | | $actions['edit'] = "<a href='comment.php?action=editcomment&c={$comment->comment_ID}' title='" . esc_attr__( 'Edit comment' ) . "'>". __( 'Edit' ) . '</a>'; |
542 | | |
543 | | $format = '<a data-comment-id="%d" data-post-id="%d" data-action="%s" class="%s" title="%s" href="#">%s</a>'; |
544 | | |
545 | | $actions['quickedit'] = sprintf( $format, $comment->comment_ID, $comment->comment_post_ID, 'edit', 'vim-q comment-inline',esc_attr__( 'Edit this item inline' ), __( 'Quick Edit' ) ); |
546 | | |
547 | | $actions['reply'] = sprintf( $format, $comment->comment_ID, $comment->comment_post_ID, 'replyto', 'vim-r comment-inline', esc_attr__( 'Reply to this comment' ), __( 'Reply' ) ); |
548 | | } |
549 | | |
550 | | /** This filter is documented in wp-admin/includes/dashboard.php */ |
551 | | $actions = apply_filters( 'comment_row_actions', array_filter( $actions ), $comment ); |
552 | | |
553 | | $i = 0; |
554 | | $out .= '<div class="row-actions">'; |
555 | | foreach ( $actions as $action => $link ) { |
556 | | ++$i; |
557 | | ( ( ( 'approve' == $action || 'unapprove' == $action ) && 2 === $i ) || 1 === $i ) ? $sep = '' : $sep = ' | '; |
558 | | |
559 | | // Reply and quickedit need a hide-if-no-js span when not added with ajax |
560 | | if ( ( 'reply' == $action || 'quickedit' == $action ) && ! defined('DOING_AJAX') ) |
561 | | $action .= ' hide-if-no-js'; |
562 | | elseif ( ( $action == 'untrash' && $the_comment_status == 'trash' ) || ( $action == 'unspam' && $the_comment_status == 'spam' ) ) { |
563 | | if ( '1' == get_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', true ) ) |
564 | | $action .= ' approve'; |
565 | | else |
566 | | $action .= ' unapprove'; |
567 | | } |
568 | | |
569 | | $out .= "<span class='$action'>$sep$link</span>"; |
570 | | } |
571 | | $out .= '</div>'; |
572 | | |
573 | | $out .= '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __( 'Show more details' ) . '</span></button>'; |
574 | | |
575 | | return $out; |
576 | | } |
577 | | |
578 | | /** |
579 | | * |
580 | | * @param object $comment |
581 | | */ |
582 | | public function column_cb( $comment ) { |
583 | | if ( $this->user_can ) { ?> |
584 | | <label class="screen-reader-text" for="cb-select-<?php echo $comment->comment_ID; ?>"><?php _e( 'Select comment' ); ?></label> |
585 | | <input id="cb-select-<?php echo $comment->comment_ID; ?>" type="checkbox" name="delete_comments[]" value="<?php echo $comment->comment_ID; ?>" /> |
586 | | <?php |
587 | | } |
588 | | } |
589 | | |
590 | | /** |
591 | | * @param object $comment |
592 | | */ |
593 | | public function column_comment( $comment ) { |
594 | | $comment_url = esc_url( get_comment_link( $comment ) ); |
595 | | |
596 | | echo '<div class="comment-author">'; |
597 | | $this->column_author( $comment ); |
598 | | echo '</div>'; |
599 | | |
600 | | echo '<div class="submitted-on">'; |
601 | | /* translators: 2: comment date, 3: comment time */ |
602 | | printf( __( 'Submitted on <a href="%1$s">%2$s at %3$s</a>' ), $comment_url, |
603 | | /* translators: comment date format. See http://php.net/date */ |
604 | | get_comment_date( __( 'Y/m/d' ), $comment ), |
605 | | get_comment_date( get_option( 'time_format' ), $comment ) |
606 | | ); |
607 | | |
608 | | if ( $comment->comment_parent ) { |
609 | | $parent = get_comment( $comment->comment_parent ); |
610 | | if ( $parent ) { |
611 | | $parent_link = esc_url( get_comment_link( $parent ) ); |
612 | | $name = get_comment_author( $parent ); |
613 | | printf( ' | '.__( 'In reply to <a href="%1$s">%2$s</a>.' ), $parent_link, $name ); |
614 | | } |
615 | | } |
616 | | |
617 | | echo '</div>'; |
618 | | comment_text( $comment ); |
619 | | if ( $this->user_can ) { ?> |
620 | | <div id="inline-<?php echo $comment->comment_ID; ?>" class="hidden"> |
621 | | <textarea class="comment" rows="1" cols="1"><?php |
622 | | /** This filter is documented in wp-admin/includes/comment.php */ |
623 | | echo esc_textarea( apply_filters( 'comment_edit_pre', $comment->comment_content ) ); |
624 | | ?></textarea> |
625 | | <div class="author-email"><?php echo esc_attr( $comment->comment_author_email ); ?></div> |
626 | | <div class="author"><?php echo esc_attr( $comment->comment_author ); ?></div> |
627 | | <div class="author-url"><?php echo esc_attr( $comment->comment_author_url ); ?></div> |
628 | | <div class="comment_status"><?php echo $comment->comment_approved; ?></div> |
629 | | </div> |
630 | | <?php |
631 | | } |
632 | | } |
633 | | |
634 | | /** |
635 | | * |
636 | | * @global string $comment_status |
637 | | * |
638 | | * @param object $comment |
639 | | */ |
640 | | public function column_author( $comment ) { |
641 | | global $comment_status; |
642 | | |
643 | | $author_url = get_comment_author_url( $comment ); |
644 | | |
645 | | $author_url_display = untrailingslashit( preg_replace( '|^http(s)?://(www\.)?|i', '', $author_url ) ); |
646 | | if ( strlen( $author_url_display ) > 50 ) { |
647 | | $author_url_display = wp_html_excerpt( $author_url_display, 49, '…' ); |
648 | | } |
649 | | |
650 | | echo "<strong>"; comment_author( $comment ); echo '</strong><br />'; |
651 | | if ( ! empty( $author_url_display ) ) { |
652 | | printf( '<a href="%s">%s</a><br />', esc_url( $author_url ), esc_html( $author_url_display ) ); |
653 | | } |
654 | | |
655 | | if ( $this->user_can ) { |
656 | | if ( ! empty( $comment->comment_author_email ) ) { |
657 | | /* This filter is documented in wp-includes/comment-template.php */ |
658 | | $email = apply_filters( 'comment_email', $comment->comment_author_email, $comment ); |
659 | | |
660 | | if ( ! empty( $email ) && '@' !== $email ) { |
661 | | printf( '<a href=\'mailto:%1$s\'>%1$s</a><br />', $email ); |
662 | | } |
663 | | } |
664 | | |
665 | | $author_ip = get_comment_author_IP( $comment ); |
666 | | if ( $author_ip ) { |
667 | | $author_ip_url = add_query_arg( array( 's' => $author_ip, 'mode' => 'detail' ), 'edit-comments.php' ); |
668 | | if ( 'spam' == $comment_status ) { |
669 | | $author_ip_url = add_query_arg( 'comment_status', 'spam', $author_ip_url ); |
670 | | } |
671 | | printf( '<a href="%s">%s</a>', esc_url( $author_ip_url ), $author_ip ); |
672 | | } |
673 | | } |
674 | | } |
675 | | |
676 | | /** |
677 | | * |
678 | | * @return string |
679 | | */ |
680 | | public function column_date( $comment ) { |
681 | | return get_comment_date( __( 'Y/m/d \a\t g:i a' ), $comment ); |
682 | | } |
683 | | |
684 | | /** |
685 | | * @access public |
686 | | */ |
687 | | public function column_response() { |
688 | | $post = get_post(); |
689 | | |
690 | | if ( ! $post ) { |
691 | | return; |
692 | | } |
693 | | |
694 | | if ( isset( $this->pending_count[$post->ID] ) ) { |
695 | | $pending_comments = $this->pending_count[$post->ID]; |
696 | | } else { |
697 | | $_pending_count_temp = get_pending_comments_num( array( $post->ID ) ); |
698 | | $pending_comments = $this->pending_count[$post->ID] = $_pending_count_temp[$post->ID]; |
699 | | } |
700 | | |
701 | | if ( current_user_can( 'edit_post', $post->ID ) ) { |
702 | | $post_link = "<a href='" . get_edit_post_link( $post->ID ) . "' class='comments-edit-item-link'>"; |
703 | | $post_link .= esc_html( get_the_title( $post->ID ) ) . '</a>'; |
704 | | } else { |
705 | | $post_link = esc_html( get_the_title( $post->ID ) ); |
706 | | } |
707 | | |
708 | | echo '<div class="response-links">'; |
709 | | if ( 'attachment' == $post->post_type && ( $thumb = wp_get_attachment_image( $post->ID, array( 80, 60 ), true ) ) ) { |
710 | | echo $thumb; |
711 | | } |
712 | | echo $post_link; |
713 | | $post_type_object = get_post_type_object( $post->post_type ); |
714 | | echo "<a href='" . get_permalink( $post->ID ) . "' class='comments-view-item-link'>" . $post_type_object->labels->view_item . '</a>'; |
715 | | echo '<span class="post-com-count-wrapper post-com-count-', $post->ID, '">'; |
716 | | $this->comments_bubble( $post->ID, $pending_comments ); |
717 | | echo '</span> '; |
718 | | echo '</div>'; |
719 | | } |
720 | | |
721 | | /** |
722 | | * |
723 | | * @param object $comment |
724 | | * @param string $column_name |
725 | | */ |
726 | | public function column_default( $comment, $column_name ) { |
727 | | /** |
728 | | * Fires when the default column output is displayed for a single row. |
729 | | * |
730 | | * @since 2.8.0 |
731 | | * |
732 | | * @param string $column_name The custom column's name. |
733 | | * @param int $comment->comment_ID The custom column's unique ID number. |
734 | | */ |
735 | | do_action( 'manage_comments_custom_column', $column_name, $comment->comment_ID ); |
736 | | } |
737 | | } |
738 | | |
739 | | /** |