PluginProbe ʕ •ᴥ•ʔ
Media Cleaner: Clean your WordPress! / 5.0.0
Media Cleaner: Clean your WordPress! v5.0.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 views 7 years ago admin.php 7 years ago checkers.php 8 years ago core.php 7 years ago custom_checkers.php 8 years ago media-cleaner.css 7 years ago media-cleaner.js 7 years ago media-cleaner.php 7 years ago readme.txt 7 years ago scan.php 7 years ago ui.php 7 years ago
ui.php
471 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_filter( 'media_row_actions', array( $this, 'media_row_actions' ), 10, 2 );
23 }
24
25 /**
26 * Renders a view within the views directory.
27 * @param string $view The name of the view to render
28 * @param array $data
29 * An associative array of variables to bind to the view.
30 * Each key turns into a variable name.
31 * @return string Rendered view
32 */
33 function render_view( $view, $data = null ) {
34 ob_start();
35 if ( is_array( $data ) ) extract( $data );
36 include( __DIR__ . "/views/$view.php" );
37 return ob_get_clean();
38 }
39
40 function admin_menu() {
41 //load_plugin_textdomain( 'media-cleaner', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
42 add_media_page( 'Media Cleaner', 'Cleaner', 'manage_options', 'media-cleaner', array( $this, 'wpmc_screen' ) );
43 }
44
45 function wpmc_screen() {
46 global $wpdb, $wplr;
47 echo $this->render_view( 'menu-screen', array(
48 'wpdb' => $wpdb,
49 'wplr' => $wplr,
50 'ui' => $this,
51 'core' => $this->core,
52 'admin' => $this->admin
53 ) );
54 }
55
56 function wp_enqueue_scripts() {
57 wp_enqueue_style( 'wp-jquery-ui-dialog' );
58 wp_enqueue_script( 'jquery-ui-dialog' );
59 wp_enqueue_style( 'media-cleaner-css', plugins_url( '/media-cleaner.css', __FILE__ ) );
60 wp_enqueue_script( 'media-cleaner', plugins_url( '/media-cleaner.js', __FILE__ ), array( 'jquery', 'jquery-ui-dialog' ), "3.7.0", true );
61 }
62
63 /**
64 *
65 * DASHBOARD
66 *
67 */
68
69 function admin_inline_js() {
70 echo "<script type='text/javascript'>\n";
71 echo 'var wpmc_cfg = {
72 timeout: ' . ( (int) $this->core->get_max_execution_time() ) * 1000 . ',
73 delay: ' . get_option( 'wpmc_delay', 100 ) . ',
74 postsBuffer:' . get_option( 'wpmc_posts_buffer', 5 ) . ',
75 mediasBuffer:' . get_option( 'wpmc_medias_buffer', 100 ) . ',
76 analysisBuffer: ' . get_option( 'wpmc_analysis_buffer', 50 ) . ',
77 isPro: ' . ( $this->admin->is_registered() ? '1' : '0') . ',
78 scanFiles: ' . ( ( get_option( 'wpmc_method', 'media' ) == 'files' && $this->admin->is_registered() ) ? '1' : '0' ) . ',
79 scanMedia: ' . ( get_option( 'wpmc_method', 'media' ) == 'media' ? '1' : '0' ) . ' };';
80 echo "\n</script>";
81 }
82
83 /*******************************************************************************
84 * METABOX FOR USAGE
85 ******************************************************************************/
86
87 function add_metabox() {
88 add_meta_box( 'mfrh_media_usage_box', 'Media Cleaner', array( $this, 'display_metabox' ), 'attachment', 'side', 'default' );
89 }
90
91 function display_metabox( $post ) {
92 $this->core->log( "Media Edit > Checking Media #{$post->ID}" );
93 $success = $this->core->wpmc_check_media( $post->ID, true );
94 $this->core->log( "Success $success\n" );
95 if ( $success ) {
96 if ( $this->core->last_analysis == "CONTENT" ) {
97 echo "Found in content.";
98 }
99 else if ( $this->core->last_analysis == "CONTENT (ID)" ) {
100 echo "Found in content (as an ID).";
101 }
102 else if ( $this->core->last_analysis == "CONTENT (URL)" ) {
103 echo "Found in content (as an URL).";
104 }
105 else if ( $this->core->last_analysis == "THEME" ) {
106 echo "Found in theme.";
107 }
108 else if ( $this->core->last_analysis == "PAGE BUILDER" ) {
109 echo "Found in Page Builder.";
110 }
111 else if ( $this->core->last_analysis == "GALLERY" ) {
112 echo "Found in gallery.";
113 }
114 else if ( $this->core->last_analysis == "META" ) {
115 echo "Found in meta.";
116 }
117 else if ( $this->core->last_analysis == "META (ID)" ) {
118 echo "Found in meta (as an ID).";
119 }
120 else if ( $this->core->last_analysis == "META (URL)" ) {
121 echo "Found in meta (as an URL).";
122 }
123 else if ( $this->core->last_analysis == "META ACF (ID)" ) {
124 echo "Found in ACF meta (as an ID).";
125 }
126 else if ( $this->core->last_analysis == "META ACF (URL)" ) {
127 echo "Found in ACF meta (as an URL).";
128 }
129 else if ( $this->core->last_analysis == "WIDGET" ) {
130 echo "Found in widget.";
131 }
132 else {
133 echo "It seems to be used as: " . $this->core->last_analysis;
134 }
135 }
136 else {
137 echo "Doesn't seem to be used.";
138 }
139 }
140
141 function media_row_actions( $actions, $post ) {
142 global $current_screen;
143 if ( 'upload' != $current_screen->id )
144 return $actions;
145 global $wpdb;
146 $table_name = $wpdb->prefix . "mclean_scan";
147 $res = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE postId = %d", $post->ID ) );
148 if ( !empty( $res ) && isset( $actions['delete'] ) )
149 $actions['delete'] = "<a href='?page=media-cleaner&view=deleted'>" .
150 __( 'Delete with Media Cleaner', 'media-cleaner' ) . "</a>";
151 if ( !empty( $res ) && isset( $actions['trash'] ) )
152 $actions['trash'] = "<a href='?page=media-cleaner'>" .
153 __( 'Trash with Media Cleaner', 'media-cleaner' ) . "</a>";
154 if ( !empty( $res ) && isset( $actions['untrash'] ) ) {
155 $actions['untrash'] = "<a href='?page=media-cleaner&view=deleted'>" .
156 __( 'Restore with Media Cleaner', 'media-cleaner' ) . "</a>";
157 }
158 return $actions;
159 }
160
161 /*******************************************************************************
162 * ASYNCHRONOUS AJAX FUNCTIONS
163 ******************************************************************************/
164
165 function wp_ajax_wpmc_prepare_do() {
166 $limit = isset( $_POST['limit'] ) ? $_POST['limit'] : 0;
167 $limitsize = get_option( 'wpmc_posts_buffer', 5 );
168 if ( empty( $limit ) )
169 $this->core->wpmc_reset_issues();
170
171 $method = get_option( 'wpmc_method', 'media' );
172 $check_library = get_option(' wpmc_media_library', true );
173 $check_postmeta = get_option( 'wpmc_postmeta', false );
174 $check_posts = get_option( 'wpmc_posts', false );
175 $check_widgets = get_option( 'wpmc_widgets', false );
176 if ( $method == 'media' && !$check_posts && !$check_postmeta && !$check_widgets ) {
177 echo json_encode( array(
178 'results' => array(),
179 'success' => true,
180 'finished' => true,
181 'message' => __( "Posts, Meta and Widgets analysis are all off. Done.", 'media-cleaner' )
182 ) );
183 die();
184 }
185 if ( $method == 'files' && $check_library && !$check_posts && !$check_postmeta && !$check_widgets ) {
186 echo json_encode( array(
187 'results' => array(),
188 'success' => true,
189 'finished' => true,
190 'message' => __( "Posts, Meta and Widgets analysis are all off. Done.", 'media-cleaner' )
191 ) );
192 die();
193 }
194
195 global $wpdb;
196 // Maybe we could avoid to check more post_types.
197 // SELECT post_type, COUNT(*) FROM `wp_posts` GROUP BY post_type
198 $posts = $wpdb->get_col( $wpdb->prepare( "SELECT p.ID FROM $wpdb->posts p
199 WHERE p.post_status != 'inherit'
200 AND p.post_status != 'trash'
201 AND p.post_type != 'attachment'
202 AND p.post_type != 'shop_order'
203 AND p.post_type != 'shop_order_refund'
204 AND p.post_type != 'nav_menu_item'
205 AND p.post_type != 'revision'
206 AND p.post_type != 'auto-draft'
207 AND p.post_type != 'wphb_minify_group'
208 AND p.post_type != 'customize_changeset'
209 AND p.post_type != 'oembed_cache'
210 AND p.post_type NOT LIKE '%acf-%'
211 AND p.post_type NOT LIKE '%edd_%'
212 LIMIT %d, %d", $limit, $limitsize
213 )
214 );
215
216 $found = array();
217
218 // Only at the beginning
219 if ( empty( $limit ) ) {
220
221 $this->core->log( "Analyzing for references:" );
222
223 $theme_ids = array();
224 $theme_urls = array();
225 $this->core->get_images_from_themes( $theme_ids, $theme_urls );
226 $this->core->add_reference_id( $theme_ids, 'THEME' );
227 $this->core->add_reference_url( $theme_urls, 'THEME' );
228
229 // Only on Start: Analyze Widgets
230 if ( get_option( 'wpmc_widgets', false ) ) {
231 $widgets_ids = array();
232 $widgets_urls = array();
233 $this->core->get_images_from_widgets( $widgets_ids, $widgets_urls );
234 $this->core->add_reference_id( $widgets_ids, 'WIDGET' );
235 $this->core->add_reference_url( $widgets_urls, 'WIDGET' );
236 }
237
238 // Only on Start: Analyze WooCommerce Categories Images
239 if ( class_exists( 'WooCommerce' ) ) {
240 $metas = $wpdb->get_col( "SELECT meta_value
241 FROM $wpdb->termmeta
242 WHERE meta_key LIKE '%thumbnail_id%'"
243 );
244 if ( count( $metas ) > 0 ) {
245 $postmeta_images_ids = array();
246 foreach ( $metas as $meta )
247 if ( is_numeric( $meta ) && $meta > 0 )
248 array_push( $postmeta_images_ids, $meta );
249 $this->core->add_reference_id( $postmeta_images_ids, 'META (ID)' );
250 }
251 }
252 }
253
254 $this->core->timeout_check_start( count( $posts ) );
255
256 foreach ( $posts as $post ) {
257 $this->core->timeout_check();
258 // Run the scanners
259 if ( $check_postmeta )
260 do_action( 'wpmc_scan_postmeta', $post );
261 if ( $check_posts ) {
262 // Get HTML for this post
263 $html = get_post_field( 'post_content', $post );
264 // Scan on the raw TML content
265 do_action( 'wpmc_scan_post', $html, $post );
266 $html = do_shortcode( $html );
267 $html = wp_make_content_images_responsive( $html );
268 // Scan with shortcodes resolved and src-set
269 do_action( 'wpmc_scan_post', $html, $post );
270 }
271 $this->core->timeout_check_additem();
272 }
273 // Write the references cached by the scanners
274 $this->core->write_references();
275
276 $finished = count( $posts ) < $limitsize;
277 if ( $finished ) {
278 $found = array();
279 // Optimize DB (but that takes too long!)
280 //$table_name = $wpdb->prefix . "mclean_refs";
281 // $wpdb->query ("DELETE a FROM $table_name as a, $table_name as b
282 // WHERE (a.mediaId = b.mediaId OR a.mediaId IS NULL AND b.mediaId IS NULL)
283 // AND (a.mediaUrl = b.mediaUrl OR a.mediaUrl IS NULL AND b.mediaUrl IS NULL)
284 // AND (a.originType = b.originType OR a.originType IS NULL AND b.originType IS NULL)
285 // AND (a.origin = b.origin OR a.origin IS NULL AND b.origin IS NULL)
286 // AND a.ID < b.ID;" );
287 // $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;" );
288 // $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;" );
289 }
290 if ( $finished && get_option( 'wpmc_debuglogs', false ) ) {
291 //$this->core->log( print_r( $found, true ) );
292 }
293 echo json_encode(
294 array(
295 'success' => true,
296 'finished' => $finished,
297 'limit' => $limit + $limitsize,
298 'message' => __( "Posts checked.", 'media-cleaner' ) )
299 );
300 die();
301 }
302
303 function wp_ajax_wpmc_scan() {
304 global $wpdb;
305
306 $method = get_option( 'wpmc_method', 'media' );
307 if ( !$this->admin->is_registered() )
308 $method = 'media';
309 $path = isset( $_POST['path'] ) ? $_POST['path'] : null;
310 $limit = isset( $_POST['limit'] ) ? $_POST['limit'] : 0;
311 $limitsize = get_option( 'wpmc_medias_buffer', 100 );
312
313 if ( $method == 'files' ) {
314 $output = apply_filters( 'wpmc_list_uploaded_files', array(
315 'results' => array(), 'success' => false, 'message' => __( "Unavailable.", 'media-cleaner' )
316 ), $path );
317 echo json_encode( $output );
318 die();
319 }
320
321 if ( $method == 'media' ) {
322 // Prevent double scanning by removing filesystem entries that we have DB entries for
323 $results = $wpdb->get_col( $wpdb->prepare( "SELECT p.ID FROM $wpdb->posts p
324 WHERE p.post_status = 'inherit'
325 AND p.post_type = 'attachment'
326 LIMIT %d, %d", $limit, $limitsize
327 )
328 );
329 $finished = count( $results ) < $limitsize;
330 echo json_encode(
331 array(
332 'results' => $results,
333 'success' => true,
334 'finished' => $finished,
335 'limit' => $limit + $limitsize,
336 'message' => __( "Medias retrieved.", 'media-cleaner' ) )
337 );
338 die();
339 }
340
341 // No task.
342 echo json_encode( array( 'success' => false, 'message' => __( "No task.", 'media-cleaner' ) ) );
343 die();
344 }
345
346 function wp_ajax_wpmc_scan_do() {
347 // For debug, to pretend there is a timeout
348 //$this->core->deepsleep(10);
349 //header("HTTP/1.0 408 Request Timeout");
350 //exit;
351
352 ob_start();
353 $type = $_POST['type'];
354 $data = $_POST['data'];
355 $this->core->timeout_check_start( count( $data ) );
356 $success = 0;
357 foreach ( $data as $piece ) {
358 $this->core->timeout_check();
359 if ( $type == 'file' ) {
360 $this->core->log( "Check File: {$piece}" );
361 $result = ( apply_filters( 'wpmc_check_file', true, $piece ) ? 1 : 0 );
362 $this->core->log( "Success " . $result . "\n" );
363 $success += $result;
364 }
365 else if ( $type == 'media' ) {
366 $this->core->log( "Checking Media #{$piece}" );
367 $result = ( $this->core->wpmc_check_media( $piece ) ? 1 : 0 );
368 $this->core->log( "Success " . $result . "\n" );
369 $success += $result;
370 }
371 $this->core->timeout_check_additem();
372 }
373 ob_end_clean();
374 echo json_encode(
375 array(
376 'success' => true,
377 'result' => array( 'type' => $type, 'data' => $data, 'success' => $success ),
378 'message' => __( "Items checked.", 'media-cleaner' )
379 )
380 );
381 die();
382 }
383
384 function wp_ajax_wpmc_get_all_issues() {
385 global $wpdb;
386 $isTrash = ( isset( $_POST['isTrash'] ) && $_POST['isTrash'] == 1 ) ? true : false;
387 $table_name = $wpdb->prefix . "mclean_scan";
388 $q = "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = " . ( $isTrash ? 1 : 0 );
389 if ( $search = ( isset( $_POST['s'] ) && $_POST['s'] ) ? sanitize_text_field( $_POST['s'] ) : '' )
390 $q = $wpdb->prepare( $q . ' AND path LIKE %s', '%' . $wpdb->esc_like( $search ) . '%' );
391 $ids = $wpdb->get_col( $q );
392
393 echo json_encode(
394 array(
395 'results' => array( 'ids' => $ids ),
396 'success' => true,
397 'message' => __( "List generated.", 'media-cleaner' )
398 )
399 );
400 die;
401 }
402
403 function wp_ajax_wpmc_get_all_deleted() {
404 global $wpdb;
405 $table_name = $wpdb->prefix . "mclean_scan";
406 $ids = $wpdb->get_col( "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = 1" );
407 echo json_encode(
408 array(
409 'results' => array( 'ids' => $ids ),
410 'success' => true,
411 'message' => __( "List generated.", 'media-cleaner' )
412 )
413 );
414 die;
415 }
416
417 function wp_ajax_wpmc_delete_do() {
418 ob_start();
419 $data = $_POST['data'];
420 $success = 0;
421 foreach ( $data as $piece ) {
422 $success += ( $this->core->wpmc_delete( $piece ) ? 1 : 0 );
423 }
424 ob_end_clean();
425 echo json_encode(
426 array(
427 'success' => true,
428 'result' => array( 'data' => $data, 'success' => $success ),
429 'message' => __( "Status unknown.", 'media-cleaner' )
430 )
431 );
432 die();
433 }
434
435 function wp_ajax_wpmc_ignore_do() {
436 ob_start();
437 $data = $_POST['data'];
438 $success = 0;
439 foreach ( $data as $piece ) {
440 $success += ( $this->core->wpmc_ignore( $piece ) ? 1 : 0 );
441 }
442 ob_end_clean();
443 echo json_encode(
444 array(
445 'success' => true,
446 'result' => array( 'data' => $data, 'success' => $success ),
447 'message' => __( "Status unknown.", 'media-cleaner' )
448 )
449 );
450 die();
451 }
452
453 function wp_ajax_wpmc_recover_do() {
454 ob_start();
455 $data = $_POST['data'];
456 $success = 0;
457 foreach ( $data as $piece ) {
458 $success += ( $this->core->wpmc_recover( $piece ) ? 1 : 0 );
459 }
460 ob_end_clean();
461 echo json_encode(
462 array(
463 'success' => true,
464 'result' => array( 'data' => $data, 'success' => $success ),
465 'message' => __( "Status unknown.", 'media-cleaner' )
466 )
467 );
468 die();
469 }
470 }
471