Media Cleaner - Version 5.2.1

Version Description

  • Add: Support for My Calendar (thanks to Mike Meinz).
  • Add: Support for iFrames (thanks to Mike Meinz).
  • Update: Code cleaning, reorganization and optimization.
Download this release

Release Info

Developer TigrouMeow
Plugin Icon 128x128 Media Cleaner
Version 5.2.1
Comparing to
See all releases

Code changes from version 5.2.0 to 5.2.1

admin.php CHANGED
@@ -4,8 +4,6 @@ include "common/admin.php";
4
 
5
  class Meow_WPMC_Admin extends MeowApps_Admin {
6
 
7
- public $core;
8
-
9
  public function __construct( $prefix, $mainfile, $domain ) {
10
  parent::__construct( $prefix, $mainfile, $domain );
11
  add_action( 'admin_menu', array( $this, 'app_menu' ) );
@@ -346,6 +344,7 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
346
  // }
347
 
348
  function admin_debuglogs_callback( $args ) {
 
349
  $debuglogs = get_option( 'wpmc_debuglogs' );
350
  $clearlogs = isset ( $_GET[ 'clearlogs' ] ) ? $_GET[ 'clearlogs' ] : 0;
351
  if ( $clearlogs && file_exists( plugin_dir_path( __FILE__ ) . '/media-cleaner.log' ) ) {
@@ -356,7 +355,7 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
356
  $html .= '<label for="wpmc_debuglogs"> ' . $args[0] . '</label><br>';
357
  $html .= '<small>' . __( 'Creates an internal log file, for debugging purposes.', 'media-cleaner' );
358
  if ( $debuglogs && !file_exists( plugin_dir_path( __FILE__ ) . '/media-cleaner.log' ) ) {
359
- if ( !$this->core->log( "Testing the logging feature. It works!" ) ) {
360
  $html .= sprintf( __( '<br /><b>Cannot create the logging file. Logging will not work. The plugin as a whole might not be able to work neither.</b>', 'media-cleaner' ), plugin_dir_url( __FILE__ ) );
361
  }
362
  }
4
 
5
  class Meow_WPMC_Admin extends MeowApps_Admin {
6
 
 
 
7
  public function __construct( $prefix, $mainfile, $domain ) {
8
  parent::__construct( $prefix, $mainfile, $domain );
9
  add_action( 'admin_menu', array( $this, 'app_menu' ) );
344
  // }
345
 
346
  function admin_debuglogs_callback( $args ) {
347
+ global $wpmc;
348
  $debuglogs = get_option( 'wpmc_debuglogs' );
349
  $clearlogs = isset ( $_GET[ 'clearlogs' ] ) ? $_GET[ 'clearlogs' ] : 0;
350
  if ( $clearlogs && file_exists( plugin_dir_path( __FILE__ ) . '/media-cleaner.log' ) ) {
355
  $html .= '<label for="wpmc_debuglogs"> ' . $args[0] . '</label><br>';
356
  $html .= '<small>' . __( 'Creates an internal log file, for debugging purposes.', 'media-cleaner' );
357
  if ( $debuglogs && !file_exists( plugin_dir_path( __FILE__ ) . '/media-cleaner.log' ) ) {
358
+ if ( !$wpmc->log( "Testing the logging feature. It works!" ) ) {
359
  $html .= sprintf( __( '<br /><b>Cannot create the logging file. Logging will not work. The plugin as a whole might not be able to work neither.</b>', 'media-cleaner' ), plugin_dir_url( __FILE__ ) );
360
  }
361
  }
api.php ADDED
@@ -0,0 +1,338 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Meow_WPMC_API {
4
+
5
+ function __construct( $core, $admin ) {
6
+ $this->core = $core;
7
+ $this->admin = $admin;
8
+ add_action( 'wp_ajax_wpmc_prepare_do', array( $this, 'wp_ajax_wpmc_prepare_do' ) );
9
+ add_action( 'wp_ajax_wpmc_scan', array( $this, 'wp_ajax_wpmc_scan' ) );
10
+ add_action( 'wp_ajax_wpmc_scan_do', array( $this, 'wp_ajax_wpmc_scan_do' ) );
11
+ add_action( 'wp_ajax_wpmc_get_all_issues', array( $this, 'wp_ajax_wpmc_get_all_issues' ) );
12
+ add_action( 'wp_ajax_wpmc_get_all_deleted', array( $this, 'wp_ajax_wpmc_get_all_deleted' ) );
13
+ add_action( 'wp_ajax_wpmc_delete_do', array( $this, 'wp_ajax_wpmc_delete_do' ) );
14
+ add_action( 'wp_ajax_wpmc_ignore_do', array( $this, 'wp_ajax_wpmc_ignore_do' ) );
15
+ add_action( 'wp_ajax_wpmc_recover_do', array( $this, 'wp_ajax_wpmc_recover_do' ) );
16
+ add_action( 'wp_ajax_wpmc_validate_option', array( $this, 'wp_ajax_wpmc_validate_option' ) );
17
+ }
18
+
19
+ /*******************************************************************************
20
+ * ASYNCHRONOUS AJAX FUNCTIONS
21
+ ******************************************************************************/
22
+
23
+ function wp_ajax_wpmc_prepare_do() {
24
+ $limit = isset( $_POST['limit'] ) ? $_POST['limit'] : 0;
25
+ $limitsize = get_option( 'wpmc_posts_buffer', 5 );
26
+ if ( empty( $limit ) )
27
+ $this->core->reset_issues();
28
+
29
+ $method = get_option( 'wpmc_method', 'media' );
30
+ $check_library = get_option(' wpmc_media_library', true );
31
+ $check_postmeta = get_option( 'wpmc_postmeta', false );
32
+ $check_posts = get_option( 'wpmc_posts', false );
33
+ $check_widgets = get_option( 'wpmc_widgets', false );
34
+ if ( $method == 'media' && !$check_posts && !$check_postmeta && !$check_widgets ) {
35
+ echo json_encode( array(
36
+ 'results' => array(),
37
+ 'success' => true,
38
+ 'finished' => true,
39
+ 'message' => __( "Posts, Meta and Widgets analysis are all off. Done.", 'media-cleaner' )
40
+ ) );
41
+ die();
42
+ }
43
+ if ( $method == 'files' && $check_library && !$check_posts && !$check_postmeta && !$check_widgets ) {
44
+ echo json_encode( array(
45
+ 'results' => array(),
46
+ 'success' => true,
47
+ 'finished' => true,
48
+ 'message' => __( "Posts, Meta and Widgets analysis are all off. Done.", 'media-cleaner' )
49
+ ) );
50
+ die();
51
+ }
52
+
53
+ // Initialize the parsers
54
+ do_action( 'wpmc_initialize_parsers' );
55
+
56
+ global $wpdb;
57
+ // Maybe we could avoid to check more post_types.
58
+ // SELECT post_type, COUNT(*) FROM `wp_posts` GROUP BY post_type
59
+ $posts = $wpdb->get_col( $wpdb->prepare( "SELECT p.ID FROM $wpdb->posts p
60
+ WHERE p.post_status != 'inherit'
61
+ AND p.post_status != 'trash'
62
+ AND p.post_type != 'attachment'
63
+ AND p.post_type != 'shop_order'
64
+ AND p.post_type != 'shop_order_refund'
65
+ AND p.post_type != 'nav_menu_item'
66
+ AND p.post_type != 'revision'
67
+ AND p.post_type != 'auto-draft'
68
+ AND p.post_type != 'wphb_minify_group'
69
+ AND p.post_type != 'customize_changeset'
70
+ AND p.post_type != 'oembed_cache'
71
+ AND p.post_type NOT LIKE '%acf-%'
72
+ AND p.post_type NOT LIKE '%edd_%'
73
+ LIMIT %d, %d", $limit, $limitsize
74
+ )
75
+ );
76
+
77
+ $found = array();
78
+
79
+ // Only at the beginning
80
+ if ( empty( $limit ) ) {
81
+ $this->core->log( "Parsed references:" );
82
+ if ( get_option( 'wpmc_widgets', false ) ) {
83
+
84
+ global $wp_registered_widgets;
85
+ $syswidgets = $wp_registered_widgets;
86
+ $active_widgets = get_option( 'sidebars_widgets' );
87
+ foreach ( $active_widgets as $sidebar_name => $widgets ) {
88
+ if ( $sidebar_name != 'wp_inactive_widgets' && !empty( $widgets ) && is_array( $widgets ) ) {
89
+ foreach ( $widgets as $key => $widget ) {
90
+ do_action( 'wpmc_scan_widget', $syswidgets[$widget] );
91
+ }
92
+ }
93
+ }
94
+
95
+ do_action( 'wpmc_scan_widgets' );
96
+ }
97
+ do_action( 'wpmc_scan_once' );
98
+ }
99
+
100
+ $this->core->timeout_check_start( count( $posts ) );
101
+
102
+ foreach ( $posts as $post ) {
103
+ $this->core->timeout_check();
104
+ // Run the scanners
105
+ if ( $check_postmeta )
106
+ do_action( 'wpmc_scan_postmeta', $post );
107
+ if ( $check_posts ) {
108
+ // Get HTML for this post
109
+ $html = get_post_field( 'post_content', $post );
110
+
111
+ // Scan on the raw HTML content (useless?)
112
+ //do_action( 'wpmc_scan_post', $html, $post );
113
+
114
+ // This code was moved to the core.php (get_urls_from_html)
115
+ //$html = do_shortcode( $html );
116
+ //$html = wp_make_content_images_responsive( $html );
117
+ // Scan with shortcodes resolved and src-set
118
+
119
+ do_action( 'wpmc_scan_post', $html, $post );
120
+ }
121
+ $this->core->timeout_check_additem();
122
+ }
123
+
124
+ // Write the references cached by the scanners
125
+ $this->core->write_references();
126
+
127
+ $finished = count( $posts ) < $limitsize;
128
+ if ( $finished ) {
129
+ $this->core->log();
130
+ $found = array();
131
+ // Optimize DB (but that takes too long!)
132
+ //$table_name = $wpdb->prefix . "mclean_refs";
133
+ // $wpdb->query ("DELETE a FROM $table_name as a, $table_name as b
134
+ // WHERE (a.mediaId = b.mediaId OR a.mediaId IS NULL AND b.mediaId IS NULL)
135
+ // AND (a.mediaUrl = b.mediaUrl OR a.mediaUrl IS NULL AND b.mediaUrl IS NULL)
136
+ // AND (a.originType = b.originType OR a.originType IS NULL AND b.originType IS NULL)
137
+ // AND (a.origin = b.origin OR a.origin IS NULL AND b.origin IS NULL)
138
+ // AND a.ID < b.ID;" );
139
+ // $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;" );
140
+ // $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;" );
141
+ }
142
+ if ( $finished && get_option( 'wpmc_debuglogs', false ) ) {
143
+ //$this->core->log( print_r( $found, true ) );
144
+ }
145
+ echo json_encode(
146
+ array(
147
+ 'success' => true,
148
+ 'finished' => $finished,
149
+ 'limit' => $limit + $limitsize,
150
+ 'message' => __( "Posts checked.", 'media-cleaner' ) )
151
+ );
152
+ die();
153
+ }
154
+
155
+ function wp_ajax_wpmc_scan() {
156
+ global $wpdb;
157
+
158
+ $method = get_option( 'wpmc_method', 'media' );
159
+ if ( !$this->admin->is_registered() )
160
+ $method = 'media';
161
+ $path = isset( $_POST['path'] ) ? $_POST['path'] : null;
162
+ $limit = isset( $_POST['limit'] ) ? $_POST['limit'] : 0;
163
+ $limitsize = get_option( 'wpmc_medias_buffer', 100 );
164
+
165
+ if ( $method == 'files' ) {
166
+ $output = apply_filters( 'wpmc_list_uploaded_files', array(
167
+ 'results' => array(), 'success' => false, 'message' => __( "Unavailable.", 'media-cleaner' )
168
+ ), $path );
169
+ echo json_encode( $output );
170
+ die();
171
+ }
172
+
173
+ if ( $method == 'media' ) {
174
+ // Prevent double scanning by removing filesystem entries that we have DB entries for
175
+ $results = $wpdb->get_col( $wpdb->prepare( "SELECT p.ID FROM $wpdb->posts p
176
+ WHERE p.post_status = 'inherit'
177
+ AND p.post_type = 'attachment'
178
+ LIMIT %d, %d", $limit, $limitsize
179
+ )
180
+ );
181
+ $finished = count( $results ) < $limitsize;
182
+ echo json_encode(
183
+ array(
184
+ 'results' => $results,
185
+ 'success' => true,
186
+ 'finished' => $finished,
187
+ 'limit' => $limit + $limitsize,
188
+ 'message' => __( "Medias retrieved.", 'media-cleaner' ) )
189
+ );
190
+ die();
191
+ }
192
+
193
+ // No task.
194
+ echo json_encode( array( 'success' => false, 'message' => __( "No task.", 'media-cleaner' ) ) );
195
+ die();
196
+ }
197
+
198
+ function wp_ajax_wpmc_scan_do() {
199
+ // For debug, to pretend there is a timeout
200
+ //$this->core->deepsleep(10);
201
+ //header("HTTP/1.0 408 Request Timeout");
202
+ //exit;
203
+
204
+ ob_start();
205
+ $type = $_POST['type'];
206
+ $data = $_POST['data'];
207
+ $this->core->timeout_check_start( count( $data ) );
208
+ $success = 0;
209
+ foreach ( $data as $piece ) {
210
+ $this->core->timeout_check();
211
+ if ( $type == 'file' ) {
212
+ $this->core->log( "Check File: {$piece}" );
213
+ $result = ( apply_filters( 'wpmc_check_file', true, $piece ) ? 1 : 0 );
214
+ if ( $result )
215
+ $success += $result;
216
+ }
217
+ else if ( $type == 'media' ) {
218
+ $this->core->log( "Checking Media #{$piece}" );
219
+ $result = ( $this->core->check_media( $piece ) ? 1 : 0 );
220
+ if ( $result )
221
+ $success += $result;
222
+ }
223
+ $this->core->log();
224
+ $this->core->timeout_check_additem();
225
+ }
226
+ ob_end_clean();
227
+ echo json_encode(
228
+ array(
229
+ 'success' => true,
230
+ 'result' => array( 'type' => $type, 'data' => $data, 'success' => $success ),
231
+ 'message' => __( "Items checked.", 'media-cleaner' )
232
+ )
233
+ );
234
+ die();
235
+ }
236
+
237
+ function wp_ajax_wpmc_get_all_issues() {
238
+ global $wpdb;
239
+ $isTrash = ( isset( $_POST['isTrash'] ) && $_POST['isTrash'] == 1 ) ? true : false;
240
+ $table_name = $wpdb->prefix . "mclean_scan";
241
+ $q = "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = " . ( $isTrash ? 1 : 0 );
242
+ if ( $search = ( isset( $_POST['s'] ) && $_POST['s'] ) ? sanitize_text_field( $_POST['s'] ) : '' )
243
+ $q = $wpdb->prepare( $q . ' AND path LIKE %s', '%' . $wpdb->esc_like( $search ) . '%' );
244
+ $ids = $wpdb->get_col( $q );
245
+
246
+ echo json_encode(
247
+ array(
248
+ 'results' => array( 'ids' => $ids ),
249
+ 'success' => true,
250
+ 'message' => __( "List generated.", 'media-cleaner' )
251
+ )
252
+ );
253
+ die;
254
+ }
255
+
256
+ function wp_ajax_wpmc_get_all_deleted() {
257
+ global $wpdb;
258
+ $table_name = $wpdb->prefix . "mclean_scan";
259
+ $ids = $wpdb->get_col( "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = 1" );
260
+ echo json_encode(
261
+ array(
262
+ 'results' => array( 'ids' => $ids ),
263
+ 'success' => true,
264
+ 'message' => __( "List generated.", 'media-cleaner' )
265
+ )
266
+ );
267
+ die;
268
+ }
269
+
270
+ function wp_ajax_wpmc_delete_do() {
271
+ ob_start();
272
+ $data = $_POST['data'];
273
+ $success = 0;
274
+ foreach ( $data as $piece ) {
275
+ $success += ( $this->core->delete( $piece ) ? 1 : 0 );
276
+ }
277
+ ob_end_clean();
278
+ echo json_encode(
279
+ array(
280
+ 'success' => true,
281
+ 'result' => array( 'data' => $data, 'success' => $success ),
282
+ 'message' => __( "Status unknown.", 'media-cleaner' )
283
+ )
284
+ );
285
+ die();
286
+ }
287
+
288
+ function wp_ajax_wpmc_ignore_do() {
289
+ ob_start();
290
+ $data = $_POST['data'];
291
+ $success = 0;
292
+ foreach ( $data as $piece ) {
293
+ $success += ( $this->core->ignore( $piece ) ? 1 : 0 );
294
+ }
295
+ ob_end_clean();
296
+ echo json_encode(
297
+ array(
298
+ 'success' => true,
299
+ 'result' => array( 'data' => $data, 'success' => $success ),
300
+ 'message' => __( "Status unknown.", 'media-cleaner' )
301
+ )
302
+ );
303
+ die();
304
+ }
305
+
306
+ function wp_ajax_wpmc_recover_do() {
307
+ ob_start();
308
+ $data = $_POST['data'];
309
+ $success = 0;
310
+ foreach ( $data as $piece ) {
311
+ $success += ( $this->core->recover( $piece ) ? 1 : 0 );
312
+ }
313
+ ob_end_clean();
314
+ echo json_encode(
315
+ array(
316
+ 'success' => true,
317
+ 'result' => array( 'data' => $data, 'success' => $success ),
318
+ 'message' => __( "Status unknown.", 'media-cleaner' )
319
+ )
320
+ );
321
+ die();
322
+ }
323
+
324
+ function wp_ajax_wpmc_validate_option() {
325
+ $name = $_POST['name']; // Option Name
326
+ $value = $_POST['value']; // Option Value
327
+ $value = wp_unslash( $value ); // Unescape backslashes
328
+ $validated = $this->admin->validate_option( $name, $value );
329
+ if ( $validated instanceof WP_Error ) { // Invalid value
330
+ $error = array (
331
+ 'code' => $validated->get_error_code() ?: 'invalid_option',
332
+ 'message' => $validated->get_error_message() ?: __( "Invalid Option Value", 'media-cleaner' )
333
+ );
334
+ wp_send_json_error( $error );
335
+ }
336
+ wp_send_json_success();
337
+ }
338
+ }
checkers.php DELETED
@@ -1,48 +0,0 @@
1
- <?php
2
-
3
- class Meow_WPMC_Checkers {
4
-
5
- private $core;
6
-
7
- public function __construct( $core ) {
8
- $this->core = $core;
9
- }
10
-
11
- function check( $file, $mediaId ) {
12
- global $wpdb;
13
- if ( !empty( $mediaId ) ) {
14
- $res = $this->check_media( $mediaId );
15
- if ($res)
16
- return $res;
17
- }
18
- if ( !empty( $file ) )
19
- return $this->check_file( $file );
20
- }
21
-
22
- function check_file( $file ) {
23
- global $wpdb;
24
- $table = $wpdb->prefix . "mclean_refs";
25
- // Is this make the results better?
26
- //$file = $this->core->wpmc_clean_uploaded_filename( $file );
27
- $row = $wpdb->get_row( $wpdb->prepare( "SELECT originType FROM $table WHERE mediaUrl = %s", $file ) );
28
- if ( empty( $row ) )
29
- return false;
30
- $this->core->log( "File {$file} found as {$row->originType}" );
31
- $this->core->last_analysis = $row->originType;
32
- return true;
33
- }
34
-
35
- function check_media( $mediaId ) {
36
- global $wpdb;
37
- $table = $wpdb->prefix . "mclean_refs";
38
- $row = $wpdb->get_row( $wpdb->prepare( "SELECT originType FROM $table WHERE mediaId = %d", $mediaId ) );
39
- if ( empty( $row ) )
40
- return false;
41
- $this->core->log( "Media {$mediaId} found as {$row->originType}" );
42
- $this->core->last_analysis = $row->originType;
43
- return true;
44
- }
45
-
46
- }
47
-
48
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
core.php CHANGED
@@ -2,20 +2,25 @@
2
 
3
  class Meow_WPMC_Core {
4
 
5
- public $checkers = null;
6
  public $admin = null;
7
  public $last_analysis = null;
8
  public $last_analysis_ids = null;
9
  private $regex_file = '/[A-Za-z0-9-_,\s]+[.]{1}(MIMETYPES)/';
10
  public $current_method = 'media';
11
  private $refcache = array();
 
 
 
12
 
13
  public function __construct( $admin ) {
14
  $this->admin = $admin;
15
- if ( is_admin() )
16
- $this->admin_init();
17
-
18
- // Initializers
 
 
 
19
  add_action( 'wpmc_initialize_parsers', array( $this, 'initialize_parsers' ), 10, 0 );
20
  }
21
 
@@ -24,12 +29,6 @@ class Meow_WPMC_Core {
24
  new MeowApps_WPMC_Parsers();
25
  }
26
 
27
- function admin_init() {
28
- $this->current_method = get_option( 'wpmc_method', 'media' );
29
- $types = "jpg|jpeg|jpe|gif|png|tiff|bmp|csv|pdf|xls|xlsx|doc|docx|tiff|mp3|mp4|wav|lua";
30
- $this->regex_file = str_replace( "MIMETYPES", $types, $this->regex_file );
31
- }
32
-
33
  function deepsleep( $seconds ) {
34
  $start_time = time();
35
  while( true ) {
@@ -113,7 +112,7 @@ class Meow_WPMC_Core {
113
  $vals = get_option( 'wpseo_titles' );
114
  $url = $vals['company_logo'];
115
  if ( $this->is_url($url) )
116
- return $this->wpmc_clean_url( $url );
117
  return null;
118
  }
119
 
@@ -128,12 +127,42 @@ class Meow_WPMC_Core {
128
 
129
  $dom = new DOMDocument();
130
  @$dom->loadHTML( $html ); // mm change
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
  // Images, src, srcset
133
  $imgs = $dom->getElementsByTagName( 'img' );
134
- $results = array();
135
  foreach ( $imgs as $img ) {
136
- $src = $this->wpmc_clean_url( $img->getAttribute('src') );
137
  array_push( $results, $src );
138
  $srcset = $img->getAttribute('srcset');
139
  if ( !empty( $srcset ) ) {
@@ -141,7 +170,7 @@ class Meow_WPMC_Core {
141
  foreach ( $setImgs as $setImg ) {
142
  $finalSetImg = explode( ' ', trim( $setImg ) );
143
  if ( is_array( $finalSetImg ) ) {
144
- array_push( $results, $this->wpmc_clean_url( $finalSetImg[0] ) );
145
  }
146
  }
147
  }
@@ -152,7 +181,7 @@ class Meow_WPMC_Core {
152
  foreach ( $urls as $url ) {
153
  $url_href = $url->getAttribute('href'); // mm change
154
  if ( $this->is_url( $url_href ) ) { // mm change
155
- $src = $this->wpmc_clean_url( $url_href ); // mm change
156
  if ( !empty( $src ) )
157
  array_push( $results, $src );
158
  }
@@ -163,7 +192,7 @@ class Meow_WPMC_Core {
163
  if ( !empty( $res ) && isset( $res[1] ) && count( $res[1] ) > 0 ) {
164
  foreach ( $res[1] as $url ) {
165
  if ( $this->is_url($url) )
166
- array_push( $results, $this->wpmc_clean_url( $url ) );
167
  }
168
  }
169
 
@@ -172,7 +201,7 @@ class Meow_WPMC_Core {
172
  if ( !empty( $res ) && isset( $res[1] ) && count( $res[1] ) > 0 ) {
173
  foreach ( $res[1] as $url ) {
174
  if ( $this->is_url($url) )
175
- array_push( $results, $this->wpmc_clean_url( $url ) );
176
  }
177
  }
178
 
@@ -191,7 +220,7 @@ class Meow_WPMC_Core {
191
  array_push( $ids, $value );
192
  else
193
  if ( $this->is_url( $value ) )
194
- array_push( $urls, $this->wpmc_clean_url( $value ) );
195
  }
196
  }
197
  }
@@ -202,7 +231,7 @@ class Meow_WPMC_Core {
202
  // USE CURRENT THEME AND WP API
203
  $ch = get_custom_header();
204
  if ( !empty( $ch ) && !empty( $ch->url ) ) {
205
- array_push( $urls, $this->wpmc_clean_url( $ch->url ) );
206
  }
207
  if ( !empty( $ch ) && !empty( $ch->attachment_id ) ) {
208
  array_push( $ids, $ch->attachment_id );
@@ -213,7 +242,7 @@ class Meow_WPMC_Core {
213
  }
214
  $cd = get_background_image();
215
  if ( !empty( $cd ) ) {
216
- array_push( $urls, $this->wpmc_clean_url( $cd ) );
217
  }
218
  $photography_hero_image = get_theme_mod( 'photography_hero_image' );
219
  if ( !empty( $photography_hero_image ) ) {
@@ -225,14 +254,17 @@ class Meow_WPMC_Core {
225
  }
226
  }
227
 
228
- function log( $data, $force = false ) {
229
  if ( !get_option( 'wpmc_debuglogs', false ) && !$force )
230
  return;
231
  $fh = @fopen( trailingslashit( dirname(__FILE__) ) . '/media-cleaner.log', 'a' );
232
  if ( !$fh )
233
  return false;
234
  $date = date( "Y-m-d H:i:s" );
235
- fwrite( $fh, "$date: {$data}\n" );
 
 
 
236
  fclose( $fh );
237
  return true;
238
  }
@@ -243,9 +275,8 @@ class Meow_WPMC_Core {
243
  *
244
  */
245
 
246
- function wpmc_trashdir() {
247
- $upload_folder = wp_upload_dir();
248
- return trailingslashit( $upload_folder['basedir'] ) . 'wpmc-trash';
249
  }
250
 
251
  /**
@@ -254,10 +285,9 @@ class Meow_WPMC_Core {
254
  *
255
  */
256
 
257
- function wpmc_recover_file( $path ) {
258
- $basedir = wp_upload_dir();
259
- $originalPath = trailingslashit( $basedir['basedir'] ) . $path;
260
- $trashPath = trailingslashit( $this->wpmc_trashdir() ) . $path;
261
  $path_parts = pathinfo( $originalPath );
262
  if ( !file_exists( $path_parts['dirname'] ) && !wp_mkdir_p( $path_parts['dirname'] ) ) {
263
  die( 'Failed to create folder.' );
@@ -272,7 +302,7 @@ class Meow_WPMC_Core {
272
  return true;
273
  }
274
 
275
- function wpmc_recover( $id ) {
276
  global $wpdb;
277
  $table_name = $wpdb->prefix . "mclean_scan";
278
  $issue = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $id ), OBJECT );
@@ -280,7 +310,7 @@ class Meow_WPMC_Core {
280
 
281
  // Files
282
  if ( $issue->type == 0 ) {
283
- $this->wpmc_recover_file( $issue->path );
284
  $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 0 WHERE id = %d", $id ) );
285
  return true;
286
  }
@@ -293,11 +323,11 @@ class Meow_WPMC_Core {
293
  error_log( "Media {$issue->postId} does not have attached file anymore." );
294
  return false;
295
  }
296
- $mainfile = $this->wpmc_clean_uploaded_filename( $fullpath );
297
  $baseUp = pathinfo( $mainfile );
298
  $baseUp = $baseUp['dirname'];
299
- $file = $this->wpmc_clean_uploaded_filename( $fullpath );
300
- if ( !$this->wpmc_recover_file( $file ) ) {
301
  $this->log( "Could not recover $file." );
302
  error_log( "Media Cleaner: Could not recover $file." );
303
  }
@@ -305,15 +335,14 @@ class Meow_WPMC_Core {
305
  // If images, copy the other files as well
306
  $meta = wp_get_attachment_metadata( $issue->postId );
307
  $isImage = isset( $meta, $meta['width'], $meta['height'] );
308
- $sizes = $this->wpmc_get_image_sizes();
309
  if ( $isImage && isset( $meta['sizes'] ) ) {
310
  foreach ( $meta['sizes'] as $name => $attr ) {
311
  if ( isset( $attr['file'] ) ) {
312
- $filepath = wp_upload_dir();
313
- $filepath = $filepath['basedir'];
314
  $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
315
- $file = $this->wpmc_clean_uploaded_filename( $filepath );
316
- if ( !$this->wpmc_recover_file( $file ) ) {
317
  $this->log( "Could not recover $file." );
318
  error_log( "Media Cleaner: Could not recover $file." );
319
  }
@@ -328,11 +357,10 @@ class Meow_WPMC_Core {
328
  }
329
  }
330
 
331
- function wpmc_trash_file( $fileIssuePath ) {
332
  global $wpdb;
333
- $basedir = wp_upload_dir();
334
- $originalPath = trailingslashit( $basedir['basedir'] ) . $fileIssuePath;
335
- $trashPath = trailingslashit( $this->wpmc_trashdir() ) . $fileIssuePath;
336
  $path_parts = pathinfo( $trashPath );
337
 
338
  try {
@@ -358,11 +386,11 @@ class Meow_WPMC_Core {
358
  catch ( Exception $e ) {
359
  return false;
360
  }
361
- $this->wpmc_clean_dir( dirname( $originalPath ) );
362
  return true;
363
  }
364
 
365
- function wpmc_ignore( $id ) {
366
  global $wpdb;
367
  $table_name = $wpdb->prefix . "mclean_scan";
368
  $issue = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $id ), OBJECT );
@@ -370,13 +398,13 @@ class Meow_WPMC_Core {
370
  $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET ignored = 0 WHERE id = %d", $id ) );
371
  else {
372
  if ( (int) $issue->deleted ) // If it is in trash, recover it
373
- $this->wpmc_recover( $id );
374
  $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET ignored = 1 WHERE id = %d", $id ) );
375
  }
376
  return true;
377
  }
378
 
379
- function wpmc_endsWith( $haystack, $needle )
380
  {
381
  $length = strlen( $needle );
382
  if ( $length == 0 )
@@ -384,20 +412,20 @@ class Meow_WPMC_Core {
384
  return ( substr( $haystack, -$length ) === $needle );
385
  }
386
 
387
- function wpmc_clean_dir( $dir ) {
388
  if ( !file_exists( $dir ) )
389
  return;
390
- else if ( $this->wpmc_endsWith( $dir, 'uploads' ) )
391
  return;
392
  $found = array_diff( scandir( $dir ), array( '.', '..' ) );
393
  if ( count( $found ) < 1 ) {
394
  if ( rmdir( $dir ) ) {
395
- $this->wpmc_clean_dir( dirname( $dir ) );
396
  }
397
  }
398
  }
399
 
400
- function wpmc_delete( $id ) {
401
  global $wpdb;
402
  $table_name = $wpdb->prefix . "mclean_scan";
403
  $issue = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $id ), OBJECT );
@@ -406,7 +434,7 @@ class Meow_WPMC_Core {
406
 
407
  // Make sure there isn't a media DB entry
408
  if ( $issue->type == 0 ) {
409
- $attachmentid = $this->wpmc_find_attachment_id_by_file( $issue->path );
410
  if ( $attachmentid ) {
411
  $this->log( "Issue listed as filesystem but Media {$attachmentid} exists." );
412
  }
@@ -416,19 +444,19 @@ class Meow_WPMC_Core {
416
 
417
  if ( $issue->deleted == 0 ) {
418
  // Move file to the trash
419
- if ( $this->wpmc_trash_file( $issue->path ) )
420
  $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 1, ignored = 0 WHERE id = %d", $id ) );
421
  return true;
422
  }
423
  else {
424
  // Delete file from the trash
425
- $trashPath = trailingslashit( $this->wpmc_trashdir() ) . $issue->path;
426
  if ( !unlink( $trashPath ) ) {
427
  $this->log( "Failed to delete the file." );
428
  error_log( "Media Cleaner: Failed to delete the file." );
429
  }
430
  $wpdb->query( $wpdb->prepare( "DELETE FROM $table_name WHERE id = %d", $id ) );
431
- $this->wpmc_clean_dir( dirname( $trashPath ) );
432
  return true;
433
  }
434
  }
@@ -438,11 +466,11 @@ class Meow_WPMC_Core {
438
  // Move Media to trash
439
  // Let's copy the images to the trash so that it can be recovered.
440
  $fullpath = get_attached_file( $issue->postId );
441
- $mainfile = $this->wpmc_clean_uploaded_filename( $fullpath );
442
  $baseUp = pathinfo( $mainfile );
443
  $baseUp = $baseUp['dirname'];
444
- $file = $this->wpmc_clean_uploaded_filename( $fullpath );
445
- if ( !$this->wpmc_trash_file( $file ) ) {
446
  $this->log( "Could not trash $file." );
447
  error_log( "Media Cleaner: Could not trash $file." );
448
  return false;
@@ -451,15 +479,14 @@ class Meow_WPMC_Core {
451
  // If images, check the other files as well
452
  $meta = wp_get_attachment_metadata( $issue->postId );
453
  $isImage = isset( $meta, $meta['width'], $meta['height'] );
454
- $sizes = $this->wpmc_get_image_sizes();
455
  if ( $isImage && isset( $meta['sizes'] ) ) {
456
  foreach ( $meta['sizes'] as $name => $attr ) {
457
  if ( isset( $attr['file'] ) ) {
458
- $filepath = wp_upload_dir();
459
- $filepath = $filepath['basedir'];
460
  $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
461
- $file = $this->wpmc_clean_uploaded_filename( $filepath );
462
- if ( !$this->wpmc_trash_file( $file ) ) {
463
  $this->log( "Could not trash $file." );
464
  error_log( "Media Cleaner: Could not trash $file." );
465
  }
@@ -474,7 +501,7 @@ class Meow_WPMC_Core {
474
  // Trash Media definitely by recovering it (to be like a normal Media) and remove it through the
475
  // standard WordPress workflow
476
  if ( MEDIA_TRASH )
477
- $this->wpmc_recover( $id );
478
  wp_delete_attachment( $issue->postId, true );
479
  $wpdb->query( $wpdb->prepare( "DELETE FROM $table_name WHERE id = %d", $id ) );
480
  return true;
@@ -568,7 +595,7 @@ class Meow_WPMC_Core {
568
  $this->refcache = array();
569
  }
570
 
571
- function wpmc_check_is_ignore( $file ) {
572
  global $wpdb;
573
  $table_name = $wpdb->prefix . "mclean_scan";
574
  $count = $wpdb->get_var( "SELECT COUNT(*)
@@ -581,10 +608,10 @@ class Meow_WPMC_Core {
581
  return ($count > 0);
582
  }
583
 
584
- function wpmc_find_attachment_id_by_file( $file ) {
585
  global $wpdb;
586
  $postmeta_table_name = $wpdb->prefix . 'postmeta';
587
- $file = $this->wpmc_clean_uploaded_filename( $file );
588
  $sql = $wpdb->prepare( "SELECT post_id
589
  FROM {$postmeta_table_name}
590
  WHERE meta_key = '_wp_attached_file'
@@ -599,7 +626,7 @@ class Meow_WPMC_Core {
599
  return $ret;
600
  }
601
 
602
- function wpmc_get_image_sizes() {
603
  $sizes = array();
604
  global $_wp_additional_image_sizes;
605
  foreach ( get_intermediate_image_sizes() as $s ) {
@@ -625,7 +652,13 @@ class Meow_WPMC_Core {
625
  }
626
 
627
  function is_url( $url ) {
628
- return ( (!empty($url)) && is_string($url) && strlen($url)>4 && ( strtolower(substr($url,0,4))=='http' || $url[0]=='/' ) );
 
 
 
 
 
 
629
  }
630
 
631
  function clean_url_from_resolution_ref( &$url ) {
@@ -633,39 +666,51 @@ class Meow_WPMC_Core {
633
  }
634
 
635
  // From a url to the shortened and cleaned url (for example '2013/02/file.png')
636
- function wpmc_clean_url( $url ) {
637
- if ( empty( $url ) )
638
- return $url;
639
- $upload_folder = wp_upload_dir();
640
- $baseurl = $upload_folder['baseurl'];
641
- if ( substr( $url, 0, 2 ) === "//" ) {
642
- $url = "http:" . $url;
643
- }
644
- elseif ( $url[0]=="/" ) {
645
- $url = get_site_url() . $url;
646
- }
647
- $baseurl = str_replace( 'https://', 'http://', $baseurl );
648
- $baseurl = str_replace( 'http://www.', 'http://', $baseurl );
649
- $newurl = str_replace( 'https://', 'http://', $url );
650
- $newurl = str_replace( 'http://www.', 'http://', $newurl );
651
- $newurl = str_replace( $baseurl, '', $newurl );
652
-
653
- // https://wordpress.org/support/topic/links-containing-encoded-special-characters/
654
- $newurl = urldecode( trim( $newurl, "/" ) );
655
- return $newurl;
656
  }
657
 
658
  // From a fullpath to the shortened and cleaned path (for example '2013/02/file.png')
659
- function wpmc_clean_uploaded_filename( $fullpath ) {
660
- $upload_folder = wp_upload_dir();
661
- $basedir = $upload_folder['basedir'];
662
  $file = str_replace( $basedir, '', $fullpath );
663
  $file = str_replace( "./", "", $file );
664
  $file = trim( $file, "/" );
665
  return $file;
666
  }
667
 
668
- function wpmc_check_media( $attachmentId, $checkOnly = false ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
669
 
670
  $this->last_analysis = "N/A";
671
 
@@ -676,7 +721,7 @@ class Meow_WPMC_Core {
676
  // Get the main file
677
  global $wpdb;
678
  $fullpath = get_attached_file( $attachmentId );
679
- $mainfile = $this->wpmc_clean_uploaded_filename( $fullpath );
680
  $baseUp = pathinfo( $mainfile );
681
  $baseUp = $baseUp['dirname'];
682
  $size = 0;
@@ -696,29 +741,28 @@ class Meow_WPMC_Core {
696
  // Analysis
697
  $this->last_analysis = "NONE";
698
  $this->log( "Checking Media #{$attachmentId}: {$mainfile}" );
699
- if ( $this->wpmc_check_is_ignore( $mainfile, $attachmentId ) ) {
700
  $this->last_analysis = "IGNORED";
701
  return true;
702
  }
703
- if ( $this->checkers->check( $mainfile, $attachmentId ) )
704
  return true;
705
 
706
  // If images, check the other files as well
707
  $countfiles = 0;
708
- $sizes = $this->wpmc_get_image_sizes();
709
  if ( $isImage && isset( $meta['sizes'] ) ) {
710
  foreach ( $meta['sizes'] as $name => $attr ) {
711
  if ( isset( $attr['file'] ) ) {
712
- $filepath = wp_upload_dir();
713
- $filepath = $filepath['basedir'];
714
  $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
715
  if ( file_exists( $filepath ) )
716
  $size += filesize( $filepath );
717
- $file = $this->wpmc_clean_uploaded_filename( $filepath );
718
  $countfiles++;
719
  // Analysis
720
  $this->log( "Checking Media #{$attachmentId}: {$file}" );
721
- if ( $this->checkers->check( $mainfile, $attachmentId ) )
722
  return true;
723
  }
724
  }
@@ -745,7 +789,7 @@ class Meow_WPMC_Core {
745
  }
746
 
747
  // Delete all issues
748
- function wpmc_reset_issues( $includingIgnored = false ) {
749
  global $wpdb;
750
  $table_name = $wpdb->prefix . "mclean_scan";
751
  if ( $includingIgnored ) {
@@ -759,24 +803,6 @@ class Meow_WPMC_Core {
759
  }
760
  $table_name = $wpdb->prefix . "mclean_refs";
761
  $wpdb->query("TRUNCATE $table_name");
762
-
763
- // Delete the old transient. Let's delete those lines later.
764
- delete_transient( "wpmc_theme_ids" );
765
- delete_transient( "wpmc_theme_urls" );
766
- delete_transient( "wpmc_widgets_ids" );
767
- delete_transient( "wpmc_widgets_urls" );
768
- delete_transient( "wpmc_posts_images_urls" );
769
- delete_transient( "wpmc_posts_images_ids" );
770
- delete_transient( "wpmc_postmeta_images_urls" );
771
- delete_transient( "wpmc_postmeta_images_ids" );
772
- delete_transient( "wpmc_postmeta_images_acf_urls" );
773
- delete_transient( "wpmc_postmeta_images_acf_ids" );
774
- delete_transient( "wpmc_posts_images_visualcomposer" );
775
- delete_transient( "wpmc_galleries_images_visualcomposer" );
776
- delete_transient( "wpmc_galleries_images_fusionbuilder" );
777
- delete_transient( "wpmc_galleries_images_woocommerce" );
778
- delete_transient( "wpmc_galleries_images_divi" );
779
- delete_transient( "wpmc_galleries_images_urls" );
780
  }
781
 
782
  function echo_issue( $issue ) {
2
 
3
  class Meow_WPMC_Core {
4
 
 
5
  public $admin = null;
6
  public $last_analysis = null;
7
  public $last_analysis_ids = null;
8
  private $regex_file = '/[A-Za-z0-9-_,\s]+[.]{1}(MIMETYPES)/';
9
  public $current_method = 'media';
10
  private $refcache = array();
11
+ public $servername = null;
12
+ public $upload_folder = null;
13
+ public $contentDir = null; // becomes 'wp-content/uploads'
14
 
15
  public function __construct( $admin ) {
16
  $this->admin = $admin;
17
+ $site_url = get_site_url();
18
+ $this->current_method = get_option( 'wpmc_method', 'media' );
19
+ $types = "jpg|jpeg|jpe|gif|png|tiff|bmp|csv|pdf|xls|xlsx|doc|docx|tiff|mp3|mp4|wav|lua";
20
+ $this->regex_file = str_replace( "MIMETYPES", $types, $this->regex_file );
21
+ $this->servername = str_replace( 'http://', '', str_replace( 'https://', '', $site_url ) );
22
+ $this->upload_folder = wp_upload_dir();
23
+ $this->contentDir = substr( $this->upload_folder['baseurl'], 1 + strlen( $site_url ) );
24
  add_action( 'wpmc_initialize_parsers', array( $this, 'initialize_parsers' ), 10, 0 );
25
  }
26
 
29
  new MeowApps_WPMC_Parsers();
30
  }
31
 
 
 
 
 
 
 
32
  function deepsleep( $seconds ) {
33
  $start_time = time();
34
  while( true ) {
112
  $vals = get_option( 'wpseo_titles' );
113
  $url = $vals['company_logo'];
114
  if ( $this->is_url($url) )
115
+ return $this->clean_url( $url );
116
  return null;
117
  }
118
 
127
 
128
  $dom = new DOMDocument();
129
  @$dom->loadHTML( $html ); // mm change
130
+ $results = array();
131
+
132
+ // IFrames (by Mike Meinz)
133
+ $iframes = $dom->getElementsByTagName( 'iframe' );
134
+ foreach($iframes as $iframe) {
135
+ $iframe_src = $iframe->getAttribute( 'src' );
136
+ // Ignore if the iframe src is not on this server
137
+ if ( ( strpos( $iframe_src, $this->servername ) !== false) || ( substr( $iframe_src, 0, 1 ) == "/" ) ) {
138
+ // Create a new DOM Document to hold iframe
139
+ $iframe_doc = new DOMDocument();
140
+ // Load the url's contents into the DOM
141
+ libxml_use_internal_errors(true); // ignore html formatting problems
142
+ $rslt = $iframe_doc->loadHTMLFile( $iframe_src );
143
+ libxml_clear_errors();
144
+ if ( $rslt ) {
145
+ // Get the resulting html
146
+ $iframe_html = $iframe_doc->saveHTML();
147
+ if ( $iframe_html !== false ) {
148
+ // Scan for links in the iframe
149
+ $iframe_urls = $this->get_urls_from_html( $iframe_html ); // Recursion
150
+ if ( !empty( $iframe_urls ) ) {
151
+ $results = array_merge( $results, $iframe_urls );
152
+ }
153
+ }
154
+ }
155
+ else {
156
+ trigger_error( "Failed to load iframe: " . $iframe_src );
157
+ }
158
+ }
159
+ }
160
+
161
 
162
  // Images, src, srcset
163
  $imgs = $dom->getElementsByTagName( 'img' );
 
164
  foreach ( $imgs as $img ) {
165
+ $src = $this->clean_url( $img->getAttribute('src') );
166
  array_push( $results, $src );
167
  $srcset = $img->getAttribute('srcset');
168
  if ( !empty( $srcset ) ) {
170
  foreach ( $setImgs as $setImg ) {
171
  $finalSetImg = explode( ' ', trim( $setImg ) );
172
  if ( is_array( $finalSetImg ) ) {
173
+ array_push( $results, $this->clean_url( $finalSetImg[0] ) );
174
  }
175
  }
176
  }
181
  foreach ( $urls as $url ) {
182
  $url_href = $url->getAttribute('href'); // mm change
183
  if ( $this->is_url( $url_href ) ) { // mm change
184
+ $src = $this->clean_url( $url_href ); // mm change
185
  if ( !empty( $src ) )
186
  array_push( $results, $src );
187
  }
192
  if ( !empty( $res ) && isset( $res[1] ) && count( $res[1] ) > 0 ) {
193
  foreach ( $res[1] as $url ) {
194
  if ( $this->is_url($url) )
195
+ array_push( $results, $this->clean_url( $url ) );
196
  }
197
  }
198
 
201
  if ( !empty( $res ) && isset( $res[1] ) && count( $res[1] ) > 0 ) {
202
  foreach ( $res[1] as $url ) {
203
  if ( $this->is_url($url) )
204
+ array_push( $results, $this->clean_url( $url ) );
205
  }
206
  }
207
 
220
  array_push( $ids, $value );
221
  else
222
  if ( $this->is_url( $value ) )
223
+ array_push( $urls, $this->clean_url( $value ) );
224
  }
225
  }
226
  }
231
  // USE CURRENT THEME AND WP API
232
  $ch = get_custom_header();
233
  if ( !empty( $ch ) && !empty( $ch->url ) ) {
234
+ array_push( $urls, $this->clean_url( $ch->url ) );
235
  }
236
  if ( !empty( $ch ) && !empty( $ch->attachment_id ) ) {
237
  array_push( $ids, $ch->attachment_id );
242
  }
243
  $cd = get_background_image();
244
  if ( !empty( $cd ) ) {
245
+ array_push( $urls, $this->clean_url( $cd ) );
246
  }
247
  $photography_hero_image = get_theme_mod( 'photography_hero_image' );
248
  if ( !empty( $photography_hero_image ) ) {
254
  }
255
  }
256
 
257
+ function log( $data = null, $force = false ) {
258
  if ( !get_option( 'wpmc_debuglogs', false ) && !$force )
259
  return;
260
  $fh = @fopen( trailingslashit( dirname(__FILE__) ) . '/media-cleaner.log', 'a' );
261
  if ( !$fh )
262
  return false;
263
  $date = date( "Y-m-d H:i:s" );
264
+ if ( is_null( $data ) )
265
+ fwrite( $fh, "\n" );
266
+ else
267
+ fwrite( $fh, "$date: {$data}\n" );
268
  fclose( $fh );
269
  return true;
270
  }
275
  *
276
  */
277
 
278
+ function get_trashdir() {
279
+ return trailingslashit( $this->upload_folder['basedir'] ) . 'wpmc-trash';
 
280
  }
281
 
282
  /**
285
  *
286
  */
287
 
288
+ function recover_file( $path ) {
289
+ $originalPath = trailingslashit( $this->upload_folder['basedir'] ) . $path;
290
+ $trashPath = trailingslashit( $this->get_trashdir() ) . $path;
 
291
  $path_parts = pathinfo( $originalPath );
292
  if ( !file_exists( $path_parts['dirname'] ) && !wp_mkdir_p( $path_parts['dirname'] ) ) {
293
  die( 'Failed to create folder.' );
302
  return true;
303
  }
304
 
305
+ function recover( $id ) {
306
  global $wpdb;
307
  $table_name = $wpdb->prefix . "mclean_scan";
308
  $issue = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $id ), OBJECT );
310
 
311
  // Files
312
  if ( $issue->type == 0 ) {
313
+ $this->recover_file( $issue->path );
314
  $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 0 WHERE id = %d", $id ) );
315
  return true;
316
  }
323
  error_log( "Media {$issue->postId} does not have attached file anymore." );
324
  return false;
325
  }
326
+ $mainfile = $this->clean_uploaded_filename( $fullpath );
327
  $baseUp = pathinfo( $mainfile );
328
  $baseUp = $baseUp['dirname'];
329
+ $file = $this->clean_uploaded_filename( $fullpath );
330
+ if ( !$this->recover_file( $file ) ) {
331
  $this->log( "Could not recover $file." );
332
  error_log( "Media Cleaner: Could not recover $file." );
333
  }
335
  // If images, copy the other files as well
336
  $meta = wp_get_attachment_metadata( $issue->postId );
337
  $isImage = isset( $meta, $meta['width'], $meta['height'] );
338
+ $sizes = $this->get_image_sizes();
339
  if ( $isImage && isset( $meta['sizes'] ) ) {
340
  foreach ( $meta['sizes'] as $name => $attr ) {
341
  if ( isset( $attr['file'] ) ) {
342
+ $filepath = $this->upload_folder['basedir'];
 
343
  $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
344
+ $file = $this->clean_uploaded_filename( $filepath );
345
+ if ( !$this->recover_file( $file ) ) {
346
  $this->log( "Could not recover $file." );
347
  error_log( "Media Cleaner: Could not recover $file." );
348
  }
357
  }
358
  }
359
 
360
+ function trash_file( $fileIssuePath ) {
361
  global $wpdb;
362
+ $originalPath = trailingslashit( $this->upload_folder['basedir'] ) . $fileIssuePath;
363
+ $trashPath = trailingslashit( $this->get_trashdir() ) . $fileIssuePath;
 
364
  $path_parts = pathinfo( $trashPath );
365
 
366
  try {
386
  catch ( Exception $e ) {
387
  return false;
388
  }
389
+ $this->clean_dir( dirname( $originalPath ) );
390
  return true;
391
  }
392
 
393
+ function ignore( $id ) {
394
  global $wpdb;
395
  $table_name = $wpdb->prefix . "mclean_scan";
396
  $issue = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $id ), OBJECT );
398
  $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET ignored = 0 WHERE id = %d", $id ) );
399
  else {
400
  if ( (int) $issue->deleted ) // If it is in trash, recover it
401
+ $this->recover( $id );
402
  $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET ignored = 1 WHERE id = %d", $id ) );
403
  }
404
  return true;
405
  }
406
 
407
+ function endsWith( $haystack, $needle )
408
  {
409
  $length = strlen( $needle );
410
  if ( $length == 0 )
412
  return ( substr( $haystack, -$length ) === $needle );
413
  }
414
 
415
+ function clean_dir( $dir ) {
416
  if ( !file_exists( $dir ) )
417
  return;
418
+ else if ( $this->endsWith( $dir, 'uploads' ) )
419
  return;
420
  $found = array_diff( scandir( $dir ), array( '.', '..' ) );
421
  if ( count( $found ) < 1 ) {
422
  if ( rmdir( $dir ) ) {
423
+ $this->clean_dir( dirname( $dir ) );
424
  }
425
  }
426
  }
427
 
428
+ function delete( $id ) {
429
  global $wpdb;
430
  $table_name = $wpdb->prefix . "mclean_scan";
431
  $issue = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $id ), OBJECT );
434
 
435
  // Make sure there isn't a media DB entry
436
  if ( $issue->type == 0 ) {
437
+ $attachmentid = $this->find_media_id_from_file( $issue->path );
438
  if ( $attachmentid ) {
439
  $this->log( "Issue listed as filesystem but Media {$attachmentid} exists." );
440
  }
444
 
445
  if ( $issue->deleted == 0 ) {
446
  // Move file to the trash
447
+ if ( $this->trash_file( $issue->path ) )
448
  $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 1, ignored = 0 WHERE id = %d", $id ) );
449
  return true;
450
  }
451
  else {
452
  // Delete file from the trash
453
+ $trashPath = trailingslashit( $this->get_trashdir() ) . $issue->path;
454
  if ( !unlink( $trashPath ) ) {
455
  $this->log( "Failed to delete the file." );
456
  error_log( "Media Cleaner: Failed to delete the file." );
457
  }
458
  $wpdb->query( $wpdb->prepare( "DELETE FROM $table_name WHERE id = %d", $id ) );
459
+ $this->clean_dir( dirname( $trashPath ) );
460
  return true;
461
  }
462
  }
466
  // Move Media to trash
467
  // Let's copy the images to the trash so that it can be recovered.
468
  $fullpath = get_attached_file( $issue->postId );
469
+ $mainfile = $this->clean_uploaded_filename( $fullpath );
470
  $baseUp = pathinfo( $mainfile );
471
  $baseUp = $baseUp['dirname'];
472
+ $file = $this->clean_uploaded_filename( $fullpath );
473
+ if ( !$this->trash_file( $file ) ) {
474
  $this->log( "Could not trash $file." );
475
  error_log( "Media Cleaner: Could not trash $file." );
476
  return false;
479
  // If images, check the other files as well
480
  $meta = wp_get_attachment_metadata( $issue->postId );
481
  $isImage = isset( $meta, $meta['width'], $meta['height'] );
482
+ $sizes = $this->get_image_sizes();
483
  if ( $isImage && isset( $meta['sizes'] ) ) {
484
  foreach ( $meta['sizes'] as $name => $attr ) {
485
  if ( isset( $attr['file'] ) ) {
486
+ $filepath = $this->upload_folder['basedir'];
 
487
  $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
488
+ $file = $this->clean_uploaded_filename( $filepath );
489
+ if ( !$this->trash_file( $file ) ) {
490
  $this->log( "Could not trash $file." );
491
  error_log( "Media Cleaner: Could not trash $file." );
492
  }
501
  // Trash Media definitely by recovering it (to be like a normal Media) and remove it through the
502
  // standard WordPress workflow
503
  if ( MEDIA_TRASH )
504
+ $this->recover( $id );
505
  wp_delete_attachment( $issue->postId, true );
506
  $wpdb->query( $wpdb->prepare( "DELETE FROM $table_name WHERE id = %d", $id ) );
507
  return true;
595
  $this->refcache = array();
596
  }
597
 
598
+ function check_is_ignore( $file ) {
599
  global $wpdb;
600
  $table_name = $wpdb->prefix . "mclean_scan";
601
  $count = $wpdb->get_var( "SELECT COUNT(*)
608
  return ($count > 0);
609
  }
610
 
611
+ function find_media_id_from_file( $file ) {
612
  global $wpdb;
613
  $postmeta_table_name = $wpdb->prefix . 'postmeta';
614
+ $file = $this->clean_uploaded_filename( $file );
615
  $sql = $wpdb->prepare( "SELECT post_id
616
  FROM {$postmeta_table_name}
617
  WHERE meta_key = '_wp_attached_file'
626
  return $ret;
627
  }
628
 
629
+ function get_image_sizes() {
630
  $sizes = array();
631
  global $_wp_additional_image_sizes;
632
  foreach ( get_intermediate_image_sizes() as $s ) {
652
  }
653
 
654
  function is_url( $url ) {
655
+ return ( (
656
+ !empty( $url ) ) &&
657
+ is_string( $url ) &&
658
+ strlen( $url ) > 4 && (
659
+ strtolower( substr( $url, 0, 4) ) == 'http' || $url[0] == '/'
660
+ )
661
+ );
662
  }
663
 
664
  function clean_url_from_resolution_ref( &$url ) {
666
  }
667
 
668
  // From a url to the shortened and cleaned url (for example '2013/02/file.png')
669
+ function clean_url( $url ) {
670
+ $dirIndex = strpos( $url, $this->contentDir );
671
+ if ( empty( $url ) || $dirIndex == false )
672
+ return null;
673
+ return urldecode( substr( $url, 1 + strlen( $this->contentDir ) + $dirIndex ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
674
  }
675
 
676
  // From a fullpath to the shortened and cleaned path (for example '2013/02/file.png')
677
+ function clean_uploaded_filename( $fullpath ) {
678
+ $basedir = $this->upload_folder['basedir'];
 
679
  $file = str_replace( $basedir, '', $fullpath );
680
  $file = str_replace( "./", "", $file );
681
  $file = trim( $file, "/" );
682
  return $file;
683
  }
684
 
685
+ /*
686
+ Check if the file or the Media ID is used in the install.
687
+ That file or ID will be checked against the database of references created by the plugin
688
+ by the parsers.
689
+ */
690
+ public function reference_exists( $file, $mediaId ) {
691
+ global $wpdb;
692
+ $table = $wpdb->prefix . "mclean_refs";
693
+ $row = null;
694
+ if ( !empty( $mediaId ) ) {
695
+ $row = $wpdb->get_row( $wpdb->prepare( "SELECT originType FROM $table WHERE mediaId = %d", $mediaId ) );
696
+ if ( !empty( $row ) ) {
697
+ $this->last_analysis = $row->originType;
698
+ $this->log( "OK! Media #{$mediaId} used by {$row->originType}" );
699
+ return true;
700
+ }
701
+ }
702
+ if ( !empty( $file ) ) {
703
+ $row = $wpdb->get_row( $wpdb->prepare( "SELECT originType FROM $table WHERE mediaUrl = %s", $file ) );
704
+ if ( !empty( $row ) ) {
705
+ $this->last_analysis = $row->originType;
706
+ $this->log( "OK! File {$file} used by {$row->originType}" );
707
+ return true;
708
+ }
709
+ }
710
+ return false;
711
+ }
712
+
713
+ function check_media( $attachmentId, $checkOnly = false ) {
714
 
715
  $this->last_analysis = "N/A";
716
 
721
  // Get the main file
722
  global $wpdb;
723
  $fullpath = get_attached_file( $attachmentId );
724
+ $mainfile = $this->clean_uploaded_filename( $fullpath );
725
  $baseUp = pathinfo( $mainfile );
726
  $baseUp = $baseUp['dirname'];
727
  $size = 0;
741
  // Analysis
742
  $this->last_analysis = "NONE";
743
  $this->log( "Checking Media #{$attachmentId}: {$mainfile}" );
744
+ if ( $this->check_is_ignore( $mainfile, $attachmentId ) ) {
745
  $this->last_analysis = "IGNORED";
746
  return true;
747
  }
748
+ if ( $this->reference_exists( $mainfile, $attachmentId ) )
749
  return true;
750
 
751
  // If images, check the other files as well
752
  $countfiles = 0;
753
+ $sizes = $this->get_image_sizes();
754
  if ( $isImage && isset( $meta['sizes'] ) ) {
755
  foreach ( $meta['sizes'] as $name => $attr ) {
756
  if ( isset( $attr['file'] ) ) {
757
+ $filepath = $this->upload_folder['basedir'];
 
758
  $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
759
  if ( file_exists( $filepath ) )
760
  $size += filesize( $filepath );
761
+ $file = $this->clean_uploaded_filename( $filepath );
762
  $countfiles++;
763
  // Analysis
764
  $this->log( "Checking Media #{$attachmentId}: {$file}" );
765
+ if ( $this->reference_exists( $mainfile, $attachmentId ) )
766
  return true;
767
  }
768
  }
789
  }
790
 
791
  // Delete all issues
792
+ function reset_issues( $includingIgnored = false ) {
793
  global $wpdb;
794
  $table_name = $wpdb->prefix . "mclean_scan";
795
  if ( $includingIgnored ) {
803
  }
804
  $table_name = $wpdb->prefix . "mclean_refs";
805
  $wpdb->query("TRUNCATE $table_name");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
806
  }
807
 
808
  function echo_issue( $issue ) {
media-cleaner.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Media Cleaner
4
  Plugin URI: https://meowapps.com
5
  Description: Clean your Media Library, many options, trash system.
6
- Version: 5.2.0
7
  Author: Jordy Meow
8
  Author URI: https://meowapps.com
9
  Text Domain: media-cleaner
@@ -14,68 +14,29 @@ Originally developed for two of my websites:
14
  */
15
 
16
  if ( class_exists( 'Meow_WPMC_Core' ) ) {
17
- function wpmc_pro_admin_notices() {
18
  echo '<div class="error"><p>Thanks for installing the Pro version of Media Cleaner :) However, the free version is still enabled. Please disable or uninstall it.</p></div>';
19
  }
20
- add_action( 'admin_notices', 'wpmc_pro_admin_notices' );
21
  return;
22
  }
23
 
24
  if ( is_admin() ) {
25
 
26
  global $wpmc_version;
27
- $wpmc_version = '5.2.0';
 
28
 
29
- // Admin
30
  require __DIR__ . '/admin.php';
31
- $wpmc_admin = new Meow_WPMC_Admin( 'wpmc', __FILE__, 'media-cleaner' );
32
-
33
- // Core
34
  require __DIR__ . '/core.php';
35
- global $wpmc;
36
- $wpmc = new Meow_WPMC_Core( $wpmc_admin );
37
- $wpmc_admin->core = $wpmc;
38
-
39
- // UI
40
  require __DIR__ . '/ui.php';
41
- new Meow_WPMC_UI( $wpmc, $wpmc_admin );
42
-
43
- /*******************************************************************************
44
- * TODO: OLD PRO, THIS FUNCTION SHOULD BE REMOVED IN THE FUTURE
45
- ******************************************************************************/
46
-
47
- add_action( 'admin_notices', 'wpmc_meow_old_version_admin_notices' );
48
-
49
- function wpmc_meow_old_version_admin_notices() {
50
- if ( isset( $_POST['wpmc_reset_sub'] ) ) {
51
- delete_transient( 'wpmc_validated' );
52
- delete_option( 'wpmc_pro_serial' );
53
- delete_option( 'wpmc_pro_status' );
54
- }
55
- $subscr_id = get_option( 'wpmc_pro_serial', "" );
56
- if ( empty( $subscr_id ) )
57
- return;
58
- $forever = strpos( $subscr_id, 'F-' ) !== false;
59
- $yearly = strpos( $subscr_id, 'I-' ) !== false;
60
- if ( !$forever && !$yearly )
61
- return;
62
- ?>
63
- <div class="error">
64
- <p>
65
- <h2>IMPORTANT MESSAGE ABOUT MEDIA CLEANER</h2>
66
- In order to comply with WordPress.org, BIG CHANGES in the code and how the plugin was sold were to be made. The plugin needs requires to be purchased and updated through the new <a target='_blank' href="https://store.meowapps.com">Meow Apps Store</a>. This store is also more robust (keys, websites management, invoices, etc). Now, since WordPress.org only accepts free plugins on its repository, this is the one currently installed. Therefore, you need to take an action. <b>Please click here to know more about your license and to learn what to do: <a target='_blank' href='https://meowapps.com/?mkey=<?php echo $subscr_id ?>'>License <?php echo $subscr_id ?></a></b>.
67
- </p>
68
- <p>
69
- <form method="post" action="">
70
- <input type="hidden" name="wpmc_reset_sub" value="true">
71
- <input type="submit" name="submit" id="submit" class="button" value="Got it. Clear this!">
72
- <br /><small><b>Make sure you followed the instruction before clicking this button.</b></small>
73
- </form>
74
- </p>
75
- </div>
76
- <?php
77
- }
78
 
 
 
 
 
 
79
  }
80
 
81
  ?>
3
  Plugin Name: Media Cleaner
4
  Plugin URI: https://meowapps.com
5
  Description: Clean your Media Library, many options, trash system.
6
+ Version: 5.2.1
7
  Author: Jordy Meow
8
  Author URI: https://meowapps.com
9
  Text Domain: media-cleaner
14
  */
15
 
16
  if ( class_exists( 'Meow_WPMC_Core' ) ) {
17
+ function wpmc_thanks_admin_notices() {
18
  echo '<div class="error"><p>Thanks for installing the Pro version of Media Cleaner :) However, the free version is still enabled. Please disable or uninstall it.</p></div>';
19
  }
20
+ add_action( 'admin_notices', 'wpmc_thanks_admin_notices' );
21
  return;
22
  }
23
 
24
  if ( is_admin() ) {
25
 
26
  global $wpmc_version;
27
+ global $wpmc;
28
+ $wpmc_version = '5.2.1';
29
 
 
30
  require __DIR__ . '/admin.php';
 
 
 
31
  require __DIR__ . '/core.php';
 
 
 
 
 
32
  require __DIR__ . '/ui.php';
33
+ require __DIR__ . '/api.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
+ wpmc_init( __FILE__ );
36
+ $admin = new Meow_WPMC_Admin( 'wpmc', __FILE__, 'media-cleaner' );
37
+ $wpmc = new Meow_WPMC_Core( $admin );
38
+ new Meow_WPMC_UI( $wpmc, $admin );
39
+ new Meow_WPMC_API( $wpmc, $admin );
40
  }
41
 
42
  ?>
parsers.php CHANGED
@@ -21,6 +21,12 @@ class MeowApps_WPMC_Parsers {
21
 
22
  if ( class_exists( 'MetaSliderPlugin' ) || class_exists( 'MetaSliderPro' ) ) // mm change
23
  require_once( 'parsers/metaslider.php' );
 
 
 
 
 
 
24
  }
25
  }
26
 
21
 
22
  if ( class_exists( 'MetaSliderPlugin' ) || class_exists( 'MetaSliderPro' ) ) // mm change
23
  require_once( 'parsers/metaslider.php' );
24
+
25
+ if ( function_exists( 'mc_show_sidebar' ) )
26
+ require_once( 'parsers/my-calendar.php' );
27
+
28
+ if ( class_exists( 'Mega_Menu' ) )
29
+ require_once( 'parsers/maxmegamenu.php' );
30
  }
31
  }
32
 
parsers/acf.php CHANGED
@@ -70,7 +70,7 @@ function wpmc_scan_postmeta_acf_field( $field, $id, $recursion_limit = -1 ) {
70
  if ( !empty( $field['value']['id'] ) )
71
  array_push( $postmeta_images_acf_ids, $field['value']['id'] );
72
  if ( !empty( $field['value']['url'] ) )
73
- array_push( $postmeta_images_acf_urls, $wpmc->wpmc_clean_url( $field['value']['url'] ) );
74
  }
75
  // ACF Image ID
76
  else if ( $field['type'] == 'image' && $format == 'id' && !empty( $field['value'] ) ) {
@@ -78,7 +78,7 @@ function wpmc_scan_postmeta_acf_field( $field, $id, $recursion_limit = -1 ) {
78
  }
79
  // ACF Image URL
80
  else if ( $field['type'] == 'image' && $format == 'url' && !empty( $field['value'] ) ) {
81
- array_push( $postmeta_images_acf_urls, $wpmc->wpmc_clean_url( $field['value'] ) );
82
  }
83
  // ACF Gallery
84
  else if ( $field['type'] == 'gallery' && !empty( $field['value'] ) ) {
70
  if ( !empty( $field['value']['id'] ) )
71
  array_push( $postmeta_images_acf_ids, $field['value']['id'] );
72
  if ( !empty( $field['value']['url'] ) )
73
+ array_push( $postmeta_images_acf_urls, $wpmc->clean_url( $field['value']['url'] ) );
74
  }
75
  // ACF Image ID
76
  else if ( $field['type'] == 'image' && $format == 'id' && !empty( $field['value'] ) ) {
78
  }
79
  // ACF Image URL
80
  else if ( $field['type'] == 'image' && $format == 'url' && !empty( $field['value'] ) ) {
81
+ array_push( $postmeta_images_acf_urls, $wpmc->clean_url( $field['value'] ) );
82
  }
83
  // ACF Gallery
84
  else if ( $field['type'] == 'gallery' && !empty( $field['value'] ) ) {
parsers/acf_widgets.php CHANGED
@@ -23,7 +23,7 @@ function get_images_from_acfwidgets( $widget) {
23
  $OptionRows = $wpdb->get_results( $wpdb->prepare( $q, $LikeKey ) , ARRAY_N );
24
  if ( $wpdb->last_error ) {
25
  error_log( $q . " " . $wpdb->last_error );
26
- $this->log( $q . " " . $wpdb->last_error );
27
  die( $wpdb->last_error );
28
  }
29
  if ( count( $OptionRows ) > 0 ) {
@@ -47,7 +47,7 @@ function get_images_from_acfwidgets( $widget) {
47
  // *** A link field may contain a link or be empty
48
  if ( strpos( $row[0], 'link' ) || strpos( $row[0], 'url' ) !== false ) {
49
  if ( $wpmc->is_url($row[1]) ) {
50
- $url = $wpmc->wpmc_clean_url($row[1]);
51
  if (!empty($url)) {
52
  array_push($ACFWidget_urls, $url);
53
  }
23
  $OptionRows = $wpdb->get_results( $wpdb->prepare( $q, $LikeKey ) , ARRAY_N );
24
  if ( $wpdb->last_error ) {
25
  error_log( $q . " " . $wpdb->last_error );
26
+ $wpmc->log( $q . " " . $wpdb->last_error );
27
  die( $wpdb->last_error );
28
  }
29
  if ( count( $OptionRows ) > 0 ) {
47
  // *** A link field may contain a link or be empty
48
  if ( strpos( $row[0], 'link' ) || strpos( $row[0], 'url' ) !== false ) {
49
  if ( $wpmc->is_url($row[1]) ) {
50
+ $url = $wpmc->clean_url($row[1]);
51
  if (!empty($url)) {
52
  array_push($ACFWidget_urls, $url);
53
  }
parsers/common.php CHANGED
@@ -48,7 +48,7 @@ class MeowApps_WPMC_Parser {
48
  if ( !empty( $widget_data[$instance_id]['url'] ) ) {
49
  $url = $widget_data[$instance_id]['url'];
50
  if ( $wpmc->is_url( $url ) ) {
51
- $url = $wpmc->wpmc_clean_url( $url );
52
  if ( !empty($url) )
53
  array_push( $urls, $url );
54
  }
@@ -94,7 +94,7 @@ class MeowApps_WPMC_Parser {
94
  $galleries = get_post_galleries_images( $id );
95
  foreach ( $galleries as $gallery ) {
96
  foreach ( $gallery as $image ) {
97
- array_push( $galleries_images, $wpmc->wpmc_clean_url( $image ) );
98
  }
99
  }
100
 
48
  if ( !empty( $widget_data[$instance_id]['url'] ) ) {
49
  $url = $widget_data[$instance_id]['url'];
50
  if ( $wpmc->is_url( $url ) ) {
51
+ $url = $wpmc->clean_url( $url );
52
  if ( !empty($url) )
53
  array_push( $urls, $url );
54
  }
94
  $galleries = get_post_galleries_images( $id );
95
  foreach ( $galleries as $gallery ) {
96
  foreach ( $gallery as $image ) {
97
+ array_push( $galleries_images, $wpmc->clean_url( $image ) );
98
  }
99
  }
100
 
parsers/maxmegamenu.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Max Mega Menu (https://wordpress.org/plugins/megamenu/)
4
+ // Added by Mike Meinz
5
+ //
6
+
7
+ add_action('wpmc_scan_widgets', 'wpmc_scan_widgets_maxmegamenu');
8
+
9
+ function wpmc_scan_widgets_maxmegamenu() {
10
+ global $wpmc;
11
+ global $wpdb;
12
+ $urls = array();
13
+ $q = "SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_menu_item_url' and LENGTH(TRIM(meta_value)) > 0;";
14
+ $rows = $wpdb->get_col($q);
15
+ if ( $wpdb->last_error ) {
16
+ error_log($q . " " . $wpdb->last_error);
17
+ $wpmc->log($q . " " . $wpdb->last_error);
18
+ die($wpdb->last_error);
19
+ }
20
+
21
+ if ( count( $rows ) > 0 ) {
22
+ foreach( $rows as $metavalue ) {
23
+ if ( ( !empty( $metavalue ) ) && $wpmc->is_url( $metavalue ) ) {
24
+ $url = $wpmc->clean_url( $metavalue );
25
+ if ( !empty( $url ) ) {
26
+ array_push( $urls, $url );
27
+ }
28
+ }
29
+ }
30
+ }
31
+
32
+ if ( !empty( $urls ) ) {
33
+ $wpmc->add_reference_url( $urls, 'MAX MEGA MENU (URL)' );
34
+ }
35
+ }
36
+
37
+ ?>
parsers/metaslider.php CHANGED
@@ -3,14 +3,8 @@
3
  add_action( 'wpmc_scan_widgets', 'wpmc_scan_widgets_metaslider' );
4
 
5
  function wpmc_scan_widgets_metaslider() {
6
- global $wpmc;
7
- $widgets_ids = array();
8
- wpmc_get_images_from_metaslider( $widgets_ids );
9
- $wpmc->add_reference_id( $widgets_ids, 'METASLIDER (ID)' ); // mm change
10
- }
11
-
12
- function wpmc_get_images_from_metaslider( &$ids ) {
13
  global $wpdb;
 
14
  $q = "SELECT object_id
15
  FROM {$wpdb->term_relationships}
16
  WHERE object_id > 0
@@ -19,12 +13,11 @@ function wpmc_get_images_from_metaslider( &$ids ) {
19
  $imageIds = $wpdb->get_col( $q );
20
  if ( $wpdb->last_error ) {
21
  error_log( $q . " " . $wpdb->last_error );
22
- $this->log( $q . " " . $wpdb->last_error );
23
  die( $wpdb->last_error );
24
  }
25
  if ( count( $imageIds) > 0 ) {
26
- $ids = array_merge( $ids, $imageIds );
27
  }
28
  }
29
-
30
  ?>
3
  add_action( 'wpmc_scan_widgets', 'wpmc_scan_widgets_metaslider' );
4
 
5
  function wpmc_scan_widgets_metaslider() {
 
 
 
 
 
 
 
6
  global $wpdb;
7
+ global $wpmc;
8
  $q = "SELECT object_id
9
  FROM {$wpdb->term_relationships}
10
  WHERE object_id > 0
13
  $imageIds = $wpdb->get_col( $q );
14
  if ( $wpdb->last_error ) {
15
  error_log( $q . " " . $wpdb->last_error );
16
+ $wpmc->log( $q . " " . $wpdb->last_error );
17
  die( $wpdb->last_error );
18
  }
19
  if ( count( $imageIds) > 0 ) {
20
+ $wpmc->add_reference_id( $imageIds, 'METASLIDER (ID)' );
21
  }
22
  }
 
23
  ?>
parsers/my-calendar.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // My Calendar (https://wordpress.org/plugins/my-calendar/)
4
+ // Added by Mike Meinz
5
+ //
6
+
7
+ add_action( 'wpmc_scan_widgets', 'wpmc_scan_widgets_mycalendar' );
8
+
9
+ function wpmc_scan_widgets_mycalendar() {
10
+ global $wpmc;
11
+ global $wpdb;
12
+ $eventurls = array();
13
+ $q = "SELECT event_desc, event_short, event_link, event_url, event_image FROM " . $wpdb->prefix . "my_calendar WHERE
14
+ (LOWER(event_desc) like '%http%' or
15
+ LOWER(event_short) like '%http%' or
16
+ LOWER(event_link) like 'http%' or
17
+ LOWER(event_image) like 'http%' or
18
+ LOWER(event_url) like 'http%');";
19
+ $rows = $wpdb->get_results( $q, ARRAY_N );
20
+ if ( $wpdb->last_error ) {
21
+ error_log( $q . " " . $wpdb->last_error );
22
+ $wpmc->log( $q . " " . $wpdb->last_error );
23
+ die( $wpdb->last_error );
24
+ }
25
+ if ( count( $rows ) > 0 ) {
26
+ foreach ( $rows as $row ) {
27
+ if ( !empty($row[0]) ) { // event_desc
28
+ $urls = $wpmc->get_urls_from_html( $row[0] );
29
+ $eventurls = array_merge( $eventurls, $urls);
30
+ }
31
+ if ( !empty($row[1]) ) { // event_short
32
+ $urls = $wpmc->get_urls_from_html( $row[1] );
33
+ $eventurls = array_merge( $eventurls, $urls);
34
+ }
35
+ if ( !empty($row[2]) ) { // event_link
36
+ array_push( $eventurls, $wpmc->clean_url( $row[2] ) );
37
+ }
38
+ if ( !empty($row[3]) ) { // event_url
39
+ array_push( $eventurls, $wpmc->clean_url( $row[3] ) );
40
+ }
41
+ if ( !empty($row[4]) ) { // event_image
42
+ array_push( $eventurls, $wpmc->clean_url( $row[4] ) );
43
+ }
44
+
45
+ }
46
+ }
47
+
48
+ if ( !empty( $eventurls ) ) {
49
+ $wpmc->add_reference_url( $eventurls, 'MY CALENDAR (URL)' );
50
+ }
51
+ }
52
+
53
+ ?>
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: clean, delete, file, files, images, image, media, library, upload, acf
4
  Requires at least: 4.8
5
  Tested up to: 5.1
6
  Requires PHP: 7.0
7
- Stable tag: 5.2.0
8
 
9
  Clean your WordPress (broken media, unused media, files). It has its own trash and recovery features. Please read the description.
10
 
@@ -52,6 +52,11 @@ Again, this plugin deletes files so be careful! Backup is not only important, it
52
 
53
  == Changelog ==
54
 
 
 
 
 
 
55
  = 5.2.0 =
56
  * Update: Many optimizations, modules and big sections of the code are now only loaded when really needed.
57
  * Fix: Filenames with spaces weren't detected correctly and other.
4
  Requires at least: 4.8
5
  Tested up to: 5.1
6
  Requires PHP: 7.0
7
+ Stable tag: 5.2.1
8
 
9
  Clean your WordPress (broken media, unused media, files). It has its own trash and recovery features. Please read the description.
10
 
52
 
53
  == Changelog ==
54
 
55
+ = 5.2.1 =
56
+ * Add: Support for My Calendar (thanks to Mike Meinz).
57
+ * Add: Support for iFrames (thanks to Mike Meinz).
58
+ * Update: Code cleaning, reorganization and optimization.
59
+
60
  = 5.2.0 =
61
  * Update: Many optimizations, modules and big sections of the code are now only loaded when really needed.
62
  * Fix: Filenames with spaces weren't detected correctly and other.
media-cleaner.js → scripts/dashboard.js RENAMED
File without changes
settings.js → scripts/settings.js RENAMED
File without changes
media-cleaner.css → scripts/style.css RENAMED
File without changes
ui.php CHANGED
@@ -1,8 +1,30 @@
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;
@@ -11,15 +33,6 @@ class Meow_WPMC_UI {
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
 
@@ -57,17 +70,17 @@ class Meow_WPMC_UI {
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
  }
@@ -103,63 +116,13 @@ class Meow_WPMC_UI {
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.";
@@ -186,325 +149,4 @@ class Meow_WPMC_UI {
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
  }
1
  <?php
2
 
3
  class Meow_WPMC_UI {
4
+
5
  private $core = null;
6
  private $admin = null;
7
+ private $foundTypes = array(
8
+ "CONTENT" => "Found in content.",
9
+ "CONTENT (ID)" => "Found in content (as an ID).",
10
+ "CONTENT (URL)" => "Found in content (as an URL).",
11
+ "THEME" => "Found in theme.",
12
+ "PAGE BUILDER" => "Found in Page Builder.",
13
+ "GALLERY" => "Found in gallery.",
14
+ "META" => "Found in meta.",
15
+ "META (ID)" => "Found in meta (as an ID).",
16
+ "META (URL)" => "Found in meta (as an URL).",
17
+ "META ACF (ID)" => "Found in meta (as an URL).",
18
+ "META ACF (URL)" => "Found in meta (as an URL).",
19
+ "WIDGET" => "Found in widget.",
20
+ "ACF WIDGET (ID)" => "Found in ACF Widget (as an ID).",
21
+ "ACF WIDGET (URL)" => "Found in ACF Widget (as an URL).",
22
+ "ATTACHMENT (ID)" => "Found in Attachment (as an ID).",
23
+ "METASLIDER (ID)" => "Found in MetaSlider (as an ID).",
24
+ "MY CALENDAR (URL)" => "Found in My Calendar (as an URL).",
25
+ "MAX MEGA MENU (URL)" => "Found in Max Mega Menu (as an URL).",
26
+ "SITE ICON" => "Found in Site Icon."
27
+ );
28
 
29
  function __construct( $core, $admin ) {
30
  $this->core = $core;
33
  add_action( 'admin_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) );
34
  add_action( 'admin_print_scripts', array( $this, 'admin_inline_js' ) );
35
  add_action( 'add_meta_boxes', array( $this, 'add_metabox' ) );
 
 
 
 
 
 
 
 
 
36
  add_filter( 'media_row_actions', array( $this, 'media_row_actions' ), 10, 2 );
37
  }
38
 
70
  function wp_enqueue_scripts() {
71
  wp_enqueue_style( 'wp-jquery-ui-dialog' );
72
  wp_enqueue_script( 'jquery-ui-dialog' );
73
+ wp_enqueue_style( 'media-cleaner-css', plugins_url( '/scripts/style.css', __FILE__ ) );
74
 
75
  $screen = get_current_screen();
76
  global $wpmc_version;
77
  switch ( $screen->id ) {
78
  case 'media_page_media-cleaner': // Media > Cleaner
79
+ wp_enqueue_script( 'media-cleaner', plugins_url( '/scripts/dashboard.js', __FILE__ ), array( 'jquery', 'jquery-ui-dialog' ),
80
  $wpmc_version, true );
81
  break;
82
  case 'meow-apps_page_wpmc_settings-menu': // Meow Apps > Media Cleaner (Settings)
83
+ wp_enqueue_script( 'media-cleaner-settings', plugins_url( '/scripts/settings.js', __FILE__ ), array( 'jquery' ),
84
  $wpmc_version, true );
85
  break;
86
  }
116
 
117
  function display_metabox( $post ) {
118
  $this->core->log( "Media Edit > Checking Media #{$post->ID}" );
119
+ $success = $this->core->check_media( $post->ID, true );
120
  $this->core->log( "Success $success\n" );
121
  if ( $success ) {
122
+ if ( array_key_exists( $this->core->last_analysis, $this->foundTypes ) )
123
+ echo $this->foundTypes[ $this->core->last_analysis ];
124
+ else
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  echo "It seems to be used as: " . $this->core->last_analysis;
 
126
  }
127
  else {
128
  echo "Doesn't seem to be used.";
149
  return $actions;
150
  }
151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  }
views/menu-screen.php CHANGED
@@ -8,7 +8,7 @@
8
  $reset = isset ( $_GET[ 'reset' ] ) ? $_GET[ 'reset' ] : 0;
9
  if ( $reset ) {
10
  wpmc_reset();
11
- $core->wpmc_reset_issues();
12
  }
13
  $s = isset ( $_GET[ 's' ] ) ? sanitize_text_field( $_GET[ 's' ] ) : null;
14
  $table_name = $wpdb->prefix . "mclean_scan";
8
  $reset = isset ( $_GET[ 'reset' ] ) ? $_GET[ 'reset' ] : 0;
9
  if ( $reset ) {
10
  wpmc_reset();
11
+ $core->reset_issues();
12
  }
13
  $s = isset ( $_GET[ 's' ] ) ? sanitize_text_field( $_GET[ 's' ] ) : null;
14
  $table_name = $wpdb->prefix . "mclean_scan";