PluginProbe
Disable Comments & Delete All Comments / trunk
Disable Comments & Delete All Comments vtrunk
1.3.3 1.3.2 trunk 1.0.0 1.0.4 1.0.5 1.0.8 1.0.9 1.1.1 1.1.3 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.3.0 1.3.1
comments-plus / admin / pages / class-page-delete-comments.php

class-page-delete-comments.php in Disable Comments & Delete All Comments trunk, at admin/pages/class-page-delete-comments.php

520 lines 16.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Exit if accessed directly
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 /**
8 * Страница общи�
9 настроек для этого плагина.
10 *
11 * Может быть использована только, если этот плагин используется как отдельный плагин, а не как аддон
12 * дя плагина Clearfy. Если плагин загружен, как аддон для Clearfy, эта страница не будет подключена.
13 *
14 * Поддерживает режим работы с мультисаймами. Вы можете увидеть эту страницу в панели настройки сети.
15 *
16 * @author Alex Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
17 *
18 * @copyright (c) 2018 Webraftic Ltd
19 */
20 class WbcrCmp_DeleteCommentsPage extends WBCR\Factory_Templates_134\Pages\PageBase {
21
22 /**
23 * {@inheritDoc}
24 *
25 * @var string
26 */
27 public $id = "delete_comments";
28
29 /**
30 * {@inheritDoc}
31 *
32 * @var string
33 */
34 public $type = "page";
35
36 /**
37 * {@inheritDoc}
38 *
39 * @var string
40 */
41 public $page_menu_dashicon = 'dashicons-testimonial';
42
43 /**
44 * {@inheritDoc}
45 *
46 * @var bool
47 */
48 public $available_for_multisite = true;
49
50 /**
51 * {@inheritDoc}
52 *
53 * @since 1.1.0
54 * @var bool
55 */
56 public $show_right_sidebar_in_options = true;
57
58 /**
59 * WbcrCmp_DeleteCommentsPage constructor.
60 *
61 * @author Alexander Kovalev <alex.kovalevv@gmail.com>
62 *
63 * @param \Wbcr_Factory480_Plugin $plugin
64 */
65 public function __construct( Wbcr_Factory480_Plugin $plugin ) {
66 $this->menu_title = __( 'Delete Comments', 'comments-plus' );
67
68 parent::__construct( $plugin );
69 }
70
71 /**
72 * {@inheritDoc}
73 *
74 * @param $notices
75 * @param Wbcr_Factory480_Plugin $plugin
76 *
77 * @return array
78 * @see libs\factory\pages\themplates\FactoryPages480_ImpressiveThemplate
79 */
80 public function getActionNotices( $notices ) {
81
82 $notices[] = [
83 'conditions' => [
84 'wbcr_cmp_clear_comments' => 1
85 ],
86 'type' => 'success',
87 'message' => __( 'All comments have been deleted.', 'comments-plus' )
88 ];
89
90 $notices[] = [
91 'conditions' => [
92 'wbcr_cmp_clear_comments_error' => 1,
93 'wbcr_cmp_code' => 'interal_error'
94 ],
95 'type' => 'danger',
96 'message' => __( 'An internal error occurred while trying to delete comments. Please try again later.', 'comments-plus' )
97 ];
98
99 return $notices;
100 }
101
102 public function getStats() {
103 if ( WCM_Plugin::app()->isNetworkActive() ) {
104 $stats = $this->getMultisiteStats();
105 } else {
106 $stats = $this->getSiteStats();
107 }
108
109 return $stats;
110 }
111
112 public function getMultisiteStats() {
113 $stats = [];
114 foreach ( WCM_Plugin::app()->getActiveSites() as $site ) {
115 switch_to_blog( $site->blog_id );
116 $site_stats = $this->getSiteStats();
117 $stats = $this->mergeStats( $stats, $site_stats );
118 restore_current_blog();
119 }
120
121 return $stats;
122 }
123
124 public function mergeStats( $current_stats, $new_stats ) {
125 if ( ! isset( $current_stats['stat_data'] ) ) {
126 $current_stats['stat_data'] = $new_stats['stat_data'];
127 } else {
128 $comment_fields = [ 'total_comments', 'order_notes_count', 'spamcount', 'unpcount', 'trashcount' ];
129 foreach ( $comment_fields as $comment_field ) {
130 if ( is_null( $current_stats['stat_data'][0]->$comment_field ) ) {
131 $current_stats['stat_data'][0]->$comment_field = 0;
132 }
133 if ( is_null( $new_stats['stat_data'][0]->$comment_field ) ) {
134 $new_stats['stat_data'][0]->$comment_field = 0;
135 }
136 if ( $new_stats['stat_data'][0]->$comment_field ) {
137 $current_stats['stat_data'][0]->$comment_field = $current_stats['stat_data'][0]->$comment_field + $new_stats['stat_data'][0]->$comment_field;
138 }
139 }
140 }
141
142 if ( ! isset( $current_stats['post_types'] ) ) {
143 $current_stats['post_types'] = $new_stats['post_types'];
144 } else {
145 foreach ( $new_stats['post_types'] as $post_type_key => $post_type ) {
146 if ( array_key_exists( $post_type_key, $current_stats['post_types'] ) ) {
147 $current_stats['post_types'][ $post_type_key ]['comments_count'] += $new_stats['post_types'][ $post_type_key ]['comments_count'];
148 } else {
149 $current_stats['post_types'][ $post_type_key ] = $new_stats['post_types'][ $post_type_key ];
150 }
151 }
152 }
153
154 return $current_stats;
155 }
156
157
158 public function getSiteStats() {
159 global $wpdb;
160 $stat_data = $wpdb->get_results( "SELECT count(*) as total_comments,
161 SUM(comment_type='order_note') as order_notes_count,
162 SUM(comment_approved='spam') as spamcount,
163 SUM(comment_approved='0') as unpcount,
164 SUM(comment_approved='trash') as trashcount
165 FROM {$wpdb->prefix}comments" );
166
167 $stat_data_by_post_type = $wpdb->get_results( "SELECT
168 SUM(comment_count) as type_comments_count, post_type
169 FROM $wpdb->posts
170 GROUP BY post_type" );
171
172 $types = get_post_types( [ 'public' => true ], 'objects' );
173
174 $post_types = [];
175 foreach ( (array) $types as $type_name => $type ) {
176 $comments_count = 0;
177 if ( ! empty( $stat_data_by_post_type ) ) {
178 foreach ( (array) $stat_data_by_post_type as $post_type_stat_value ) {
179 if ( $post_type_stat_value->post_type == $type_name ) {
180 $comments_count = $post_type_stat_value->type_comments_count;
181 }
182 }
183 }
184
185 $post_types[ $type_name ] = [ 'label' => $type->label, 'comments_count' => $comments_count ];
186 }
187
188 return [
189 'stat_data' => $stat_data,
190 'post_types' => $post_types
191 ];
192 }
193
194 /**
195 * Prints the content of the page
196 *
197 * @see libs\factory\pages\themplates\FactoryPages480_ImpressiveThemplate
198 */
199 public function showPageContent() {
200 $stats = $this->getStats();
201 $stat_data = $stats['stat_data'];
202 $post_types = $stats['post_types'];
203
204 ?>
205 <script>
206 /**
207 * Select all types by one click.
208 */
209 jQuery(document).ready(function($) {
210 updateCommentsCounter();
211
212 var allTypesCheckbox = $('#wbcr-cmp-all-types-checkbox');
213
214 allTypesCheckbox.click(function() {
215 $('.wbcr-cmp-post-type-checkbox').prop("checked", $(this).prop("checked"));
216 updateCommentsCounter()
217 });
218
219 $('.wbcr-cmp-post-type-checkbox').click(function() {
220 if( !$(this).prop("checked") ) {
221 allTypesCheckbox.prop("checked", false);
222 }
223 updateCommentsCounter();
224 });
225
226 $('input[name="wbcr_cmp_delete_order_notes"]').click(function() {
227 updateCommentsCounter();
228 });
229
230 $('.wbcr-cmp-delete-comments-button').click(function() {
231 var confrimDelete = confirm('<?php _e( 'Are you sure you want to permanently delete comments from the database? This action cannot be undone. Make sure you have a backup before proceeding.', 'comments-plus' ); ?>');
232
233 if( !confrimDelete ) {
234 return false;
235 }
236
237 $(this).submit();
238 });
239
240 function updateCommentsCounter() {
241 var commentsCount = 0;
242 $('.wbcr-cmp-post-type-checkbox:checked, input[name="wbcr_cmp_delete_order_notes"]:checked').each(function() {
243 commentsCount += $(this).data('comments-number');
244 });
245
246 $('.wbcr-cmp-delete-comments-button').val('<?php _e( 'Delete ', 'comments-plus' ) ?>(' + commentsCount + ')');
247 }
248 });
249 </script>
250 <div class="wbcr-factory-page-group-header" style="margin-top:0;">
251 <strong><?php _e( 'Comment Cleaning Tools', 'comments-plus' ) ?></strong>
252 <p>
253 <?php _e( 'These functions are useful for globally disabling comments or cleaning spam comments in bulk.', 'comments-plus' ) ?>
254 </p>
255 </div>
256 <form method="post" action="<?= $this->getActionUrl( 'delete-all-comments' ) ?>" style="padding: 20px;">
257 <h5><?php _e( 'Remove all comments', 'comments-plus' ); ?></h5>
258 <p><?php _e( 'You can delete all comments in your database with one click.', 'comments-plus' ); ?></p>
259 <p><strong><?php _e( 'Choose post types', 'comments-plus' ); ?></strong>
260 <div style="height:150px; width:400px; padding:10px 10px 0; background: #fff; border:1px solid #ccc; overflow-y: scroll; overflow-x:hidden;">
261 <p>
262 <label>
263 <input type="checkbox" id="wbcr-cmp-all-types-checkbox" name="wbcr_cmp_post_type[]" value="all" checked/> <?php _e( 'Select All Post Types', 'comments-plus' ); ?>
264 </label>
265 </p>
266 <?php foreach ( (array) $post_types as $key => $type ): ?>
267 <p>
268 <label>
269 <input type="checkbox" data-comments-number="<?= $type['comments_count'] ?>" class="wbcr-cmp-post-type-checkbox" name="wbcr_cmp_post_type[]" value="<?= esc_attr( $key ) ?>" checked/> <?= $type['label'] ?>
270 (<?= $type['comments_count'] ?>)
271 </label>
272 </p>
273 <?php endforeach; ?>
274 </div>
275 <?php if ( class_exists( 'WooCommerce' ) ):
276 ?>
277 <p style="margin:15px 0 0">
278 <label>
279 <input type="checkbox" data-comments-number="<?= $stat_data[0]->order_notes_count ?>" name="wbcr_cmp_delete_order_notes" value="1"/> <?php printf( __( 'Delete Woocommerce order notices? (%d)', 'comments-plus' ), $stat_data[0]->order_notes_count ); ?>
280 </label>
281 </p>
282 <?php endif;
283 ?>
284 <p style="margin-top:15px;">
285 <input type="submit" name="wbcr_cmp_delete_all" class="button button-default wbcr-cmp-delete-comments-button" value="<?php printf( __( 'Delete (%s)', 'comments-plus' ), $stat_data[0]->total_comments ); ?>">
286 </p>
287 <?php wp_nonce_field( $this->getResultId() . '_delete_all_comments' ) ?>
288 </form>
289 <div style="padding: 20px;">
290 <hr/>
291 <h5><?php _e( 'Remove spam comments', 'comments-plus' ); ?></h5>
292 <p><?php _e( 'You can remove only spam comments from the database with one click.', 'comments-plus' ); ?></p>
293 <a href="<?= wp_nonce_url( $this->getActionUrl( 'delete-spam-comments' ), $this->getResultId() . '_delete_spam_comments' ) ?>" class="button button-default wbcr-cmp-delete-comments-button">
294 <?php printf( __( 'Delete (%d)', 'comments-plus' ), $stat_data[0]->spamcount ); ?>
295 </a>
296 <hr/>
297 <h5><?php _e( 'Remove unapproved comments', 'comments-plus' ); ?></h5>
298 <p><?php _e( 'You can remove only unapproved comments from the database with one click.', 'comments-plus' ); ?></p>
299 <a href="<?= wp_nonce_url( $this->getActionUrl( 'delete-unaproved-comments' ), $this->getResultId() . '_delete_unaproved_comments' ) ?>" class="button button-default wbcr-cmp-delete-comments-button">
300 <?php printf( __( 'Delete (%d)', 'comments-plus' ), $stat_data[0]->unpcount ); ?>
301 </a>
302 <hr/>
303 <h5><?php _e( 'Remove trashed comments', 'comments-plus' ); ?></h5>
304 <p><?php _e( 'You can remove only trashed comments from the database with one click.', 'comments-plus' ); ?></p>
305 <a href="<?= wp_nonce_url( $this->getActionUrl( 'delete-trash-comments' ), $this->getResultId() . '_delete_trash_comments' ) ?>" class="button button-default wbcr-cmp-delete-comments-button">
306 <?php printf( __( 'Delete (%d)', 'comments-plus' ), $stat_data[0]->trashcount ); ?>
307 </a>
308 </div>
309 <?php
310 }
311
312 /**
313 * @return bool
314 */
315 protected function deleteAllComments() {
316 global $wpdb;
317 $delete_order_notes = $this->request->post( 'wbcr_cmp_delete_order_notes', false, 'intval' );
318
319 if ( $wpdb->query( "TRUNCATE $wpdb->commentmeta" ) != false ) {
320 $delete_all_sql = "TRUNCATE $wpdb->comments";
321 if ( class_exists( 'WooCommerce' ) ) {
322 if ( ! $delete_order_notes ) {
323 $delete_all_sql = "DELETE FROM $wpdb->comments WHERE comment_type != 'order_note'";
324 }
325 }
326 if ( $wpdb->query( $delete_all_sql ) != false ) {
327 $wpdb->query( "UPDATE $wpdb->posts SET comment_count = 0 WHERE post_author != 0" );
328 $wpdb->query( "OPTIMIZE TABLE $wpdb->commentmeta" );
329 $wpdb->query( "OPTIMIZE TABLE $wpdb->comments" );
330
331 return true;
332 }
333 }
334
335 return false;
336 }
337
338 /**
339 * @param string $post_type
340 *
341 * @return bool
342 */
343 protected function deleteCommentsByPostType( $post_type = 'post' ) {
344 global $wpdb;
345
346 $delete_order_notes = $this->request->post( 'wbcr_cmp_delete_order_notes', false, 'intval' );
347
348 $wpdb->query( "DELETE cmeta FROM $wpdb->commentmeta cmeta INNER JOIN $wpdb->comments comments ON cmeta.comment_id=comments.comment_ID INNER JOIN $wpdb->posts posts ON comments.comment_post_ID=posts.ID WHERE posts.post_type = '%s'" );
349
350 $delete_certain_sql = "DELETE comments FROM $wpdb->comments comments INNER JOIN $wpdb->posts posts ON comments.comment_post_ID=posts.ID WHERE posts.post_type = '%s'";
351
352 if ( class_exists( 'WooCommerce' ) ) {
353 if ( ! $delete_order_notes ) {
354 $delete_certain_sql .= " and comment_type != 'order_note'";
355 }
356 }
357
358 $wpdb->query( $wpdb->prepare( $delete_certain_sql, $post_type ) );
359 $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET comment_count = 0 WHERE post_author != 0 AND post_type = '%s'", $post_type ) );
360
361 return true;
362 }
363
364 /**
365 * @param $post_types
366 *
367 * @return bool
368 */
369 protected function deleteCommentsByPostTypes( $post_types ) {
370 global $wpdb;
371
372 if ( empty( $post_types ) || ! is_array( $post_types ) ) {
373 return false;
374 }
375
376 foreach ( $post_types as $post_type ) {
377 $this->deleteCommentsByPostType( $post_type );
378 }
379
380 $wpdb->query( "OPTIMIZE TABLE $wpdb->commentmeta" );
381 $wpdb->query( "OPTIMIZE TABLE $wpdb->comments" );
382
383 return true;
384 }
385
386 /**
387 * This action deletes all comments from the database without restoring.
388 */
389 public function deleteAllCommentsAction() {
390 if ( ! current_user_can( $this->capabilitiy ) ) {
391 return;
392 }
393 check_admin_referer( $this->getResultId() . '_delete_all_comments' );
394
395 if ( isset( $_POST['wbcr_cmp_delete_all'] ) ) {
396 $post_types = $this->request->post( 'wbcr_cmp_post_type', [], true );
397
398 $result = false;
399
400 if ( empty( $post_types ) || in_array( 'all', $post_types ) ) {
401 if ( WCM_Plugin::app()->isNetworkActive() ) {
402 foreach ( WCM_Plugin::app()->getActiveSites() as $site ) {
403 switch_to_blog( $site->blog_id );
404 $result = $this->deleteAllComments();
405 restore_current_blog();
406 }
407 } else {
408 $result = $this->deleteAllComments();
409 }
410 } else {
411 if ( WCM_Plugin::app()->isNetworkActive() ) {
412 foreach ( WCM_Plugin::app()->getActiveSites() as $site ) {
413 switch_to_blog( $site->blog_id );
414 $result = $this->deleteCommentsByPostTypes( $post_types );
415 restore_current_blog();
416 }
417 } else {
418 $result = $this->deleteCommentsByPostTypes( $post_types );
419 }
420 }
421
422 if ( $result ) {
423 $this->redirectToAction( 'index', [
424 'wbcr_cmp_clear_comments' => '1'
425 ] );
426 } else {
427 $this->redirectToAction( 'index', [
428 'wbcr_cmp_clear_comments_error' => '1',
429 'wbcr_cmp_code' => 'interal_error',
430 ] );
431 }
432 }
433
434 $this->redirectToAction( 'index' );
435 }
436
437 /**
438 * The basic function of deleting comments.
439 *
440 * @param int|string $type
441 */
442 public function deleteComments( $type = 0 ) {
443 if ( in_array( $type, [ 'spam', 'trash', 0 ] ) ) {
444
445 if ( WCM_Plugin::app()->isNetworkActive() ) {
446 foreach ( WCM_Plugin::app()->getActiveSites() as $site ) {
447 switch_to_blog( $site->blog_id );
448 $this->deleteCommentsByType( $type );
449 restore_current_blog();
450 }
451 } else {
452 $this->deleteCommentsByType( $type );
453 }
454
455 $this->redirectToAction( 'index', [
456 'wbcr_cmp_clear_comments' => '1'
457 ] );
458 }
459 }
460
461 /**
462 * @param int $type
463 *
464 * @return false|int
465 */
466 private function deleteCommentsByType( $type = 0 ) {
467 global $wpdb;
468
469 $wpdb->query( "DELETE cmeta
470 FROM $wpdb->commentmeta cmeta
471 INNER JOIN {$wpdb->comments} comments ON cmeta.comment_id=comments.comment_ID
472 WHERE comment_approved='{$type}'" );
473
474 $res = $wpdb->query( "DELETE FROM {$wpdb->comments} WHERE comment_approved='{$type}'" );
475
476 if ( $res ) {
477 $wpdb->query( "OPTIMIZE TABLE {$wpdb->comments}" );
478 $wpdb->query( "OPTIMIZE TABLE {$wpdb->commentmeta}" );
479 }
480
481 return $res;
482 }
483
484 /**
485 * This action deletes spam comments
486 */
487 public function deleteSpamCommentsAction() {
488 if ( ! current_user_can( $this->capabilitiy ) ) {
489 return;
490 }
491 check_admin_referer( $this->getResultId() . '_delete_spam_comments' );
492
493 $this->deleteComments( 'spam' );
494 }
495
496 /**
497 * This action deletes unaproved comments
498 */
499 public function deleteUnaprovedCommentsAction() {
500 if ( ! current_user_can( $this->capabilitiy ) ) {
501 return;
502 }
503 check_admin_referer( $this->getResultId() . '_delete_unaproved_comments' );
504
505 $this->deleteComments();
506 }
507
508 /**
509 * This action deletes trash comments
510 */
511 public function deleteTrashCommentsAction() {
512 if ( ! current_user_can( $this->capabilitiy ) ) {
513 return;
514 }
515 check_admin_referer( $this->getResultId() . '_delete_trash_comments' );
516
517 $this->deleteComments( 'trash' );
518 }
519 }
520