PluginProbe
Disable Comments & Delete All Comments / 1.1.6
Disable Comments & Delete All Comments v1.1.6
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 1.1.6, at admin/pages/class-page-delete-comments.php

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