PluginProbe ʕ •ᴥ•ʔ
Media Cleaner: Clean your WordPress! / 5.2.0
Media Cleaner: Clean your WordPress! v5.2.0
7.1.1 7.1.0 7.0.9 7.0.8 trunk 3.6.8 3.6.9 3.7.0 3.8.0 3.9.0 4.0.0 4.0.2 4.0.4 4.0.6 4.0.7 4.1.0 4.2.0 4.2.2 4.2.3 4.2.4 4.2.5 4.4.0 4.4.2 4.4.4 4.4.6 4.4.7 4.4.8 4.5.0 4.5.4 4.5.6 4.5.7 4.5.8 4.6.2 4.6.3 4.8.0 4.8.4 5.0.0 5.0.1 5.1.0 5.1.1 5.1.3 5.2.0 5.2.1 5.2.4 5.4.0 5.4.1 5.4.2 5.4.3 5.4.4 5.4.5 5.4.6 5.4.9 5.5.0 5.5.1 5.5.2 5.5.3 5.5.4 5.5.7 5.5.8 5.6.1 5.6.2 5.6.3 5.6.4 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.0.6 6.0.7 6.0.8 6.0.9 6.1.2 6.1.3 6.1.4 6.1.5 6.1.6 6.1.7 6.1.8 6.1.9 6.2.0 6.2.1 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.2.8 6.3.0 6.3.1 6.3.2 6.3.4 6.3.5 6.3.7 6.3.8 6.3.9 6.4.0 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.4.7 6.4.8 6.4.9 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.5.5 6.5.6 6.5.7 6.5.8 6.5.9 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.6.6 6.6.7 6.6.8 6.6.9 6.7.0 6.7.1 6.7.2 6.7.3 6.7.4 6.7.5 6.7.6 6.7.7 6.7.8 6.7.9 6.8.0 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.8.6 6.8.7 6.8.8 6.8.9 6.9.0 6.9.1 6.9.2 6.9.3 6.9.4 6.9.5 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.0.6 7.0.7
media-cleaner / ui.php
media-cleaner Last commit date
common 7 years ago parsers 7 years ago views 7 years ago admin.php 7 years ago checkers.php 8 years ago core.php 7 years ago media-cleaner.css 7 years ago media-cleaner.js 7 years ago media-cleaner.php 7 years ago parsers.php 7 years ago readme.txt 7 years ago settings.js 7 years ago ui.php 7 years ago
ui.php
511 lines
1 <?php
2
3 class Meow_WPMC_UI {
4 private $core = null;
5 private $admin = null;
6
7 function __construct( $core, $admin ) {
8 $this->core = $core;
9 $this->admin = $admin;
10 add_action( 'admin_menu', array( $this, 'admin_menu' ) );
11 add_action( 'admin_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) );
12 add_action( 'admin_print_scripts', array( $this, 'admin_inline_js' ) );
13 add_action( 'add_meta_boxes', array( $this, 'add_metabox' ) );
14 add_action( 'wp_ajax_wpmc_prepare_do', array( $this, 'wp_ajax_wpmc_prepare_do' ) );
15 add_action( 'wp_ajax_wpmc_scan', array( $this, 'wp_ajax_wpmc_scan' ) );
16 add_action( 'wp_ajax_wpmc_scan_do', array( $this, 'wp_ajax_wpmc_scan_do' ) );
17 add_action( 'wp_ajax_wpmc_get_all_issues', array( $this, 'wp_ajax_wpmc_get_all_issues' ) );
18 add_action( 'wp_ajax_wpmc_get_all_deleted', array( $this, 'wp_ajax_wpmc_get_all_deleted' ) );
19 add_action( 'wp_ajax_wpmc_delete_do', array( $this, 'wp_ajax_wpmc_delete_do' ) );
20 add_action( 'wp_ajax_wpmc_ignore_do', array( $this, 'wp_ajax_wpmc_ignore_do' ) );
21 add_action( 'wp_ajax_wpmc_recover_do', array( $this, 'wp_ajax_wpmc_recover_do' ) );
22 add_action( 'wp_ajax_wpmc_validate_option', array( $this, 'wp_ajax_wpmc_validate_option' ) );
23 add_filter( 'media_row_actions', array( $this, 'media_row_actions' ), 10, 2 );
24 }
25
26 /**
27 * Renders a view within the views directory.
28 * @param string $view The name of the view to render
29 * @param array $data
30 * An associative array of variables to bind to the view.
31 * Each key turns into a variable name.
32 * @return string Rendered view
33 */
34 function render_view( $view, $data = null ) {
35 ob_start();
36 if ( is_array( $data ) ) extract( $data );
37 include( __DIR__ . "/views/$view.php" );
38 return ob_get_clean();
39 }
40
41 function admin_menu() {
42 //load_plugin_textdomain( 'media-cleaner', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
43 add_media_page( 'Media Cleaner', 'Cleaner', 'manage_options', 'media-cleaner', array( $this, 'wpmc_screen' ) );
44 }
45
46 function wpmc_screen() {
47 global $wpdb, $wplr;
48 echo $this->render_view( 'menu-screen', array(
49 'wpdb' => $wpdb,
50 'wplr' => $wplr,
51 'ui' => $this,
52 'core' => $this->core,
53 'admin' => $this->admin
54 ) );
55 }
56
57 function wp_enqueue_scripts() {
58 wp_enqueue_style( 'wp-jquery-ui-dialog' );
59 wp_enqueue_script( 'jquery-ui-dialog' );
60 wp_enqueue_style( 'media-cleaner-css', plugins_url( '/media-cleaner.css', __FILE__ ) );
61
62 $screen = get_current_screen();
63 global $wpmc_version;
64 switch ( $screen->id ) {
65 case 'media_page_media-cleaner': // Media > Cleaner
66 wp_enqueue_script( 'media-cleaner', plugins_url( '/media-cleaner.js', __FILE__ ), array( 'jquery', 'jquery-ui-dialog' ),
67 $wpmc_version, true );
68 break;
69 case 'meow-apps_page_wpmc_settings-menu': // Meow Apps > Media Cleaner (Settings)
70 wp_enqueue_script( 'media-cleaner-settings', plugins_url( '/settings.js', __FILE__ ), array( 'jquery' ),
71 $wpmc_version, true );
72 break;
73 }
74 }
75
76 /**
77 *
78 * DASHBOARD
79 *
80 */
81
82 function admin_inline_js() {
83 echo "<script type='text/javascript'>\n";
84 echo 'var wpmc_cfg = {
85 timeout: ' . ( (int) $this->core->get_max_execution_time() ) * 1000 . ',
86 delay: ' . get_option( 'wpmc_delay', 100 ) . ',
87 postsBuffer:' . get_option( 'wpmc_posts_buffer', 5 ) . ',
88 mediasBuffer:' . get_option( 'wpmc_medias_buffer', 100 ) . ',
89 analysisBuffer: ' . get_option( 'wpmc_analysis_buffer', 50 ) . ',
90 isPro: ' . ( $this->admin->is_registered() ? '1' : '0') . ',
91 scanFiles: ' . ( ( get_option( 'wpmc_method', 'media' ) == 'files' && $this->admin->is_registered() ) ? '1' : '0' ) . ',
92 scanMedia: ' . ( get_option( 'wpmc_method', 'media' ) == 'media' ? '1' : '0' ) . ' };';
93 echo "\n</script>";
94 }
95
96 /*******************************************************************************
97 * METABOX FOR USAGE
98 ******************************************************************************/
99
100 function add_metabox() {
101 add_meta_box( 'mfrh_media_usage_box', 'Media Cleaner', array( $this, 'display_metabox' ), 'attachment', 'side', 'default' );
102 }
103
104 function display_metabox( $post ) {
105 $this->core->log( "Media Edit > Checking Media #{$post->ID}" );
106 $success = $this->core->wpmc_check_media( $post->ID, true );
107 $this->core->log( "Success $success\n" );
108 if ( $success ) {
109 if ( $this->core->last_analysis == "CONTENT" ) {
110 echo "Found in content.";
111 }
112 else if ( $this->core->last_analysis == "CONTENT (ID)" ) {
113 echo "Found in content (as an ID).";
114 }
115 else if ( $this->core->last_analysis == "CONTENT (URL)" ) {
116 echo "Found in content (as an URL).";
117 }
118 else if ( $this->core->last_analysis == "THEME" ) {
119 echo "Found in theme.";
120 }
121 else if ( $this->core->last_analysis == "PAGE BUILDER" ) {
122 echo "Found in Page Builder.";
123 }
124 else if ( $this->core->last_analysis == "GALLERY" ) {
125 echo "Found in gallery.";
126 }
127 else if ( $this->core->last_analysis == "META" ) {
128 echo "Found in meta.";
129 }
130 else if ( $this->core->last_analysis == "META (ID)" ) {
131 echo "Found in meta (as an ID).";
132 }
133 else if ( $this->core->last_analysis == "META (URL)" ) {
134 echo "Found in meta (as an URL).";
135 }
136 else if ( $this->core->last_analysis == "META ACF (ID)" ) {
137 echo "Found in ACF meta (as an ID).";
138 }
139 else if ( $this->core->last_analysis == "META ACF (URL)" ) {
140 echo "Found in ACF meta (as an URL).";
141 }
142 else if ( $this->core->last_analysis == "WIDGET" ) {
143 echo "Found in widget.";
144 }
145 else if ( $this->core->last_analysis == "ACF WIDGET (ID)" ) {
146 echo "Found in ACF Widget (as an ID).";
147 }
148 else if ( $this->core->last_analysis == "ACF WIDGET (URL)" ) {
149 echo "Found in ACF Widget (as an URL).";
150 }
151 else if ( $this->core->last_analysis == "ATTACHMENT (ID)" ) {
152 echo "Found in Attachment.";
153 }
154 else if ( $this->core->last_analysis == "METASLIDER (ID)" ) { // mm change
155 echo "Found in MetaSlider (as an ID)."; // mm change
156 }
157 else if ( $this->core->last_analysis == "SITE ICON" ) {
158 echo "Found in Site Icon.";
159 }
160 else {
161 echo "It seems to be used as: " . $this->core->last_analysis;
162 }
163 }
164 else {
165 echo "Doesn't seem to be used.";
166 }
167 }
168
169 function media_row_actions( $actions, $post ) {
170 global $current_screen;
171 if ( 'upload' != $current_screen->id )
172 return $actions;
173 global $wpdb;
174 $table_name = $wpdb->prefix . "mclean_scan";
175 $res = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE postId = %d", $post->ID ) );
176 if ( !empty( $res ) && isset( $actions['delete'] ) )
177 $actions['delete'] = "<a href='?page=media-cleaner&view=deleted'>" .
178 __( 'Delete with Media Cleaner', 'media-cleaner' ) . "</a>";
179 if ( !empty( $res ) && isset( $actions['trash'] ) )
180 $actions['trash'] = "<a href='?page=media-cleaner'>" .
181 __( 'Trash with Media Cleaner', 'media-cleaner' ) . "</a>";
182 if ( !empty( $res ) && isset( $actions['untrash'] ) ) {
183 $actions['untrash'] = "<a href='?page=media-cleaner&view=deleted'>" .
184 __( 'Restore with Media Cleaner', 'media-cleaner' ) . "</a>";
185 }
186 return $actions;
187 }
188
189 /*******************************************************************************
190 * ASYNCHRONOUS AJAX FUNCTIONS
191 ******************************************************************************/
192
193 function wp_ajax_wpmc_prepare_do() {
194 $limit = isset( $_POST['limit'] ) ? $_POST['limit'] : 0;
195 $limitsize = get_option( 'wpmc_posts_buffer', 5 );
196 if ( empty( $limit ) )
197 $this->core->wpmc_reset_issues();
198
199 $method = get_option( 'wpmc_method', 'media' );
200 $check_library = get_option(' wpmc_media_library', true );
201 $check_postmeta = get_option( 'wpmc_postmeta', false );
202 $check_posts = get_option( 'wpmc_posts', false );
203 $check_widgets = get_option( 'wpmc_widgets', false );
204 if ( $method == 'media' && !$check_posts && !$check_postmeta && !$check_widgets ) {
205 echo json_encode( array(
206 'results' => array(),
207 'success' => true,
208 'finished' => true,
209 'message' => __( "Posts, Meta and Widgets analysis are all off. Done.", 'media-cleaner' )
210 ) );
211 die();
212 }
213 if ( $method == 'files' && $check_library && !$check_posts && !$check_postmeta && !$check_widgets ) {
214 echo json_encode( array(
215 'results' => array(),
216 'success' => true,
217 'finished' => true,
218 'message' => __( "Posts, Meta and Widgets analysis are all off. Done.", 'media-cleaner' )
219 ) );
220 die();
221 }
222
223 // Initialize the parsers
224 do_action( 'wpmc_initialize_parsers' );
225
226 global $wpdb;
227 // Maybe we could avoid to check more post_types.
228 // SELECT post_type, COUNT(*) FROM `wp_posts` GROUP BY post_type
229 $posts = $wpdb->get_col( $wpdb->prepare( "SELECT p.ID FROM $wpdb->posts p
230 WHERE p.post_status != 'inherit'
231 AND p.post_status != 'trash'
232 AND p.post_type != 'attachment'
233 AND p.post_type != 'shop_order'
234 AND p.post_type != 'shop_order_refund'
235 AND p.post_type != 'nav_menu_item'
236 AND p.post_type != 'revision'
237 AND p.post_type != 'auto-draft'
238 AND p.post_type != 'wphb_minify_group'
239 AND p.post_type != 'customize_changeset'
240 AND p.post_type != 'oembed_cache'
241 AND p.post_type NOT LIKE '%acf-%'
242 AND p.post_type NOT LIKE '%edd_%'
243 LIMIT %d, %d", $limit, $limitsize
244 )
245 );
246
247 $found = array();
248
249 // Only at the beginning
250 if ( empty( $limit ) ) {
251 $this->core->log( "Analyzing for references:" );
252 if ( get_option( 'wpmc_widgets', false ) ) {
253
254 global $wp_registered_widgets;
255 $syswidgets = $wp_registered_widgets;
256 $active_widgets = get_option( 'sidebars_widgets' );
257 foreach ( $active_widgets as $sidebar_name => $widgets ) {
258 if ( $sidebar_name != 'wp_inactive_widgets' && !empty( $widgets ) && is_array( $widgets ) ) {
259 foreach ( $widgets as $key => $widget ) {
260 do_action( 'wpmc_scan_widget', $syswidgets[$widget] );
261 }
262 }
263 }
264
265 do_action( 'wpmc_scan_widgets' );
266 }
267 do_action( 'wpmc_scan_once' );
268 }
269
270 $this->core->timeout_check_start( count( $posts ) );
271
272 foreach ( $posts as $post ) {
273 $this->core->timeout_check();
274 // Run the scanners
275 if ( $check_postmeta )
276 do_action( 'wpmc_scan_postmeta', $post );
277 if ( $check_posts ) {
278 // Get HTML for this post
279 $html = get_post_field( 'post_content', $post );
280
281 // Scan on the raw HTML content (useless?)
282 //do_action( 'wpmc_scan_post', $html, $post );
283
284 // This code was moved to the core.php (get_urls_from_html)
285 //$html = do_shortcode( $html );
286 //$html = wp_make_content_images_responsive( $html );
287 // Scan with shortcodes resolved and src-set
288
289 do_action( 'wpmc_scan_post', $html, $post );
290 }
291 $this->core->timeout_check_additem();
292 }
293
294 // Write the references cached by the scanners
295 $this->core->write_references();
296
297 $finished = count( $posts ) < $limitsize;
298 if ( $finished ) {
299 $found = array();
300 // Optimize DB (but that takes too long!)
301 //$table_name = $wpdb->prefix . "mclean_refs";
302 // $wpdb->query ("DELETE a FROM $table_name as a, $table_name as b
303 // WHERE (a.mediaId = b.mediaId OR a.mediaId IS NULL AND b.mediaId IS NULL)
304 // AND (a.mediaUrl = b.mediaUrl OR a.mediaUrl IS NULL AND b.mediaUrl IS NULL)
305 // AND (a.originType = b.originType OR a.originType IS NULL AND b.originType IS NULL)
306 // AND (a.origin = b.origin OR a.origin IS NULL AND b.origin IS NULL)
307 // AND a.ID < b.ID;" );
308 // $wpdb->query ("DELETE a FROM $table_name as a, $table_name as b WHERE a.mediaId = b.mediaId AND a.mediaId > 0 AND a.ID < b.ID;" );
309 // $wpdb->query ("DELETE a FROM $table_name as a, $table_name as b WHERE a.mediaUrl = b.mediaUrl AND LENGTH(a.mediaUrl) > 1 AND a.ID < b.ID;" );
310 }
311 if ( $finished && get_option( 'wpmc_debuglogs', false ) ) {
312 //$this->core->log( print_r( $found, true ) );
313 }
314 echo json_encode(
315 array(
316 'success' => true,
317 'finished' => $finished,
318 'limit' => $limit + $limitsize,
319 'message' => __( "Posts checked.", 'media-cleaner' ) )
320 );
321 die();
322 }
323
324 function wp_ajax_wpmc_scan() {
325 global $wpdb;
326
327 $method = get_option( 'wpmc_method', 'media' );
328 if ( !$this->admin->is_registered() )
329 $method = 'media';
330 $path = isset( $_POST['path'] ) ? $_POST['path'] : null;
331 $limit = isset( $_POST['limit'] ) ? $_POST['limit'] : 0;
332 $limitsize = get_option( 'wpmc_medias_buffer', 100 );
333
334 if ( $method == 'files' ) {
335 $output = apply_filters( 'wpmc_list_uploaded_files', array(
336 'results' => array(), 'success' => false, 'message' => __( "Unavailable.", 'media-cleaner' )
337 ), $path );
338 echo json_encode( $output );
339 die();
340 }
341
342 if ( $method == 'media' ) {
343 // Prevent double scanning by removing filesystem entries that we have DB entries for
344 $results = $wpdb->get_col( $wpdb->prepare( "SELECT p.ID FROM $wpdb->posts p
345 WHERE p.post_status = 'inherit'
346 AND p.post_type = 'attachment'
347 LIMIT %d, %d", $limit, $limitsize
348 )
349 );
350 $finished = count( $results ) < $limitsize;
351 echo json_encode(
352 array(
353 'results' => $results,
354 'success' => true,
355 'finished' => $finished,
356 'limit' => $limit + $limitsize,
357 'message' => __( "Medias retrieved.", 'media-cleaner' ) )
358 );
359 die();
360 }
361
362 // No task.
363 echo json_encode( array( 'success' => false, 'message' => __( "No task.", 'media-cleaner' ) ) );
364 die();
365 }
366
367 function wp_ajax_wpmc_scan_do() {
368 // For debug, to pretend there is a timeout
369 //$this->core->deepsleep(10);
370 //header("HTTP/1.0 408 Request Timeout");
371 //exit;
372
373 // Initialize the checkers
374 include_once( 'checkers.php' );
375 $this->core->checkers = new Meow_WPMC_Checkers( $this->core );
376
377 ob_start();
378 $type = $_POST['type'];
379 $data = $_POST['data'];
380 $this->core->timeout_check_start( count( $data ) );
381 $success = 0;
382 foreach ( $data as $piece ) {
383 $this->core->timeout_check();
384 if ( $type == 'file' ) {
385 $this->core->log( "\nCheck File: {$piece}" );
386 $result = ( apply_filters( 'wpmc_check_file', true, $piece ) ? 1 : 0 );
387 $this->core->log( "Success " . $result );
388 $success += $result;
389 }
390 else if ( $type == 'media' ) {
391 $this->core->log( "\nChecking Media #{$piece}" );
392 $result = ( $this->core->wpmc_check_media( $piece ) ? 1 : 0 );
393 $this->core->log( "Success " . $result );
394 $success += $result;
395 }
396 $this->core->timeout_check_additem();
397 }
398 ob_end_clean();
399 echo json_encode(
400 array(
401 'success' => true,
402 'result' => array( 'type' => $type, 'data' => $data, 'success' => $success ),
403 'message' => __( "Items checked.", 'media-cleaner' )
404 )
405 );
406 die();
407 }
408
409 function wp_ajax_wpmc_get_all_issues() {
410 global $wpdb;
411 $isTrash = ( isset( $_POST['isTrash'] ) && $_POST['isTrash'] == 1 ) ? true : false;
412 $table_name = $wpdb->prefix . "mclean_scan";
413 $q = "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = " . ( $isTrash ? 1 : 0 );
414 if ( $search = ( isset( $_POST['s'] ) && $_POST['s'] ) ? sanitize_text_field( $_POST['s'] ) : '' )
415 $q = $wpdb->prepare( $q . ' AND path LIKE %s', '%' . $wpdb->esc_like( $search ) . '%' );
416 $ids = $wpdb->get_col( $q );
417
418 echo json_encode(
419 array(
420 'results' => array( 'ids' => $ids ),
421 'success' => true,
422 'message' => __( "List generated.", 'media-cleaner' )
423 )
424 );
425 die;
426 }
427
428 function wp_ajax_wpmc_get_all_deleted() {
429 global $wpdb;
430 $table_name = $wpdb->prefix . "mclean_scan";
431 $ids = $wpdb->get_col( "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = 1" );
432 echo json_encode(
433 array(
434 'results' => array( 'ids' => $ids ),
435 'success' => true,
436 'message' => __( "List generated.", 'media-cleaner' )
437 )
438 );
439 die;
440 }
441
442 function wp_ajax_wpmc_delete_do() {
443 ob_start();
444 $data = $_POST['data'];
445 $success = 0;
446 foreach ( $data as $piece ) {
447 $success += ( $this->core->wpmc_delete( $piece ) ? 1 : 0 );
448 }
449 ob_end_clean();
450 echo json_encode(
451 array(
452 'success' => true,
453 'result' => array( 'data' => $data, 'success' => $success ),
454 'message' => __( "Status unknown.", 'media-cleaner' )
455 )
456 );
457 die();
458 }
459
460 function wp_ajax_wpmc_ignore_do() {
461 ob_start();
462 $data = $_POST['data'];
463 $success = 0;
464 foreach ( $data as $piece ) {
465 $success += ( $this->core->wpmc_ignore( $piece ) ? 1 : 0 );
466 }
467 ob_end_clean();
468 echo json_encode(
469 array(
470 'success' => true,
471 'result' => array( 'data' => $data, 'success' => $success ),
472 'message' => __( "Status unknown.", 'media-cleaner' )
473 )
474 );
475 die();
476 }
477
478 function wp_ajax_wpmc_recover_do() {
479 ob_start();
480 $data = $_POST['data'];
481 $success = 0;
482 foreach ( $data as $piece ) {
483 $success += ( $this->core->wpmc_recover( $piece ) ? 1 : 0 );
484 }
485 ob_end_clean();
486 echo json_encode(
487 array(
488 'success' => true,
489 'result' => array( 'data' => $data, 'success' => $success ),
490 'message' => __( "Status unknown.", 'media-cleaner' )
491 )
492 );
493 die();
494 }
495
496 function wp_ajax_wpmc_validate_option() {
497 $name = $_POST['name']; // Option Name
498 $value = $_POST['value']; // Option Value
499 $value = wp_unslash( $value ); // Unescape backslashes
500 $validated = $this->admin->validate_option( $name, $value );
501 if ( $validated instanceof WP_Error ) { // Invalid value
502 $error = array (
503 'code' => $validated->get_error_code() ?: 'invalid_option',
504 'message' => $validated->get_error_message() ?: __( "Invalid Option Value", 'media-cleaner' )
505 );
506 wp_send_json_error( $error );
507 }
508 wp_send_json_success();
509 }
510 }
511