Media Cleaner - Version 5.5.7

Version Description

  • Update: UI improved in many ways, I hope you will love it more!
  • Add: Filter by issue, and allow to delete those specific issues.
  • Add: Support for the original image (-scaled) feature added in a recent version of WP.
  • Add: Support for Custom Product Tabs.
  • Add: Support for Support for FAT Portfolio.
  • Update: Better support for translations.
  • Update: Better support for Revolution Slider.
  • Update: Added additional checks for DOM parser and check if the DOM module is loaded.
  • Fix: 100% of the code was checked and a few tiny issues were fixed here and there.
  • Info: This plugin is a lot of work. Please help me by giving it a nice review, here. At the same time, I would love to know if you would prefer the results to be refreshed automatically instead of having to click on refresh. Thank you :)
Download this release

Release Info

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

Code changes from version 5.5.4 to 5.5.7

.vscode/launch.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+
8
+ {
9
+ "name": "Listen for XDebug",
10
+ "type": "php",
11
+ "request": "launch",
12
+ "port": 9000,
13
+ "pathMappings": {
14
+ "/app": "${workspaceRoot}/app"
15
+ }
16
+ },
17
+ {
18
+ "name": "Launch currently open script",
19
+ "type": "php",
20
+ "request": "launch",
21
+ "program": "${file}",
22
+ "cwd": "${fileDirname}",
23
+ "port": 9000
24
+ }
25
+ ]
26
+ }
admin.php CHANGED
@@ -45,7 +45,6 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
45
  }
46
 
47
  function admin_notices() {
48
-
49
  $mediasBuffer = get_option( 'wpmc_medias_buffer', null );
50
  $postsBuffer = get_option( 'wpmc_posts_buffer', null );
51
  $analysisBuffer = get_option( 'wpmc_analysis_buffer', null );
@@ -60,8 +59,18 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
60
  if ( !is_numeric( $delay ) )
61
  update_option( 'wpmc_delay', 100 );
62
 
 
 
 
 
 
 
 
 
63
  if ( !$this->is_registered() && get_option( 'wpmc_method', 'media' ) == 'files' ) {
64
- _e( "<div class='error'><p>The Pro version is required to scan files. You can <a target='_blank' href='http://meowapps.com/plugin/media-cleaner'>get a serial for the Pro version here</a>.</p></div>", 'media-cleaner' );
 
 
65
  }
66
  }
67
 
@@ -77,46 +86,46 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
77
 
78
  // SUBMENU > Settings > Settings (Scanning)
79
  add_settings_section( 'wpmc_settings', null, null, 'wpmc_settings-menu' );
80
- add_settings_field( 'wpmc_method', "Method",
81
  array( $this, 'admin_method_callback' ),
82
  'wpmc_settings-menu', 'wpmc_settings' );
83
- add_settings_field( 'wpmc_content', "Content",
84
  array( $this, 'admin_content_callback' ),
85
  'wpmc_settings-menu', 'wpmc_settings' );
86
- add_settings_field( 'wpmc_media_library', "Media Library",
87
  array( $this, 'admin_media_library_callback' ),
88
  'wpmc_settings-menu', 'wpmc_settings' );
89
- add_settings_field( 'wpmc_live_content', "Live Content<br />(Pro)",
90
  array( $this, 'admin_live_content_callback' ),
91
  'wpmc_settings-menu', 'wpmc_settings' );
92
- // add_settings_field( 'wpmc_posts', "Posts",
93
  // array( $this, 'admin_posts_callback' ),
94
  // 'wpmc_settings-menu', 'wpmc_settings' );
95
- // add_settings_field( 'wpmc_postmeta', "Post Meta",
96
  // array( $this, 'admin_postmeta_callback' ),
97
  // 'wpmc_settings-menu', 'wpmc_settings' );
98
- // add_settings_field( 'wpmc_widgets', "Widgets",
99
  // array( $this, 'admin_widgets_callback' ),
100
  // 'wpmc_settings-menu', 'wpmc_settings' );
101
- // add_settings_field( 'wpmc_shortcode', "Shortcodes<br />(Pro)",
102
  // array( $this, 'admin_shortcode_callback' ),
103
  // 'wpmc_settings-menu', 'wpmc_settings' );
104
- // add_settings_field( 'wpmc_background', "Background CSS<br />(Pro)",
105
  // array( $this, 'admin_background_callback' ),
106
  // 'wpmc_settings-menu', 'wpmc_settings' );
107
- add_settings_field( 'wpmc_debuglogs', "Logs",
108
  array( $this, 'admin_debuglogs_callback' ),
109
- 'wpmc_settings-menu', 'wpmc_settings', array( "Enable" ) );
110
 
111
  // SUBMENU > Settings > Filters
112
  add_settings_section( 'wpmc_filters_settings', null, null, 'wpmc_filters_settings-menu' );
113
- add_settings_field( 'wpmc_thumbnails_only', "Thumbnails Only",
114
  array( $this, 'admin_thumbnails_only_callback' ),
115
  'wpmc_filters_settings-menu', 'wpmc_filters_settings' );
116
 
117
  add_settings_field(
118
  'wpmc_dirs_filter',
119
- 'Directories Filter',
120
  array( $this, 'admin_dirs_filter_callback' ),
121
  'wpmc_filters_settings-menu',
122
  'wpmc_filters_settings'
@@ -124,7 +133,7 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
124
 
125
  add_settings_field(
126
  'wpmc_files_filter',
127
- 'Files Filter',
128
  array( $this, 'admin_files_filter_callback' ),
129
  'wpmc_filters_settings-menu',
130
  'wpmc_filters_settings'
@@ -132,31 +141,31 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
132
 
133
  // SUBMENU > Settings > UI
134
  add_settings_section( 'wpmc_ui_settings', null, null, 'wpmc_ui_settings-menu' );
135
- add_settings_field( 'wpmc_hide_thumbnails', "Thumbnails",
136
  array( $this, 'admin_hide_thumbnails_callback' ),
137
  'wpmc_ui_settings-menu', 'wpmc_ui_settings' );
138
- add_settings_field( 'wpmc_hide_warning', "Warning Message",
139
  array( $this, 'admin_hide_warning_callback' ),
140
  'wpmc_ui_settings-menu', 'wpmc_ui_settings' );
141
- add_settings_field( 'wpmc_results_per_page', "Results Per Page",
142
  array( $this, 'admin_results_per_page' ),
143
  'wpmc_ui_settings-menu', 'wpmc_ui_settings' );
144
 
145
  // SUBMENU > Settings > Advanced
146
  add_settings_section( 'wpmc_advanced_settings', null, null, 'wpmc_advanced_settings-menu' );
147
- add_settings_field( 'wpmc_medias_buffer', "Medias Buffer",
148
  array( $this, 'admin_medias_buffer_callback' ),
149
  'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
150
- add_settings_field( 'wpmc_posts_buffer', "Posts Buffer",
151
  array( $this, 'admin_posts_buffer_callback' ),
152
  'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
153
- add_settings_field( 'wpmc_analysis_buffer', "Analysis Buffer",
154
  array( $this, 'admin_analysis_buffer_callback' ),
155
  'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
156
- add_settings_field( 'wpmc_delay', "Delay (in ms)",
157
  array( $this, 'admin_delay_callback' ),
158
  'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
159
- add_settings_field( 'wpmc_shortcodes_disabled', "Shortcodes",
160
  array( $this, 'admin_shortcodes_disabled_callback' ),
161
  'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
162
 
@@ -185,44 +194,45 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
185
  function admin_medias_buffer_callback( $args ) {
186
  $value = get_option( 'wpmc_medias_buffer', 100 );
187
  $html = '<input type="number" style="width: 100%;" id="wpmc_medias_buffer" name="wpmc_medias_buffer" value="' . $value . '" />';
188
- $html .= '<br /><span class="description">The number of media entries to read at a time. This is fast, so the value should be between 50 and 1000.</label>';
189
  echo $html;
190
  }
191
 
192
  function admin_posts_buffer_callback( $args ) {
193
  $value = get_option( 'wpmc_posts_buffer', 5 );
194
  $html = '<input type="number" style="width: 100%;" id="wpmc_posts_buffer" name="wpmc_posts_buffer" value="' . $value . '" />';
195
- $html .= '<br /><span class="description">The number of posts (and any other post types) to analyze at a time. This is the most intense part of the process. Recommended value is between 1 (slow server) and 20 (excellent server).</label>';
196
  echo $html;
197
  }
198
 
199
  function admin_analysis_buffer_callback( $args ) {
200
  $value = get_option( 'wpmc_analysis_buffer', 100 );
201
  $html = '<input type="number" style="width: 100%;" id="wpmc_analysis_buffer" name="wpmc_analysis_buffer" value="' . $value . '" />';
202
- $html .= '<br /><span class="description">The number of media entries or files to analyze at a time. This is the main part of the process, but is is much faster than analyzing each post. Recommended value is between 20 (slow server) and 1000 (excellent server).</label>';
203
  echo $html;
204
  }
205
 
206
  function admin_delay_callback( $args ) {
207
  $value = get_option( 'wpmc_delay', 100 );
208
  $html = '<input type="number" style="width: 100%;" id="wpmc_delay" name="wpmc_delay" value="' . $value . '" />';
209
- $html .= '<br /><span class="description">Time to wait between each request (in milliseconds). The overall process is intensive so this gives the chance to your server to chill out a bit. A very good server doesn\'t need it, but a slow/shared hosting might even reject requests if they are too fast and frequent. Recommended value is actually 0, 100 for safety, 2000 or 5000 if your hosting is kind of cheap.</label>';
210
  echo $html;
211
  }
212
 
213
  function admin_settings() {
214
  ?>
215
- <div class="wrap">
216
  <?php
217
  echo $this->display_title( "Media Cleaner" );
218
  ?>
219
  <div class="meow-section meow-group">
220
  <div class="meow-box meow-col meow-span_2_of_2">
221
- <h3>How to use</h3>
222
  <div class="inside">
223
- <?php echo _e( "You can choose two kind of methods. Usually, users like to analyze their Media Library for images which are not in used (Media Library Method + Content Check), and then, their Filesystem for images which aren't registered in the Media Library (Filesystem Method + Media Library Check). Check the <a target=\"_blank\" href=\"https://meowapps.com/media-cleaner-tutorial/\">tutorial</a> for more information.", 'media-cleaner' ); ?>
224
  <p class="submit">
225
  <a class="button button-primary" href="upload.php?page=media-cleaner"><?php echo _e( "Access Media Cleaner Dashboard", 'media-cleaner' ); ?></a>
 
226
  </p>
227
  </div>
228
  </div>
@@ -233,7 +243,7 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
233
  <div class="meow-col meow-span_1_of_2">
234
 
235
  <div class="meow-box">
236
- <h3>Scanning</h3>
237
  <div class="inside">
238
  <form method="post" action="options.php">
239
  <?php settings_fields( 'wpmc_settings' ); ?>
@@ -244,7 +254,7 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
244
  </div>
245
 
246
  <div class="meow-box">
247
- <h3>Filters</h3>
248
  <div class="inside">
249
  <form method="post" action="options.php">
250
  <?php settings_fields( 'wpmc_filters_settings' ); ?>
@@ -261,7 +271,7 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
261
  <?php $this->display_serialkey_box( "https://meowapps.com/plugin/media-cleaner/" ); ?>
262
 
263
  <div class="meow-box">
264
- <h3>UI</h3>
265
  <div class="inside">
266
  <form method="post" action="options.php">
267
  <?php settings_fields( 'wpmc_ui_settings' ); ?>
@@ -272,7 +282,7 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
272
  </div>
273
 
274
  <div class="meow-box">
275
- <h3>Advanced</h3>
276
  <div class="inside">
277
  <form method="post" action="options.php">
278
  <?php settings_fields( 'wpmc_advanced_settings' ); ?>
@@ -327,33 +337,12 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
327
  function admin_method_callback( $args ) {
328
  $value = get_option( 'wpmc_method', 'media' );
329
  $html = '<select id="wpmc_method" name="wpmc_method">
330
- <option ' . selected( 'media', $value, false ) . 'value="media">Media Library</option>
331
- <option ' . disabled( $this->is_registered(), false, false ) . ' ' . selected( 'files', $value, false ) . 'value="files">Filesystem (Pro)</option>
332
- </select><small><br />' . __( 'Check the <a target="_blank" href="https://meowapps.com/media-cleaner-tutorial/">tutorial</a> for more information.', 'media-cleaner' ) . '</small>';
333
-
334
- // TODO: This is temporary
335
- // $html .= '<br /><br /><small><b style="color: red;">Notice: </b><b> Those settings will be simplified soon. Have a look <a href="https://trello.com/c/qrCuITg8/55-cleaner-simplification-of-the-settings" target="_blank">here</a> and let me know in the comments if you like the idea or not.</b></small>';
336
-
337
  echo $html;
338
  }
339
 
340
-
341
- // function admin_shortcode_callback( $args ) {
342
- // $value = get_option( 'wpmc_shortcode', null );
343
- // $html = '<input ' . disabled( $this->is_registered(), false, false ) . ' type="checkbox" id="wpmc_shortcode" name="wpmc_shortcode" value="1" ' .
344
- // checked( 1, get_option( 'wpmc_shortcode' ), false ) . '/>';
345
- // $html .= '<label>Resolve</label><br /><small>The shortcodes you are using in your <b>posts</b> and/or <b>widgets</b> (depending on your options) will be resolved and analyzed. You don\'t need to have this option enabled for the WP Gallery (as it is covered by the Galleries option).</small>';
346
- // echo $html;
347
- // }
348
-
349
- // function admin_background_callback( $args ) {
350
- // $value = get_option( 'wpmc_background', null );
351
- // $html = '<input ' . disabled( $this->is_registered(), false, false ) . ' type="checkbox" id="wpmc_background" name="wpmc_background" value="1" ' .
352
- // checked( 1, get_option( 'wpmc_background' ), false ) . '/>';
353
- // $html .= '<label>Analyze</label><br /><small>When parsing HTML, the CSS inline background will also be analyzed. A few page builders are using this.</small>';
354
- // echo $html;
355
- // }
356
-
357
  function admin_debuglogs_callback( $args ) {
358
  global $wpmc;
359
  $debuglogs = get_option( 'wpmc_debuglogs' );
@@ -371,7 +360,11 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
371
  }
372
  }
373
  if ( file_exists( plugin_dir_path( __FILE__ ) . '/media-cleaner.log' ) ) {
374
- $html .= sprintf( __( '<br />The <a target="_blank" href="%smedia-cleaner.log">log file</a> is available. You can also <a href="?page=wpmc_settings-menu&clearlogs=true">clear</a> it.', 'media-cleaner' ), plugin_dir_url( __FILE__ ) );
 
 
 
 
375
  }
376
  $html .= '</small>';
377
  echo $html;
@@ -382,7 +375,7 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
382
  $html = '<input type="checkbox" id="wpmc_media_library" name="wpmc_media_library" value="1" ' .
383
  disabled( get_option( 'wpmc_method', 'media' ) == 'files', false, false ) . ' ' .
384
  checked( 1, $value, false ) . '/>';
385
- $html .= '<label>Check</label><br /><small>Checks if the file is linked to a media. <i>Only matters to the Filesystem Method.</i></small>';
386
  echo $html;
387
  }
388
 
@@ -390,16 +383,16 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
390
  $value = get_option( 'wpmc_content', true );
391
  $html = '<input type="checkbox" id="wpmc_content" name="wpmc_content" value="1" ' .
392
  checked( 1, $value, false ) . '/>';
393
- $html .= '<label>Check</label><br /><small>Check if the media/file is used in the content, such as Posts, Pages (and other Post Types), Metadata, Widgets, etc.</small>';
394
  echo $html;
395
  }
396
 
397
  function admin_live_content_callback( $args ) {
398
  $value = get_option( 'wpmc_live_content', false );
399
- $html = '<input ' . disabled( $this->is_registered(), false, false ) .
400
  ' type="checkbox" id="wpmc_content" name="wpmc_live_content" value="1" ' .
401
  checked( 1, $value, false ) . '/>';
402
- $html .= '<label>Check</label><br /><small>The live version of the website will be also analyzed (as if a visitor was loading it). <i>This will increase the accuracy of the results.</i></small>';
403
  echo $html;
404
  }
405
 
@@ -407,7 +400,7 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
407
  $value = get_option( 'wpmc_shortcodes_disabled', null );
408
  $html = '<input type="checkbox" id="wpmc_shortcodes_disabled" name="wpmc_shortcodes_disabled" value="1" ' .
409
  checked( 1, get_option( 'wpmc_shortcodes_disabled' ), false ) . '/>';
410
- $html .= '<label>Disable Analysis</label><br /><small>Resolving shortcodes increase accuracy, but makes the process slower and takes more memory.</small>';
411
  echo $html;
412
  }
413
 
@@ -415,7 +408,7 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
415
  $value = get_option( 'wpmc_hide_thumbnails', null );
416
  $html = '<input type="checkbox" id="wpmc_hide_thumbnails" name="wpmc_hide_thumbnails" value="1" ' .
417
  checked( 1, get_option( 'wpmc_hide_thumbnails' ), false ) . '/>';
418
- $html .= '<label>Hide</label><br /><small>If you prefer not to see the thumbnails.</small>';
419
  echo $html;
420
  }
421
 
@@ -423,7 +416,7 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
423
  $value = get_option( 'wpmc_hide_warning', null );
424
  $html = '<input type="checkbox" id="wpmc_hide_warning" name="wpmc_hide_warning" value="1" ' .
425
  checked( 1, get_option( 'wpmc_hide_warning' ), false ) . '/>';
426
- $html .= '<label>Hide</label><br /><small>Have you read it twice? If yes, hide it :)</small>';
427
  echo $html;
428
  }
429
 
@@ -440,7 +433,7 @@ HTML;
440
  $html = '<input type="checkbox" id="wpmc_thumbnails_only" name="wpmc_thumbnails_only" value="1" ' .
441
  disabled( get_option( 'wpmc_method', 'media' ) == 'files', false, false ) . ' ' .
442
  checked( 1, get_option( 'wpmc_thumbnails_only' ), false ) . '/>';
443
- $html .= '<label>Enable</label><br /><small>Restrict the filesystem scan to thumbnails (files containing the resolution). If none of the checks above are selected, you will get the list of all the thumbnails and be able to remove them.</small>';
444
  echo $html;
445
  }
446
 
45
  }
46
 
47
  function admin_notices() {
 
48
  $mediasBuffer = get_option( 'wpmc_medias_buffer', null );
49
  $postsBuffer = get_option( 'wpmc_posts_buffer', null );
50
  $analysisBuffer = get_option( 'wpmc_analysis_buffer', null );
59
  if ( !is_numeric( $delay ) )
60
  update_option( 'wpmc_delay', 100 );
61
 
62
+ $reset = isset ( $_GET[ 'reset' ] ) ? $_GET[ 'reset' ] : 0;
63
+ if ( $reset ) {
64
+ wpmc_reset();
65
+ echo "<div class='notice notice-error'><p>";
66
+ _e( "The Media Cleaner's database has been deleted. It will be re-created automatically next time you visit the Media Cleaner Dashboard.", 'media-cleaner' );
67
+ echo "</p></div>";
68
+ }
69
+
70
  if ( !$this->is_registered() && get_option( 'wpmc_method', 'media' ) == 'files' ) {
71
+ echo "<div class='notice notice-error'><p>";
72
+ _e( "The Pro version is required to scan files. You can <a target='_blank' href='http://meowapps.com/plugin/media-cleaner'>get a serial for the Pro version here</a>.", 'media-cleaner' );
73
+ echo "</p></div>";
74
  }
75
  }
76
 
86
 
87
  // SUBMENU > Settings > Settings (Scanning)
88
  add_settings_section( 'wpmc_settings', null, null, 'wpmc_settings-menu' );
89
+ add_settings_field( 'wpmc_method', __( 'Method', 'media-cleaner' ),
90
  array( $this, 'admin_method_callback' ),
91
  'wpmc_settings-menu', 'wpmc_settings' );
92
+ add_settings_field( 'wpmc_content', __( 'Content', 'media-cleaner' ),
93
  array( $this, 'admin_content_callback' ),
94
  'wpmc_settings-menu', 'wpmc_settings' );
95
+ add_settings_field( 'wpmc_media_library', __( 'Media Library', 'media-cleaner' ),
96
  array( $this, 'admin_media_library_callback' ),
97
  'wpmc_settings-menu', 'wpmc_settings' );
98
+ add_settings_field( 'wpmc_live_content', __( 'Live Content<br />(Pro)', 'media-cleaner' ),
99
  array( $this, 'admin_live_content_callback' ),
100
  'wpmc_settings-menu', 'wpmc_settings' );
101
+ // add_settings_field( 'wpmc_posts', __( 'Posts', 'media-cleaner' ),
102
  // array( $this, 'admin_posts_callback' ),
103
  // 'wpmc_settings-menu', 'wpmc_settings' );
104
+ // add_settings_field( 'wpmc_postmeta', __( 'Post Meta', 'media-cleaner' ),
105
  // array( $this, 'admin_postmeta_callback' ),
106
  // 'wpmc_settings-menu', 'wpmc_settings' );
107
+ // add_settings_field( 'wpmc_widgets', __( 'Widgets', 'media-cleaner' ),
108
  // array( $this, 'admin_widgets_callback' ),
109
  // 'wpmc_settings-menu', 'wpmc_settings' );
110
+ // add_settings_field( 'wpmc_shortcode', __( 'Shortcodes<br />(Pro)', 'media-cleaner' ),
111
  // array( $this, 'admin_shortcode_callback' ),
112
  // 'wpmc_settings-menu', 'wpmc_settings' );
113
+ // add_settings_field( 'wpmc_background', __( 'Background CSS<br />(Pro), 'media-cleaner' ),
114
  // array( $this, 'admin_background_callback' ),
115
  // 'wpmc_settings-menu', 'wpmc_settings' );
116
+ add_settings_field( 'wpmc_debuglogs', __( 'Logs', 'media-cleaner' ),
117
  array( $this, 'admin_debuglogs_callback' ),
118
+ 'wpmc_settings-menu', 'wpmc_settings', array( __( 'Enable', 'media-cleaner' ) ) );
119
 
120
  // SUBMENU > Settings > Filters
121
  add_settings_section( 'wpmc_filters_settings', null, null, 'wpmc_filters_settings-menu' );
122
+ add_settings_field( 'wpmc_thumbnails_only', __( 'Thumbnails Only', 'media-cleaner' ),
123
  array( $this, 'admin_thumbnails_only_callback' ),
124
  'wpmc_filters_settings-menu', 'wpmc_filters_settings' );
125
 
126
  add_settings_field(
127
  'wpmc_dirs_filter',
128
+ __( 'Directories Filter', 'media-cleaner' ),
129
  array( $this, 'admin_dirs_filter_callback' ),
130
  'wpmc_filters_settings-menu',
131
  'wpmc_filters_settings'
133
 
134
  add_settings_field(
135
  'wpmc_files_filter',
136
+ __( 'Files Filter', 'media-cleaner' ),
137
  array( $this, 'admin_files_filter_callback' ),
138
  'wpmc_filters_settings-menu',
139
  'wpmc_filters_settings'
141
 
142
  // SUBMENU > Settings > UI
143
  add_settings_section( 'wpmc_ui_settings', null, null, 'wpmc_ui_settings-menu' );
144
+ add_settings_field( 'wpmc_hide_thumbnails', __( 'Thumbnails', 'media-cleaner' ),
145
  array( $this, 'admin_hide_thumbnails_callback' ),
146
  'wpmc_ui_settings-menu', 'wpmc_ui_settings' );
147
+ add_settings_field( 'wpmc_hide_warning', __( 'Warning Message', 'media-cleaner' ),
148
  array( $this, 'admin_hide_warning_callback' ),
149
  'wpmc_ui_settings-menu', 'wpmc_ui_settings' );
150
+ add_settings_field( 'wpmc_results_per_page', __( 'Results Per Page', 'media-cleaner' ),
151
  array( $this, 'admin_results_per_page' ),
152
  'wpmc_ui_settings-menu', 'wpmc_ui_settings' );
153
 
154
  // SUBMENU > Settings > Advanced
155
  add_settings_section( 'wpmc_advanced_settings', null, null, 'wpmc_advanced_settings-menu' );
156
+ add_settings_field( 'wpmc_medias_buffer', __( 'Medias Buffer', 'media-cleaner' ),
157
  array( $this, 'admin_medias_buffer_callback' ),
158
  'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
159
+ add_settings_field( 'wpmc_posts_buffer', __( 'Posts Buffer', 'media-cleaner' ),
160
  array( $this, 'admin_posts_buffer_callback' ),
161
  'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
162
+ add_settings_field( 'wpmc_analysis_buffer', __( 'Analysis Buffer', 'media-cleaner' ),
163
  array( $this, 'admin_analysis_buffer_callback' ),
164
  'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
165
+ add_settings_field( 'wpmc_delay', __( 'Delay (in ms)', 'media-cleaner' ),
166
  array( $this, 'admin_delay_callback' ),
167
  'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
168
+ add_settings_field( 'wpmc_shortcodes_disabled', __( 'Shortcodes', 'media-cleaner' ),
169
  array( $this, 'admin_shortcodes_disabled_callback' ),
170
  'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
171
 
194
  function admin_medias_buffer_callback( $args ) {
195
  $value = get_option( 'wpmc_medias_buffer', 100 );
196
  $html = '<input type="number" style="width: 100%;" id="wpmc_medias_buffer" name="wpmc_medias_buffer" value="' . $value . '" />';
197
+ $html .= '<br /><span class="description">' . __( 'The number of media entries to read at a time. This is fast, so the value should be between 50 and 1000.', 'media-cleaner' ) . '</span>';
198
  echo $html;
199
  }
200
 
201
  function admin_posts_buffer_callback( $args ) {
202
  $value = get_option( 'wpmc_posts_buffer', 5 );
203
  $html = '<input type="number" style="width: 100%;" id="wpmc_posts_buffer" name="wpmc_posts_buffer" value="' . $value . '" />';
204
+ $html .= '<br /><span class="description">' . __( 'The number of posts (and any other post types) to analyze at a time. This is the most intense part of the process. Recommended value is between 1 (slow server) and 20 (excellent server).', 'media-cleaner' ) . '</span>';
205
  echo $html;
206
  }
207
 
208
  function admin_analysis_buffer_callback( $args ) {
209
  $value = get_option( 'wpmc_analysis_buffer', 100 );
210
  $html = '<input type="number" style="width: 100%;" id="wpmc_analysis_buffer" name="wpmc_analysis_buffer" value="' . $value . '" />';
211
+ $html .= '<br /><span class="description">' . __( 'The number of media entries or files to analyze at a time. This is the main part of the process, but is is much faster than analyzing each post. Recommended value is between 20 (slow server) and 1000 (excellent server).', 'media-cleaner' ) . '</span>';
212
  echo $html;
213
  }
214
 
215
  function admin_delay_callback( $args ) {
216
  $value = get_option( 'wpmc_delay', 100 );
217
  $html = '<input type="number" style="width: 100%;" id="wpmc_delay" name="wpmc_delay" value="' . $value . '" />';
218
+ $html .= '<br /><span class="description">' . __( 'Time to wait between each request (in milliseconds). The overall process is intensive so this gives the chance to your server to chill out a bit. A very good server doesn\'t need it, but a slow/shared hosting might even reject requests if they are too fast and frequent. Recommended value is actually 0, 100 for safety, 2000 or 5000 if your hosting is kind of cheap.', 'media-cleaner' ) . '</span>';
219
  echo $html;
220
  }
221
 
222
  function admin_settings() {
223
  ?>
224
+ <div class="wrap wrap-media-cleaner">
225
  <?php
226
  echo $this->display_title( "Media Cleaner" );
227
  ?>
228
  <div class="meow-section meow-group">
229
  <div class="meow-box meow-col meow-span_2_of_2">
230
+ <h3><?php _e('How to use', 'media-cleaner' ); ?></h3>
231
  <div class="inside">
232
+ <?php _e( "You can choose two kind of methods. Usually, users like to analyze their Media Library for images which are not in used (Media Library Method + Content Check), and then, their Filesystem for images which aren't registered in the Media Library (Filesystem Method + Media Library Check). Check the <a target=\"_blank\" href=\"https://meowapps.com/media-cleaner-tutorial/\">tutorial</a> for more information.", 'media-cleaner' ); ?>
233
  <p class="submit">
234
  <a class="button button-primary" href="upload.php?page=media-cleaner"><?php echo _e( "Access Media Cleaner Dashboard", 'media-cleaner' ); ?></a>
235
+ <a id='wpmc_reset' href='?page=wpmc_settings-menu&reset=1' class='button button-red exclusive' style='margin-left: 5px;'><span style="top: 4px; position: relative; left: -5px;" class="dashicons dashicons-sos"></span><?php _e('Delete Cleaner DB', 'media-cleaner'); ?></a>
236
  </p>
237
  </div>
238
  </div>
243
  <div class="meow-col meow-span_1_of_2">
244
 
245
  <div class="meow-box">
246
+ <h3><?php _e('Scanning', 'media-cleaner' ); ?></h3>
247
  <div class="inside">
248
  <form method="post" action="options.php">
249
  <?php settings_fields( 'wpmc_settings' ); ?>
254
  </div>
255
 
256
  <div class="meow-box">
257
+ <h3><?php _e('Filters', 'media-cleaner' ); ?></h3>
258
  <div class="inside">
259
  <form method="post" action="options.php">
260
  <?php settings_fields( 'wpmc_filters_settings' ); ?>
271
  <?php $this->display_serialkey_box( "https://meowapps.com/plugin/media-cleaner/" ); ?>
272
 
273
  <div class="meow-box">
274
+ <h3><?php _e('UI', 'media-cleaner' ); ?></h3>
275
  <div class="inside">
276
  <form method="post" action="options.php">
277
  <?php settings_fields( 'wpmc_ui_settings' ); ?>
282
  </div>
283
 
284
  <div class="meow-box">
285
+ <h3><?php _e('Advanced', 'media-cleaner' ); ?></h3>
286
  <div class="inside">
287
  <form method="post" action="options.php">
288
  <?php settings_fields( 'wpmc_advanced_settings' ); ?>
337
  function admin_method_callback( $args ) {
338
  $value = get_option( 'wpmc_method', 'media' );
339
  $html = '<select id="wpmc_method" name="wpmc_method">
340
+ <option ' . selected( 'media', $value, false ) . 'value="media">' . __( 'Media Library', 'media-cleaner' ) .'</option>
341
+ <option ' . disabled( $this->is_registered(), false, false ) . ' ' . selected( 'files', $value, false ) . 'value="files">' . __( 'Filesystem (Pro)', 'media-cleaner' ) .'</option>
342
+ </select><br /><small>' . __( 'Check the <a target="_blank" href="https://meowapps.com/media-cleaner-tutorial/">tutorial</a> for more information.', 'media-cleaner' ) . '</small>';
 
 
 
 
343
  echo $html;
344
  }
345
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
  function admin_debuglogs_callback( $args ) {
347
  global $wpmc;
348
  $debuglogs = get_option( 'wpmc_debuglogs' );
360
  }
361
  }
362
  if ( file_exists( plugin_dir_path( __FILE__ ) . '/media-cleaner.log' ) ) {
363
+ $html .= sprintf(
364
+ // translators: %s is a plugin directory url
365
+ __( '<br />The <a target="_blank" href="%smedia-cleaner.log">log file</a> is available. You can also <a href="?page=wpmc_settings-menu&clearlogs=true">clear</a> it.', 'media-cleaner' ),
366
+ plugin_dir_url( __FILE__ )
367
+ );
368
  }
369
  $html .= '</small>';
370
  echo $html;
375
  $html = '<input type="checkbox" id="wpmc_media_library" name="wpmc_media_library" value="1" ' .
376
  disabled( get_option( 'wpmc_method', 'media' ) == 'files', false, false ) . ' ' .
377
  checked( 1, $value, false ) . '/>';
378
+ $html .= '<label>' . __( 'Check', 'media-cleaner' ) . '</label><br /><small>' . __( 'Checks if the file is linked to a media. <i>Only matters to the Filesystem Method.</i>', 'media-cleaner' ) . '</small>';
379
  echo $html;
380
  }
381
 
383
  $value = get_option( 'wpmc_content', true );
384
  $html = '<input type="checkbox" id="wpmc_content" name="wpmc_content" value="1" ' .
385
  checked( 1, $value, false ) . '/>';
386
+ $html .= '<label>' . __( 'Check', 'media-cleaner' ) . '</label><br /><small>' . __( 'Check if the media/file is used in the content, such as Posts, Pages (and other Post Types), Metadata, Widgets, etc.', 'media-cleaner' ) . '</small>';
387
  echo $html;
388
  }
389
 
390
  function admin_live_content_callback( $args ) {
391
  $value = get_option( 'wpmc_live_content', false );
392
+ $html = '<input ' . disabled( $this->is_registered(), false, false ) .
393
  ' type="checkbox" id="wpmc_content" name="wpmc_live_content" value="1" ' .
394
  checked( 1, $value, false ) . '/>';
395
+ $html .= '<label>' . __( 'Check', 'media-cleaner' ) . '</label><br /><small>' . __( 'The live version of the website will be also analyzed (as if a visitor was loading it). <i>This will increase the accuracy of the results.</i>', 'media-cleaner' ) . '</small>';
396
  echo $html;
397
  }
398
 
400
  $value = get_option( 'wpmc_shortcodes_disabled', null );
401
  $html = '<input type="checkbox" id="wpmc_shortcodes_disabled" name="wpmc_shortcodes_disabled" value="1" ' .
402
  checked( 1, get_option( 'wpmc_shortcodes_disabled' ), false ) . '/>';
403
+ $html .= '<label>' . __( 'Disable Analysis', 'media-cleaner' ) . '</label><br /><small>' . __( 'Resolving shortcodes increase accuracy, but makes the process slower and takes more memory.', 'media-cleaner' ) . '</small>';
404
  echo $html;
405
  }
406
 
408
  $value = get_option( 'wpmc_hide_thumbnails', null );
409
  $html = '<input type="checkbox" id="wpmc_hide_thumbnails" name="wpmc_hide_thumbnails" value="1" ' .
410
  checked( 1, get_option( 'wpmc_hide_thumbnails' ), false ) . '/>';
411
+ $html .= '<label>' . __( 'Hide', 'media-cleaner' ) . '</label><br /><small>' . __( 'If you prefer not to see the thumbnails.', 'media-cleaner' ) . '</small>';
412
  echo $html;
413
  }
414
 
416
  $value = get_option( 'wpmc_hide_warning', null );
417
  $html = '<input type="checkbox" id="wpmc_hide_warning" name="wpmc_hide_warning" value="1" ' .
418
  checked( 1, get_option( 'wpmc_hide_warning' ), false ) . '/>';
419
+ $html .= '<label>' . __( 'Hide', 'media-cleaner' ) . '</label><br /><small>' . __( 'Have you read it twice? If yes, hide it :)', 'media-cleaner' ) . '</small>';
420
  echo $html;
421
  }
422
 
433
  $html = '<input type="checkbox" id="wpmc_thumbnails_only" name="wpmc_thumbnails_only" value="1" ' .
434
  disabled( get_option( 'wpmc_method', 'media' ) == 'files', false, false ) . ' ' .
435
  checked( 1, get_option( 'wpmc_thumbnails_only' ), false ) . '/>';
436
+ $html .= '<label>' . __( 'Enable', 'media-cleaner' ) . '</label><br /><small>' . __( 'Restrict the filesystem scan to thumbnails (files containing the resolution). If none of the checks above are selected, you will get the list of all the thumbnails and be able to remove them.', 'media-cleaner' ) . '</small>';
437
  echo $html;
438
  }
439
 
api.php CHANGED
@@ -6,9 +6,9 @@ class Meow_WPMC_API {
6
  $this->core = $core;
7
  $this->engine = $engine;
8
  $this->admin = $admin;
9
- add_action( 'wp_ajax_wpmc_prepare_do', array( $this, 'wp_ajax_wpmc_prepare_do' ) );
10
- add_action( 'wp_ajax_wpmc_scan', array( $this, 'wp_ajax_wpmc_scan' ) );
11
- add_action( 'wp_ajax_wpmc_scan_do', array( $this, 'wp_ajax_wpmc_scan_do' ) );
12
  add_action( 'wp_ajax_wpmc_get_all_issues', array( $this, 'wp_ajax_wpmc_get_all_issues' ) );
13
  add_action( 'wp_ajax_wpmc_get_all_deleted', array( $this, 'wp_ajax_wpmc_get_all_deleted' ) );
14
  add_action( 'wp_ajax_wpmc_delete_do', array( $this, 'wp_ajax_wpmc_delete_do' ) );
@@ -21,44 +21,60 @@ class Meow_WPMC_API {
21
  * ASYNCHRONOUS AJAX FUNCTIONS
22
  ******************************************************************************/
23
 
24
- function wp_ajax_wpmc_prepare_do() {
 
25
  $limit = isset( $_POST['limit'] ) ? $_POST['limit'] : 0;
 
26
  $limitsize = get_option( 'wpmc_posts_buffer', 5 );
27
- $finished = $this->engine->parse( $limit, $limitsize, $message ); // $message is set by run()
28
- echo json_encode(
29
- array(
30
- 'success' => true,
31
- 'finished' => $finished,
32
- 'limit' => $limit + $limitsize,
33
- 'message' => $message )
 
 
 
 
 
 
 
 
 
 
34
  );
 
35
  die();
36
  }
37
 
38
- function wp_ajax_wpmc_scan() {
 
39
  global $wpdb;
40
-
41
- $method = get_option( 'wpmc_method', 'media' );
42
- if ( !$this->admin->is_registered() )
43
- $method = 'media';
44
 
45
  if ( $method == 'files' ) {
46
  $output = null;
47
  $path = isset( $_POST['path'] ) ? $_POST['path'] : null;
48
  $files = $this->engine->get_files( $path );
49
-
50
  if ( $files === null ) {
51
  $output = array(
52
- 'results' => array(),
53
- 'success' => true,
54
- 'message' => __( "No files for this path ($path).", 'media-cleaner' )
 
 
55
  );
56
  }
57
  else {
58
- $output = array(
59
- 'results' => $files,
60
- 'success' => true,
61
- 'message' => __( "Files retrieved.", 'media-cleaner' )
 
 
 
 
62
  );
63
  }
64
  echo json_encode( $output );
@@ -70,14 +86,17 @@ class Meow_WPMC_API {
70
  $limitsize = get_option( 'wpmc_medias_buffer', 100 );
71
  $results = $this->engine->get_media_entries( $limit, $limitsize );
72
  $finished = count( $results ) < $limitsize;
73
- echo json_encode(
74
- array(
75
- 'results' => $results,
76
- 'success' => true,
77
- 'finished' => $finished,
78
- 'limit' => $limit + $limitsize,
79
- 'message' => __( "Medias retrieved.", 'media-cleaner' ) )
 
 
80
  );
 
81
  die();
82
  }
83
 
@@ -86,45 +105,53 @@ class Meow_WPMC_API {
86
  die();
87
  }
88
 
89
- function wp_ajax_wpmc_scan_do() {
90
- // For debug, to pretend there is a timeout
91
- //$this->core->deepsleep(10);
92
- //header("HTTP/1.0 408 Request Timeout");
93
- //exit;
94
 
95
  ob_start();
96
- $type = $_POST['type'];
97
  $data = $_POST['data'];
 
 
98
  $this->core->timeout_check_start( count( $data ) );
99
  $success = 0;
100
- if ( $type == 'file' ) {
101
  do_action( 'wpmc_check_file_init' ); // Build_CroppedFile_Cache() in pro core.php
102
  }
103
  foreach ( $data as $piece ) {
104
  $this->core->timeout_check();
105
- if ( $type == 'file' ) {
106
  $this->core->log( "Check File: {$piece}" );
107
-
108
  $result = ( $this->engine->check_file( $piece ) ? 1 : 0 );
109
-
110
  if ( $result )
111
  $success += $result;
112
  }
113
- else if ( $type == 'media' ) {
114
  $this->core->log( "Checking Media #{$piece}" );
115
  $result = ( $this->engine->check_media( $piece ) ? 1 : 0 );
116
- if ( $result )
117
  $success += $result;
 
118
  }
119
  $this->core->log();
120
  $this->core->timeout_check_additem();
121
  }
122
  ob_end_clean();
 
 
 
 
 
 
123
  echo json_encode(
124
  array(
125
  'success' => true,
126
- 'result' => array( 'type' => $type, 'data' => $data, 'success' => $success ),
127
- 'message' => __( "Items checked.", 'media-cleaner' )
 
 
128
  )
129
  );
130
  die();
@@ -135,10 +162,15 @@ class Meow_WPMC_API {
135
  $isTrash = ( isset( $_POST['isTrash'] ) && $_POST['isTrash'] == 1 ) ? true : false;
136
  $table_name = $wpdb->prefix . "mclean_scan";
137
  $q = "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = " . ( $isTrash ? 1 : 0 );
138
- if ( $search = ( isset( $_POST['s'] ) && $_POST['s'] ) ? sanitize_text_field( $_POST['s'] ) : '' )
 
 
 
 
139
  $q = $wpdb->prepare( $q . ' AND path LIKE %s', '%' . $wpdb->esc_like( $search ) . '%' );
 
 
140
  $ids = $wpdb->get_col( $q );
141
-
142
  echo json_encode(
143
  array(
144
  'results' => array( 'ids' => $ids ),
6
  $this->core = $core;
7
  $this->engine = $engine;
8
  $this->admin = $admin;
9
+ add_action( 'wp_ajax_wpmc_extract_references', array( $this, 'wp_ajax_wpmc_extract_references' ) );
10
+ add_action( 'wp_ajax_wpmc_retrieve_targets', array( $this, 'wp_ajax_wpmc_retrieve_targets' ) );
11
+ add_action( 'wp_ajax_wpmc_check_targets', array( $this, 'wp_ajax_wpmc_check_targets' ) );
12
  add_action( 'wp_ajax_wpmc_get_all_issues', array( $this, 'wp_ajax_wpmc_get_all_issues' ) );
13
  add_action( 'wp_ajax_wpmc_get_all_deleted', array( $this, 'wp_ajax_wpmc_get_all_deleted' ) );
14
  add_action( 'wp_ajax_wpmc_delete_do', array( $this, 'wp_ajax_wpmc_delete_do' ) );
21
  * ASYNCHRONOUS AJAX FUNCTIONS
22
  ******************************************************************************/
23
 
24
+ // Anayze the posts to extract the references.
25
+ function wp_ajax_wpmc_extract_references() {
26
  $limit = isset( $_POST['limit'] ) ? $_POST['limit'] : 0;
27
+ $source = isset( $_POST['source'] ) ? $_POST['source'] : null;
28
  $limitsize = get_option( 'wpmc_posts_buffer', 5 );
29
+
30
+ $finished = false;
31
+ if ( $source === 'content' )
32
+ $finished = $this->engine->extractRefsFromContent( $limit, $limitsize, $message ); // $message is set by run()
33
+ else if ( $source === 'media' )
34
+ $finished = $this->engine->extractRefsFromLibrary( $limit, $limitsize, $message ); // $message is set by run()
35
+ else {
36
+ error_log('Media Cleaner: No source was mentioned while calling the extract_references action.');
37
+ }
38
+
39
+ $output = array(
40
+ 'success' => true,
41
+ 'action' => 'extract_references',
42
+ 'source' => $source,
43
+ 'limit' => $limit + $limitsize,
44
+ 'finished' => $finished,
45
+ 'message' => $message,
46
  );
47
+ echo json_encode( $output );
48
  die();
49
  }
50
 
51
+ // Retrieve either the the Media IDs or the files which need to be scanned.
52
+ function wp_ajax_wpmc_retrieve_targets() {
53
  global $wpdb;
54
+ $method = $this->core->current_method;
 
 
 
55
 
56
  if ( $method == 'files' ) {
57
  $output = null;
58
  $path = isset( $_POST['path'] ) ? $_POST['path'] : null;
59
  $files = $this->engine->get_files( $path );
 
60
  if ( $files === null ) {
61
  $output = array(
62
+ 'success' => true,
63
+ 'action' => 'retrieve_targets',
64
+ 'method' => 'files',
65
+ 'message' => __( "No files for this path ($path).", 'media-cleaner' ),
66
+ 'results' => array(),
67
  );
68
  }
69
  else {
70
+ // translators: %d is a count of files
71
+ $message = sprintf( __( "Retrieved %d targets.", 'media-cleaner' ), count( $files ) );
72
+ $output = array(
73
+ 'success' => true,
74
+ 'action' => 'retrieve_targets',
75
+ 'method' => 'files',
76
+ 'message' => $message,
77
+ 'results' => $files,
78
  );
79
  }
80
  echo json_encode( $output );
86
  $limitsize = get_option( 'wpmc_medias_buffer', 100 );
87
  $results = $this->engine->get_media_entries( $limit, $limitsize );
88
  $finished = count( $results ) < $limitsize;
89
+ $message = sprintf( __( "Retrieved %d targets.", 'media-cleaner' ), count( $results ) );
90
+ $output = array(
91
+ 'success' => true,
92
+ 'action' => 'retrieve_targets',
93
+ 'method' => 'media',
94
+ 'limit' => $limit + $limitsize,
95
+ 'finished' => $finished,
96
+ 'message' => $message,
97
+ 'results' => $results,
98
  );
99
+ echo json_encode( $output );
100
  die();
101
  }
102
 
105
  die();
106
  }
107
 
108
+ // Actual scan (by giving a media ID or a file path)
109
+ function wp_ajax_wpmc_check_targets() {
110
+
111
+ // DEBUG: Simulate a timeout
112
+ // $this->core->deepsleep(10); header("HTTP/1.0 408 Request Timeout"); exit;
113
 
114
  ob_start();
 
115
  $data = $_POST['data'];
116
+ $method = $this->core->current_method;
117
+
118
  $this->core->timeout_check_start( count( $data ) );
119
  $success = 0;
120
+ if ( $method == 'files' ) {
121
  do_action( 'wpmc_check_file_init' ); // Build_CroppedFile_Cache() in pro core.php
122
  }
123
  foreach ( $data as $piece ) {
124
  $this->core->timeout_check();
125
+ if ( $method == 'files' ) {
126
  $this->core->log( "Check File: {$piece}" );
 
127
  $result = ( $this->engine->check_file( $piece ) ? 1 : 0 );
 
128
  if ( $result )
129
  $success += $result;
130
  }
131
+ else if ( $method == 'media' ) {
132
  $this->core->log( "Checking Media #{$piece}" );
133
  $result = ( $this->engine->check_media( $piece ) ? 1 : 0 );
134
+ if ( $result ) {
135
  $success += $result;
136
+ }
137
  }
138
  $this->core->log();
139
  $this->core->timeout_check_additem();
140
  }
141
  ob_end_clean();
142
+ $elapsed = $this->core->timeout_get_elapsed();
143
+ $message = sprintf(
144
+ // translators: %1$d is a number of targets, %2$d is a number of issues, %3$s is elapsed time in milliseconds
145
+ __( 'Checked %1$d targets and found %2$d issues in %3$s.', 'media-cleaner' ),
146
+ count( $data ), count( $data ) - $success, $elapsed
147
+ );
148
  echo json_encode(
149
  array(
150
  'success' => true,
151
+ 'action' => 'check_targets',
152
+ 'method' => $method,
153
+ 'message' => $message,
154
+ 'results' => $success,
155
  )
156
  );
157
  die();
162
  $isTrash = ( isset( $_POST['isTrash'] ) && $_POST['isTrash'] == 1 ) ? true : false;
163
  $table_name = $wpdb->prefix . "mclean_scan";
164
  $q = "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = " . ( $isTrash ? 1 : 0 );
165
+ if ( isset( $_POST['filter'] ) && !empty( $_POST['filter'] ) ) {
166
+ $filter = sanitize_text_field( $_POST['filter']['filter'] );
167
+ $search = sanitize_text_field( $_POST['filter']['search'] );
168
+ }
169
+ if ( !empty( $search ) )
170
  $q = $wpdb->prepare( $q . ' AND path LIKE %s', '%' . $wpdb->esc_like( $search ) . '%' );
171
+ if ( !empty( $filter ) )
172
+ $q = $wpdb->prepare( $q . ' AND issue = %s', $filter );
173
  $ids = $wpdb->get_col( $q );
 
174
  echo json_encode(
175
  array(
176
  'results' => array( 'ids' => $ids ),
common/admin.php CHANGED
@@ -52,18 +52,19 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
52
  }
53
  }
54
  }
55
-
56
  add_filter( 'edd_sl_api_request_verify_ssl', array( $this, 'request_verify_ssl' ), 10, 0 );
57
  }
58
 
59
  function wp_ajax_meow_perf_load() {
60
- return 'Did nothing but a blank request.';
61
  }
62
 
63
  function wp_ajax_meow_file_check() {
64
  $tmpfile = wp_tempnam();
65
  unlink( $tmpfile );
66
- return "Created and deleted $tmpfile.";
 
67
  }
68
 
69
  function request_verify_ssl() {
@@ -106,19 +107,28 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
106
  }
107
  $rating_date = get_option( $this->prefix . '_rating_date' );
108
  echo '<div class="notice notice-success" data-rating-date="' . date( 'Y-m-d', $rating_date ) . '">';
109
- echo '<p style="font-size: 100%;">You have been using <b>' . $this->nice_name_from_file( $this->mainfile ) . '</b> for some time now. Thank you! Could you kindly share your opinion with me, along with, maybe, features you would like to see implemented? Then, please <a style="font-weight: bold; color: #b926ff;" target="_blank" href="https://wordpress.org/support/plugin/' . $this->nice_short_url_from_file( $this->mainfile ) . '/reviews/?rate=5#new-post">write a little review</a>. That will also bring me joy and motivation, and I will get back to you :) <u>In the case you already have written a review</u>, please check again. Many reviews got removed from WordPress recently.';
 
 
 
 
 
 
110
  echo '<p>
111
  <form method="post" action="" style="float: right;">
112
  <input type="hidden" name="' . $this->prefix . '_never_remind_me" value="true">
113
- <input type="submit" name="submit" id="submit" class="button button-red" value="Never remind me!">
 
114
  </form>
115
  <form method="post" action="" style="float: right; margin-right: 10px;">
116
  <input type="hidden" name="' . $this->prefix . '_remind_me" value="true">
117
- <input type="submit" name="submit" id="submit" class="button button-primary" value="Remind me in a few weeks...">
 
118
  </form>
119
  <form method="post" action="" style="float: right; margin-right: 10px;">
120
  <input type="hidden" name="' . $this->prefix . '_did_it" value="true">
121
- <input type="submit" name="submit" id="submit" class="button button-primary" value="Yes, I did it!">
 
122
  </form>
123
  <div style="clear: both;"></div>
124
  </p>
@@ -154,11 +164,15 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
154
  return;
155
  }
156
  echo '<div class="error">';
157
- echo '<p>It looks like you are using the free version of the plugin (<b>' . $this->nice_name_from_file( $this->mainfile ) . '</b>) but a license for the Pro version was also found. The Pro version might have been replaced by the Free version during an update (might be caused by a temporarily issue). If it is the case, <b>please download it again</b> from the <a target="_blank" href="https://store.meowapps.com">Meow Store</a>. If you wish to continue using the free version and clear this message, click on this button.';
 
 
 
158
  echo '<p>
159
  <form method="post" action="">
160
  <input type="hidden" name="' . $this->prefix . '_reset_sub" value="true">
161
- <input type="submit" name="submit" id="submit" class="button" value="Remove the license">
 
162
  </form>
163
  </p>
164
  ';
@@ -208,13 +222,13 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
208
  }
209
 
210
  add_settings_section( 'meowapps_common_settings', null, null, 'meowapps_common_settings-menu' );
211
- add_settings_field( 'meowapps_hide_meowapps', "Main Menu",
212
  array( $this, 'meowapps_hide_dashboard_callback' ),
213
  'meowapps_common_settings-menu', 'meowapps_common_settings' );
214
- add_settings_field( 'meowapps_force_sslverify', "SSL Verify",
215
  array( $this, 'meowapps_force_sslverify_callback' ),
216
  'meowapps_common_settings-menu', 'meowapps_common_settings' );
217
- // add_settings_field( 'meowapps_hide_ads', "Ads",
218
  // array( $this, 'meowapps_hide_ads_callback' ),
219
  // 'meowapps_common_settings-menu', 'meowapps_common_settings' );
220
  register_setting( 'meowapps_common_settings', 'force_sslverify' );
@@ -226,36 +240,42 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
226
  $value = get_option( 'meowapps_hide_ads', null );
227
  $html = '<input type="checkbox" id="meowapps_hide_ads" name="meowapps_hide_ads" value="1" ' .
228
  checked( 1, get_option( 'meowapps_hide_ads' ), false ) . '/>';
229
- $html .= __( '<label>Hide</label><br /><small>Doesn\'t display the ads.</small>', $this->domain );
230
- echo $html;
231
  }
232
 
233
  function meowapps_hide_dashboard_callback() {
234
  $value = get_option( 'meowapps_hide_meowapps', null );
235
  $html = '<input type="checkbox" id="meowapps_hide_meowapps" name="meowapps_hide_meowapps" value="1" ' .
236
  checked( 1, get_option( 'meowapps_hide_meowapps' ), false ) . '/>';
237
- $html .= __( '<label>Hide <b>Meow Apps</b> Menu</label><br /><small>Hide Meow Apps menu and all its components, for a cleaner admin. This option will be reset if a new Meow Apps plugin is installed. <b>Once activated, an option will be added in your General settings to display it again.</b></small>', $this->domain );
238
- echo $html;
239
  }
240
 
241
  function meowapps_force_sslverify_callback() {
242
  $value = get_option( 'force_sslverify', null );
243
  $html = '<input type="checkbox" id="force_sslverify" name="force_sslverify" value="1" ' .
244
  checked( 1, get_option( 'force_sslverify' ), false ) . '/>';
245
- $html .= __( '<label>Force</label><br /><small>Updates and licenses checks are usually made without checking SSL certificates and it is actually fine this way. But if you are intransigent when it comes to SSL matters, this option will force it.</small>', $this->domain );
246
- echo $html;
247
  }
248
 
249
  function display_serialkey_box( $url = "https://meowapps.com/" ) {
250
  $html = '<div class="meow-box">';
251
- $html .= '<h3 class="' . ( $this->is_registered( $this->prefix ) ? 'meow-bk-blue' : 'meow-bk-red' ) . '">Pro Version ' .
252
- ( $this->is_registered( $this->prefix ) ? '(enabled)' : '(disabled)' ) . '</h3>';
253
- $html .= '<div class="inside">';
 
 
254
  echo $html;
255
- $html = apply_filters( $this->prefix . '_meowapps_license_input', ( 'More information about the Pro version here:
256
- <a target="_blank" href="' . $url . '">' . $url . '</a>. If you actually bought the Pro version already, please remove the current plugin and download the Pro version from your account at the <a target="_blank" href="https://store.meowapps.com/account/downloads/">Meow Apps Store</a>.' ), $url );
257
- $html .= '</div>';
258
- $html .= '</div>';
 
 
 
 
259
  echo $html;
260
  }
261
 
@@ -271,7 +291,7 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
271
  $pluginpath = trailingslashit( plugin_dir_path( __FILE__ ) ) . '../../' . $plugin;
272
  if ( !file_exists( $pluginpath ) ) {
273
  $url = wp_nonce_url( "update.php?action=install-plugin&plugin=$plugin", "install-plugin_$plugin" );
274
- return "<a href='$url'><small><span class='' style='float: right;'>install</span></small></a>";
275
  }
276
  }
277
  else {
@@ -293,12 +313,12 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
293
  'activate-plugin_' . $plugin_file );
294
  return '<small><span style="color: black; float: right;">off
295
  (<a style="color: rgba(30,140,190,1); text-decoration: none;" href="' .
296
- $url . '">enable</a>)</span></small>';
297
  }
298
  }
299
 
300
  function common_url( $file ) {
301
- die( "Meow Apps: The function common_url( \$file ) needs to be overriden." );
302
  // Normally, this should be used:
303
  // return plugin_dir_url( __FILE__ ) . ( '\/common\/' . $file );
304
  }
@@ -309,8 +329,8 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
309
 
310
  function plugins_loaded() {
311
  if ( isset( $_GET[ 'tool' ] ) && $_GET[ 'tool' ] == 'error_log' ) {
312
- $sec = "5";
313
- header( "Refresh: $sec;" );
314
  }
315
  }
316
 
@@ -318,7 +338,7 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
318
 
319
  echo '<div class="wrap meow-dashboard">';
320
  if ( isset( $_GET['tool'] ) && $_GET['tool'] == 'phpinfo' ) {
321
- echo "<a href=\"javascript:history.go(-1)\">< Go back</a><br /><br />";
322
  echo '<div id="phpinfo">';
323
  ob_start();
324
  phpinfo();
@@ -329,20 +349,25 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
329
  echo "</div>";
330
  }
331
  else if ( isset( $_GET['tool'] ) && $_GET['tool'] == 'error_log' ) {
332
- $log_msg = '=== MEOW APPS DEBUG (This is not an error) ===';
333
  if ( isset( $_POST['write_logs'] ) ) {
334
  error_log( $log_msg );
335
  }
336
  $errorpath = ini_get( 'error_log' );
337
- echo "<a href=\"javascript:history.go(-1)\">< Go back</a><br /><br />";
338
  echo '
339
  <form method="post">
340
  <input type="hidden" name="write_logs" value="true">
341
- <input class="button button-primary" type="submit" value="Write in the Error Logs">
342
  </form><br />';
343
  echo '<div id="error_log">';
344
  if ( file_exists( $errorpath ) ) {
345
- echo "Now (auto-reload every 5 seconds): [" . date( "d-M-Y H:i:s", time() ) . " UTC]<br /><br /><h2 style='margin: 0px;'>Errors (order by latest)</h2>";
 
 
 
 
 
346
  $errors = file_get_contents( $errorpath );
347
  $errors = explode( "\n", $errors );
348
  $errors = array_reverse( $errors );
@@ -350,7 +375,7 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
350
  echo $errors;
351
  }
352
  else {
353
- echo "The PHP Error Logs cannot be found. Please ask your hosting service for it.";
354
  }
355
  echo "</div>";
356
 
@@ -363,27 +388,27 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
363
  <?php _e( 'Meow Apps is run by Jordy Meow, a photographer and software developer living in Japan (and taking <a target="_blank" href="http://offbeatjapan.org">a lot of photos</a>). Meow Apps is a suite of plugins focusing on photography, imaging, optimization and it teams up with the best players in the community (other themes and plugins developers). For more information, please check <a href="http://meowapps.com" target="_blank">Meow Apps</a>.', $this->domain )
364
  ?>
365
  </p>
366
-
367
- <h2 style="margin-bottom: 0px; margin-top: 25px;">Featured Plugins</h2>
368
  <div class="meow-row meow-featured-plugins">
369
  <div class="meow-box meow-col meow-span_1_of_2">
370
  <ul class="">
371
  <li><img src='<?= $this->common_url( 'img/media-cleaner.jpg' ) ?>' />
372
  <a href='https://meowapps.com/plugin/media-cleaner/'><b>Media Cleaner</b></a>
373
  <?php echo $this->check_install( 'media-cleaner' ) ?><br />
374
- Detect the files which are not in use.</li>
375
  <li><img src='<?= $this->common_url( 'img/media-file-renamer.jpg' ) ?>' />
376
  <a href='https://meowapps.com/plugin/media-file-renamer/'><b>Media File Renamer</b></a>
377
- <?php echo $this->check_install( 'media-file-renamer' ) ?><br />
378
- For nicer filenames and a better SEO.</li>
379
  <li><img src='<?= $this->common_url( 'img/default.png' ) ?>' />
380
  <a href='https://meowapps.com/plugin/contact-form-block/'><b>Contact Form Block</b></a>
381
  <?php echo $this->check_install( 'contact-form-block' ) ?><br />
382
- A simpler, nicer, prettier contact form.</li>
383
  <!--li><img src='<?= $this->common_url( 'img/wp-retina-2x.jpg' ) ?>' />
384
  <a href='https://meowapps.com/plugin/wp-retina-2x/'><b>WP Retina 2x</b></a>
385
  <?php echo $this->check_install( 'wp-retina-2x' ) ?><br />
386
- The famous plugin that adds Retina support.</li-->
387
 
388
  </ul>
389
  </div>
@@ -392,38 +417,38 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
392
  <li><img src='<?= $this->common_url( 'img/meow-gallery.jpg' ) ?>' />
393
  <a href='https://meowapps.com/plugin/meow-gallery/'><b>Meow Gallery</b></a>
394
  <?php echo $this->check_install( 'meow-gallery' ) ?><br />
395
- Beautiful but lightweight gallery with many layouts. The only one that allows you to uninstall it without losing anything.</li>
396
  <li><img src='<?= $this->common_url( 'img/meow-lightbox.jpg' ) ?>' />
397
  <a href='https://meowapps.com/plugin/meow-lightbox/'><b>Meow Lightbox</b></a>
398
  <?php echo $this->check_install( 'meow-lightbox' ) ?><br />
399
- Pretty and ultra-optimized Lightbox which can also display your EXIF data. You will love it.</li>
400
  <li><img src='<?= $this->common_url( 'img/wplr-sync.jpg' ) ?>' />
401
  <a href='https://meowapps.com/plugin/wplr-sync/'><b>WP/LR Sync</b></a>
402
  <?php echo $this->check_install( 'wplr-sync' ) ?><br />
403
- Synchronize your Lightroom to your WordPress. This plugin is loved by all the photographers using Lightroom and WordPress.</li>
404
  </ul>
405
  </div>
406
  </div>
407
 
408
- <h2>WordPress Performance & Recommendations</h2>
409
  <div style="background: white; padding: 5px 15px 5px 15px; box-shadow: 2px 2px 1px rgba(0,0,0,.02); margin-bottom: 15px;">
410
  <p><?php _e( 'The <b>Empty Request Time</b> helps you analyzing the raw performance of your install by giving you the average time it takes to run an empty request to your server. You can try to disable some plugins (or change their options) then and click on Reset to see how it influences the results. With <b>File Operation Time</b>, you will find out if your server is slow with files. An excellent install would have an Empty Request Time of less than 500 ms. Keep it absolutely under 2,000 ms. File Operation Time should take only a few milliseconds more than the Empty Request Time. For more information about this, <a href="https://meowapps.com/clean-optimize-wordpress/#Optimize_your_Empty_Request_Time" target="_blank">click here</a>.', $this->domain ); ?></p>
411
  </div>
412
 
413
  <div style="float: left; margin-right: 10px; text-align: center; padding: 10px; background: white; width: 200px; border: 1px solid #e2e2e2;">
414
- <div style='font-size: 14px; line-height: 14px; margin-bottom: 20px;'>Empty Request Time</div>
415
- <div style='font-size: 32px; line-height: 32px; margin-bottom: 10px;' id='meow-perf-load-average'>N/A</div>
416
- <div style='font-size: 12px; line-height: 12px; margin-bottom: 20px;'>Based on
417
- <span id='meow-perf-load-count'>0</span> request(s)
418
  </div>
419
  <input type='submit' style='text-align: center; width: 100%;' id="meow-perf-reset" value="Reset" class="button button-primary">
420
  </div>
421
-
422
  <div style="float: left; margin-right: 10px; text-align: center; padding: 10px; background: white; width: 200px; border: 1px solid #e2e2e2;">
423
- <div style='font-size: 14px; line-height: 14px; margin-bottom: 20px;'>File Operation Time</div>
424
- <div style='font-size: 32px; line-height: 32px; margin-bottom: 10px;' id='meow-file-check-time'>N/A</div>
425
- <div style='font-size: 12px; line-height: 12px; margin-bottom: 20px;'>Create temporary file and delete it.</div>
426
- <input type='submit' style='text-align: center; width: 100%;' id="meow-file-check-start" value="Check" class="button button-primary">
427
  </div>
428
 
429
  <div style="clear: both;"></div>
@@ -436,7 +461,7 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
436
  $('#meow-perf-reset').on('click', function () {
437
  calls = 0;
438
  times = [];
439
- $('#meow-perf-load-average').text('N/A');
440
  $('#meow-perf-load-count').text('0');
441
  });
442
 
@@ -455,7 +480,7 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
455
  times.push(time);
456
  var sum = times.reduce(function(a, b) { return a + b; });
457
  var avg = Math.ceil(sum / times.length);
458
- $('#meow-perf-load-average').text(avg + ' ms');
459
  $('#meow-perf-load-count').text(calls);
460
  setTimeout(perfLoad, 5000);
461
  });
@@ -472,8 +497,8 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
472
  }).done(function (response) {
473
  var end = new Date().getTime();
474
  var time = end - start;
475
- $('#meow-file-check-time').text(time + ' ms');
476
- $('#meow-file-check-start').text('Check');
477
  });
478
  };
479
 
@@ -483,7 +508,7 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
483
  });
484
 
485
  setTimeout(perfLoad, 1500);
486
-
487
  })(jQuery);
488
  </script>
489
 
@@ -491,22 +516,22 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
491
  <p>
492
  <?php _e( 'Too many WordPress installs are blown-up with useless and/or huge plugins, and bad practices. But that is because most users are overwhelmed by the diversity and immensity of the WordPress jungle. One rule of thumb is to keep your install the simplest as possible, with the least number of plugins (avoiding heavy ones too) and a good hosting service (avoid VPS except if you know exactly what you are doing). Articles are kept being updated on the Meow Apps website, with all the latest recommendations: ', $this->domain )?>
493
  <a href='https://meowapps.com/debugging-wordpress/' target='_blank'>
494
- How To Debug</a>,
495
  <a href='https://meowapps.com/seo-optimization/' target='_blank'>
496
- SEO Checklist & Optimization</a>,
497
  <a href='https://meowapps.com/clean-optimize-wordpress/' target='_blank'>
498
- Clean Up and Optimize</a>,
499
  <a href='https://meowapps.com/optimize-images-cdn/' target='_blank'>
500
- Optimize Images</a>,
501
  <a href='https://meowapps.com/best-hosting-services-wordpress/' target='_blank'>
502
  Best Hosting Services</a>.
503
  </p>
504
  </div>
505
 
506
- <h2 style="margin-bottom: 0px; margin-top: 25px;">Common Options & Tools</h2>
507
  <div class="meow-row">
508
  <div class="meow-box meow-col meow-span_2_of_3">
509
- <h3><span class="dashicons dashicons-admin-tools"></span> Common</h3>
510
  <div class="inside">
511
  <form method="post" action="options.php">
512
  <?php settings_fields( 'meowapps_common_settings' ); ?>
@@ -517,17 +542,17 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
517
  </div>
518
 
519
  <div class="meow-box meow-col meow-span_1_of_3">
520
- <h3><span class="dashicons dashicons-admin-tools"></span> Debug</h3>
521
  <div class="inside">
522
  <ul>
523
- <li><a href="?page=meowapps-main-menu&amp;tool=error_log">Display Error Log</a></li>
524
- <li><a href="?page=meowapps-main-menu&amp;tool=phpinfo">Display PHP Info</a></li>
525
  </ul>
526
  </div>
527
  </div>
528
 
529
  <div class="meow-box meow-col meow-span_1_of_3">
530
- <h3><span class="dashicons dashicons-admin-tools"></span> Post Types (used by this install)</h3>
531
  <div class="inside">
532
  <?php
533
  global $wpdb;
@@ -537,7 +562,7 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
537
  $result = array();
538
  foreach( $types as $type )
539
  array_push( $result, "{$type->type} ({$type->count})" );
540
- echo implode( $result, ', ' );
541
  ?>
542
  </div>
543
  </div>
@@ -548,8 +573,12 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
548
  }
549
 
550
  function admin_footer_text( $current ) {
551
- return "Thanks for using <a href='https://meowapps.com'>Meow Apps</a>! This is the Meow Admin " .
552
- MeowApps_Admin::$admin_version . ". <br /><i>Loaded from " . __FILE__ . "</i>";
 
 
 
 
553
  }
554
 
555
  // HELPERS
52
  }
53
  }
54
  }
55
+
56
  add_filter( 'edd_sl_api_request_verify_ssl', array( $this, 'request_verify_ssl' ), 10, 0 );
57
  }
58
 
59
  function wp_ajax_meow_perf_load() {
60
+ return __( 'Did nothing but a blank request.', $this->domain );
61
  }
62
 
63
  function wp_ajax_meow_file_check() {
64
  $tmpfile = wp_tempnam();
65
  unlink( $tmpfile );
66
+ // translators: %s is a filename of an empty temporary file
67
+ return sprintf( __( 'Created and deleted %s', $this->domain ), $tmpfile );
68
  }
69
 
70
  function request_verify_ssl() {
107
  }
108
  $rating_date = get_option( $this->prefix . '_rating_date' );
109
  echo '<div class="notice notice-success" data-rating-date="' . date( 'Y-m-d', $rating_date ) . '">';
110
+ echo '<p style="font-size: 100%;">';
111
+ printf(
112
+ // translators: %1$s is a plugin nicename, %2$s is a short url (slug)
113
+ __( 'You have been using <b>%1$s</b> for some time now. Thank you! Could you kindly share your opinion with me, along with, maybe, features you would like to see implemented? Then, please <a style="font-weight: bold; color: #b926ff;" target="_blank" href="https://wordpress.org/support/plugin/%2$s/reviews/?rate=5#new-post">write a little review</a>. That will also bring me joy and motivation, and I will get back to you :) <u>In the case you already have written a review</u>, please check again. Many reviews got removed from WordPress recently.', $this->domain ),
114
+ $this->nice_name_from_file( $this->mainfile ),
115
+ $this->nice_short_url_from_file( $this->mainfile )
116
+ );
117
  echo '<p>
118
  <form method="post" action="" style="float: right;">
119
  <input type="hidden" name="' . $this->prefix . '_never_remind_me" value="true">
120
+ <input type="submit" name="submit" id="submit" class="button button-red" value="'
121
+ . __( 'Never remind me!', $this->domain ) . '">
122
  </form>
123
  <form method="post" action="" style="float: right; margin-right: 10px;">
124
  <input type="hidden" name="' . $this->prefix . '_remind_me" value="true">
125
+ <input type="submit" name="submit" id="submit" class="button button-primary" value="'
126
+ . __( 'Remind me in a few weeks...', $this->domain ) . '">
127
  </form>
128
  <form method="post" action="" style="float: right; margin-right: 10px;">
129
  <input type="hidden" name="' . $this->prefix . '_did_it" value="true">
130
+ <input type="submit" name="submit" id="submit" class="button button-primary" value="'
131
+ . __( 'Yes, I did it!', $this->domain ) . '">
132
  </form>
133
  <div style="clear: both;"></div>
134
  </p>
164
  return;
165
  }
166
  echo '<div class="error">';
167
+ printf(
168
+ // translators: %s is a plugin nicename
169
+ __( '<p>It looks like you are using the free version of the plugin (<b>%s</b>) but a license for the Pro version was also found. The Pro version might have been replaced by the Free version during an update (might be caused by a temporarily issue). If it is the case, <b>please download it again</b> from the <a target="_blank" href="https://store.meowapps.com">Meow Store</a>. If you wish to continue using the free version and clear this message, click on this button.', $this->domain ),
170
+ $this->nice_name_from_file( $this->mainfile ) );
171
  echo '<p>
172
  <form method="post" action="">
173
  <input type="hidden" name="' . $this->prefix . '_reset_sub" value="true">
174
+ <input type="submit" name="submit" id="submit" class="button" value="'
175
+ . __( 'Remove the license', $this->domain ) . '">
176
  </form>
177
  </p>
178
  ';
222
  }
223
 
224
  add_settings_section( 'meowapps_common_settings', null, null, 'meowapps_common_settings-menu' );
225
+ add_settings_field( 'meowapps_hide_meowapps', __( 'Main Menu', $this->domain ),
226
  array( $this, 'meowapps_hide_dashboard_callback' ),
227
  'meowapps_common_settings-menu', 'meowapps_common_settings' );
228
+ add_settings_field( 'meowapps_force_sslverify', __( 'SSL Verify', $this->domain ),
229
  array( $this, 'meowapps_force_sslverify_callback' ),
230
  'meowapps_common_settings-menu', 'meowapps_common_settings' );
231
+ // add_settings_field( 'meowapps_hide_ads', __( 'Ads', $this->domain ),
232
  // array( $this, 'meowapps_hide_ads_callback' ),
233
  // 'meowapps_common_settings-menu', 'meowapps_common_settings' );
234
  register_setting( 'meowapps_common_settings', 'force_sslverify' );
240
  $value = get_option( 'meowapps_hide_ads', null );
241
  $html = '<input type="checkbox" id="meowapps_hide_ads" name="meowapps_hide_ads" value="1" ' .
242
  checked( 1, get_option( 'meowapps_hide_ads' ), false ) . '/>';
243
+ $html .= __( '<label>Hide</label><br /><small>Doesn\'t display the ads.</small>', $this->domain );
244
+ echo $html;
245
  }
246
 
247
  function meowapps_hide_dashboard_callback() {
248
  $value = get_option( 'meowapps_hide_meowapps', null );
249
  $html = '<input type="checkbox" id="meowapps_hide_meowapps" name="meowapps_hide_meowapps" value="1" ' .
250
  checked( 1, get_option( 'meowapps_hide_meowapps' ), false ) . '/>';
251
+ $html .= __( '<label>Hide <b>Meow Apps</b> Menu</label><br /><small>Hide Meow Apps menu and all its components, for a cleaner admin. This option will be reset if a new Meow Apps plugin is installed. <b>Once activated, an option will be added in your General settings to display it again.</b></small>', $this->domain );
252
+ echo $html;
253
  }
254
 
255
  function meowapps_force_sslverify_callback() {
256
  $value = get_option( 'force_sslverify', null );
257
  $html = '<input type="checkbox" id="force_sslverify" name="force_sslverify" value="1" ' .
258
  checked( 1, get_option( 'force_sslverify' ), false ) . '/>';
259
+ $html .= __( '<label>Force</label><br /><small>Updates and licenses checks are usually made without checking SSL certificates and it is actually fine this way. But if you are intransigent when it comes to SSL matters, this option will force it.</small>', $this->domain );
260
+ echo $html;
261
  }
262
 
263
  function display_serialkey_box( $url = "https://meowapps.com/" ) {
264
  $html = '<div class="meow-box">';
265
+ $html .= '<h3 class="' . ( $this->is_registered( $this->prefix ) ? 'meow-bk-blue' : 'meow-bk-red' ) . '">'
266
+ . __( 'Pro Version', $this->domain ) . ' '
267
+ . ( $this->is_registered( $this->prefix ) ? __( '(enabled)', $this->domain ) : __( '(disabled)', $this->domain ) )
268
+ . '</h3>';
269
+ $html .= '<div class="inside">';
270
  echo $html;
271
+ $html = apply_filters(
272
+ $this->prefix . '_meowapps_license_input',
273
+ sprintf(
274
+ // translators: %1$s is a url attribute, %2$s is a url visible for user
275
+ __( 'More information about the Pro version here: <a target="_blank" href="%1$s">%2$s</a>. If you actually bought the Pro version already, please remove the current plugin and download the Pro version from your account at the <a target="_blank" href="https://store.meowapps.com/account/downloads/">Meow Apps Store</a>.', $this->domain ), $url, $url ),
276
+ $url );
277
+ $html .= '</div>';
278
+ $html .= '</div>';
279
  echo $html;
280
  }
281
 
291
  $pluginpath = trailingslashit( plugin_dir_path( __FILE__ ) ) . '../../' . $plugin;
292
  if ( !file_exists( $pluginpath ) ) {
293
  $url = wp_nonce_url( "update.php?action=install-plugin&plugin=$plugin", "install-plugin_$plugin" );
294
+ return "<a href='$url'><small><span class='' style='float: right;'>" . __( 'install', $this->domain ) . "</span></small></a>";
295
  }
296
  }
297
  else {
313
  'activate-plugin_' . $plugin_file );
314
  return '<small><span style="color: black; float: right;">off
315
  (<a style="color: rgba(30,140,190,1); text-decoration: none;" href="' .
316
+ $url . '">' . __( 'enable', $this->domain ) . '</a>)</span></small>';
317
  }
318
  }
319
 
320
  function common_url( $file ) {
321
+ die( __( "Meow Apps: The function common_url( \$file ) needs to be overriden.", $this->domain ) );
322
  // Normally, this should be used:
323
  // return plugin_dir_url( __FILE__ ) . ( '\/common\/' . $file );
324
  }
329
 
330
  function plugins_loaded() {
331
  if ( isset( $_GET[ 'tool' ] ) && $_GET[ 'tool' ] == 'error_log' ) {
332
+ $sec = "5";
333
+ header( "Refresh: $sec;" );
334
  }
335
  }
336
 
338
 
339
  echo '<div class="wrap meow-dashboard">';
340
  if ( isset( $_GET['tool'] ) && $_GET['tool'] == 'phpinfo' ) {
341
+ echo "<a href=\"javascript:history.go(-1)\">< ". __( 'Go back', $this->domain ) . "</a><br /><br />";
342
  echo '<div id="phpinfo">';
343
  ob_start();
344
  phpinfo();
349
  echo "</div>";
350
  }
351
  else if ( isset( $_GET['tool'] ) && $_GET['tool'] == 'error_log' ) {
352
+ $log_msg = __( '=== MEOW APPS DEBUG (This is not an error) ===', $this->domain );
353
  if ( isset( $_POST['write_logs'] ) ) {
354
  error_log( $log_msg );
355
  }
356
  $errorpath = ini_get( 'error_log' );
357
+ echo "<a href=\"javascript:history.go(-1)\">< ". __( 'Go back', $this->domain ) . "</a><br /><br />";
358
  echo '
359
  <form method="post">
360
  <input type="hidden" name="write_logs" value="true">
361
+ <input class="button button-primary" type="submit" value=" ' . __( 'Write in the Error Logs', $this->domain ) . '">
362
  </form><br />';
363
  echo '<div id="error_log">';
364
  if ( file_exists( $errorpath ) ) {
365
+ printf(
366
+ // translators: %s is a preformatted timestamp
367
+ __( "Now (auto-reload every 5 seconds): [%s UTC]", $this->domain ),
368
+ date( "d-M-Y H:i:s", time() )
369
+ );
370
+ echo "<br /><br /><h2 style='margin: 0px;'>" . __( 'Errors (order by latest)', $this->domain ) . "</h2>";
371
  $errors = file_get_contents( $errorpath );
372
  $errors = explode( "\n", $errors );
373
  $errors = array_reverse( $errors );
375
  echo $errors;
376
  }
377
  else {
378
+ _e( "The PHP Error Logs cannot be found. Please ask your hosting service for it.", $this->domain );
379
  }
380
  echo "</div>";
381
 
388
  <?php _e( 'Meow Apps is run by Jordy Meow, a photographer and software developer living in Japan (and taking <a target="_blank" href="http://offbeatjapan.org">a lot of photos</a>). Meow Apps is a suite of plugins focusing on photography, imaging, optimization and it teams up with the best players in the community (other themes and plugins developers). For more information, please check <a href="http://meowapps.com" target="_blank">Meow Apps</a>.', $this->domain )
389
  ?>
390
  </p>
391
+
392
+ <h2 style="margin-bottom: 0px; margin-top: 25px;"><?php _e( 'Featured Plugins', $this->domain ); ?></h2>
393
  <div class="meow-row meow-featured-plugins">
394
  <div class="meow-box meow-col meow-span_1_of_2">
395
  <ul class="">
396
  <li><img src='<?= $this->common_url( 'img/media-cleaner.jpg' ) ?>' />
397
  <a href='https://meowapps.com/plugin/media-cleaner/'><b>Media Cleaner</b></a>
398
  <?php echo $this->check_install( 'media-cleaner' ) ?><br />
399
+ <?php _e( 'Detect the files which are not in use.', $this->domain ); ?></li>
400
  <li><img src='<?= $this->common_url( 'img/media-file-renamer.jpg' ) ?>' />
401
  <a href='https://meowapps.com/plugin/media-file-renamer/'><b>Media File Renamer</b></a>
402
+ <?php echo $this->check_install( 'media-file-renamer' ) ?><br />
403
+ <?php _e( 'For nicer filenames and a better SEO.', $this->domain ); ?></li>
404
  <li><img src='<?= $this->common_url( 'img/default.png' ) ?>' />
405
  <a href='https://meowapps.com/plugin/contact-form-block/'><b>Contact Form Block</b></a>
406
  <?php echo $this->check_install( 'contact-form-block' ) ?><br />
407
+ <?php _e( 'A simpler, nicer, prettier contact form.', $this->domain ); ?></li>
408
  <!--li><img src='<?= $this->common_url( 'img/wp-retina-2x.jpg' ) ?>' />
409
  <a href='https://meowapps.com/plugin/wp-retina-2x/'><b>WP Retina 2x</b></a>
410
  <?php echo $this->check_install( 'wp-retina-2x' ) ?><br />
411
+ <?php _e( 'The famous plugin that adds Retina support.', $this->domain ); ?></li-->
412
 
413
  </ul>
414
  </div>
417
  <li><img src='<?= $this->common_url( 'img/meow-gallery.jpg' ) ?>' />
418
  <a href='https://meowapps.com/plugin/meow-gallery/'><b>Meow Gallery</b></a>
419
  <?php echo $this->check_install( 'meow-gallery' ) ?><br />
420
+ <?php _e( 'Beautiful but lightweight gallery with many layouts. The only one that allows you to uninstall it without losing anything.', $this->domain ); ?></li>
421
  <li><img src='<?= $this->common_url( 'img/meow-lightbox.jpg' ) ?>' />
422
  <a href='https://meowapps.com/plugin/meow-lightbox/'><b>Meow Lightbox</b></a>
423
  <?php echo $this->check_install( 'meow-lightbox' ) ?><br />
424
+ <?php _e( 'Pretty and ultra-optimized Lightbox which can also display your EXIF data. You will love it.', $this->domain ); ?></li>
425
  <li><img src='<?= $this->common_url( 'img/wplr-sync.jpg' ) ?>' />
426
  <a href='https://meowapps.com/plugin/wplr-sync/'><b>WP/LR Sync</b></a>
427
  <?php echo $this->check_install( 'wplr-sync' ) ?><br />
428
+ <?php _e( 'Synchronize your Lightroom to your WordPress. This plugin is loved by all the photographers using Lightroom and WordPress.', $this->domain ); ?></li>
429
  </ul>
430
  </div>
431
  </div>
432
 
433
+ <h2><?php _e( 'WordPress Performance & Recommendations', $this->domain ); ?></h2>
434
  <div style="background: white; padding: 5px 15px 5px 15px; box-shadow: 2px 2px 1px rgba(0,0,0,.02); margin-bottom: 15px;">
435
  <p><?php _e( 'The <b>Empty Request Time</b> helps you analyzing the raw performance of your install by giving you the average time it takes to run an empty request to your server. You can try to disable some plugins (or change their options) then and click on Reset to see how it influences the results. With <b>File Operation Time</b>, you will find out if your server is slow with files. An excellent install would have an Empty Request Time of less than 500 ms. Keep it absolutely under 2,000 ms. File Operation Time should take only a few milliseconds more than the Empty Request Time. For more information about this, <a href="https://meowapps.com/clean-optimize-wordpress/#Optimize_your_Empty_Request_Time" target="_blank">click here</a>.', $this->domain ); ?></p>
436
  </div>
437
 
438
  <div style="float: left; margin-right: 10px; text-align: center; padding: 10px; background: white; width: 200px; border: 1px solid #e2e2e2;">
439
+ <div style='font-size: 14px; line-height: 14px; margin-bottom: 20px;'><?php _e( 'Empty Request Time', $this->domain ); ?></div>
440
+ <div style='font-size: 32px; line-height: 32px; margin-bottom: 10px;' id='meow-perf-load-average'><?php _e( 'N/A', $this->domain ); ?></div>
441
+ <div style='font-size: 12px; line-height: 12px; margin-bottom: 20px;'><?php _e( 'Based on', $this->domain ); ?>
442
+ <span id='meow-perf-load-count'>0</span> <?php _e( 'request(s)', $this->domain ); ?>
443
  </div>
444
  <input type='submit' style='text-align: center; width: 100%;' id="meow-perf-reset" value="Reset" class="button button-primary">
445
  </div>
446
+
447
  <div style="float: left; margin-right: 10px; text-align: center; padding: 10px; background: white; width: 200px; border: 1px solid #e2e2e2;">
448
+ <div style='font-size: 14px; line-height: 14px; margin-bottom: 20px;'><?php _e( 'File Operation Time', $this->domain ); ?></div>
449
+ <div style='font-size: 32px; line-height: 32px; margin-bottom: 10px;' id='meow-file-check-time'><?php _e( 'N/A', $this->domain ); ?></div>
450
+ <div style='font-size: 12px; line-height: 12px; margin-bottom: 20px;'><?php _e( 'Create temporary file and delete it.', $this->domain ); ?></div>
451
+ <input type='submit' style='text-align: center; width: 100%;' id="meow-file-check-start" value="<?php _e( 'Check', $this->domain ); ?>" class="button button-primary">
452
  </div>
453
 
454
  <div style="clear: both;"></div>
461
  $('#meow-perf-reset').on('click', function () {
462
  calls = 0;
463
  times = [];
464
+ $('#meow-perf-load-average').text('<?php _e( "N/A", $this->domain ); ?>');
465
  $('#meow-perf-load-count').text('0');
466
  });
467
 
480
  times.push(time);
481
  var sum = times.reduce(function(a, b) { return a + b; });
482
  var avg = Math.ceil(sum / times.length);
483
+ $('#meow-perf-load-average').text(avg + ' <?php _e( "ms", $this->domain ); ?>');
484
  $('#meow-perf-load-count').text(calls);
485
  setTimeout(perfLoad, 5000);
486
  });
497
  }).done(function (response) {
498
  var end = new Date().getTime();
499
  var time = end - start;
500
+ $('#meow-file-check-time').text(time + ' <?php _e( "ms", $this->domain ); ?>');
501
+ $('#meow-file-check-start').text('<?php _e( "Check", $this->domain ); ?>');
502
  });
503
  };
504
 
508
  });
509
 
510
  setTimeout(perfLoad, 1500);
511
+
512
  })(jQuery);
513
  </script>
514
 
516
  <p>
517
  <?php _e( 'Too many WordPress installs are blown-up with useless and/or huge plugins, and bad practices. But that is because most users are overwhelmed by the diversity and immensity of the WordPress jungle. One rule of thumb is to keep your install the simplest as possible, with the least number of plugins (avoiding heavy ones too) and a good hosting service (avoid VPS except if you know exactly what you are doing). Articles are kept being updated on the Meow Apps website, with all the latest recommendations: ', $this->domain )?>
518
  <a href='https://meowapps.com/debugging-wordpress/' target='_blank'>
519
+ How To Debug</a>,
520
  <a href='https://meowapps.com/seo-optimization/' target='_blank'>
521
+ SEO Checklist & Optimization</a>,
522
  <a href='https://meowapps.com/clean-optimize-wordpress/' target='_blank'>
523
+ Clean Up and Optimize</a>,
524
  <a href='https://meowapps.com/optimize-images-cdn/' target='_blank'>
525
+ Optimize Images</a>,
526
  <a href='https://meowapps.com/best-hosting-services-wordpress/' target='_blank'>
527
  Best Hosting Services</a>.
528
  </p>
529
  </div>
530
 
531
+ <h2 style="margin-bottom: 0px; margin-top: 25px;"><?php _e( 'Common Options & Tools', $this->domain ); ?></h2>
532
  <div class="meow-row">
533
  <div class="meow-box meow-col meow-span_2_of_3">
534
+ <h3><span class="dashicons dashicons-admin-tools"></span> <?php _e( 'Common', $this->domain ); ?></h3>
535
  <div class="inside">
536
  <form method="post" action="options.php">
537
  <?php settings_fields( 'meowapps_common_settings' ); ?>
542
  </div>
543
 
544
  <div class="meow-box meow-col meow-span_1_of_3">
545
+ <h3><span class="dashicons dashicons-admin-tools"></span> <?php _e( 'Debug', $this->domain ); ?></h3>
546
  <div class="inside">
547
  <ul>
548
+ <li><a href="?page=meowapps-main-menu&amp;tool=error_log"><?php _e( 'Display Error Log', $this->domain ); ?></a></li>
549
+ <li><a href="?page=meowapps-main-menu&amp;tool=phpinfo"><?php _e( 'Display PHP Info', $this->domain ); ?></a></li>
550
  </ul>
551
  </div>
552
  </div>
553
 
554
  <div class="meow-box meow-col meow-span_1_of_3">
555
+ <h3><span class="dashicons dashicons-admin-tools"></span> <?php _e( 'Post Types (used by this install)', $this->domain ); ?></h3>
556
  <div class="inside">
557
  <?php
558
  global $wpdb;
562
  $result = array();
563
  foreach( $types as $type )
564
  array_push( $result, "{$type->type} ({$type->count})" );
565
+ echo implode( ', ', $result );
566
  ?>
567
  </div>
568
  </div>
573
  }
574
 
575
  function admin_footer_text( $current ) {
576
+ return sprintf(
577
+ // translators: %1$s is the version of the interface; %2$s is a file path.
578
+ __( 'Thanks for using <a href="https://meowapps.com">Meow Apps</a>! This is the Meow Admin %1$s <br /><i>Loaded from %2$s </i>', $this->domain ),
579
+ MeowApps_Admin::$admin_version,
580
+ __FILE__
581
+ );
582
  }
583
 
584
  // HELPERS
core.php CHANGED
@@ -91,6 +91,10 @@ class Meow_WPMC_Core {
91
  $this->get_max_execution_time();
92
  }
93
 
 
 
 
 
94
  function timeout_check() {
95
  $this->time_elapsed = time() - $this->start_time;
96
  $this->time_remaining = $this->max_execution_time - $this->wordpress_init_time - $this->time_elapsed;
@@ -161,8 +165,15 @@ class Meow_WPMC_Core {
161
  $html = wp_make_content_images_responsive( $html );
162
 
163
  // Create the DOM Document
 
 
 
 
 
 
164
  $dom = new DOMDocument();
165
  @$dom->loadHTML( $html );
 
166
  $results = array();
167
 
168
  // <meta> tags in <head> area
@@ -417,40 +428,22 @@ class Meow_WPMC_Core {
417
  // Media
418
  else if ( $issue->type == 1 ) {
419
 
420
- // Copy the main file back
421
- $fullpath = get_attached_file( $issue->postId );
422
- if ( empty( $fullpath ) ) {
423
- error_log( "Media {$issue->postId} does not have attached file anymore." );
424
- return false;
425
- }
426
- $mainfile = $this->clean_uploaded_filename( $fullpath );
427
- $baseUp = pathinfo( $mainfile );
428
- $baseUp = $baseUp['dirname'];
429
- $file = $this->clean_uploaded_filename( $fullpath );
430
- if ( !$this->recover_file( $file ) ) {
431
- $this->log( "Could not recover $file." );
432
- error_log( "Media Cleaner: Could not recover $file." );
433
- }
434
-
435
- // If images, copy the other files as well
436
- $meta = wp_get_attachment_metadata( $issue->postId );
437
- $isImage = isset( $meta, $meta['width'], $meta['height'] );
438
- $sizes = $this->get_image_sizes();
439
- if ( $isImage && isset( $meta['sizes'] ) ) {
440
- foreach ( $meta['sizes'] as $name => $attr ) {
441
- if ( isset( $attr['file'] ) ) {
442
- $filepath = $this->upload_folder['basedir'];
443
- $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
444
- $file = $this->clean_uploaded_filename( $filepath );
445
- if ( !$this->recover_file( $file ) ) {
446
- $this->log( "Could not recover $file." );
447
- error_log( "Media Cleaner: Could not recover $file." );
448
- }
449
- }
450
  }
451
  }
452
  if ( !wp_untrash_post( $issue->postId ) ) {
453
- error_log( "Cleaner: Failed to Untrash Post {$issue->postId} (but deleted it from Cleaner DB)." );
454
  }
455
  $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 0 WHERE id = %d", $id ) );
456
  return true;
@@ -565,32 +558,11 @@ class Meow_WPMC_Core {
565
  if ( $issue->deleted == 0 && MEDIA_TRASH ) {
566
  // Move Media to trash
567
  // Let's copy the images to the trash so that it can be recovered.
568
- $fullpath = get_attached_file( $issue->postId );
569
- $mainfile = $this->clean_uploaded_filename( $fullpath );
570
- $baseUp = pathinfo( $mainfile );
571
- $baseUp = $baseUp['dirname'];
572
- $file = $this->clean_uploaded_filename( $fullpath );
573
- if ( !$this->trash_file( $file ) ) {
574
- $this->log( "Could not trash $file." );
575
- error_log( "Media Cleaner: Could not trash $file." );
576
- return false;
577
- }
578
-
579
- // If images, check the other files as well
580
- $meta = wp_get_attachment_metadata( $issue->postId );
581
- $isImage = isset( $meta, $meta['width'], $meta['height'] );
582
- $sizes = $this->get_image_sizes();
583
- if ( $isImage && isset( $meta['sizes'] ) ) {
584
- foreach ( $meta['sizes'] as $name => $attr ) {
585
- if ( isset( $attr['file'] ) ) {
586
- $filepath = $this->upload_folder['basedir'];
587
- $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
588
- $file = $this->clean_uploaded_filename( $filepath );
589
- if ( !$this->trash_file( $file ) ) {
590
- $this->log( "Could not trash $file." );
591
- error_log( "Media Cleaner: Could not trash $file." );
592
- }
593
- }
594
  }
595
  }
596
  wp_delete_attachment( $issue->postId, false );
@@ -837,67 +809,60 @@ class Meow_WPMC_Core {
837
  return false;
838
  }
839
 
840
- function check_media( $attachmentId, $checkOnly = false ) {
841
-
842
- $this->last_analysis = "N/A";
843
-
844
- // Is it an image?
845
- $meta = wp_get_attachment_metadata( $attachmentId );
846
- $isImage = isset( $meta, $meta['width'], $meta['height'] );
847
-
848
- // Get the main file
849
- global $wpdb;
850
  $fullpath = get_attached_file( $attachmentId );
851
  $mainfile = $this->clean_uploaded_filename( $fullpath );
 
852
  $baseUp = pathinfo( $mainfile );
853
- $baseUp = $baseUp['dirname'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
854
  $size = 0;
855
  $countfiles = 0;
856
- $issue = 'NO_CONTENT';
857
- if ( file_exists( $fullpath ) ) {
858
-
859
- // Special scan: Broken only!
860
- if ( !$this->check_content && !$this->check_postmeta && !$this->check_posts && !$this->check_widgets )
861
- return true;
862
 
863
- $size = filesize( $fullpath );
 
864
 
865
- // Analysis
866
- $this->last_analysis = "NONE";
867
- $this->log( "Checking Media #{$attachmentId}: {$mainfile}" );
868
- if ( $this->check_is_ignore( $mainfile, $attachmentId ) ) {
869
- $this->last_analysis = "IGNORED";
870
- return true;
871
- }
872
- if ( $this->reference_exists( $mainfile, $attachmentId ) )
873
  return true;
874
-
875
- // If images, check the other files as well
876
- $countfiles = 0;
877
- $sizes = $this->get_image_sizes();
878
- if ( $isImage && isset( $meta['sizes'] ) ) {
879
- foreach ( $meta['sizes'] as $name => $attr ) {
880
- if ( isset( $attr['file'] ) ) {
881
- $filepath = $this->upload_folder['basedir'];
882
- $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
883
- if ( file_exists( $filepath ) )
884
- $size += filesize( $filepath );
885
- $file = $this->clean_uploaded_filename( $filepath );
886
- $countfiles++;
887
- // Analysis
888
- $this->log( "Checking Media #{$attachmentId}: {$file}" );
889
- if ( $this->reference_exists( $mainfile, $attachmentId ) )
890
- return true;
891
- }
892
- }
893
- }
894
- } else {
895
  $this->log( "File {$fullpath} does not exist." );
896
  $issue = 'ORPHAN_MEDIA';
897
  }
898
-
899
  if ( !$checkOnly ) {
 
900
  $table_name = $wpdb->prefix . "mclean_scan";
 
901
  $wpdb->insert( $table_name,
902
  array(
903
  'time' => current_time('mysql'),
@@ -912,6 +877,83 @@ class Meow_WPMC_Core {
912
  return false;
913
  }
914
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
915
  // Delete all issues
916
  function reset_issues( $includingIgnored = false ) {
917
  global $wpdb;
@@ -931,19 +973,19 @@ class Meow_WPMC_Core {
931
 
932
  function echo_issue( $issue ) {
933
  if ( $issue == 'NO_CONTENT' ) {
934
- _e( "Seems not in use.", 'media-cleaner' );
935
  }
936
- else if ( $issue == 'NO_MEDIA' ) {
937
- _e( "Not in Media Library.", 'media-cleaner' );
938
  }
939
  else if ( $issue == 'ORPHAN_RETINA' ) {
940
- _e( "Orphan retina.", 'media-cleaner' );
941
  }
942
  else if ( $issue == 'ORPHAN_WEBP' ) {
943
- _e( "Orphan WebP.", 'media-cleaner' );
944
  }
945
  else if ( $issue == 'ORPHAN_MEDIA' ) {
946
- _e( "File not found.", 'media-cleaner' );
947
  }
948
  else {
949
  echo $issue;
@@ -957,23 +999,26 @@ class Meow_WPMC_Core {
957
  */
958
 
959
  function wpmc_init( $mainfile ) {
960
- //register_activation_hook( $mainfile, 'wpmc_reset' );
961
  //register_deactivation_hook( $mainfile, 'wpmc_uninstall' );
962
  register_uninstall_hook( $mainfile, 'wpmc_uninstall' );
963
  }
964
 
 
 
 
 
965
  function wpmc_reset () {
966
- wpmc_uninstall();
967
- wpmc_install();
968
- $upload_folder = wp_upload_dir();
969
- $basedir = $upload_folder['basedir'];
970
- if ( !is_writable( $basedir ) ) {
971
- echo '<div class="error"><p>' . __( 'The directory for uploads is not writable. Media Cleaner will only be able to scan.', 'media-cleaner' ) . '</p></div>';
972
- }
973
 
 
 
 
974
  }
975
 
976
- function wpmc_install() {
977
  global $wpdb;
978
  $table_name = $wpdb->prefix . "mclean_scan";
979
  $charset_collate = $wpdb->get_charset_collate();
@@ -989,7 +1034,7 @@ function wpmc_install() {
989
  issue TINYTEXT NOT NULL,
990
  PRIMARY KEY (id)
991
  ) " . $charset_collate . ";" ;
992
- require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
993
  dbDelta( $sql );
994
  $sql="ALTER TABLE $table_name ADD INDEX IgnoredIndex (ignored) USING BTREE;";
995
  $wpdb->query($sql);
@@ -1004,11 +1049,19 @@ function wpmc_install() {
1004
  originType VARBINARY(32) NOT NULL,
1005
  PRIMARY KEY (id)
1006
  ) " . $charset_collate . ";";
1007
- require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
1008
  dbDelta( $sql );
1009
  }
1010
 
1011
- function wpmc_uninstall () {
 
 
 
 
 
 
 
 
1012
  global $wpdb;
1013
  $table_name1 = $wpdb->prefix . "mclean_scan";
1014
  $table_name2 = $wpdb->prefix . "mclean_refs";
91
  $this->get_max_execution_time();
92
  }
93
 
94
+ function timeout_get_elapsed() {
95
+ return $this->time_elapsed . 'ms';
96
+ }
97
+
98
  function timeout_check() {
99
  $this->time_elapsed = time() - $this->start_time;
100
  $this->time_remaining = $this->max_execution_time - $this->wordpress_init_time - $this->time_elapsed;
165
  $html = wp_make_content_images_responsive( $html );
166
 
167
  // Create the DOM Document
168
+ if ( !class_exists("DOMDocument") ) {
169
+ error_log( 'Media Cleaner: The DOM extension for PHP is not installed.' );
170
+ throw new Error( 'The DOM extension for PHP is not installed.' );
171
+ }
172
+
173
+ libxml_use_internal_errors(true);
174
  $dom = new DOMDocument();
175
  @$dom->loadHTML( $html );
176
+ libxml_clear_errors();
177
  $results = array();
178
 
179
  // <meta> tags in <head> area
428
  // Media
429
  else if ( $issue->type == 1 ) {
430
 
431
+ // DEBUG: Seems useless, but there was this condition before
432
+ // $fullpath = get_attached_file( $issue->postId );
433
+ // if ( empty( $fullpath ) ) {
434
+ // error_log( "Media {$issue->postId} does not have attached file anymore." );
435
+ // return false;
436
+ // }
437
+
438
+ $paths = $this->get_paths_from_attachment( $issue->postId );
439
+ foreach ( $paths as $path ) {
440
+ if ( !$this->recover_file( $path ) ) {
441
+ $this->log( "Could not recover $path." );
442
+ error_log( "Media Cleaner: Could not recover $path." );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
443
  }
444
  }
445
  if ( !wp_untrash_post( $issue->postId ) ) {
446
+ error_log( "Media Cleaner: Failed to Untrash Post {$issue->postId} (but deleted it from Cleaner DB)." );
447
  }
448
  $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 0 WHERE id = %d", $id ) );
449
  return true;
558
  if ( $issue->deleted == 0 && MEDIA_TRASH ) {
559
  // Move Media to trash
560
  // Let's copy the images to the trash so that it can be recovered.
561
+ $paths = $this->get_paths_from_attachment( $issue->postId );
562
+ foreach ( $paths as $path ) {
563
+ if ( !$this->trash_file( $path ) ) {
564
+ $this->log( "Could not trash $path." );
565
+ error_log( "Media Cleaner: Could not trash $path." );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
566
  }
567
  }
568
  wp_delete_attachment( $issue->postId, false );
809
  return false;
810
  }
811
 
812
+ function get_paths_from_attachment( $attachmentId ) {
813
+ $paths = array();
 
 
 
 
 
 
 
 
814
  $fullpath = get_attached_file( $attachmentId );
815
  $mainfile = $this->clean_uploaded_filename( $fullpath );
816
+ array_push( $paths, $mainfile );
817
  $baseUp = pathinfo( $mainfile );
818
+ $filespath = trailingslashit( $this->upload_folder['basedir'] ) . trailingslashit( $baseUp['dirname'] );
819
+ $meta = wp_get_attachment_metadata( $attachmentId );
820
+ if ( isset( $meta['original_image'] ) ) {
821
+ $original_image = $this->clean_uploaded_filename( $filespath . $meta['original_image'] );
822
+ array_push( $paths, $original_image );
823
+ }
824
+ $isImage = isset( $meta, $meta['width'], $meta['height'] );
825
+ $sizes = $this->get_image_sizes();
826
+ if ( $isImage && isset( $meta['sizes'] ) ) {
827
+ foreach ( $meta['sizes'] as $name => $attr ) {
828
+ if ( isset( $attr['file'] ) ) {
829
+ $file = $this->clean_uploaded_filename( $filespath . $attr['file'] );
830
+ array_push( $paths, $file );
831
+ }
832
+ }
833
+ }
834
+ return $paths;
835
+ }
836
+
837
+ function check_media( $attachmentId, $checkOnly = false ) {
838
  $size = 0;
839
  $countfiles = 0;
840
+ $check_broken_media = !$this->check_content;
841
+ $fullpath = get_attached_file( $attachmentId );
842
+ $is_broken = !file_exists( $fullpath );
 
 
 
843
 
844
+ if ( $check_broken_media && !$is_broken )
845
+ return true;
846
 
847
+ $issue = 'NO_CONTENT';
848
+ $paths = $this->get_paths_from_attachment( $attachmentId );
849
+ foreach ( $paths as $path ) {
850
+ if ( $this->check_content && $this->reference_exists( $path, $attachmentId ) )
 
 
 
 
851
  return true;
852
+ $filepath = trailingslashit( $this->upload_folder['basedir'] ) . $path;
853
+ if ( file_exists( $filepath ) )
854
+ $size += filesize( $filepath );
855
+ $countfiles++;
856
+ }
857
+
858
+ if ( $is_broken ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
859
  $this->log( "File {$fullpath} does not exist." );
860
  $issue = 'ORPHAN_MEDIA';
861
  }
 
862
  if ( !$checkOnly ) {
863
+ global $wpdb;
864
  $table_name = $wpdb->prefix . "mclean_scan";
865
+ $mainfile = $this->clean_uploaded_filename( $fullpath );
866
  $wpdb->insert( $table_name,
867
  array(
868
  'time' => current_time('mysql'),
877
  return false;
878
  }
879
 
880
+ // DEBUG: A new check_media function was written (2020/02), which is faster
881
+ // and more optimized - but it's better to keep this one just as a reference in case of issue.
882
+ // function check_media( $attachmentId, $checkOnly = false ) {
883
+ // $this->last_analysis = "N/A";
884
+
885
+ // // Is it an image?
886
+ // $meta = wp_get_attachment_metadata( $attachmentId );
887
+ // $isImage = isset( $meta, $meta['width'], $meta['height'] );
888
+
889
+ // // Get the main file
890
+ // global $wpdb;
891
+ // $fullpath = get_attached_file( $attachmentId );
892
+ // $mainfile = $this->clean_uploaded_filename( $fullpath );
893
+ // $baseUp = pathinfo( $mainfile );
894
+ // $baseUp = $baseUp['dirname'];
895
+
896
+ // $size = 0;
897
+ // $countfiles = 0;
898
+ // $issue = 'NO_CONTENT';
899
+ // if ( file_exists( $fullpath ) ) {
900
+
901
+ // // Special scan: Broken only!
902
+ // if ( !$this->check_content && !$this->check_postmeta && !$this->check_posts && !$this->check_widgets )
903
+ // return true;
904
+
905
+ // $size = filesize( $fullpath );
906
+
907
+ // // Analysis
908
+ // $this->last_analysis = "NONE";
909
+ // $this->log( "Checking Media #{$attachmentId}: {$mainfile}" );
910
+ // if ( $this->check_is_ignore( $mainfile, $attachmentId ) ) {
911
+ // $this->last_analysis = "IGNORED";
912
+ // return true;
913
+ // }
914
+ // if ( $this->reference_exists( $mainfile, $attachmentId ) )
915
+ // return true;
916
+
917
+ // // If images, check the other files as well
918
+ // $countfiles = 0;
919
+ // $sizes = $this->get_image_sizes();
920
+ // if ( $isImage && isset( $meta['sizes'] ) ) {
921
+ // foreach ( $meta['sizes'] as $name => $attr ) {
922
+ // if ( isset( $attr['file'] ) ) {
923
+ // $filepath = $this->upload_folder['basedir'];
924
+ // $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
925
+ // if ( file_exists( $filepath ) )
926
+ // $size += filesize( $filepath );
927
+ // $file = $this->clean_uploaded_filename( $filepath );
928
+ // $countfiles++;
929
+ // // Analysis
930
+ // $this->log( "Checking Media #{$attachmentId}: {$file}" );
931
+ // if ( $this->reference_exists( $file, $attachmentId ) )
932
+ // return true;
933
+ // }
934
+ // }
935
+ // }
936
+ // } else {
937
+ // $this->log( "File {$fullpath} does not exist." );
938
+ // $issue = 'ORPHAN_MEDIA';
939
+ // }
940
+
941
+ // if ( !$checkOnly ) {
942
+ // $table_name = $wpdb->prefix . "mclean_scan";
943
+ // $wpdb->insert( $table_name,
944
+ // array(
945
+ // 'time' => current_time('mysql'),
946
+ // 'type' => 1,
947
+ // 'size' => $size,
948
+ // 'path' => $mainfile . ( $countfiles > 0 ? ( " (+ " . $countfiles . " files)" ) : "" ),
949
+ // 'postId' => $attachmentId,
950
+ // 'issue' => $issue
951
+ // )
952
+ // );
953
+ // }
954
+ // return false;
955
+ // }
956
+
957
  // Delete all issues
958
  function reset_issues( $includingIgnored = false ) {
959
  global $wpdb;
973
 
974
  function echo_issue( $issue ) {
975
  if ( $issue == 'NO_CONTENT' ) {
976
+ _e( "Seems not use", 'media-cleaner' );
977
  }
978
+ else if ( $issue == 'ORPHAN_FILE' ) {
979
+ _e( "Not in Library", 'media-cleaner' );
980
  }
981
  else if ( $issue == 'ORPHAN_RETINA' ) {
982
+ _e( "Orphan Retina", 'media-cleaner' );
983
  }
984
  else if ( $issue == 'ORPHAN_WEBP' ) {
985
+ _e( "Orphan WebP", 'media-cleaner' );
986
  }
987
  else if ( $issue == 'ORPHAN_MEDIA' ) {
988
+ _e( "No attached file", 'media-cleaner' );
989
  }
990
  else {
991
  echo $issue;
999
  */
1000
 
1001
  function wpmc_init( $mainfile ) {
1002
+ //register_activation_hook( $mainfile, 'wpmc_install' );
1003
  //register_deactivation_hook( $mainfile, 'wpmc_uninstall' );
1004
  register_uninstall_hook( $mainfile, 'wpmc_uninstall' );
1005
  }
1006
 
1007
+ function wpmc_install() {
1008
+ wpmc_create_database();
1009
+ }
1010
+
1011
  function wpmc_reset () {
1012
+ wpmc_remove_database();
1013
+ wpmc_create_database();
1014
+ }
 
 
 
 
1015
 
1016
+ function wpmc_uninstall () {
1017
+ wpmc_remove_options();
1018
+ wpmc_remove_database();
1019
  }
1020
 
1021
+ function wpmc_create_database() {
1022
  global $wpdb;
1023
  $table_name = $wpdb->prefix . "mclean_scan";
1024
  $charset_collate = $wpdb->get_charset_collate();
1034
  issue TINYTEXT NOT NULL,
1035
  PRIMARY KEY (id)
1036
  ) " . $charset_collate . ";" ;
1037
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
1038
  dbDelta( $sql );
1039
  $sql="ALTER TABLE $table_name ADD INDEX IgnoredIndex (ignored) USING BTREE;";
1040
  $wpdb->query($sql);
1049
  originType VARBINARY(32) NOT NULL,
1050
  PRIMARY KEY (id)
1051
  ) " . $charset_collate . ";";
1052
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
1053
  dbDelta( $sql );
1054
  }
1055
 
1056
+ function wpmc_remove_options() {
1057
+ global $wpdb;
1058
+ $options = $wpdb->get_results( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'wpmc_%'" );
1059
+ foreach( $options as $option ) {
1060
+ delete_option( $option->option_name );
1061
+ }
1062
+ }
1063
+
1064
+ function wpmc_remove_database() {
1065
  global $wpdb;
1066
  $table_name1 = $wpdb->prefix . "mclean_scan";
1067
  $table_name2 = $wpdb->prefix . "mclean_refs";
engine.php CHANGED
@@ -12,23 +12,23 @@ class Meow_WPMC_Engine {
12
  */
13
 
14
  // Parse the posts for references (based on $limit and $limitsize for paging the scan)
15
- function parse( $limit, $limitsize, &$message = '' ) {
16
  if ( empty( $limit ) )
17
  $this->core->reset_issues();
18
 
19
- $method = get_option( 'wpmc_method', 'media' );
20
  $check_library = get_option(' wpmc_media_library', true );
21
  $check_content = get_option( 'wpmc_content', true );
22
- //$check_postmeta = get_option( 'wpmc_postmeta', false );
23
- //$check_posts = get_option( 'wpmc_posts', false );
24
- //$check_widgets = get_option( 'wpmc_widgets', true );
25
 
26
  if ( $method == 'media' && !$check_content ) {
27
- $message = __( "Posts, content analysis is off. Done.", 'media-cleaner' );
28
  return true;
29
  }
30
- if ( $method == 'files' && $check_library && !$check_content ) {
31
- $message = __( "Posts, library check and content analysis are off. Done.", 'media-cleaner' );
 
 
 
32
  return true;
33
  }
34
 
@@ -51,7 +51,7 @@ class Meow_WPMC_Engine {
51
 
52
  // Only at the beginning
53
  if ( empty( $limit ) ) {
54
- $this->core->log( "Parsed references:" );
55
  //if ( get_option( 'wpmc_widgets', false ) ) {
56
 
57
  global $wp_registered_widgets;
@@ -94,7 +94,57 @@ class Meow_WPMC_Engine {
94
  $finished = count( $posts ) < $limitsize;
95
  if ( $finished )
96
  $this->core->log();
97
- $message = __( "Posts checked.", 'media-cleaner' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  return $finished;
99
  }
100
 
12
  */
13
 
14
  // Parse the posts for references (based on $limit and $limitsize for paging the scan)
15
+ function extractRefsFromContent( $limit, $limitsize, &$message = '' ) {
16
  if ( empty( $limit ) )
17
  $this->core->reset_issues();
18
 
19
+ $method = $this->core->current_method;
20
  $check_library = get_option(' wpmc_media_library', true );
21
  $check_content = get_option( 'wpmc_content', true );
 
 
 
22
 
23
  if ( $method == 'media' && !$check_content ) {
24
+ $message = __( "Skipped, as Content is not selected.", 'media-cleaner' );
25
  return true;
26
  }
27
+ // DEBUG: This condition was used in a previous version of the plugin
28
+ // but it looks like a mistake. The $check_library was removed.
29
+ // if ( $method == 'files' && $check_library && !$check_content ) {
30
+ if ( $method == 'files' && !$check_content ) {
31
+ $message = __( "Skipped, as Content is not selected.", 'media-cleaner' );
32
  return true;
33
  }
34
 
51
 
52
  // Only at the beginning
53
  if ( empty( $limit ) ) {
54
+ $this->core->log( "References from Content:" );
55
  //if ( get_option( 'wpmc_widgets', false ) ) {
56
 
57
  global $wp_registered_widgets;
94
  $finished = count( $posts ) < $limitsize;
95
  if ( $finished )
96
  $this->core->log();
97
+ $elapsed = $this->core->timeout_get_elapsed();
98
+ $message = sprintf(
99
+ // translators: %1$d is number of posts, %2$s is time in milliseconds
100
+ __( "Extracted references from %1\$d posts in %2\$s.", 'media-cleaner' ), count( $posts ), $elapsed
101
+ );
102
+ return $finished;
103
+ }
104
+
105
+ // Parse the posts for references (based on $limit and $limitsize for paging the scan)
106
+ function extractRefsFromLibrary( $limit, $limitsize, &$message = '' ) {
107
+ $method = $this->core->current_method;
108
+ if ( $method == 'media' ) {
109
+ $message = __( "Skipped, as it is not needed for the Media Library method.", 'media-cleaner' );
110
+ return true;
111
+ }
112
+ $check_library = get_option(' wpmc_media_library', true );
113
+ if ( !$check_library ) {
114
+ $message = __( "Skipped, as Media Library is not selected.", 'media-cleaner' );
115
+ return true;
116
+ }
117
+
118
+ global $wpdb;
119
+ $medias = $wpdb->get_col( $wpdb->prepare( "SELECT p.ID FROM $wpdb->posts p
120
+ WHERE p.post_status = 'inherit'
121
+ AND p.post_type = 'attachment'
122
+ LIMIT %d, %d", $limit, $limitsize
123
+ )
124
+ );
125
+
126
+ // Only at the beginning
127
+ if ( empty( $limit ) ) {
128
+ $this->core->log( "References from Media Library:" );
129
+ }
130
+
131
+ $this->core->timeout_check_start( count( $medias ) );
132
+ foreach ( $medias as $media ) {
133
+ $this->core->timeout_check();
134
+ // Check the media
135
+ $paths = $this->core->get_paths_from_attachment( $media );
136
+ $this->core->add_reference_url( $paths, 'MEDIA LIBRARY' );
137
+ $this->core->timeout_check_additem();
138
+ }
139
+
140
+ // Write the references found (and cached) by the parsers
141
+ $this->core->write_references();
142
+
143
+ $finished = count( $medias ) < $limitsize;
144
+ if ( $finished )
145
+ $this->core->log();
146
+ $elapsed = $this->core->timeout_get_elapsed();
147
+ $message = sprintf( __( "Extracted references from %d $medias in %s.", 'media-cleaner' ), count( $medias ), $elapsed );
148
  return $finished;
149
  }
150
 
languages/media-cleaner-ru_RU.mo ADDED
Binary file
languages/media-cleaner-ru_RU.po ADDED
@@ -0,0 +1,1104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Translation of Plugins - Media Cleaner - Development (trunk) in Russian
2
+ # This file is distributed under the same license as the Plugins - Media Cleaner - Development (trunk) package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Plugins - Media Cleaner - Development (trunk)\n"
6
+ "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/media-cleaner-"
7
+ "pro\n"
8
+ "POT-Creation-Date: 2020-01-30T12:27:36+03:00\n"
9
+ "PO-Revision-Date: 2020-01-30 12:27+0300\n"
10
+ "Last-Translator: Ilya Ivanov <czweerwolf@gmail.com>\n"
11
+ "Language-Team: \n"
12
+ "Language: ru\n"
13
+ "MIME-Version: 1.0\n"
14
+ "Content-Type: text/plain; charset=UTF-8\n"
15
+ "Content-Transfer-Encoding: 8bit\n"
16
+ "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
17
+ "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
18
+ "X-Generator: Poedit 2.2.4\n"
19
+
20
+ #. Plugin Name of the plugin
21
+ msgid "Media Cleaner Pro"
22
+ msgstr "Media Cleaner Pro"
23
+
24
+ #. Plugin URI of the plugin
25
+ #. Author URI of the plugin
26
+ msgid "https://meowapps.com"
27
+ msgstr "https://meowapps.com"
28
+
29
+ #. Description of the plugin
30
+ msgid "Clean your Media Library, many options, trash system."
31
+ msgstr ""
32
+ "Почистите вашу библиотеку медиафайлов: много настроек, поддержка удаления "
33
+ "в корзину."
34
+
35
+ #. Author of the plugin
36
+ msgid "Jordy Meow"
37
+ msgstr "Jordy Meow"
38
+
39
+ #: admin.php:41
40
+ msgid "Invalid Regular-Expression"
41
+ msgstr "Неверное регулярное выражение"
42
+
43
+ #: admin.php:66
44
+ msgid ""
45
+ "The Media Cleaner's database has been deleted. It will be re-created "
46
+ "automatically next time you visit the Media Cleaner Dashboard."
47
+ msgstr ""
48
+ "База данных Media Cleaner была удалена. Она автоматически пересоздастся "
49
+ "в следующий раз, когда вы посетите панель управления Media Cleaner."
50
+
51
+ #: admin.php:72
52
+ msgid ""
53
+ "The Pro version is required to scan files. You can <a target='_blank' "
54
+ "href='http://meowapps.com/plugin/media-cleaner'>get a serial for the Pro "
55
+ "version here</a>."
56
+ msgstr ""
57
+ "Для сканирования файлов необходима версия Pro. Вы можете <a target='_blank' "
58
+ "href='http://meowapps.com/plugin/media-cleaner'>получить серийный номер для "
59
+ "версии Pro здесь</a>."
60
+
61
+ #: admin.php:89
62
+ msgid "Method"
63
+ msgstr "Метод"
64
+
65
+ #: admin.php:92
66
+ msgid "Content"
67
+ msgstr "Содержимое"
68
+
69
+ #: admin.php:95 admin.php:340
70
+ msgid "Media Library"
71
+ msgstr "Библиотека медиазаписей"
72
+
73
+ #: admin.php:98
74
+ msgid "Live Content<br />(Pro)"
75
+ msgstr "Живое содержимое<br />(Pro)"
76
+
77
+ #: admin.php:116
78
+ msgid "Logs"
79
+ msgstr "Журналы"
80
+
81
+ #: admin.php:118 admin.php:436
82
+ msgid "Enable"
83
+ msgstr "Включить"
84
+
85
+ #: admin.php:122
86
+ msgid "Thumbnails Only"
87
+ msgstr "Только миниатюры"
88
+
89
+ #: admin.php:128
90
+ msgid "Directories Filter"
91
+ msgstr "Фильтр директорий"
92
+
93
+ #: admin.php:136
94
+ msgid "Files Filter"
95
+ msgstr "Фильтр файлов"
96
+
97
+ #: admin.php:144
98
+ msgid "Thumbnails"
99
+ msgstr "Миниатюры"
100
+
101
+ #: admin.php:147
102
+ msgid "Warning Message"
103
+ msgstr "Предупреждающее сообщение"
104
+
105
+ #: admin.php:150
106
+ msgid "Results Per Page"
107
+ msgstr "Результатов на странице"
108
+
109
+ #: admin.php:156
110
+ msgid "Medias Buffer"
111
+ msgstr "Буфер медиазаписей"
112
+
113
+ #: admin.php:159
114
+ msgid "Posts Buffer"
115
+ msgstr "Буфер записей"
116
+
117
+ #: admin.php:162
118
+ msgid "Analysis Buffer"
119
+ msgstr "Буфер анализа"
120
+
121
+ #: admin.php:165
122
+ msgid "Delay (in ms)"
123
+ msgstr "Задержка (в мс)"
124
+
125
+ #: admin.php:168
126
+ msgid "Shortcodes"
127
+ msgstr "Шорткоды"
128
+
129
+ #: admin.php:197
130
+ msgid ""
131
+ "The number of media entries to read at a time. This is fast, so the value "
132
+ "should be between 50 and 1000."
133
+ msgstr ""
134
+ "Сколько медиазаписей читать за один раз. Это быстро, поэтому значение должно "
135
+ "быть между 50 и 1000."
136
+
137
+ #: admin.php:204
138
+ msgid ""
139
+ "The number of posts (and any other post types) to analyze at a time. This is "
140
+ "the most intense part of the process. Recommended value is between 1 (slow "
141
+ "server) and 20 (excellent server)."
142
+ msgstr ""
143
+ "Сколько записей (или записей произвольного типа) анализировать за один раз. "
144
+ "Это наиболее интенсивная часть процесса. Рекомендуемое значение — между 1 "
145
+ "(для медленных серверов) и 20 (для отличных серверов)."
146
+
147
+ #: admin.php:211
148
+ msgid ""
149
+ "The number of media entries or files to analyze at a time. This is the main "
150
+ "part of the process, but is is much faster than analyzing each post. "
151
+ "Recommended value is between 20 (slow server) and 1000 (excellent server)."
152
+ msgstr ""
153
+ "Сколько медиазаписей или медиафайлов анализировать за 1 раз. Это основная "
154
+ "часть процесса, но она гораздо быстрее, чем анализ каждой записи. "
155
+ "Рекомендуемое значение — между 20 (для слабых серверов) и 1000 (для отличных "
156
+ "серверов)."
157
+
158
+ #: admin.php:218
159
+ msgid ""
160
+ "Time to wait between each request (in milliseconds). The overall process is "
161
+ "intensive so this gives the chance to your server to chill out a bit. A very "
162
+ "good server doesn't need it, but a slow/shared hosting might even reject "
163
+ "requests if they are too fast and frequent. Recommended value is actually 0, "
164
+ "100 for safety, 2000 or 5000 if your hosting is kind of cheap."
165
+ msgstr ""
166
+ "Сколько времени ждать между запросами (в миллисекундах). Поскольку в целом "
167
+ "процесс довольно интенсивный, эта настройка дает серверу возможность слегка "
168
+ "передохнуть. Очень хороший сервер в этом не нуждается, но медленный/"
169
+ "виртуальный хостинг может даже отклонять запросы, если они слишком быстрые и "
170
+ "частые. Рекомендуемое значение на самом деле 0, но для безопасности — 100; "
171
+ "если у вас хостинг из разряда дешёвых — 2000 или 5000."
172
+
173
+ #: admin.php:230
174
+ msgid "How to use"
175
+ msgstr "Как использовать"
176
+
177
+ #: admin.php:232
178
+ msgid ""
179
+ "You can choose two kind of methods. Usually, users like to analyze their "
180
+ "Media Library for images which are not in used (Media Library Method + "
181
+ "Content Check), and then, their Filesystem for images which aren't "
182
+ "registered in the Media Library (Filesystem Method + Media Library Check). "
183
+ "Check the <a target=\"_blank\" href=\"https://meowapps.com/media-cleaner-"
184
+ "tutorial/\">tutorial</a> for more information."
185
+ msgstr ""
186
+ "Вы можете использовать два подхода к выбору методов. Как правило, "
187
+ "пользователи предпочитают искать неиспользуемые изображения в библиотеке "
188
+ "медиафайлов (метод «Библиотека медиафайлов» + флаг «проверка» напротив "
189
+ "пункта «Содержимое»), а затем — проверять свою файловую систему на наличие "
190
+ "изображений, которые не зарегистрированы в библиотеке медиафайлов (метод "
191
+ "«Файловая система» + флаг «проверка» напротив пункта «Библиотека "
192
+ "медиафайлов»). Сверьтесь с <a target=\"_blank\" href=\"https://meowapps.com/"
193
+ "media-cleaner-tutorial/\">обучающей инструкцией</a>, чтобы узнать больше."
194
+
195
+ #: admin.php:234
196
+ msgid "Access Media Cleaner Dashboard"
197
+ msgstr "Перейти в панель управления Media Cleaner"
198
+
199
+ #: admin.php:235
200
+ msgid "Delete Cleaner DB"
201
+ msgstr "Удалить Cleaner DB"
202
+
203
+ #: admin.php:246
204
+ msgid "Scanning"
205
+ msgstr "Сканирование"
206
+
207
+ #: admin.php:257
208
+ msgid "Filters"
209
+ msgstr "Фильтры"
210
+
211
+ #: admin.php:274
212
+ msgid "UI"
213
+ msgstr "Интерфейс"
214
+
215
+ #: admin.php:285
216
+ msgid "Advanced"
217
+ msgstr "Продвинутые настройки"
218
+
219
+ #: admin.php:341
220
+ msgid "Filesystem (Pro)"
221
+ msgstr "Файловая система (Pro)"
222
+
223
+ #: admin.php:342
224
+ msgid ""
225
+ "Check the <a target=\"_blank\" href=\"https://meowapps.com/media-cleaner-"
226
+ "tutorial/\">tutorial</a> for more information."
227
+ msgstr ""
228
+ "Обратитесь к <a target=\"_blank\" href=\"https://meowapps.com/media-cleaner-"
229
+ "tutorial/\">обучающей инструкции</a> за дополнительными сведениями."
230
+
231
+ #: admin.php:356
232
+ msgid "Creates an internal log file, for debugging purposes."
233
+ msgstr "Создаёт внутренний файл журнала, в целях отладки."
234
+
235
+ #: admin.php:359
236
+ msgid ""
237
+ "<br /><b>Cannot create the logging file. Logging will not work. The plugin "
238
+ "as a whole might not be able to work neither.</b>"
239
+ msgstr ""
240
+ "<br /><b>Не удалось создать файл журнала. Ведение журнала не будет работать. "
241
+ "Вероятно, что и сам плагин не сможет функционировать.</b>"
242
+
243
+ #. translators: %s is a plugin directory url
244
+ #: admin.php:365
245
+ msgid ""
246
+ "<br />The <a target=\"_blank\" href=\"%smedia-cleaner.log\">log file</a> is "
247
+ "available. You can also <a href=\"?page=wpmc_settings-menu&clearlogs=true"
248
+ "\">clear</a> it."
249
+ msgstr ""
250
+ "<br />Доступен<a target=\"_blank\" href=\"%smedia-cleaner.log\">файл "
251
+ "журнала</a>. Вы можете <a href=\"?page=wpmc_settings-menu&clearlogs=true"
252
+ "\">очистить</a> его."
253
+
254
+ #: admin.php:378 admin.php:386 admin.php:395 common/admin.php:451
255
+ #: common/admin.php:501
256
+ msgid "Check"
257
+ msgstr "Проверить"
258
+
259
+ #: admin.php:378
260
+ msgid ""
261
+ "Checks if the file is linked to a media. <i>Only matters to the Filesystem "
262
+ "Method.</i>"
263
+ msgstr ""
264
+ "Проверяет, связан ли файл с записью. <i>Играет роль только для метода "
265
+ "«Файловая система».</i>"
266
+
267
+ #: admin.php:386
268
+ msgid ""
269
+ "Check if the media/file is used in the content, such as Posts, Pages (and "
270
+ "other Post Types), Metadata, Widgets, etc."
271
+ msgstr ""
272
+ "Првоеряет, используется ли медиафайл/медиазапись в содержимом, таком как "
273
+ "Записи, Страницы (и прочие типы записей), Метаданные, Виджеты и др."
274
+
275
+ #: admin.php:395
276
+ msgid ""
277
+ "The live version of the website will be also analyzed (as if a visitor was "
278
+ "loading it). <i>This will increase the accuracy of the results.</i>"
279
+ msgstr ""
280
+ "Живая версия сайта тоже будет проанализирована (как если бы посетитель "
281
+ "загружал её). <i>Это увеличит точность результатов.</i>"
282
+
283
+ #: admin.php:403
284
+ msgid "Disable Analysis"
285
+ msgstr "Отключить анализ"
286
+
287
+ #: admin.php:403
288
+ msgid ""
289
+ "Resolving shortcodes increase accuracy, but makes the process slower and "
290
+ "takes more memory."
291
+ msgstr ""
292
+ "Получение шорткодов увеличивает точность, но замедляет процесс и потребляет "
293
+ "больше памяти."
294
+
295
+ #: admin.php:411 admin.php:419
296
+ msgid "Hide"
297
+ msgstr "Скрыть"
298
+
299
+ #: admin.php:411
300
+ msgid "If you prefer not to see the thumbnails."
301
+ msgstr "Если вы предпочитаете не видеть миниатюры."
302
+
303
+ #: admin.php:419
304
+ msgid "Have you read it twice? If yes, hide it :)"
305
+ msgstr "Вы прочли его дважды? Если да, скройте :)"
306
+
307
+ #: admin.php:436
308
+ msgid ""
309
+ "Restrict the filesystem scan to thumbnails (files containing the "
310
+ "resolution). If none of the checks above are selected, you will get the list "
311
+ "of all the thumbnails and be able to remove them."
312
+ msgstr ""
313
+ "Ограничить файловую систему сканированием миниатюр (файлов, содержащих "
314
+ "разрешение). Если ни одна из указанных выше проверок не выбрана, вы получите "
315
+ "список всех миниатюр и сможете удалить их."
316
+
317
+ #. translators: %d is a count of files
318
+ #: api.php:71 api.php:89
319
+ msgid "Retrieved %d targets."
320
+ msgstr "Получено %d целей."
321
+
322
+ #: api.php:104
323
+ msgid "No task."
324
+ msgstr "Нет задачи."
325
+
326
+ #. translators: %1$d is a number of targets, %2$d is a number of issues, %3$s is elapsed time in milliseconds
327
+ #: api.php:145
328
+ msgid "Checked %1$d targets and found %2$d issues in %3$s."
329
+ msgstr "Проверено %1$d целей и найдено %2$d проблем в %3$s."
330
+
331
+ #: api.php:178 api.php:192
332
+ msgid "List generated."
333
+ msgstr "Список создан."
334
+
335
+ #: api.php:210 api.php:228 api.php:246
336
+ msgid "Status unknown."
337
+ msgstr "Статус неизвестен."
338
+
339
+ #: api.php:260
340
+ msgid "Invalid Option Value"
341
+ msgstr "Неверное значение параметра"
342
+
343
+ #: common/admin.php:60
344
+ msgid "Did nothing but a blank request."
345
+ msgstr "Ничего не произошло, кроме пустого запроса."
346
+
347
+ #. translators: %s is a filename of an empty temporary file
348
+ #: common/admin.php:67
349
+ msgid "Created and deleted %s"
350
+ msgstr "Создан и удалён %s"
351
+
352
+ #. translators: %1$s is a plugin nicename, %2$s is a short url (slug)
353
+ #: common/admin.php:113
354
+ msgid ""
355
+ "You have been using <b>%1$s</b> for some time now. Thank you! Could you "
356
+ "kindly share your opinion with me, along with, maybe, features you would "
357
+ "like to see implemented? Then, please <a style=\"font-weight: bold; color: "
358
+ "#b926ff;\" target=\"_blank\" href=\"https://wordpress.org/support/plugin/"
359
+ "%2$s/reviews/?rate=5#new-post\">write a little review</a>. That will also "
360
+ "bring me joy and motivation, and I will get back to you :) <u>In the case "
361
+ "you already have written a review</u>, please check again. Many reviews got "
362
+ "removed from WordPress recently."
363
+ msgstr ""
364
+ "Вы используете <b>%1$s</b> уже некоторое время. Спасибо! Не могли бы вы "
365
+ "любезно поделиться со мной своим мнением, наряду с, возможно, функциями, "
366
+ "которые вы хотели бы видеть реализованными? Тогда, пожалуйста, <a style="
367
+ "\"font-weight: bold; color: #b926ff;\" target=\"_blank\" href=\"https://"
368
+ "wordpress.org/support/plugin/%2$s/reviews/?rate=5#new-post\">напишите "
369
+ "небольшой отзыв</a>. Это принесёт мне радость, и я верну её вам :) <u>В "
370
+ "случае, если вы уже оставляли отзыв</u>, пожалуйста, взгляните на него ещё "
371
+ "разок. Многие отзывы недавно были удалены из WordPress."
372
+
373
+ #: common/admin.php:121
374
+ msgid "Never remind me!"
375
+ msgstr "Никогда не напоминайте!"
376
+
377
+ #: common/admin.php:126
378
+ msgid "Remind me in a few weeks..."
379
+ msgstr "Напомните мне через пару недель..."
380
+
381
+ #: common/admin.php:131
382
+ msgid "Yes, I did it!"
383
+ msgstr "Да, я сделал это!"
384
+
385
+ #. translators: %s is a plugin nicename
386
+ #: common/admin.php:169
387
+ msgid ""
388
+ "<p>It looks like you are using the free version of the plugin (<b>%s</b>) "
389
+ "but a license for the Pro version was also found. The Pro version might have "
390
+ "been replaced by the Free version during an update (might be caused by a "
391
+ "temporarily issue). If it is the case, <b>please download it again</b> from "
392
+ "the <a target=\"_blank\" href=\"https://store.meowapps.com\">Meow Store</a>. "
393
+ "If you wish to continue using the free version and clear this message, click "
394
+ "on this button."
395
+ msgstr ""
396
+ "<p>Кажется, вы используете бесплатную версию плагина (<b>%s</b>), но и "
397
+ "лицензия от версии Pro обнаружена тоже. Версия Pro могла быть замещена "
398
+ "бесплатной версией во время обновления (такое может случиться из-за "
399
+ "временных накладок). В этом случае, <b>пожалуйста, скачайте её заново</b> из "
400
+ "<a target=\"_blank\" href=\"https://store.meowapps.com\">Магазине Meow</a>. "
401
+ "Если вы хотите продолжить пользоваться бесплатной версией и убрать это "
402
+ "сообщение, щёлкните на эту кнопку."
403
+
404
+ #: common/admin.php:175
405
+ msgid "Remove the license"
406
+ msgstr "Удалить лицензию"
407
+
408
+ #: common/admin.php:219 common/admin.php:220
409
+ msgid "Dashboard"
410
+ msgstr "Панель управления"
411
+
412
+ #: common/admin.php:225
413
+ msgid "Main Menu"
414
+ msgstr "Главное меню"
415
+
416
+ #: common/admin.php:228
417
+ msgid "SSL Verify"
418
+ msgstr "Проверка SSL"
419
+
420
+ #: common/admin.php:243
421
+ msgid "<label>Hide</label><br /><small>Doesn't display the ads.</small>"
422
+ msgstr "<label>Скрыть</label><br /><small>Не отображать рекламу.</small>"
423
+
424
+ #: common/admin.php:251
425
+ msgid ""
426
+ "<label>Hide <b>Meow Apps</b> Menu</label><br /><small>Hide Meow Apps menu "
427
+ "and all its components, for a cleaner admin. This option will be reset if a "
428
+ "new Meow Apps plugin is installed. <b>Once activated, an option will be "
429
+ "added in your General settings to display it again.</b></small>"
430
+ msgstr ""
431
+ "<label>Скрыть меню <b>Meow Apps</b></label><br /><small>Скрыть меню Meow "
432
+ "Apps и все его компоненты ради чистоты панели управления. Эта настройка "
433
+ "будет сброшена при установке любого другого плагина Meow Apps. <b>При "
434
+ "активации аналогичная опция появится на странице «Общие настройки», чтобы "
435
+ "ее можно было отключить.</b></small>"
436
+
437
+ #: common/admin.php:259
438
+ msgid ""
439
+ "<label>Force</label><br /><small>Updates and licenses checks are usually "
440
+ "made without checking SSL certificates and it is actually fine this way. But "
441
+ "if you are intransigent when it comes to SSL matters, this option will force "
442
+ "it.</small>"
443
+ msgstr ""
444
+ "<label>Принудительно</label><br /><small>Обновления и проверка лицензий "
445
+ "обычно проводятся без определения подлинности SSL-сертификатов, и в целом "
446
+ "это нормально. Но если вы категорический сторонник проверки SSL, эта "
447
+ "настройка выполнит ее принудительно.</small>"
448
+
449
+ #: common/admin.php:266
450
+ msgid "Pro Version"
451
+ msgstr "Версия Pro"
452
+
453
+ #: common/admin.php:267
454
+ msgid "(enabled)"
455
+ msgstr "(включена)"
456
+
457
+ #: common/admin.php:267
458
+ msgid "(disabled)"
459
+ msgstr "(выключена)"
460
+
461
+ #. translators: %1$s is a url attribute, %2$s is a url visible for user
462
+ #: common/admin.php:275
463
+ msgid ""
464
+ "More information about the Pro version here: <a target=\"_blank\" href=\"%1$s"
465
+ "\">%2$s</a>. If you actually bought the Pro version already, please remove "
466
+ "the current plugin and download the Pro version from your account at the <a "
467
+ "target=\"_blank\" href=\"https://store.meowapps.com/account/downloads/"
468
+ "\">Meow Apps Store</a>."
469
+ msgstr ""
470
+ "Больше информации о версии Pro — здесь: <a target=\"_blank\" href=\"%1$s\">"
471
+ "%2$s</a>. Если вы уже купили платную версию, пожалуйста, удалите этот плагин "
472
+ "и скачайте версию Pro из вашей учетной записи в <a target=\"_blank\" href="
473
+ "\"https://store.meowapps.com/account/downloads/\">Магазине Meow Apps</a>."
474
+
475
+ #: common/admin.php:294
476
+ msgid "install"
477
+ msgstr "установить"
478
+
479
+ #: common/admin.php:316
480
+ msgid "enable"
481
+ msgstr "включить"
482
+
483
+ #: common/admin.php:321
484
+ msgid "Meow Apps: The function common_url( $file ) needs to be overriden."
485
+ msgstr "Meow Apps: функция common_url( $file ) должна быть переопределена."
486
+
487
+ #: common/admin.php:341 common/admin.php:357
488
+ msgid "Go back"
489
+ msgstr "Вернуться"
490
+
491
+ #: common/admin.php:352
492
+ msgid "=== MEOW APPS DEBUG (This is not an error) ==="
493
+ msgstr "=== ОТЛАДКА MEOW APPS (Это не ошибка) ==="
494
+
495
+ #: common/admin.php:361
496
+ msgid "Write in the Error Logs"
497
+ msgstr "Записать в журналы ошибок"
498
+
499
+ #. translators: %s is a preformatted timestamp
500
+ #: common/admin.php:367
501
+ msgid "Now (auto-reload every 5 seconds): [%s UTC]"
502
+ msgstr "Сейчас (автоперезагрузка каждые 5 секунд): [%s UTC]"
503
+
504
+ #: common/admin.php:370
505
+ msgid "Errors (order by latest)"
506
+ msgstr "Ошибки (сортировка по новизне)"
507
+
508
+ #: common/admin.php:378
509
+ msgid ""
510
+ "The PHP Error Logs cannot be found. Please ask your hosting service for it."
511
+ msgstr ""
512
+ "Журналы ошибок PHP не найдены. Пожалуйста, запросите их подключение у своего "
513
+ "хостера."
514
+
515
+ #: common/admin.php:388
516
+ msgid ""
517
+ "Meow Apps is run by Jordy Meow, a photographer and software developer living "
518
+ "in Japan (and taking <a target=\"_blank\" href=\"http://offbeatjapan.org\">a "
519
+ "lot of photos</a>). Meow Apps is a suite of plugins focusing on photography, "
520
+ "imaging, optimization and it teams up with the best players in the community "
521
+ "(other themes and plugins developers). For more information, please check <a "
522
+ "href=\"http://meowapps.com\" target=\"_blank\">Meow Apps</a>."
523
+ msgstr ""
524
+ "Meow Apps — проект Jordy Meow, фотографа и разработчика ПО, живущего в "
525
+ "Японии (и снимающего <a target=\"_blank\" href=\"http://offbeatjapan.org"
526
+ "\">множество фото</a>). Meow Apps — это комплект плагинов, сфокусированных "
527
+ "на фотографии, обработке изображений и оптимизации, который сотрудничает "
528
+ "с лучшими игроками сообщества (разработчиками других тем и плагинов). За "
529
+ "дополнительной информацией заходите на сайт <a href=\"http://meowapps.com\" "
530
+ "target=\"_blank\">Meow Apps</a>."
531
+
532
+ #: common/admin.php:392
533
+ msgid "Featured Plugins"
534
+ msgstr "Избранные плагины"
535
+
536
+ #: common/admin.php:399
537
+ msgid "Detect the files which are not in use."
538
+ msgstr "Обнаруживает файлы, которые не используются."
539
+
540
+ #: common/admin.php:403
541
+ msgid "For nicer filenames and a better SEO."
542
+ msgstr "Для упорядочивания названий файлов и улучшения SEO."
543
+
544
+ #: common/admin.php:407
545
+ msgid "A simpler, nicer, prettier contact form."
546
+ msgstr "Более простая, удобная и красивая контактная форма."
547
+
548
+ #: common/admin.php:411
549
+ msgid "The famous plugin that adds Retina support."
550
+ msgstr "Знаменитый плагин, который добавляет поддержку Retina."
551
+
552
+ #: common/admin.php:420
553
+ msgid ""
554
+ "Beautiful but lightweight gallery with many layouts. The only one that "
555
+ "allows you to uninstall it without losing anything."
556
+ msgstr ""
557
+ "Красивая, но легкая галерея со множеством вариантов компоновки. "
558
+ "Единственная, которая позволит вам удалить её, ничего при этом не потеряв."
559
+
560
+ #: common/admin.php:424
561
+ msgid ""
562
+ "Pretty and ultra-optimized Lightbox which can also display your EXIF data. "
563
+ "You will love it."
564
+ msgstr ""
565
+ "Красивый и супероптимизированный Лайтбокс, который может ещё и отображать "
566
+ "ваши EXIF данные. Вы полюбите его."
567
+
568
+ #: common/admin.php:428
569
+ msgid ""
570
+ "Synchronize your Lightroom to your WordPress. This plugin is loved by all "
571
+ "the photographers using Lightroom and WordPress."
572
+ msgstr ""
573
+ "Синхронизируйте Lightroom с вашим WordPress. Этот плагин обожают все "
574
+ "фотографы, которые пользуются Lightroom и WordPress."
575
+
576
+ #: common/admin.php:433
577
+ msgid "WordPress Performance & Recommendations"
578
+ msgstr "Производительность WordPress и рекомендации"
579
+
580
+ #: common/admin.php:435
581
+ msgid ""
582
+ "The <b>Empty Request Time</b> helps you analyzing the raw performance of "
583
+ "your install by giving you the average time it takes to run an empty request "
584
+ "to your server. You can try to disable some plugins (or change their "
585
+ "options) then and click on Reset to see how it influences the results. With "
586
+ "<b>File Operation Time</b>, you will find out if your server is slow with "
587
+ "files. An excellent install would have an Empty Request Time of less than "
588
+ "500 ms. Keep it absolutely under 2,000 ms. File Operation Time should take "
589
+ "only a few milliseconds more than the Empty Request Time. For more "
590
+ "information about this, <a href=\"https://meowapps.com/clean-optimize-"
591
+ "wordpress/#Optimize_your_Empty_Request_Time\" target=\"_blank\">click here</"
592
+ "a>."
593
+ msgstr ""
594
+ "<b>«Время пустого запроса»</b> помогает приблизительно оценить "
595
+ "производительность вашей установки путём измерения среднего времени, которое "
596
+ "требуется серверу на обработку пустого запроса. Вы можете попробовать "
597
+ "отключить некоторые плагины (или изменить их настройки), а затем щёлкнуть на "
598
+ "«Сбросить», чтобы проверить, как это повлияет на результаты. С помощью теста "
599
+ "<b>«Время файловой операции»</b> вы выясните, тормозит ли ваш сервер при "
600
+ "обработке файлов. В идеале время пустого запроса должно составлять "
601
+ "&#60; 500 мс. Всегда держите его в пределах 2000 мс. Файловая операция "
602
+ "должна занимать всего на несколько миллисекунд больше, чем обработка пустого "
603
+ "запроса. Чтобы получить больше информации на эту тему, <a href=\"https://"
604
+ "meowapps.com/clean-optimize-wordpress/#Optimize_your_Empty_Request_Time\" "
605
+ "target=\"_blank\">щёлкните сюда</a>."
606
+
607
+ #: common/admin.php:439
608
+ msgid "Empty Request Time"
609
+ msgstr "Время пустого запроса"
610
+
611
+ #: common/admin.php:440 common/admin.php:449 common/admin.php:464
612
+ msgid "N/A"
613
+ msgstr "Н/Д"
614
+
615
+ #: common/admin.php:441
616
+ msgid "Based on"
617
+ msgstr "На основании"
618
+
619
+ #: common/admin.php:442
620
+ msgid "request(s)"
621
+ msgstr "запрос(а, ов)"
622
+
623
+ #: common/admin.php:448
624
+ msgid "File Operation Time"
625
+ msgstr "Время файловой операции"
626
+
627
+ #: common/admin.php:450
628
+ msgid "Create temporary file and delete it."
629
+ msgstr "Создать/удалить временный файл."
630
+
631
+ #: common/admin.php:483 common/admin.php:500
632
+ msgid "ms"
633
+ msgstr "мс"
634
+
635
+ #: common/admin.php:517
636
+ msgid ""
637
+ "Too many WordPress installs are blown-up with useless and/or huge plugins, "
638
+ "and bad practices. But that is because most users are overwhelmed by the "
639
+ "diversity and immensity of the WordPress jungle. One rule of thumb is to "
640
+ "keep your install the simplest as possible, with the least number of plugins "
641
+ "(avoiding heavy ones too) and a good hosting service (avoid VPS except if "
642
+ "you know exactly what you are doing). Articles are kept being updated on the "
643
+ "Meow Apps website, with all the latest recommendations: "
644
+ msgstr ""
645
+ "Cлишком многие установки WordPress раздуты бесполезными и/или огромными "
646
+ "плагинами и применением плохих практик. А причина в том, что люди теряются "
647
+ "от разнообразия в бескрайних дебрях WordPress. Одно из основных правил — "
648
+ "сохранять свою установку настолько простой, насколько это возможно: "
649
+ "ограничиваться минимумом плагинов и отказываться от наиболее тяжелых, а "
650
+ "также пользоваться хорошим хостингом (избегайте VPS, если только не знаете в "
651
+ "точности, что делаете). Статьи на сайте Meaw Apps постоянно поддерживаются в "
652
+ "актуальном состоянии и включают все свежие рекомендации: "
653
+
654
+ #: common/admin.php:531
655
+ msgid "Common Options & Tools"
656
+ msgstr "Общие настройки и инструменты"
657
+
658
+ #: common/admin.php:534
659
+ msgid "Common"
660
+ msgstr "Общее"
661
+
662
+ #: common/admin.php:545
663
+ msgid "Debug"
664
+ msgstr "Отладка"
665
+
666
+ #: common/admin.php:548
667
+ msgid "Display Error Log"
668
+ msgstr "Показать журнал ошибок"
669
+
670
+ #: common/admin.php:549
671
+ msgid "Display PHP Info"
672
+ msgstr "Показать информацию о PHP"
673
+
674
+ #: common/admin.php:555
675
+ msgid "Post Types (used by this install)"
676
+ msgstr "Типы записей (используемые этой установкой)"
677
+
678
+ #. translators: %1$s is the version of the interface; %2$s is a file path.
679
+ #: common/admin.php:578
680
+ msgid ""
681
+ "Thanks for using <a href=\"https://meowapps.com\">Meow Apps</a>! This is the "
682
+ "Meow Admin %1$s <br /><i>Loaded from %2$s </i>"
683
+ msgstr ""
684
+ "Спасибо за использование <a href=\"https://meowapps.com\">Meow Apps</a>! Это "
685
+ "Meow Admin %1$s <br /><i>Загружено из: %2$s </i>"
686
+
687
+ #. translators: %s is a plugin version number
688
+ #: common/meowapps/admin.php:69
689
+ msgid "<b>Pro Version (%s)</b>"
690
+ msgstr "Планируемая публикация: <b>%1$s</b>"
691
+
692
+ #: common/meowapps/admin.php:71
693
+ msgid "active"
694
+ msgstr "активна"
695
+
696
+ #. translators: %s is a plugin prefix
697
+ #: common/meowapps/admin.php:74
698
+ msgid ""
699
+ "inactive, add your key in the <a href=\"admin.php?page=%s_settings-menu"
700
+ "\">settings</a>"
701
+ msgstr ""
702
+ "неактивна, добавьте свой ключ в <a href=\"admin.php?page=%s_settings-menu"
703
+ "\">настройках</a>"
704
+
705
+ #: common/meowapps/admin.php:128
706
+ msgid ""
707
+ "There was an error while validating the serial.<br />Please contact <a "
708
+ "target='_blank' href='https://meowapps.com/contact/'>Meow Apps</a> and "
709
+ "mention the following log: <br /><ul>"
710
+ msgstr ""
711
+ "Возникла ошибка при проверке серийного номера.<br />Пожалуйста, свяжитесь "
712
+ "с <a target='_blank' href='https://meowapps.com/contact/'>Meow Apps</a> "
713
+ "и перешлите этот журнал ошибок: <br /><ul>"
714
+
715
+ #. translators: %1$s is a URL attribute, %2$s is error message text
716
+ #: common/meowapps/admin.php:147
717
+ msgid ""
718
+ "Your license key has reached its activation limit <a target=\"_blank\" href="
719
+ "\"%1$s\">(%2$s)</a>."
720
+ msgstr ""
721
+ "Ваш лицензионный ключ достиг лимита по количеству активаций <a target="
722
+ "\"_blank\" href=\"%1$s\">(%2$s)</a>."
723
+
724
+ #. translators: %1$s is a URL attribute, %2$s is error message text
725
+ #: common/meowapps/admin.php:153
726
+ msgid "Your license key expired <a target=\"_blank\" href=\"%1$s\">(%2$s)</a>."
727
+ msgstr ""
728
+ "Ваш лицензионный ключ истёк <a target=\"_blank\" href=\"%1$s\">(%2$s)</a>."
729
+
730
+ #. translators: %1$s is a URL attribute, %2$s is error message text
731
+ #: common/meowapps/admin.php:159
732
+ msgid ""
733
+ "There is a problem with your subscription <a target=\"_blank\" href=\"%1$s"
734
+ "\">(%2$s)</a>."
735
+ msgstr ""
736
+ "Возникла проблема с вашей подпиской <a target=\"_blank\" href=\"%1$s"
737
+ "\">(%2$s)</a>."
738
+
739
+ #: common/meowapps/admin.php:184
740
+ msgid "Serial Key"
741
+ msgstr "Серийный номер"
742
+
743
+ #. translators: %s is a URL
744
+ #: common/meowapps/admin.php:210
745
+ msgid ""
746
+ "<small class=\"description\">Insert your serial key above. If you don't have "
747
+ "one yet, you can get one <a target=\"_blank\" href=\"%s\">here</a>. If there "
748
+ "was an error during the validation, try the <i>Retry to validate</i> button."
749
+ "</small>"
750
+ msgstr ""
751
+ "<small class=\"description\">Вставьте выше свой серийный номер. Если номера "
752
+ "у вас пока нет, вы можете получить его <a target=\"_blank\" href=\"%s"
753
+ "\">здесь</a>. Если во время проверки возникла ошибка, попробуйте кнопку "
754
+ "«<i>Проверить заново</i>».</small>"
755
+
756
+ #: common/meowapps/admin.php:216
757
+ msgid "This license never expires."
758
+ msgstr "Эта лицензия никогда не истекает."
759
+
760
+ #. translators: %s is a number of days
761
+ #: common/meowapps/admin.php:223
762
+ msgid "This license expires in %s days."
763
+ msgstr "Эта лицензия истекает через %s дней."
764
+
765
+ #: common/meowapps/admin.php:229
766
+ msgid "Retry to validate"
767
+ msgstr "Проверить заново"
768
+
769
+ #: common/meowapps/admin.php:232
770
+ msgid "Save Changes"
771
+ msgstr "Сохранить изменения"
772
+
773
+ #. translators: %1$s is a plugin name, %2$s is an opening link tag, %3$s is a plugin version number, %4$s is a closing link tag.
774
+ #: common/meowapps/updater.php:229
775
+ msgid ""
776
+ "There is a new version of %1$s available. %2$sView version %3$s details%4$s."
777
+ msgstr ""
778
+ "Доступна новая версия %1$s. %2$Просмотреть подробности версии %3$s %4$s."
779
+
780
+ #. translators: %1$s is a plugin name, %2$s is an opening link tag, %3$s is a plugin version number, %4$s is a closing link tag, %5$s is an opening link tag, %6$s is a closing link tag
781
+ #: common/meowapps/updater.php:238
782
+ msgid ""
783
+ "There is a new version of %1$s available. %2$sView version %3$s details%4$s "
784
+ "or %5$supdate now%6$s."
785
+ msgstr ""
786
+ "Доступна новая версия %1$s. %2$Просмотреть подробности версии %3$s %4$s или "
787
+ "%5$sобновить сейчас%6$s."
788
+
789
+ #: common/meowapps/updater.php:495
790
+ msgid "You do not have permission to install plugin updates"
791
+ msgstr "У вас нет прав для установки обновлений плагина"
792
+
793
+ #: common/meowapps/updater.php:495
794
+ msgid "Error"
795
+ msgstr "Ошибка"
796
+
797
+ #: core.php:969 views/menu-screen.php:125
798
+ msgid "Seems not use"
799
+ msgstr "Похоже, не используется"
800
+
801
+ #: core.php:972 views/menu-screen.php:129
802
+ msgid "Not in Library"
803
+ msgstr "Отсутствует в библиотеке"
804
+
805
+ #: core.php:975 views/menu-screen.php:131
806
+ msgid "Orphan Retina"
807
+ msgstr "Потерянное изображение Retina"
808
+
809
+ #: core.php:978 views/menu-screen.php:133
810
+ msgid "Orphan WebP"
811
+ msgstr "Потерянное изображение WebP"
812
+
813
+ #: core.php:981 views/menu-screen.php:127
814
+ msgid "No attached file"
815
+ msgstr "Неприкреплённый файл"
816
+
817
+ #: engine.php:24 engine.php:31
818
+ msgid "Skipped, as Content is not selected."
819
+ msgstr "Пропущено, так как метод «Содержимое» не выбран."
820
+
821
+ #: engine.php:109
822
+ msgid "Skipped, as it is not needed for the Media Library method."
823
+ msgstr "Пропущено, так как это не нужно при методе «Библиотека медиафайлов»."
824
+
825
+ #: engine.php:114
826
+ msgid "Skipped, as Media Library is not selected."
827
+ msgstr "Пропущено, так как метод «Библиотека медиафайлов» не выбран."
828
+
829
+ #: media-cleaner-pro.php:18
830
+ msgid ""
831
+ "Thanks for installing the Pro version of Media Cleaner :) However, the free "
832
+ "version is still enabled. Please disable or uninstall it."
833
+ msgstr ""
834
+ "Спасибо за установку версии Pro плагина Media Cleaner :) Однако бесплатная "
835
+ "версия всё ещё активна. Пожалуйста, отключите и удалите её."
836
+
837
+ #: ui.php:148
838
+ msgid "Delete with Media Cleaner"
839
+ msgstr "Удалить при помощи Media Cleaner"
840
+
841
+ #: ui.php:151
842
+ msgid "Trash with Media Cleaner"
843
+ msgstr "Отправить в корзину при помощи Media Cleaner"
844
+
845
+ #: ui.php:154
846
+ msgid "Restore with Media Cleaner"
847
+ msgstr "Восстановить при помощи Media Cleaner"
848
+
849
+ #: views/menu-screen.php:35
850
+ msgid ""
851
+ "<b>The database is not ready for Media Cleaner. The scan will not work.</b> "
852
+ "Click on the <b>Reset</b> button, it re-creates the tables required by Media "
853
+ "Cleaner. If this message still appear, contact the support."
854
+ msgstr ""
855
+ "<b>База данных не готова к работе с Media Cleaner. Сканирование не сработает."
856
+ "</b> Щёлкните на кнопку <b>«Сбросить»</b> — она пересоздаёт таблицы, "
857
+ "необходимые Media Cleaner. Если это сообщение все равно появляется, "
858
+ "обратитесь в поддержку."
859
+
860
+ #: views/menu-screen.php:44
861
+ msgid ""
862
+ "The directory for uploads is not writable. Media Cleaner will only be able "
863
+ "to scan."
864
+ msgstr ""
865
+ "Директория загрузок недоступна для записи. Media Cleaner сможет только "
866
+ "сканировать."
867
+
868
+ #: views/menu-screen.php:83
869
+ msgid "Start Scan"
870
+ msgstr "Начать сканирование"
871
+
872
+ #: views/menu-screen.php:88
873
+ msgid "Pause"
874
+ msgstr "Приостановить"
875
+
876
+ #: views/menu-screen.php:92
877
+ msgid "Delete"
878
+ msgstr "Удалить"
879
+
880
+ #: views/menu-screen.php:94
881
+ msgid "Recover"
882
+ msgstr "Восстановить"
883
+
884
+ #: views/menu-screen.php:100
885
+ msgid "Mark as Issue"
886
+ msgstr "Пометить как проблему"
887
+
888
+ #: views/menu-screen.php:102
889
+ msgid "Ignore"
890
+ msgstr "Игнорировать"
891
+
892
+ #: views/menu-screen.php:108
893
+ msgid "Empty trash"
894
+ msgstr "Очистить корзину"
895
+
896
+ #: views/menu-screen.php:109
897
+ msgid "Recover all"
898
+ msgstr "Восстановить все"
899
+
900
+ #: views/menu-screen.php:112
901
+ msgid "Delete these results"
902
+ msgstr "Удалить эти результаты"
903
+
904
+ #: views/menu-screen.php:114
905
+ msgid "Delete all"
906
+ msgstr "Удалить все"
907
+
908
+ #: views/menu-screen.php:120 views/menu-screen.php:138
909
+ msgid "Search"
910
+ msgstr "Искать"
911
+
912
+ #: views/menu-screen.php:123
913
+ msgid "All Issues"
914
+ msgstr "Все проблемы"
915
+
916
+ #: views/menu-screen.php:157
917
+ msgid ""
918
+ "<b style='color: red;'>Important.</b> <b>Backup your DB and your /uploads "
919
+ "directory before using Media Cleaner. </b> The deleted files will be "
920
+ "temporarily moved to the <b>uploads/wpmc-trash</b> directory. After testing "
921
+ "your website, you can check the <a href='?page=media-"
922
+ "cleaner&s&view=deleted'>trash</a> to either empty it or recover the media "
923
+ "and files. The Media Cleaner does its best to be safe to use. However, "
924
+ "WordPress being a very dynamic and pluggable system, it is impossible to "
925
+ "predict all the situations in which your files are used. <b style='color: "
926
+ "red;'>Again, please backup!</b> If you don't know how, give a try to this: "
927
+ "<a href='https://meow.click/blogvault' target='_blank'>BlogVault</a>. <br /"
928
+ "><br /><b style='color: red;'>Be thoughtful.</b> Don't blame Media Cleaner "
929
+ "if it deleted too many or not enough of your files. It makes cleaning "
930
+ "possible and this task is only possible this way; don't post a bad review "
931
+ "because it broke your install. <b>If you have a proper backup, there is no "
932
+ "risk</b>. Sorry for the lengthy message, but better be safe than sorry. You "
933
+ "can disable this big warning in the options if you have a Pro license. Make "
934
+ "sure you read this warning twice. Media Cleaner is awesome and always "
935
+ "getting better so I hope you will enjoy it. Thank you :)"
936
+ msgstr ""
937
+ "<b style='color: red;'>Важно.</b> <b>Прежде чем использовать Media Cleaner, "
938
+ "сделайте резервные копии своей базы данных и директории /uploads.</b> "
939
+ "Удалённые файлы будут временно перемещены в директорию <b>uploads/wpmc-"
940
+ "trash</b>. После тестирования своего сайта вы можете перейти в <a href='?"
941
+ "page=media-cleaner&s&view=deleted'>корзину</a>, чтобы очистить её или "
942
+ "восстановить медиафайлы. Media Cleaner делает всё возможное для безопасного "
943
+ "использования. Однако невозможно предсказать все ситуации, в которых ваши "
944
+ "файлы могут быть задействованы, поскольку WordPress — очень динамичная и "
945
+ "расширяемая система. <b style='color: red;'>Ещё раз: сделайте резервную "
946
+ "копию!</b> Если вы не знаете как, попробуйте этот плагин: <a href='https://"
947
+ "meow.click/blogvault' target='_blank'>BlogVault</a>. <br /><br /><b "
948
+ "style='color: red;'>Будьте предусмотрительны.</b> Не вините Media Cleaner, "
949
+ "если он удалил слишком много или слишком мало ваших файлов. Он делает "
950
+ "возможным очистку, и эту задачу можно выполнить только таким образом; не "
951
+ "публикуйте негативные отзывы, если плагин «сломал» ваш сайт. <b>Если у вас "
952
+ "есть соответствующая резервная копия, то риска нет</b>. Простите за длинное "
953
+ "сообщение, но лучше перестраховаться, чем потом сожалеть. Вы можете "
954
+ "отключить это большое предупреждение в настройках, если у вас есть лицензия "
955
+ "Pro-версии. Убедитесь, что вы прочли это предупреждение дважды. Media "
956
+ "Cleaner — прекрасный плагин, он постоянно совершенствуется, и я надеюсь, что "
957
+ "он вам понравится. Спасибо :)"
958
+
959
+ #: views/menu-screen.php:163
960
+ msgid ""
961
+ "<p>The trash for the Media Library is disabled. Any media removed by the "
962
+ "plugin will be <b>permanently deleted</b>. To enable it, modify your wp-"
963
+ "config.php file and add this line (preferably at the top): "
964
+ "<b>define( 'MEDIA_TRASH', true );</b>"
965
+ msgstr ""
966
+ "<p>Корзина библиотеки файлов отключена. Все медиафайлы, удалённые плагином, "
967
+ "будут <b>удалены окончательно</b>. Чтобы включить корзину, внесите изменения "
968
+ "в файл wp-config.php, добавив в него эту строку (желательно в начало): "
969
+ "<b>define( 'MEDIA_TRASH', true );</b>"
970
+
971
+ #: views/menu-screen.php:170
972
+ msgid ""
973
+ "This plugin is a lot of work so please consider <a target='_blank' href='//"
974
+ "meowapps.com/plugin/media-cleaner'>Media Cleaner Pro</a> in order to receive "
975
+ "support and to contribute in the evolution of it. Also, <a target='_blank' "
976
+ "href='//meowapps.com/plugin/media-cleaner'>Media Cleaner Pro</a> version "
977
+ "will also give you the option <b>to scan the physical files in your /uploads "
978
+ "folder</b> and extra checks for the common Page Builders."
979
+ msgstr ""
980
+ "Этот плагин — результат большой проделанной работы, поэтому, пожалуйста, "
981
+ "подумайте о покупке версии <a target='_blank' href='//meowapps.com/plugin/"
982
+ "media-cleaner'>Media Cleaner Pro</a>, чтобы получить доступ к техподдержке "
983
+ "и внести свой вклад в развитие проекта. Кроме того, <a target='_blank' "
984
+ "href='//meowapps.com/plugin/media-cleaner'>Media Cleaner Pro</a> даст вам "
985
+ "возможность <b>сканировать физические файлы из папки /uploads</b> и "
986
+ "проводить дополнительные проверки с поддержкой распространенных "
987
+ "конструкторов страниц."
988
+
989
+ #: views/menu-screen.php:228
990
+ msgid "<b>Important note about the following plugin(s): </b>"
991
+ msgstr "<b>Важное замечание о следующих плагинах: </b>"
992
+
993
+ #: views/menu-screen.php:230
994
+ msgid ""
995
+ "They require additional checks which are implemented in the <a "
996
+ "target='_blank' href='//meowapps.com/plugin/media-cleaner'>Media Cleaner "
997
+ "Pro</a>."
998
+ msgstr ""
999
+ "Им требуются дополнительные проверки, которые реализованы в <a "
1000
+ "target='_blank' href='//meowapps.com/plugin/media-cleaner'>Media Cleaner "
1001
+ "Pro</a>."
1002
+
1003
+ #. translators: %s is URL leading to the plugin settings page
1004
+ #: views/menu-screen.php:241
1005
+ msgid "<a href=\"%s\">Click here</a> to modify the settings."
1006
+ msgstr "<a href=\"%s\">Щёлкните здесь</a>, чтобы изменить настройки."
1007
+
1008
+ #: views/menu-screen.php:246
1009
+ msgid ""
1010
+ "Media Cleaner will analyze the Media Library for entries which aren't used "
1011
+ "in the content."
1012
+ msgstr ""
1013
+ "Media Cleaner проанализирует библиотеку медиафайлов в поисках записей, "
1014
+ "которые не используются в содержимом."
1015
+
1016
+ #: views/menu-screen.php:252
1017
+ msgid ""
1018
+ "Media Cleaner will analyze the Media Library. Since <i>Content</i> has not "
1019
+ "be checked, a special scan will be ran: <u>only broken media entries</u> "
1020
+ "will be detected."
1021
+ msgstr ""
1022
+ "Media Cleaner проанализирует библиотеку медиафайлов. Поскольку "
1023
+ "<i>«Содержимое»</i> не было выбрано, запустится специальное сканирование: "
1024
+ "будут обнаружены <u>только поврежденные медиазаписи</u>."
1025
+
1026
+ #: views/menu-screen.php:258
1027
+ msgid ""
1028
+ "Media Cleaner will analyze the filesystem for files which aren't registered "
1029
+ "in the Media Library and aren't used in the content."
1030
+ msgstr ""
1031
+ "Media Cleaner проанализирует файловую систему в поисках файлов, которые не "
1032
+ "зарегистрированы в библиотеке медиафайлов и не используются в содержимом."
1033
+
1034
+ #: views/menu-screen.php:264
1035
+ msgid ""
1036
+ "Media Cleaner will analyze the filesystem for files which aren't registered "
1037
+ "in the Media Library."
1038
+ msgstr ""
1039
+ "Media Cleaner проанализирует файловую систему в поисках файлов, которые не "
1040
+ "зарегистрированы в библиотеке медиафайлов."
1041
+
1042
+ #: views/menu-screen.php:270
1043
+ msgid ""
1044
+ "Media Cleaner will analyze the filesystem for files which aren't used in the "
1045
+ "content."
1046
+ msgstr ""
1047
+ "Media Cleaner проанализирует файловую систему в поисках файлов, которые не "
1048
+ "используются в содержимом."
1049
+
1050
+ #: views/menu-screen.php:276
1051
+ msgid "This type of scan hasn't been set."
1052
+ msgstr "Этот тип сканирования не был настроен."
1053
+
1054
+ #. translators: %1$s is a number of found issues, %2$s is a size of detected files, %3$s is a total size of files in trash
1055
+ #: views/menu-screen.php:282
1056
+ msgid ""
1057
+ "There are <b>%1$s issue(s)</b> with your files, accounting for <b>%2$s MB</"
1058
+ "b>. Your trash contains <b>%3$s MB.</b>"
1059
+ msgstr ""
1060
+ "Обнаружено <b>%1$s проблемных файлов</b>, занимающих <b>%2$s МБ</b>. В вашей "
1061
+ "корзине сейчас <b>%3$s МБ.</b>"
1062
+
1063
+ #: views/menu-screen.php:303
1064
+ msgid "Issues"
1065
+ msgstr "Проблемы"
1066
+
1067
+ #: views/menu-screen.php:304
1068
+ msgid "Ignored"
1069
+ msgstr "Игнорируемые"
1070
+
1071
+ #: views/menu-screen.php:305
1072
+ msgid "Trash"
1073
+ msgstr "Корзина"
1074
+
1075
+ #: views/menu-screen.php:316
1076
+ msgid "Thumb"
1077
+ msgstr "Миниатюра"
1078
+
1079
+ #: views/menu-screen.php:318 views/menu-screen.php:398
1080
+ msgid "Type"
1081
+ msgstr "Тип"
1082
+
1083
+ #: views/menu-screen.php:319 views/menu-screen.php:398
1084
+ msgid "Origin"
1085
+ msgstr "Источник"
1086
+
1087
+ #: views/menu-screen.php:322 views/menu-screen.php:400
1088
+ msgid "LR ID"
1089
+ msgstr "LR ID"
1090
+
1091
+ #: views/menu-screen.php:325 views/menu-screen.php:402
1092
+ msgid "Path"
1093
+ msgstr "Путь"
1094
+
1095
+ #: views/menu-screen.php:326 views/menu-screen.php:402
1096
+ msgid "Issue"
1097
+ msgstr "Проблема"
1098
+
1099
+ #: views/menu-screen.php:327 views/menu-screen.php:402
1100
+ msgid "Size"
1101
+ msgstr "Размер"
1102
+
1103
+ #~ msgid "Extracted references from %d posts in %s."
1104
+ #~ msgstr "Извлеченные ссылки из %d записей в %s."
languages/media-cleaner.pot ADDED
@@ -0,0 +1,768 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2020 Jordy Meow
2
+ # This file is distributed under the same license as the Media Cleaner Pro plugin.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Media Cleaner Pro 5.5.6\n"
6
+ "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/media-cleaner-pro\n"
7
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
8
+ "Language-Team: LANGUAGE <LL@li.org>\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "POT-Creation-Date: 2020-01-30T12:27:36+03:00\n"
13
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
+ "X-Generator: WP-CLI 2.2.0\n"
15
+
16
+ #. Plugin Name of the plugin
17
+ msgid "Media Cleaner Pro"
18
+ msgstr ""
19
+
20
+ #. Plugin URI of the plugin
21
+ #. Author URI of the plugin
22
+ msgid "https://meowapps.com"
23
+ msgstr ""
24
+
25
+ #. Description of the plugin
26
+ msgid "Clean your Media Library, many options, trash system."
27
+ msgstr ""
28
+
29
+ #. Author of the plugin
30
+ msgid "Jordy Meow"
31
+ msgstr ""
32
+
33
+ #: admin.php:41
34
+ msgid "Invalid Regular-Expression"
35
+ msgstr ""
36
+
37
+ #: admin.php:66
38
+ msgid "The Media Cleaner's database has been deleted. It will be re-created automatically next time you visit the Media Cleaner Dashboard."
39
+ msgstr ""
40
+
41
+ #: admin.php:72
42
+ msgid "The Pro version is required to scan files. You can <a target='_blank' href='http://meowapps.com/plugin/media-cleaner'>get a serial for the Pro version here</a>."
43
+ msgstr ""
44
+
45
+ #: admin.php:89
46
+ msgid "Method"
47
+ msgstr ""
48
+
49
+ #: admin.php:92
50
+ msgid "Content"
51
+ msgstr ""
52
+
53
+ #: admin.php:95
54
+ #: admin.php:340
55
+ msgid "Media Library"
56
+ msgstr ""
57
+
58
+ #: admin.php:98
59
+ msgid "Live Content<br />(Pro)"
60
+ msgstr ""
61
+
62
+ #: admin.php:116
63
+ msgid "Logs"
64
+ msgstr ""
65
+
66
+ #: admin.php:118
67
+ #: admin.php:436
68
+ msgid "Enable"
69
+ msgstr ""
70
+
71
+ #: admin.php:122
72
+ msgid "Thumbnails Only"
73
+ msgstr ""
74
+
75
+ #: admin.php:128
76
+ msgid "Directories Filter"
77
+ msgstr ""
78
+
79
+ #: admin.php:136
80
+ msgid "Files Filter"
81
+ msgstr ""
82
+
83
+ #: admin.php:144
84
+ msgid "Thumbnails"
85
+ msgstr ""
86
+
87
+ #: admin.php:147
88
+ msgid "Warning Message"
89
+ msgstr ""
90
+
91
+ #: admin.php:150
92
+ msgid "Results Per Page"
93
+ msgstr ""
94
+
95
+ #: admin.php:156
96
+ msgid "Medias Buffer"
97
+ msgstr ""
98
+
99
+ #: admin.php:159
100
+ msgid "Posts Buffer"
101
+ msgstr ""
102
+
103
+ #: admin.php:162
104
+ msgid "Analysis Buffer"
105
+ msgstr ""
106
+
107
+ #: admin.php:165
108
+ msgid "Delay (in ms)"
109
+ msgstr ""
110
+
111
+ #: admin.php:168
112
+ msgid "Shortcodes"
113
+ msgstr ""
114
+
115
+ #: admin.php:197
116
+ msgid "The number of media entries to read at a time. This is fast, so the value should be between 50 and 1000."
117
+ msgstr ""
118
+
119
+ #: admin.php:204
120
+ msgid "The number of posts (and any other post types) to analyze at a time. This is the most intense part of the process. Recommended value is between 1 (slow server) and 20 (excellent server)."
121
+ msgstr ""
122
+
123
+ #: admin.php:211
124
+ msgid "The number of media entries or files to analyze at a time. This is the main part of the process, but is is much faster than analyzing each post. Recommended value is between 20 (slow server) and 1000 (excellent server)."
125
+ msgstr ""
126
+
127
+ #: admin.php:218
128
+ msgid "Time to wait between each request (in milliseconds). The overall process is intensive so this gives the chance to your server to chill out a bit. A very good server doesn't need it, but a slow/shared hosting might even reject requests if they are too fast and frequent. Recommended value is actually 0, 100 for safety, 2000 or 5000 if your hosting is kind of cheap."
129
+ msgstr ""
130
+
131
+ #: admin.php:230
132
+ msgid "How to use"
133
+ msgstr ""
134
+
135
+ #: admin.php:232
136
+ msgid "You can choose two kind of methods. Usually, users like to analyze their Media Library for images which are not in used (Media Library Method + Content Check), and then, their Filesystem for images which aren't registered in the Media Library (Filesystem Method + Media Library Check). Check the <a target=\"_blank\" href=\"https://meowapps.com/media-cleaner-tutorial/\">tutorial</a> for more information."
137
+ msgstr ""
138
+
139
+ #: admin.php:234
140
+ msgid "Access Media Cleaner Dashboard"
141
+ msgstr ""
142
+
143
+ #: admin.php:235
144
+ msgid "Delete Cleaner DB"
145
+ msgstr ""
146
+
147
+ #: admin.php:246
148
+ msgid "Scanning"
149
+ msgstr ""
150
+
151
+ #: admin.php:257
152
+ msgid "Filters"
153
+ msgstr ""
154
+
155
+ #: admin.php:274
156
+ msgid "UI"
157
+ msgstr ""
158
+
159
+ #: admin.php:285
160
+ msgid "Advanced"
161
+ msgstr ""
162
+
163
+ #: admin.php:341
164
+ msgid "Filesystem (Pro)"
165
+ msgstr ""
166
+
167
+ #: admin.php:342
168
+ msgid "Check the <a target=\"_blank\" href=\"https://meowapps.com/media-cleaner-tutorial/\">tutorial</a> for more information."
169
+ msgstr ""
170
+
171
+ #: admin.php:356
172
+ msgid "Creates an internal log file, for debugging purposes."
173
+ msgstr ""
174
+
175
+ #: admin.php:359
176
+ msgid "<br /><b>Cannot create the logging file. Logging will not work. The plugin as a whole might not be able to work neither.</b>"
177
+ msgstr ""
178
+
179
+ #. translators: %s is a plugin directory url
180
+ #: admin.php:365
181
+ msgid "<br />The <a target=\"_blank\" href=\"%smedia-cleaner.log\">log file</a> is available. You can also <a href=\"?page=wpmc_settings-menu&clearlogs=true\">clear</a> it."
182
+ msgstr ""
183
+
184
+ #: admin.php:378
185
+ #: admin.php:386
186
+ #: admin.php:395
187
+ #: common/admin.php:451
188
+ #: common/admin.php:501
189
+ msgid "Check"
190
+ msgstr ""
191
+
192
+ #: admin.php:378
193
+ msgid "Checks if the file is linked to a media. <i>Only matters to the Filesystem Method.</i>"
194
+ msgstr ""
195
+
196
+ #: admin.php:386
197
+ msgid "Check if the media/file is used in the content, such as Posts, Pages (and other Post Types), Metadata, Widgets, etc."
198
+ msgstr ""
199
+
200
+ #: admin.php:395
201
+ msgid "The live version of the website will be also analyzed (as if a visitor was loading it). <i>This will increase the accuracy of the results.</i>"
202
+ msgstr ""
203
+
204
+ #: admin.php:403
205
+ msgid "Disable Analysis"
206
+ msgstr ""
207
+
208
+ #: admin.php:403
209
+ msgid "Resolving shortcodes increase accuracy, but makes the process slower and takes more memory."
210
+ msgstr ""
211
+
212
+ #: admin.php:411
213
+ #: admin.php:419
214
+ msgid "Hide"
215
+ msgstr ""
216
+
217
+ #: admin.php:411
218
+ msgid "If you prefer not to see the thumbnails."
219
+ msgstr ""
220
+
221
+ #: admin.php:419
222
+ msgid "Have you read it twice? If yes, hide it :)"
223
+ msgstr ""
224
+
225
+ #: admin.php:436
226
+ msgid "Restrict the filesystem scan to thumbnails (files containing the resolution). If none of the checks above are selected, you will get the list of all the thumbnails and be able to remove them."
227
+ msgstr ""
228
+
229
+ #. translators: %d is a count of files
230
+ #: api.php:71
231
+ #: api.php:89
232
+ msgid "Retrieved %d targets."
233
+ msgstr ""
234
+
235
+ #: api.php:104
236
+ msgid "No task."
237
+ msgstr ""
238
+
239
+ #. translators: %1$d is a number of targets, %2$d is a number of issues, %3$s is elapsed time in milliseconds
240
+ #: api.php:145
241
+ msgid "Checked %1$d targets and found %2$d issues in %3$s."
242
+ msgstr ""
243
+
244
+ #: api.php:178
245
+ #: api.php:192
246
+ msgid "List generated."
247
+ msgstr ""
248
+
249
+ #: api.php:210
250
+ #: api.php:228
251
+ #: api.php:246
252
+ msgid "Status unknown."
253
+ msgstr ""
254
+
255
+ #: api.php:260
256
+ msgid "Invalid Option Value"
257
+ msgstr ""
258
+
259
+ #: common/admin.php:60
260
+ msgid "Did nothing but a blank request."
261
+ msgstr ""
262
+
263
+ #. translators: %s is a filename of an empty temporary file
264
+ #: common/admin.php:67
265
+ msgid "Created and deleted %s"
266
+ msgstr ""
267
+
268
+ #. translators: %1$s is a plugin nicename, %2$s is a short url (slug)
269
+ #: common/admin.php:113
270
+ msgid "You have been using <b>%1$s</b> for some time now. Thank you! Could you kindly share your opinion with me, along with, maybe, features you would like to see implemented? Then, please <a style=\"font-weight: bold; color: #b926ff;\" target=\"_blank\" href=\"https://wordpress.org/support/plugin/%2$s/reviews/?rate=5#new-post\">write a little review</a>. That will also bring me joy and motivation, and I will get back to you :) <u>In the case you already have written a review</u>, please check again. Many reviews got removed from WordPress recently."
271
+ msgstr ""
272
+
273
+ #: common/admin.php:121
274
+ msgid "Never remind me!"
275
+ msgstr ""
276
+
277
+ #: common/admin.php:126
278
+ msgid "Remind me in a few weeks..."
279
+ msgstr ""
280
+
281
+ #: common/admin.php:131
282
+ msgid "Yes, I did it!"
283
+ msgstr ""
284
+
285
+ #. translators: %s is a plugin nicename
286
+ #: common/admin.php:169
287
+ msgid "<p>It looks like you are using the free version of the plugin (<b>%s</b>) but a license for the Pro version was also found. The Pro version might have been replaced by the Free version during an update (might be caused by a temporarily issue). If it is the case, <b>please download it again</b> from the <a target=\"_blank\" href=\"https://store.meowapps.com\">Meow Store</a>. If you wish to continue using the free version and clear this message, click on this button."
288
+ msgstr ""
289
+
290
+ #: common/admin.php:175
291
+ msgid "Remove the license"
292
+ msgstr ""
293
+
294
+ #: common/admin.php:219
295
+ #: common/admin.php:220
296
+ msgid "Dashboard"
297
+ msgstr ""
298
+
299
+ #: common/admin.php:225
300
+ msgid "Main Menu"
301
+ msgstr ""
302
+
303
+ #: common/admin.php:228
304
+ msgid "SSL Verify"
305
+ msgstr ""
306
+
307
+ #: common/admin.php:243
308
+ msgid "<label>Hide</label><br /><small>Doesn't display the ads.</small>"
309
+ msgstr ""
310
+
311
+ #: common/admin.php:251
312
+ msgid "<label>Hide <b>Meow Apps</b> Menu</label><br /><small>Hide Meow Apps menu and all its components, for a cleaner admin. This option will be reset if a new Meow Apps plugin is installed. <b>Once activated, an option will be added in your General settings to display it again.</b></small>"
313
+ msgstr ""
314
+
315
+ #: common/admin.php:259
316
+ msgid "<label>Force</label><br /><small>Updates and licenses checks are usually made without checking SSL certificates and it is actually fine this way. But if you are intransigent when it comes to SSL matters, this option will force it.</small>"
317
+ msgstr ""
318
+
319
+ #: common/admin.php:266
320
+ msgid "Pro Version"
321
+ msgstr ""
322
+
323
+ #: common/admin.php:267
324
+ msgid "(enabled)"
325
+ msgstr ""
326
+
327
+ #: common/admin.php:267
328
+ msgid "(disabled)"
329
+ msgstr ""
330
+
331
+ #. translators: %1$s is a url attribute, %2$s is a url visible for user
332
+ #: common/admin.php:275
333
+ msgid "More information about the Pro version here: <a target=\"_blank\" href=\"%1$s\">%2$s</a>. If you actually bought the Pro version already, please remove the current plugin and download the Pro version from your account at the <a target=\"_blank\" href=\"https://store.meowapps.com/account/downloads/\">Meow Apps Store</a>."
334
+ msgstr ""
335
+
336
+ #: common/admin.php:294
337
+ msgid "install"
338
+ msgstr ""
339
+
340
+ #: common/admin.php:316
341
+ msgid "enable"
342
+ msgstr ""
343
+
344
+ #: common/admin.php:321
345
+ msgid "Meow Apps: The function common_url( $file ) needs to be overriden."
346
+ msgstr ""
347
+
348
+ #: common/admin.php:341
349
+ #: common/admin.php:357
350
+ msgid "Go back"
351
+ msgstr ""
352
+
353
+ #: common/admin.php:352
354
+ msgid "=== MEOW APPS DEBUG (This is not an error) ==="
355
+ msgstr ""
356
+
357
+ #: common/admin.php:361
358
+ msgid "Write in the Error Logs"
359
+ msgstr ""
360
+
361
+ #. translators: %s is a preformatted timestamp
362
+ #: common/admin.php:367
363
+ msgid "Now (auto-reload every 5 seconds): [%s UTC]"
364
+ msgstr ""
365
+
366
+ #: common/admin.php:370
367
+ msgid "Errors (order by latest)"
368
+ msgstr ""
369
+
370
+ #: common/admin.php:378
371
+ msgid "The PHP Error Logs cannot be found. Please ask your hosting service for it."
372
+ msgstr ""
373
+
374
+ #: common/admin.php:388
375
+ msgid "Meow Apps is run by Jordy Meow, a photographer and software developer living in Japan (and taking <a target=\"_blank\" href=\"http://offbeatjapan.org\">a lot of photos</a>). Meow Apps is a suite of plugins focusing on photography, imaging, optimization and it teams up with the best players in the community (other themes and plugins developers). For more information, please check <a href=\"http://meowapps.com\" target=\"_blank\">Meow Apps</a>."
376
+ msgstr ""
377
+
378
+ #: common/admin.php:392
379
+ msgid "Featured Plugins"
380
+ msgstr ""
381
+
382
+ #: common/admin.php:399
383
+ msgid "Detect the files which are not in use."
384
+ msgstr ""
385
+
386
+ #: common/admin.php:403
387
+ msgid "For nicer filenames and a better SEO."
388
+ msgstr ""
389
+
390
+ #: common/admin.php:407
391
+ msgid "A simpler, nicer, prettier contact form."
392
+ msgstr ""
393
+
394
+ #: common/admin.php:411
395
+ msgid "The famous plugin that adds Retina support."
396
+ msgstr ""
397
+
398
+ #: common/admin.php:420
399
+ msgid "Beautiful but lightweight gallery with many layouts. The only one that allows you to uninstall it without losing anything."
400
+ msgstr ""
401
+
402
+ #: common/admin.php:424
403
+ msgid "Pretty and ultra-optimized Lightbox which can also display your EXIF data. You will love it."
404
+ msgstr ""
405
+
406
+ #: common/admin.php:428
407
+ msgid "Synchronize your Lightroom to your WordPress. This plugin is loved by all the photographers using Lightroom and WordPress."
408
+ msgstr ""
409
+
410
+ #: common/admin.php:433
411
+ msgid "WordPress Performance & Recommendations"
412
+ msgstr ""
413
+
414
+ #: common/admin.php:435
415
+ msgid "The <b>Empty Request Time</b> helps you analyzing the raw performance of your install by giving you the average time it takes to run an empty request to your server. You can try to disable some plugins (or change their options) then and click on Reset to see how it influences the results. With <b>File Operation Time</b>, you will find out if your server is slow with files. An excellent install would have an Empty Request Time of less than 500 ms. Keep it absolutely under 2,000 ms. File Operation Time should take only a few milliseconds more than the Empty Request Time. For more information about this, <a href=\"https://meowapps.com/clean-optimize-wordpress/#Optimize_your_Empty_Request_Time\" target=\"_blank\">click here</a>."
416
+ msgstr ""
417
+
418
+ #: common/admin.php:439
419
+ msgid "Empty Request Time"
420
+ msgstr ""
421
+
422
+ #: common/admin.php:440
423
+ #: common/admin.php:449
424
+ #: common/admin.php:464
425
+ msgid "N/A"
426
+ msgstr ""
427
+
428
+ #: common/admin.php:441
429
+ msgid "Based on"
430
+ msgstr ""
431
+
432
+ #: common/admin.php:442
433
+ msgid "request(s)"
434
+ msgstr ""
435
+
436
+ #: common/admin.php:448
437
+ msgid "File Operation Time"
438
+ msgstr ""
439
+
440
+ #: common/admin.php:450
441
+ msgid "Create temporary file and delete it."
442
+ msgstr ""
443
+
444
+ #: common/admin.php:483
445
+ #: common/admin.php:500
446
+ msgid "ms"
447
+ msgstr ""
448
+
449
+ #: common/admin.php:517
450
+ msgid "Too many WordPress installs are blown-up with useless and/or huge plugins, and bad practices. But that is because most users are overwhelmed by the diversity and immensity of the WordPress jungle. One rule of thumb is to keep your install the simplest as possible, with the least number of plugins (avoiding heavy ones too) and a good hosting service (avoid VPS except if you know exactly what you are doing). Articles are kept being updated on the Meow Apps website, with all the latest recommendations: "
451
+ msgstr ""
452
+
453
+ #: common/admin.php:531
454
+ msgid "Common Options & Tools"
455
+ msgstr ""
456
+
457
+ #: common/admin.php:534
458
+ msgid "Common"
459
+ msgstr ""
460
+
461
+ #: common/admin.php:545
462
+ msgid "Debug"
463
+ msgstr ""
464
+
465
+ #: common/admin.php:548
466
+ msgid "Display Error Log"
467
+ msgstr ""
468
+
469
+ #: common/admin.php:549
470
+ msgid "Display PHP Info"
471
+ msgstr ""
472
+
473
+ #: common/admin.php:555
474
+ msgid "Post Types (used by this install)"
475
+ msgstr ""
476
+
477
+ #. translators: %1$s is the version of the interface; %2$s is a file path.
478
+ #: common/admin.php:578
479
+ msgid "Thanks for using <a href=\"https://meowapps.com\">Meow Apps</a>! This is the Meow Admin %1$s <br /><i>Loaded from %2$s </i>"
480
+ msgstr ""
481
+
482
+ #. translators: %s is a plugin version number
483
+ #: common/meowapps/admin.php:69
484
+ msgid "<b>Pro Version (%s)</b>"
485
+ msgstr ""
486
+
487
+ #: common/meowapps/admin.php:71
488
+ msgid "active"
489
+ msgstr ""
490
+
491
+ #. translators: %s is a plugin prefix
492
+ #: common/meowapps/admin.php:74
493
+ msgid "inactive, add your key in the <a href=\"admin.php?page=%s_settings-menu\">settings</a>"
494
+ msgstr ""
495
+
496
+ #: common/meowapps/admin.php:128
497
+ msgid "There was an error while validating the serial.<br />Please contact <a target='_blank' href='https://meowapps.com/contact/'>Meow Apps</a> and mention the following log: <br /><ul>"
498
+ msgstr ""
499
+
500
+ #. translators: %1$s is a URL attribute, %2$s is error message text
501
+ #: common/meowapps/admin.php:147
502
+ msgid "Your license key has reached its activation limit <a target=\"_blank\" href=\"%1$s\">(%2$s)</a>."
503
+ msgstr ""
504
+
505
+ #. translators: %1$s is a URL attribute, %2$s is error message text
506
+ #: common/meowapps/admin.php:153
507
+ msgid "Your license key expired <a target=\"_blank\" href=\"%1$s\">(%2$s)</a>."
508
+ msgstr ""
509
+
510
+ #. translators: %1$s is a URL attribute, %2$s is error message text
511
+ #: common/meowapps/admin.php:159
512
+ msgid "There is a problem with your subscription <a target=\"_blank\" href=\"%1$s\">(%2$s)</a>."
513
+ msgstr ""
514
+
515
+ #: common/meowapps/admin.php:184
516
+ msgid "Serial Key"
517
+ msgstr ""
518
+
519
+ #. translators: %s is a URL
520
+ #: common/meowapps/admin.php:210
521
+ msgid "<small class=\"description\">Insert your serial key above. If you don't have one yet, you can get one <a target=\"_blank\" href=\"%s\">here</a>. If there was an error during the validation, try the <i>Retry to validate</i> button.</small>"
522
+ msgstr ""
523
+
524
+ #: common/meowapps/admin.php:216
525
+ msgid "This license never expires."
526
+ msgstr ""
527
+
528
+ #. translators: %s is a number of days
529
+ #: common/meowapps/admin.php:223
530
+ msgid "This license expires in %s days."
531
+ msgstr ""
532
+
533
+ #: common/meowapps/admin.php:229
534
+ msgid "Retry to validate"
535
+ msgstr ""
536
+
537
+ #: common/meowapps/admin.php:232
538
+ msgid "Save Changes"
539
+ msgstr ""
540
+
541
+ #. translators: %1$s is a plugin name, %2$s is an opening link tag, %3$s is a plugin version number, %4$s is a closing link tag.
542
+ #: common/meowapps/updater.php:229
543
+ msgid "There is a new version of %1$s available. %2$sView version %3$s details%4$s."
544
+ msgstr ""
545
+
546
+ #. translators: %1$s is a plugin name, %2$s is an opening link tag, %3$s is a plugin version number, %4$s is a closing link tag, %5$s is an opening link tag, %6$s is a closing link tag
547
+ #: common/meowapps/updater.php:238
548
+ msgid "There is a new version of %1$s available. %2$sView version %3$s details%4$s or %5$supdate now%6$s."
549
+ msgstr ""
550
+
551
+ #: common/meowapps/updater.php:495
552
+ msgid "You do not have permission to install plugin updates"
553
+ msgstr ""
554
+
555
+ #: common/meowapps/updater.php:495
556
+ msgid "Error"
557
+ msgstr ""
558
+
559
+ #: core.php:969
560
+ #: views/menu-screen.php:125
561
+ msgid "Seems not use"
562
+ msgstr ""
563
+
564
+ #: core.php:972
565
+ #: views/menu-screen.php:129
566
+ msgid "Not in Library"
567
+ msgstr ""
568
+
569
+ #: core.php:975
570
+ #: views/menu-screen.php:131
571
+ msgid "Orphan Retina"
572
+ msgstr ""
573
+
574
+ #: core.php:978
575
+ #: views/menu-screen.php:133
576
+ msgid "Orphan WebP"
577
+ msgstr ""
578
+
579
+ #: core.php:981
580
+ #: views/menu-screen.php:127
581
+ msgid "No attached file"
582
+ msgstr ""
583
+
584
+ #: engine.php:24
585
+ #: engine.php:31
586
+ msgid "Skipped, as Content is not selected."
587
+ msgstr ""
588
+
589
+ #: engine.php:109
590
+ msgid "Skipped, as it is not needed for the Media Library method."
591
+ msgstr ""
592
+
593
+ #: engine.php:114
594
+ msgid "Skipped, as Media Library is not selected."
595
+ msgstr ""
596
+
597
+ #: media-cleaner-pro.php:18
598
+ msgid "Thanks for installing the Pro version of Media Cleaner :) However, the free version is still enabled. Please disable or uninstall it."
599
+ msgstr ""
600
+
601
+ #: ui.php:148
602
+ msgid "Delete with Media Cleaner"
603
+ msgstr ""
604
+
605
+ #: ui.php:151
606
+ msgid "Trash with Media Cleaner"
607
+ msgstr ""
608
+
609
+ #: ui.php:154
610
+ msgid "Restore with Media Cleaner"
611
+ msgstr ""
612
+
613
+ #: views/menu-screen.php:35
614
+ msgid "<b>The database is not ready for Media Cleaner. The scan will not work.</b> Click on the <b>Reset</b> button, it re-creates the tables required by Media Cleaner. If this message still appear, contact the support."
615
+ msgstr ""
616
+
617
+ #: views/menu-screen.php:44
618
+ msgid "The directory for uploads is not writable. Media Cleaner will only be able to scan."
619
+ msgstr ""
620
+
621
+ #: views/menu-screen.php:83
622
+ msgid "Start Scan"
623
+ msgstr ""
624
+
625
+ #: views/menu-screen.php:88
626
+ msgid "Pause"
627
+ msgstr ""
628
+
629
+ #: views/menu-screen.php:92
630
+ msgid "Delete"
631
+ msgstr ""
632
+
633
+ #: views/menu-screen.php:94
634
+ msgid "Recover"
635
+ msgstr ""
636
+
637
+ #: views/menu-screen.php:100
638
+ msgid "Mark as Issue"
639
+ msgstr ""
640
+
641
+ #: views/menu-screen.php:102
642
+ msgid "Ignore"
643
+ msgstr ""
644
+
645
+ #: views/menu-screen.php:108
646
+ msgid "Empty trash"
647
+ msgstr ""
648
+
649
+ #: views/menu-screen.php:109
650
+ msgid "Recover all"
651
+ msgstr ""
652
+
653
+ #: views/menu-screen.php:112
654
+ msgid "Delete these results"
655
+ msgstr ""
656
+
657
+ #: views/menu-screen.php:114
658
+ msgid "Delete all"
659
+ msgstr ""
660
+
661
+ #: views/menu-screen.php:120
662
+ #: views/menu-screen.php:138
663
+ msgid "Search"
664
+ msgstr ""
665
+
666
+ #: views/menu-screen.php:123
667
+ msgid "All Issues"
668
+ msgstr ""
669
+
670
+ #: views/menu-screen.php:157
671
+ msgid "<b style='color: red;'>Important.</b> <b>Backup your DB and your /uploads directory before using Media Cleaner. </b> The deleted files will be temporarily moved to the <b>uploads/wpmc-trash</b> directory. After testing your website, you can check the <a href='?page=media-cleaner&s&view=deleted'>trash</a> to either empty it or recover the media and files. The Media Cleaner does its best to be safe to use. However, WordPress being a very dynamic and pluggable system, it is impossible to predict all the situations in which your files are used. <b style='color: red;'>Again, please backup!</b> If you don't know how, give a try to this: <a href='https://meow.click/blogvault' target='_blank'>BlogVault</a>. <br /><br /><b style='color: red;'>Be thoughtful.</b> Don't blame Media Cleaner if it deleted too many or not enough of your files. It makes cleaning possible and this task is only possible this way; don't post a bad review because it broke your install. <b>If you have a proper backup, there is no risk</b>. Sorry for the lengthy message, but better be safe than sorry. You can disable this big warning in the options if you have a Pro license. Make sure you read this warning twice. Media Cleaner is awesome and always getting better so I hope you will enjoy it. Thank you :)"
672
+ msgstr ""
673
+
674
+ #: views/menu-screen.php:163
675
+ msgid "<p>The trash for the Media Library is disabled. Any media removed by the plugin will be <b>permanently deleted</b>. To enable it, modify your wp-config.php file and add this line (preferably at the top): <b>define( 'MEDIA_TRASH', true );</b>"
676
+ msgstr ""
677
+
678
+ #: views/menu-screen.php:170
679
+ msgid "This plugin is a lot of work so please consider <a target='_blank' href='//meowapps.com/plugin/media-cleaner'>Media Cleaner Pro</a> in order to receive support and to contribute in the evolution of it. Also, <a target='_blank' href='//meowapps.com/plugin/media-cleaner'>Media Cleaner Pro</a> version will also give you the option <b>to scan the physical files in your /uploads folder</b> and extra checks for the common Page Builders."
680
+ msgstr ""
681
+
682
+ #: views/menu-screen.php:228
683
+ msgid "<b>Important note about the following plugin(s): </b>"
684
+ msgstr ""
685
+
686
+ #: views/menu-screen.php:230
687
+ msgid "They require additional checks which are implemented in the <a target='_blank' href='//meowapps.com/plugin/media-cleaner'>Media Cleaner Pro</a>."
688
+ msgstr ""
689
+
690
+ #. translators: %s is URL leading to the plugin settings page
691
+ #: views/menu-screen.php:241
692
+ msgid "<a href=\"%s\">Click here</a> to modify the settings."
693
+ msgstr ""
694
+
695
+ #: views/menu-screen.php:246
696
+ msgid "Media Cleaner will analyze the Media Library for entries which aren't used in the content."
697
+ msgstr ""
698
+
699
+ #: views/menu-screen.php:252
700
+ msgid "Media Cleaner will analyze the Media Library. Since <i>Content</i> has not be checked, a special scan will be ran: <u>only broken media entries</u> will be detected."
701
+ msgstr ""
702
+
703
+ #: views/menu-screen.php:258
704
+ msgid "Media Cleaner will analyze the filesystem for files which aren't registered in the Media Library and aren't used in the content."
705
+ msgstr ""
706
+
707
+ #: views/menu-screen.php:264
708
+ msgid "Media Cleaner will analyze the filesystem for files which aren't registered in the Media Library."
709
+ msgstr ""
710
+
711
+ #: views/menu-screen.php:270
712
+ msgid "Media Cleaner will analyze the filesystem for files which aren't used in the content."
713
+ msgstr ""
714
+
715
+ #: views/menu-screen.php:276
716
+ msgid "This type of scan hasn't been set."
717
+ msgstr ""
718
+
719
+ #. translators: %1$s is a number of found issues, %2$s is a size of detected files, %3$s is a total size of files in trash
720
+ #: views/menu-screen.php:282
721
+ msgid "There are <b>%1$s issue(s)</b> with your files, accounting for <b>%2$s MB</b>. Your trash contains <b>%3$s MB.</b>"
722
+ msgstr ""
723
+
724
+ #: views/menu-screen.php:303
725
+ msgid "Issues"
726
+ msgstr ""
727
+
728
+ #: views/menu-screen.php:304
729
+ msgid "Ignored"
730
+ msgstr ""
731
+
732
+ #: views/menu-screen.php:305
733
+ msgid "Trash"
734
+ msgstr ""
735
+
736
+ #: views/menu-screen.php:316
737
+ msgid "Thumb"
738
+ msgstr ""
739
+
740
+ #: views/menu-screen.php:318
741
+ #: views/menu-screen.php:398
742
+ msgid "Type"
743
+ msgstr ""
744
+
745
+ #: views/menu-screen.php:319
746
+ #: views/menu-screen.php:398
747
+ msgid "Origin"
748
+ msgstr ""
749
+
750
+ #: views/menu-screen.php:322
751
+ #: views/menu-screen.php:400
752
+ msgid "LR ID"
753
+ msgstr ""
754
+
755
+ #: views/menu-screen.php:325
756
+ #: views/menu-screen.php:402
757
+ msgid "Path"
758
+ msgstr ""
759
+
760
+ #: views/menu-screen.php:326
761
+ #: views/menu-screen.php:402
762
+ msgid "Issue"
763
+ msgstr ""
764
+
765
+ #: views/menu-screen.php:327
766
+ #: views/menu-screen.php:402
767
+ msgid "Size"
768
+ msgstr ""
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.5.4
7
  Author: Jordy Meow
8
  Author URI: https://meowapps.com
9
  Text Domain: media-cleaner
@@ -25,7 +25,7 @@ if ( is_admin() ) {
25
 
26
  global $wpmc_version;
27
  global $wpmc;
28
- $wpmc_version = '5.5.4';
29
 
30
  require __DIR__ . '/admin.php';
31
  require __DIR__ . '/core.php';
3
  Plugin Name: Media Cleaner
4
  Plugin URI: https://meowapps.com
5
  Description: Clean your Media Library, many options, trash system.
6
+ Version: 5.5.7
7
  Author: Jordy Meow
8
  Author URI: https://meowapps.com
9
  Text Domain: media-cleaner
25
 
26
  global $wpmc_version;
27
  global $wpmc;
28
+ $wpmc_version = '5.5.7';
29
 
30
  require __DIR__ . '/admin.php';
31
  require __DIR__ . '/core.php';
parsers.php CHANGED
@@ -1,30 +1,30 @@
1
- <?php
2
-
3
- class MeowApps_WPMC_Parsers {
4
-
5
- public function __construct() {
6
- // require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); // mm change
7
- require_once( 'parsers/common.php' );
8
- new MeowApps_WPMC_Parser();
9
-
10
- if ( class_exists( 'WooCommerce' ) )
11
- require_once( 'parsers/woocommerce.php' );
12
-
13
- if ( class_exists( 'Attachments' ) ) // mm change
14
- require_once( 'parsers/attachments.php' );
15
-
16
- if ( class_exists( 'MetaSliderPlugin' ) || class_exists( 'MetaSliderPro' ) ) // mm change
17
- require_once( 'parsers/metaslider.php' );
18
-
19
- if ( function_exists( 'mc_show_sidebar' ) )
20
- require_once( 'parsers/my-calendar.php' );
21
-
22
- if ( class_exists( 'Mega_Menu' ) )
23
- require_once( 'parsers/maxmegamenu.php' );
24
-
25
- if ( class_exists( 'WPSEO_Options' ) )
26
- require_once( 'parsers/wpseo.php' );
27
- }
28
- }
29
-
30
  ?>
1
+ <?php
2
+
3
+ class MeowApps_WPMC_Parsers {
4
+
5
+ public function __construct() {
6
+ // require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); // mm change
7
+ require_once( 'parsers/common.php' );
8
+ new MeowApps_WPMC_Parser();
9
+
10
+ if ( class_exists( 'WooCommerce' ) )
11
+ require_once( 'parsers/woocommerce.php' );
12
+
13
+ if ( class_exists( 'Attachments' ) ) // mm change
14
+ require_once( 'parsers/attachments.php' );
15
+
16
+ if ( class_exists( 'MetaSliderPlugin' ) || class_exists( 'MetaSliderPro' ) ) // mm change
17
+ require_once( 'parsers/metaslider.php' );
18
+
19
+ if ( function_exists( 'mc_show_sidebar' ) )
20
+ require_once( 'parsers/my-calendar.php' );
21
+
22
+ if ( class_exists( 'Mega_Menu' ) )
23
+ require_once( 'parsers/maxmegamenu.php' );
24
+
25
+ if ( class_exists( 'WPSEO_Options' ) )
26
+ require_once( 'parsers/wpseo.php' );
27
+ }
28
+ }
29
+
30
  ?>
parsers/attachments.php CHANGED
@@ -1,26 +1,26 @@
1
- <?php
2
-
3
- // Attachment (https://wordpress.org/plugins/attachments/)
4
- // Added by Mike Meinz
5
- // Discussion: https://wordpress.org/support/topic/attachments-plugin/
6
-
7
- add_action( 'wpmc_scan_postmeta', 'wpmc_scan_postmeta_attachments' );
8
-
9
- function wpmc_scan_postmeta_attachments($id) {
10
- global $wpmc;
11
- $postmeta_images_ids = array();
12
- $attachments_json = get_post_meta( $id, 'attachments', true ); // meta_key=='attachments'
13
- $attachments_decoded = is_string( $attachments_json ) ? json_decode( $attachments_json ) : false;
14
- if ( !empty( $attachments_decoded )) {
15
- foreach ( $attachments_decoded as $AttachmentData => $TheAttachment ) {
16
- foreach( $TheAttachment as $AttachmentData => $attachment ) {
17
- array_push( $postmeta_images_ids, $attachment->id );
18
- }
19
- }
20
- }
21
- if ( !empty( $postmeta_images_ids ) ) {
22
- $wpmc->add_reference_id( $postmeta_images_ids, 'ATTACHMENT (ID)' ); // mm change
23
- }
24
- }
25
-
26
  ?>
1
+ <?php
2
+
3
+ // Attachment (https://wordpress.org/plugins/attachments/)
4
+ // Added by Mike Meinz
5
+ // Discussion: https://wordpress.org/support/topic/attachments-plugin/
6
+
7
+ add_action( 'wpmc_scan_postmeta', 'wpmc_scan_postmeta_attachments' );
8
+
9
+ function wpmc_scan_postmeta_attachments($id) {
10
+ global $wpmc;
11
+ $postmeta_images_ids = array();
12
+ $attachments_json = get_post_meta( $id, 'attachments', true ); // meta_key=='attachments'
13
+ $attachments_decoded = is_string( $attachments_json ) ? json_decode( $attachments_json ) : false;
14
+ if ( !empty( $attachments_decoded )) {
15
+ foreach ( $attachments_decoded as $AttachmentData => $TheAttachment ) {
16
+ foreach( $TheAttachment as $AttachmentData => $attachment ) {
17
+ array_push( $postmeta_images_ids, $attachment->id );
18
+ }
19
+ }
20
+ }
21
+ if ( !empty( $postmeta_images_ids ) ) {
22
+ $wpmc->add_reference_id( $postmeta_images_ids, 'ATTACHMENT (ID)' ); // mm change
23
+ }
24
+ }
25
+
26
  ?>
parsers/my-calendar.php CHANGED
@@ -1,53 +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
  ?>
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
@@ -5,7 +5,7 @@ Donate link: https://commerce.coinbase.com/checkout/d047546a-77a8-41c8-9ea9-4a95
5
  Requires at least: 4.8
6
  Tested up to: 5.3
7
  Requires PHP: 7.0
8
- Stable tag: 5.5.4
9
 
10
  Clean your WordPress from unused or broken media and files. It has its own trash system and recovery features. Please read the description.
11
 
@@ -74,6 +74,18 @@ Better to be safe than sorry. This plugin deletes files! Therefore, backup is no
74
 
75
  == Changelog ==
76
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  = 5.5.4 =
78
  * Update: Creates the DB tables automatically.
79
  * Add: Support for Revolution Slider.
5
  Requires at least: 4.8
6
  Tested up to: 5.3
7
  Requires PHP: 7.0
8
+ Stable tag: 5.5.7
9
 
10
  Clean your WordPress from unused or broken media and files. It has its own trash system and recovery features. Please read the description.
11
 
74
 
75
  == Changelog ==
76
 
77
+ = 5.5.7 =
78
+ * Update: UI improved in many ways, I hope you will love it more!
79
+ * Add: Filter by issue, and allow to delete those specific issues.
80
+ * Add: Support for the original image (-scaled) feature added in a recent version of WP.
81
+ * Add: Support for Custom Product Tabs.
82
+ * Add: Support for Support for FAT Portfolio.
83
+ * Update: Better support for translations.
84
+ * Update: Better support for Revolution Slider.
85
+ * Update: Added additional checks for DOM parser and check if the DOM module is loaded.
86
+ * Fix: 100% of the code was checked and a few tiny issues were fixed here and there.
87
+ * Info: This plugin is a lot of work. Please help me by giving it a nice review, [here](https://wordpress.org/support/plugin/media-cleaner/reviews/?rate=5#new-post). At the same time, I would love to know if you would prefer the results to be refreshed automatically instead of having to click on refresh. Thank you :)
88
+
89
  = 5.5.4 =
90
  * Update: Creates the DB tables automatically.
91
  * Add: Support for Revolution Slider.
scripts/dashboard.js CHANGED
@@ -4,6 +4,11 @@ Description: Clean your Media Library and Uploads Folder.
4
  Author: Jordy Meow
5
  */
6
 
 
 
 
 
 
7
  function wpmc_pop_array(items, count) {
8
  var newItems = [];
9
  while ( newItems.length < count && items.length > 0 ) {
@@ -88,12 +93,11 @@ function wpmc_delete() {
88
  wpmc_delete_do(items, items.length);
89
  }
90
 
91
- function wpmc_delete_all(isTrash, filter = '') {
92
- var items = [];
93
  var data = {
94
  action: 'wpmc_get_all_issues',
95
  isTrash: isTrash ? 1 : 0,
96
- s: filter
97
  };
98
 
99
  jQuery.post(ajaxurl, data, function (response) {
@@ -110,7 +114,8 @@ function wpmc_update_progress(current, totalcount, isDeleting) {
110
  if (isDeleting === undefined)
111
  isDeleting = false;
112
  var action = isDeleting ? "Deleting" : "Analyzing";
113
- jQuery('#wpmc_progression').html('<span class="dashicons dashicons-controls-play"></span> ' + action + ' ' + current + "/" + totalcount + " (" + Math.round(current / totalcount * 100) + "%)");
 
114
  }
115
 
116
  function wpmc_delete_do(items, totalcount) {
@@ -178,65 +183,60 @@ function wpmc_new_context() {
178
  currentPhase: null,
179
 
180
  phases: {
181
- preparePosts: {
182
  init: function () {
183
  this.progress = 0; // Scanned posts count
184
  this.progressPrev = 0;
185
  return this;
186
  },
187
  run: function () {
188
- wpmc_prepare();
189
  },
190
  pause: function () {
191
- jQuery('#wpmc_progression').html('<span class="dashicons dashicons-controls-pause"></span> Paused at preparing posts (' + this.progress + ' posts)');
 
192
  },
193
  skip: function () {
194
  this.progress += wpmc_cfg.postsBuffer;
195
  },
196
  nextPhase: function () {
197
- if (wpmc_cfg.scanMedia)
198
- return wpmc.phases.prepareMedia;
199
- if (wpmc_cfg.scanFiles)
200
- return wpmc.phases.prepareFiles;
201
- console.error('Configuration Error'); // This shouldn't happen
202
  }
203
  },
204
- prepareFiles: {
205
  init: function () {
206
- this.progress = null; // The last scanned directory
207
- this.progressPrev = null;
208
  return this;
209
  },
210
  run: function () {
211
- wpmc_scan_type('files', this.progress);
212
  },
213
  pause: function () {
214
- jQuery('#wpmc_progression').html('<span class="dashicons dashicons-controls-pause"></span> Paused at preparing files (' + this.progress + ')');
 
215
  },
216
  skip: function () {
217
- var dir = wpmc.dirs.pop();
218
- if (dir) {
219
- wpmc.currentPhase.progressPrev = wpmc.currentPhase.progress;
220
- wpmc.currentPhase.progress = dir;
221
- }
222
- else
223
- wpmc.currentPhase = this.nextPhase().init();
224
  },
225
  nextPhase: function () {
226
- return wpmc.phases.analyze;
 
227
  }
228
  },
229
- prepareMedia: {
230
  init: function () {
231
  this.progress = 0; // Scanned media count
232
  this.progressPrev = 0;
233
  return this;
234
  },
235
  run: function () {
236
- wpmc_scan_type('medias', null, this.progress);
 
237
  },
238
  pause: function () {
239
- jQuery('#wpmc_progression').html('<span class="dashicons dashicons-controls-pause"></span> Paused at preparing media (' + this.progress + ' media)');
 
240
  },
241
  skip: function () {
242
  this.progress += wpmc_cfg.mediasBuffer;
@@ -252,17 +252,18 @@ function wpmc_new_context() {
252
  return this;
253
  },
254
  run: function () {
255
- wpmc_scan_do();
256
  },
257
  pause: function () {
258
  var current = wpmc.total - (wpmc.files.length + wpmc.medias.length);
259
  var totalcount = wpmc.total;
260
- jQuery('#wpmc_progression').html('<span class="dashicons dashicons-controls-pause"></span> Paused at ' + current + "/" + totalcount + " (" + Math.round(current / totalcount * 100) + "%)");
 
261
  },
262
  skip: function () {
263
  if (wpmc.files.length)
264
  this.currentFiles = wpmc_pop_array(wpmc.files, wpmc_cfg.analysisBuffer);
265
- if (wpmc.medias.lenght)
266
  this.currentMedia = wpmc_pop_array(wpmc.medias, wpmc_cfg.analysisBuffer);
267
  },
268
  rollback: function () {
@@ -276,63 +277,46 @@ function wpmc_new_context() {
276
  };
277
  }
278
 
279
- // WPMC GET INITIAL INFO
280
-
281
- function wpmc_scan_type_finished() {
282
-
283
- }
284
-
285
- function wpmc_scan_type_next(type, path) {
286
 
287
- }
288
-
289
- function wpmc_prepare() {
290
  if (!wpmc.currentPhase) return; // Aborted
291
-
292
  if (wpmc.isPendingPause)
293
  return wpmc_update_to_pause();
294
-
295
  setTimeout(
296
  function() {
297
  if (!wpmc.currentPhase) return; // Aborted
298
-
299
- jQuery('#wpmc_progression').html('<span class="dashicons dashicons-portfolio"></span> Preparing posts (' + wpmc.currentPhase.progress + ' posts)...');
300
-
301
  jQuery.ajax({
302
  type: 'POST',
303
  url: ajaxurl,
304
  dataType: 'text',
305
  data: {
306
- action: 'wpmc_prepare_do',
 
307
  limit: wpmc.currentPhase.progress
308
  },
309
  timeout: wpmc_cfg.timeout + 5000 // Extra 5sec for fail-safe
310
-
311
  }).done(function (response) {
312
  if (!wpmc.currentPhase) return; // Aborted
313
-
314
  var reply = wpmc_parse_response(response);
315
-
316
  if (!reply.success)
317
  return wpmc_handle_error(reply.message);
318
-
319
  if (!reply.finished) {
320
  wpmc.currentPhase.progressPrev = wpmc.currentPhase.progress;
321
  wpmc.currentPhase.progress = reply.limit;
322
  }
323
  else wpmc.currentPhase = wpmc.currentPhase.nextPhase().init();
324
-
325
  return wpmc.currentPhase.run();
326
-
327
  }).fail(function (e) { // Server Error
328
  wpmc_handle_error(e.statusText, e.status);
329
  });
330
-
331
  }, wpmc_cfg.delay
332
  );
333
  }
334
 
335
- function wpmc_scan_type(type, path = null, limit = 0) {
336
  if (!wpmc.currentPhase) return; // Aborted
337
 
338
  if (wpmc.isPendingPause)
@@ -342,10 +326,12 @@ function wpmc_scan_type(type, path = null, limit = 0) {
342
  elpath = path.replace(/^.*[\\\/]/, '');
343
  jQuery('#wpmc_progression').html('<span class="dashicons dashicons-portfolio"></span> Preparing files (' + elpath + ')...');
344
  }
345
- else if (type === 'medias')
346
  jQuery('#wpmc_progression').html('<span class="dashicons dashicons-admin-media"></span> Preparing medias (' + limit + ' medias)...');
347
- else
348
  jQuery('#wpmc_progression').html('<span class="dashicons dashicons-portfolio"></span> Preparing files...');
 
 
349
 
350
  setTimeout(
351
  function() {
@@ -354,9 +340,7 @@ function wpmc_scan_type(type, path = null, limit = 0) {
354
  url: ajaxurl,
355
  dataType: 'text',
356
  data: {
357
- action: 'wpmc_scan',
358
- medias: type === 'medias',
359
- files: type === 'files',
360
  path: path,
361
  limit: limit
362
  },
@@ -366,14 +350,16 @@ function wpmc_scan_type(type, path = null, limit = 0) {
366
  if (!wpmc.currentPhase) return; // Aborted
367
 
368
  var reply = wpmc_parse_response(response);
 
 
369
 
370
  if (!reply.success)
371
  return wpmc_handle_error(reply.message);
372
 
373
  // Store results
374
  for (var i = 0, len = reply.results.length; i < len; i++) {
375
- var r = reply.results[i];
376
- if (type === 'files') {
377
  if ( r.type === 'dir' )
378
  wpmc.dirs.push( r.path );
379
  else if ( r.type === 'file' ) {
@@ -381,22 +367,22 @@ function wpmc_scan_type(type, path = null, limit = 0) {
381
  wpmc.total++;
382
  }
383
  }
384
- else if (type === 'medias') {
385
  wpmc.medias.push( r );
386
  wpmc.total++;
387
  }
388
  }
389
 
390
  // Next query
391
- if (type === 'medias') {
392
- if (wpmc_cfg.scanFiles || !reply.finished) {
393
  wpmc.currentPhase.progressPrev = wpmc.currentPhase.progress;
394
  wpmc.currentPhase.progress = reply.limit;
395
  }
396
  else
397
  wpmc.currentPhase = wpmc.currentPhase.nextPhase().init();
398
  }
399
- else if (type === 'files') {
400
  var dir = wpmc.dirs.pop();
401
  if (dir) {
402
  wpmc.currentPhase.progressPrev = wpmc.currentPhase.progress;
@@ -433,7 +419,6 @@ function wpmc_pause() {
433
  function wpmc_update_to_pause() {
434
  if (wpmc.isPendingPause) {
435
  wpmc.currentPhase.pause();
436
-
437
  jQuery('#wpmc_pause').html('<span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-play"></span>Continue');
438
  wpmc.isPendingPause = false;
439
  wpmc.isPause = true;
@@ -493,9 +478,8 @@ function wpmc_update_to_error() {
493
  wpmc.isPause = true;
494
  }
495
 
496
- function wpmc_scan_do() {
497
  if (!wpmc.currentPhase) return; // Aborted
498
-
499
  if (wpmc.isPendingPause)
500
  return wpmc_update_to_pause();
501
 
@@ -505,20 +489,27 @@ function wpmc_scan_do() {
505
  if (wpmc.files.length > 0) {
506
  wpmc.currentPhase.currentFiles = wpmc_pop_array(wpmc.files, wpmc_cfg.analysisBuffer);
507
  expectedSuccess = wpmc.currentPhase.currentFiles.length;
508
- data = { action: 'wpmc_scan_do', type: 'file', data: wpmc.currentPhase.currentFiles };
509
  }
510
  else if (wpmc.medias.length > 0) {
511
  wpmc.currentPhase.currentMedia = wpmc_pop_array(wpmc.medias, wpmc_cfg.analysisBuffer);
512
  expectedSuccess = wpmc.currentPhase.currentMedia.length;
513
- data = { action: 'wpmc_scan_do', type: 'media', data: wpmc.currentPhase.currentMedia };
514
  }
515
  else {
516
- jQuery('#wpmc_progression').html(wpmc.issues + " issue(s) found. <a href='?page=media-cleaner'></span>Refresh</a>.");
517
-
 
 
 
 
 
 
518
  wpmc = wpmc_new_context(); // Reset the context
519
  jQuery('#wpmc_pause').hide();
520
  jQuery('#wpmc_scan').html('<span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-search"></span>Start Scan');
521
  jQuery('#wpmc_actions').trigger('idle');
 
522
  return;
523
  }
524
 
@@ -530,22 +521,15 @@ function wpmc_scan_do() {
530
  dataType: 'text',
531
  data: data,
532
  timeout: wpmc_cfg.timeout + 5000 // Extra 5sec for fail-safe
533
-
534
  }).done(function (response) {
535
  var reply = wpmc_parse_response(response);
536
-
537
  if (!reply.success)
538
  return wpmc_handle_error(reply.message);
539
-
540
- if (reply.result)
541
- wpmc.issues += expectedSuccess - reply.result.success;
542
-
543
- wpmc_scan_do();
544
-
545
  }).fail(function (e) { // Server Error
546
  wpmc_handle_error(e.statusText, e.status);
547
  });
548
-
549
  }, wpmc_cfg.delay
550
  );
551
  }
@@ -620,7 +604,7 @@ function wpmc_open_dialog(content) {
620
  wrap.trigger('busy');
621
  $('#wpmc_scan').html('Stop Scan');
622
  $('#wpmc_pause').show();
623
- wpmc.currentPhase = wpmc.phases.preparePosts.init();
624
  wpmc.currentPhase.run();
625
  });
626
 
@@ -637,10 +621,11 @@ function wpmc_open_dialog(content) {
637
  var $this = $(this);
638
  if ($this.hasClass('disabled')) return;
639
  var filter = $this.data('filter') || '';
640
- if (filter && filter != wrap.find('.search-box input[name="s"]').val()) {
 
641
  var dialog = wpmc_open_dialog({
642
  title: 'Warning',
643
- body: 'You have modified the search terms and did not click on "Search". <br>The <b>current</b> results will be deleted. Do you want to continue?',
644
  append: $('<div class="prompt">')
645
  .append(
646
  // Cancel Button
@@ -653,7 +638,7 @@ function wpmc_open_dialog(content) {
653
  $('<a class="button button-primary continue" href="#">Continue</a>').on('click', function (ev) {
654
  ev.preventDefault();
655
  dialog.dialog('close');
656
- wpmc_delete_all(false, filter);
657
  })
658
  )
659
  });
@@ -662,7 +647,7 @@ function wpmc_open_dialog(content) {
662
  else {
663
  var dialog = wpmc_open_dialog({
664
  title: 'Delete all',
665
- body: '<b>All the issues will be deleted</b>. If everything is working fine, they will actually be moved to the trash, but you should have a backup ready as well. Do you want to continue?',
666
  append: $('<div class="prompt">')
667
  .append(
668
  // Cancel Button
@@ -675,7 +660,7 @@ function wpmc_open_dialog(content) {
675
  $('<a class="button button-primary continue" href="#">Continue</a>').on('click', function (ev) {
676
  ev.preventDefault();
677
  dialog.dialog('close');
678
- wpmc_delete_all(false, filter);
679
  })
680
  )
681
  });
@@ -711,7 +696,7 @@ function wpmc_open_dialog(content) {
711
  var $this = $(this);
712
  var dialog = wpmc_open_dialog({
713
  title: "Reset",
714
- body: "This will reset the Media Cleaner database. All the information related to your trash, your latest scan and ignored entries will be lost. Do you want to continue?",
715
  append: $('<div class="prompt">')
716
  .append(
717
  // Cancel Button
4
  Author: Jordy Meow
5
  */
6
 
7
+ const WPMC_TARGET_FILES = 'files';
8
+ const WPMC_TARGET_MEDIAS = 'media';
9
+ const WPMC_SOURCE_CONTENT = 'content';
10
+ const WPMC_SOURCE_MEDIAS = 'media';
11
+
12
  function wpmc_pop_array(items, count) {
13
  var newItems = [];
14
  while ( newItems.length < count && items.length > 0 ) {
93
  wpmc_delete_do(items, items.length);
94
  }
95
 
96
+ function wpmc_delete_all(isTrash, filter = {}) {
 
97
  var data = {
98
  action: 'wpmc_get_all_issues',
99
  isTrash: isTrash ? 1 : 0,
100
+ filter: filter
101
  };
102
 
103
  jQuery.post(ajaxurl, data, function (response) {
114
  if (isDeleting === undefined)
115
  isDeleting = false;
116
  var action = isDeleting ? "Deleting" : "Analyzing";
117
+ jQuery('#wpmc_progression').html('<span class="dashicons dashicons-controls-play"></span> ' +
118
+ action + ' ' + current + "/" + totalcount + " (" + Math.round(current / totalcount * 100) + "%)");
119
  }
120
 
121
  function wpmc_delete_do(items, totalcount) {
183
  currentPhase: null,
184
 
185
  phases: {
186
+ extractReferencesFromPosts: {
187
  init: function () {
188
  this.progress = 0; // Scanned posts count
189
  this.progressPrev = 0;
190
  return this;
191
  },
192
  run: function () {
193
+ wpmc_extract_references_from(WPMC_SOURCE_CONTENT);
194
  },
195
  pause: function () {
196
+ jQuery('#wpmc_progression').html('<span class="dashicons dashicons-controls-pause"></span> Paused at preparing posts (' +
197
+ this.progress + ' posts)');
198
  },
199
  skip: function () {
200
  this.progress += wpmc_cfg.postsBuffer;
201
  },
202
  nextPhase: function () {
203
+ return wpmc.phases.extractReferencesFromMedias;
 
 
 
 
204
  }
205
  },
206
+ extractReferencesFromMedias: {
207
  init: function () {
208
+ this.progress = 0; // Scanned posts count
209
+ this.progressPrev = 0;
210
  return this;
211
  },
212
  run: function () {
213
+ wpmc_extract_references_from(WPMC_SOURCE_MEDIAS);
214
  },
215
  pause: function () {
216
+ jQuery('#wpmc_progression').html('<span class="dashicons dashicons-controls-pause"></span> Paused at preparing medias (' +
217
+ this.progress + ' medias)');
218
  },
219
  skip: function () {
220
+ this.progress += wpmc_cfg.mediasBuffer;
 
 
 
 
 
 
221
  },
222
  nextPhase: function () {
223
+ return wpmc.phases.retrieveTargetsToCheck;
224
+ console.error('Configuration Error'); // This shouldn't happen
225
  }
226
  },
227
+ retrieveTargetsToCheck: {
228
  init: function () {
229
  this.progress = 0; // Scanned media count
230
  this.progressPrev = 0;
231
  return this;
232
  },
233
  run: function () {
234
+ wpmc_retrieve_targets_for(this.method, this.method === WPMC_TARGET_FILES ? this.progress : null,
235
+ this.method === WPMC_TARGET_MEDIAS ? this.progress : 0);
236
  },
237
  pause: function () {
238
+ jQuery('#wpmc_progression').html('<span class="dashicons dashicons-controls-pause"></span> Paused at preparing media (' +
239
+ this.progress + ' media)');
240
  },
241
  skip: function () {
242
  this.progress += wpmc_cfg.mediasBuffer;
252
  return this;
253
  },
254
  run: function () {
255
+ wpmc_check_targets();
256
  },
257
  pause: function () {
258
  var current = wpmc.total - (wpmc.files.length + wpmc.medias.length);
259
  var totalcount = wpmc.total;
260
+ jQuery('#wpmc_progression').html('<span class="dashicons dashicons-controls-pause"></span> Paused at ' +
261
+ current + "/" + totalcount + " (" + Math.round(current / totalcount * 100) + "%)");
262
  },
263
  skip: function () {
264
  if (wpmc.files.length)
265
  this.currentFiles = wpmc_pop_array(wpmc.files, wpmc_cfg.analysisBuffer);
266
+ if (wpmc.medias.length)
267
  this.currentMedia = wpmc_pop_array(wpmc.medias, wpmc_cfg.analysisBuffer);
268
  },
269
  rollback: function () {
277
  };
278
  }
279
 
280
+ // Extract References from Posts
 
 
 
 
 
 
281
 
282
+ function wpmc_extract_references_from(source) {
 
 
283
  if (!wpmc.currentPhase) return; // Aborted
 
284
  if (wpmc.isPendingPause)
285
  return wpmc_update_to_pause();
 
286
  setTimeout(
287
  function() {
288
  if (!wpmc.currentPhase) return; // Aborted
289
+ jQuery('#wpmc_progression').html('<span class="dashicons dashicons-portfolio"></span> Extract references (' +
290
+ wpmc.currentPhase.progress + ' ' + source + ')...');
 
291
  jQuery.ajax({
292
  type: 'POST',
293
  url: ajaxurl,
294
  dataType: 'text',
295
  data: {
296
+ action: 'wpmc_extract_references',
297
+ source: source,
298
  limit: wpmc.currentPhase.progress
299
  },
300
  timeout: wpmc_cfg.timeout + 5000 // Extra 5sec for fail-safe
 
301
  }).done(function (response) {
302
  if (!wpmc.currentPhase) return; // Aborted
 
303
  var reply = wpmc_parse_response(response);
 
304
  if (!reply.success)
305
  return wpmc_handle_error(reply.message);
 
306
  if (!reply.finished) {
307
  wpmc.currentPhase.progressPrev = wpmc.currentPhase.progress;
308
  wpmc.currentPhase.progress = reply.limit;
309
  }
310
  else wpmc.currentPhase = wpmc.currentPhase.nextPhase().init();
 
311
  return wpmc.currentPhase.run();
 
312
  }).fail(function (e) { // Server Error
313
  wpmc_handle_error(e.statusText, e.status);
314
  });
 
315
  }, wpmc_cfg.delay
316
  );
317
  }
318
 
319
+ function wpmc_retrieve_targets_for(target, path = null, limit = 0) {
320
  if (!wpmc.currentPhase) return; // Aborted
321
 
322
  if (wpmc.isPendingPause)
326
  elpath = path.replace(/^.*[\\\/]/, '');
327
  jQuery('#wpmc_progression').html('<span class="dashicons dashicons-portfolio"></span> Preparing files (' + elpath + ')...');
328
  }
329
+ else if (target === WPMC_TARGET_MEDIAS)
330
  jQuery('#wpmc_progression').html('<span class="dashicons dashicons-admin-media"></span> Preparing medias (' + limit + ' medias)...');
331
+ else if (target === WPMC_TARGET_FILES)
332
  jQuery('#wpmc_progression').html('<span class="dashicons dashicons-portfolio"></span> Preparing files...');
333
+ else
334
+ jQuery('#wpmc_progression').html('<span class="dashicons dashicons-portfolio"></span> Preparing...');
335
 
336
  setTimeout(
337
  function() {
340
  url: ajaxurl,
341
  dataType: 'text',
342
  data: {
343
+ action: 'wpmc_retrieve_targets',
 
 
344
  path: path,
345
  limit: limit
346
  },
350
  if (!wpmc.currentPhase) return; // Aborted
351
 
352
  var reply = wpmc_parse_response(response);
353
+ var method = reply.method;
354
+ wpmc.currentPhase.method = method;
355
 
356
  if (!reply.success)
357
  return wpmc_handle_error(reply.message);
358
 
359
  // Store results
360
  for (var i = 0, len = reply.results.length; i < len; i++) {
361
+ var r = reply.results[i];
362
+ if (method === WPMC_TARGET_FILES) {
363
  if ( r.type === 'dir' )
364
  wpmc.dirs.push( r.path );
365
  else if ( r.type === 'file' ) {
367
  wpmc.total++;
368
  }
369
  }
370
+ else if (method === WPMC_TARGET_MEDIAS) {
371
  wpmc.medias.push( r );
372
  wpmc.total++;
373
  }
374
  }
375
 
376
  // Next query
377
+ if (method === WPMC_TARGET_MEDIAS) {
378
+ if (!reply.finished) {
379
  wpmc.currentPhase.progressPrev = wpmc.currentPhase.progress;
380
  wpmc.currentPhase.progress = reply.limit;
381
  }
382
  else
383
  wpmc.currentPhase = wpmc.currentPhase.nextPhase().init();
384
  }
385
+ else if (method === WPMC_TARGET_FILES) {
386
  var dir = wpmc.dirs.pop();
387
  if (dir) {
388
  wpmc.currentPhase.progressPrev = wpmc.currentPhase.progress;
419
  function wpmc_update_to_pause() {
420
  if (wpmc.isPendingPause) {
421
  wpmc.currentPhase.pause();
 
422
  jQuery('#wpmc_pause').html('<span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-play"></span>Continue');
423
  wpmc.isPendingPause = false;
424
  wpmc.isPause = true;
478
  wpmc.isPause = true;
479
  }
480
 
481
+ function wpmc_check_targets() {
482
  if (!wpmc.currentPhase) return; // Aborted
 
483
  if (wpmc.isPendingPause)
484
  return wpmc_update_to_pause();
485
 
489
  if (wpmc.files.length > 0) {
490
  wpmc.currentPhase.currentFiles = wpmc_pop_array(wpmc.files, wpmc_cfg.analysisBuffer);
491
  expectedSuccess = wpmc.currentPhase.currentFiles.length;
492
+ data = { action: 'wpmc_check_targets', method: 'file', data: wpmc.currentPhase.currentFiles };
493
  }
494
  else if (wpmc.medias.length > 0) {
495
  wpmc.currentPhase.currentMedia = wpmc_pop_array(wpmc.medias, wpmc_cfg.analysisBuffer);
496
  expectedSuccess = wpmc.currentPhase.currentMedia.length;
497
+ data = { action: 'wpmc_check_targets', method: 'media', data: wpmc.currentPhase.currentMedia };
498
  }
499
  else {
500
+ jQuery('#wpmc_progression').html("");
501
+ var issueMsg = 'No issues were found.';
502
+ if (wpmc.issues > 1)
503
+ issueMsg = wpmc.issues + ' issues were found.';
504
+ else if (wpmc.issues === 1)
505
+ issueMsg = 'Only 1 issue was found.';
506
+ jQuery('#wpmc-table').html('<div style="padding: 20px; text-align: center;"><p style="font-size: 14px; margin: 0px 0px 10px 0px;">' +
507
+ issueMsg + '</p><a class="button-primary" href="?page=media-cleaner">Display the results</a></div>');
508
  wpmc = wpmc_new_context(); // Reset the context
509
  jQuery('#wpmc_pause').hide();
510
  jQuery('#wpmc_scan').html('<span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-search"></span>Start Scan');
511
  jQuery('#wpmc_actions').trigger('idle');
512
+ //location.reload();
513
  return;
514
  }
515
 
521
  dataType: 'text',
522
  data: data,
523
  timeout: wpmc_cfg.timeout + 5000 // Extra 5sec for fail-safe
 
524
  }).done(function (response) {
525
  var reply = wpmc_parse_response(response);
 
526
  if (!reply.success)
527
  return wpmc_handle_error(reply.message);
528
+ wpmc.issues += expectedSuccess - reply.results;
529
+ wpmc_check_targets();
 
 
 
 
530
  }).fail(function (e) { // Server Error
531
  wpmc_handle_error(e.statusText, e.status);
532
  });
 
533
  }, wpmc_cfg.delay
534
  );
535
  }
604
  wrap.trigger('busy');
605
  $('#wpmc_scan').html('Stop Scan');
606
  $('#wpmc_pause').show();
607
+ wpmc.currentPhase = wpmc.phases.extractReferencesFromPosts.init();
608
  wpmc.currentPhase.run();
609
  });
610
 
621
  var $this = $(this);
622
  if ($this.hasClass('disabled')) return;
623
  var filter = $this.data('filter') || '';
624
+ var search = $this.data('search') || '';
625
+ if (search != wrap.find('.search-box input[name="s"]').val()) {
626
  var dialog = wpmc_open_dialog({
627
  title: 'Warning',
628
+ body: 'You modified the search terms without clicking on the <i>Search</i> button to refresh the results. Therefore, the <b>current</b> results will be deleted. Do you want to continue?',
629
  append: $('<div class="prompt">')
630
  .append(
631
  // Cancel Button
638
  $('<a class="button button-primary continue" href="#">Continue</a>').on('click', function (ev) {
639
  ev.preventDefault();
640
  dialog.dialog('close');
641
+ wpmc_delete_all(false, { filter, search });
642
  })
643
  )
644
  });
647
  else {
648
  var dialog = wpmc_open_dialog({
649
  title: 'Delete all',
650
+ body: '<b>All the issues will be moved to the trash</b>. Please make sure you have a backup. Do you want to continue?',
651
  append: $('<div class="prompt">')
652
  .append(
653
  // Cancel Button
660
  $('<a class="button button-primary continue" href="#">Continue</a>').on('click', function (ev) {
661
  ev.preventDefault();
662
  dialog.dialog('close');
663
+ wpmc_delete_all(false, { filter, search });
664
  })
665
  )
666
  });
696
  var $this = $(this);
697
  var dialog = wpmc_open_dialog({
698
  title: "Reset",
699
+ body: "The information related to the Media Cleaner's trash, latest scan and ignored entries will be lost. Do you want to continue?",
700
  append: $('<div class="prompt">')
701
  .append(
702
  // Cancel Button
scripts/style.css CHANGED
@@ -1,92 +1,69 @@
1
- .wp-core-ui .button-red {
2
- background-color: #9B2124;
3
- background-image: -webkit-gradient(linear, left top, left bottom, from(#C5292E), to(#9B2124));
4
- background-image: -webkit-linear-gradient(top, #C5292E, #9B2124);
5
- background-image: -moz-linear-gradient(top, #C5292E, #9B2124);
6
- background-image: -ms-linear-gradient(top, #C5292E, #9B2124);
7
- background-image: -o-linear-gradient(top, #C5292E, #9B2124);
8
- background-image: linear-gradient(to bottom, #C5292E, #9B2124);
9
- border-color: #9B2124;
10
- border-bottom-color: #8D1F21;
11
- -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
12
- box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
13
- color: #fff;
14
- text-decoration: none;
15
- text-shadow: 0 1px 0 rgba(0,0,0,0.1);
16
- float: right;
17
  }
18
 
19
- .wp-core-ui .button-red.hover,
20
- .wp-core-ui .button-red:hover,
21
- .wp-core-ui .button-red.focus,
22
- .wp-core-ui .button-red:focus {
23
- background-color: #B72629;
24
- background-image: -webkit-gradient(linear, left top, left bottom, from(#D22E30), to(#9B2124));
25
- background-image: -webkit-linear-gradient(top, #D22E30, #9B2124);
26
- background-image: -moz-linear-gradient(top, #D22E30, #9B2124);
27
- background-image: -ms-linear-gradient(top, #D22E30, #9B2124);
28
- background-image: -o-linear-gradient(top, #D22E30, #9B2124);
29
- background-image: linear-gradient(to bottom, #D22E30, #9B2124);
30
- border-color: #7F1C1F;
31
- -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.6);
32
- box-shadow: inset 0 1px 0 rgba(120,200,230,0.6);
33
- color: #fff;
34
- text-shadow: 0 -1px 0 rgba(0,0,0,0.3);
35
  }
36
 
37
- .wp-core-ui .button-red.focus,
38
- .wp-core-ui .button-red:focus {
39
- border-color: #500F0E;
40
- -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.6), 1px 1px 2px rgba(0,0,0,0.4);
41
- box-shadow: inset 0 1px 0 rgba(120,200,230,0.6), 1px 1px 2px rgba(0,0,0,0.4);
 
 
 
 
 
 
42
  }
43
 
44
- .wp-core-ui .button-red.active,
45
- .wp-core-ui .button-red.active:hover,
46
- .wp-core-ui .button-red.active:focus,
47
- .wp-core-ui .button-red:active {
48
- background: #7F1C1F;
49
- background-image: -webkit-gradient(linear, left top, left bottom, from(#9B2124), to(#B72629));
50
- background-image: -webkit-linear-gradient(top, #9B2124, #B72629);
51
- background-image: -moz-linear-gradient(top, #9B2124, #B72629);
52
- background-image: -ms-linear-gradient(top, #9B2124, #B72629);
53
- background-image: -o-linear-gradient(top, #9B2124, #B72629);
54
- background-image: linear-gradient(to bottom, #9B2124, #B72629);
55
- border-color: #601312 #AE2426 #AE2426 #AE2426;
56
- color: rgba(255,255,255,0.95);
57
- -webkit-box-shadow: inset 0 1px 0 rgba(0,0,0,0.1);
58
- box-shadow: inset 0 1px 0 rgba(0,0,0,0.1);
59
- text-shadow: 0 1px 0 rgba(0,0,0,0.1);
60
  }
61
 
62
- .wp-core-ui .button-red[disabled],
63
- .wp-core-ui .button-red:disabled,
64
- .wp-core-ui .button-red-disabled {
65
- color: #E79496 !important;
66
- background: #BA292B !important;
67
- border-color: #7F1C1F !important;
68
- -webkit-box-shadow: none !important;
69
- box-shadow: none !important;
70
- text-shadow: 0 -1px 0 rgba(0,0,0,0.1) !important;
71
- cursor: default;
72
  }
73
 
74
- /**
75
- * Dialog
76
- */
77
  #wpmc-dialog {
78
  text-align: center;
 
79
  }
80
  #wpmc-dialog .prompt {
81
  margin-top: 16px;
 
 
 
 
82
  }
83
  #wpmc-dialog .prompt .button + .button {
84
- margin-left: 16px;
85
  }
86
 
87
- /**
88
- * Settings
89
- */
90
- .meow-box form input:invalid {
91
  color: red;
92
  }
 
 
 
 
 
 
 
 
1
+ #wpmc_actions {
2
+ background: #FFF;
3
+ padding: 6px 6px 8px 6px;
4
+ height: 28px;
5
+ border-radius: 4px;
6
+ box-shadow: 0px 0px 4px #C2C2C2;
 
 
 
 
 
 
 
 
 
 
7
  }
8
 
9
+ #wpmc-paging {
10
+ float: right;
11
+ position: relative;
12
+ top: 12px;
 
 
 
 
 
 
 
 
 
 
 
 
13
  }
14
 
15
+ #wpmc-paging a {
16
+ text-decoration: none;
17
+ border: 1px solid black;
18
+ padding: 2px 5px;
19
+ border-radius: 4px;
20
+
21
+ border-color: #BEBEBE;
22
+ }
23
+
24
+ #wpmc-paging .current {
25
+ font-weight: bold;
26
  }
27
 
28
+ .wp-core-ui .button-red {
29
+ background-color: #ba1100;
30
+ border-color: #ba1100;
31
+ color: #fff;
32
+ text-decoration: none;
 
 
 
 
 
 
 
 
 
 
 
33
  }
34
 
35
+ .wp-core-ui .button-red:hover,
36
+ .wp-core-ui .button-red:focus {
37
+ background-color: #a11800;
38
+ border-color: #a11800;
39
+ color: #fff;
 
 
 
 
 
40
  }
41
 
42
+ /* Dialog */
 
 
43
  #wpmc-dialog {
44
  text-align: center;
45
+ min-height: auto !important;
46
  }
47
  #wpmc-dialog .prompt {
48
  margin-top: 16px;
49
+ display: flex;
50
+ }
51
+ #wpmc-dialog .prompt .button {
52
+ flex: 1;
53
  }
54
  #wpmc-dialog .prompt .button + .button {
55
+ margin-left: 5px;
56
  }
57
 
58
+ /* Settings */
59
+ .wrap-media-cleaner .meow-box form input:invalid {
 
 
60
  color: red;
61
  }
62
+
63
+ /* Nice layout for the notices */
64
+ .wrap-media-cleaner .notice {
65
+ margin: -10px 0px 15px;
66
+ }
67
+ .wrap-media-cleaner .notice:first-of-type {
68
+ margin: 10px 0px 15px;
69
+ }
ui.php CHANGED
@@ -1,155 +1,159 @@
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
- "PAGE BUILDER (ID)" => "Found in Page Builder (as an ID).",
14
- "PAGE BUILDER (URL)" => "Found in Page Builder (as an URL).",
15
- "GALLERY" => "Found in gallery.",
16
- "META" => "Found in meta.",
17
- "META (ID)" => "Found in meta (as an ID).",
18
- "META (URL)" => "Found in meta (as an URL).",
19
- "META ACF (ID)" => "Found in meta (as an URL).",
20
- "META ACF (URL)" => "Found in meta (as an URL).",
21
- "WIDGET" => "Found in widget.",
22
- "ACF WIDGET (ID)" => "Found in ACF Widget (as an ID).",
23
- "ACF WIDGET (URL)" => "Found in ACF Widget (as an URL).",
24
- "ATTACHMENT (ID)" => "Found in Attachment (as an ID).",
25
- "METASLIDER (ID)" => "Found in MetaSlider (as an ID).",
26
- "MY CALENDAR (URL)" => "Found in My Calendar (as an URL).",
27
- "UBERMENU (URL)" => "Found in UberMenu (as an URL).",
28
- "MAX MEGA MENU (URL)" => "Found in Max Mega Menu (as an URL).",
29
- "SITE ICON" => "Found in Site Icon."
30
- );
31
-
32
- function __construct( $core, $admin ) {
33
- $this->core = $core;
34
- $this->admin = $admin;
35
- add_action( 'admin_menu', array( $this, 'admin_menu' ) );
36
- add_action( 'admin_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) );
37
- add_action( 'admin_print_scripts', array( $this, 'admin_inline_js' ) );
38
- add_action( 'add_meta_boxes', array( $this, 'add_metabox' ) );
39
- add_filter( 'media_row_actions', array( $this, 'media_row_actions' ), 10, 2 );
40
- }
41
-
42
- /**
43
- * Renders a view within the views directory.
44
- * @param string $view The name of the view to render
45
- * @param array $data
46
- * An associative array of variables to bind to the view.
47
- * Each key turns into a variable name.
48
- * @return string Rendered view
49
- */
50
- function render_view( $view, $data = null ) {
51
- ob_start();
52
- if ( is_array( $data ) ) extract( $data );
53
- include( __DIR__ . "/views/$view.php" );
54
- return ob_get_clean();
55
- }
56
-
57
- function admin_menu() {
58
- //load_plugin_textdomain( 'media-cleaner', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
59
- add_media_page( 'Media Cleaner', 'Cleaner', 'manage_options', 'media-cleaner', array( $this, 'wpmc_screen' ) );
60
- }
61
-
62
- function wpmc_screen() {
63
- global $wpdb, $wplr;
64
- echo $this->render_view( 'menu-screen', array(
65
- 'wpdb' => $wpdb,
66
- 'wplr' => $wplr,
67
- 'ui' => $this,
68
- 'core' => $this->core,
69
- 'admin' => $this->admin
70
- ) );
71
- }
72
-
73
- function wp_enqueue_scripts() {
74
- wp_enqueue_style( 'wp-jquery-ui-dialog' );
75
- wp_enqueue_script( 'jquery-ui-dialog' );
76
- wp_enqueue_style( 'media-cleaner-css', plugins_url( '/scripts/style.css', __FILE__ ) );
77
-
78
- $screen = get_current_screen();
79
- global $wpmc_version;
80
- switch ( $screen->id ) {
81
- case 'media_page_media-cleaner': // Media > Cleaner
82
- wp_enqueue_script( 'media-cleaner', plugins_url( '/scripts/dashboard.js', __FILE__ ), array( 'jquery', 'jquery-ui-dialog' ),
83
- $wpmc_version, true );
84
- break;
85
- case 'meow-apps_page_wpmc_settings-menu': // Meow Apps > Media Cleaner (Settings)
86
- wp_enqueue_script( 'media-cleaner-settings', plugins_url( '/scripts/settings.js', __FILE__ ), array( 'jquery' ),
87
- $wpmc_version, true );
88
- break;
89
- }
90
- }
91
-
92
- /**
93
- *
94
- * DASHBOARD
95
- *
96
- */
97
-
98
- function admin_inline_js() {
99
- echo "<script type='text/javascript'>\n";
100
- echo 'var wpmc_cfg = {
101
- timeout: ' . ( (int) $this->core->get_max_execution_time() ) * 1000 . ',
102
- delay: ' . get_option( 'wpmc_delay', 100 ) . ',
103
- postsBuffer:' . get_option( 'wpmc_posts_buffer', 5 ) . ',
104
- mediasBuffer:' . get_option( 'wpmc_medias_buffer', 100 ) . ',
105
- analysisBuffer: ' . get_option( 'wpmc_analysis_buffer', 50 ) . ',
106
- isPro: ' . ( $this->admin->is_registered() ? '1' : '0') . ',
107
- scanFiles: ' . ( ( get_option( 'wpmc_method', 'media' ) == 'files' && $this->admin->is_registered() ) ? '1' : '0' ) . ',
108
- scanMedia: ' . ( get_option( 'wpmc_method', 'media' ) == 'media' ? '1' : '0' ) . ' };';
109
- echo "\n</script>";
110
- }
111
-
112
- /*******************************************************************************
113
- * METABOX FOR USAGE
114
- ******************************************************************************/
115
-
116
- function add_metabox() {
117
- add_meta_box( 'mfrh_media_usage_box', 'Media Cleaner', array( $this, 'display_metabox' ), 'attachment', 'side', 'default' );
118
- }
119
-
120
- function display_metabox( $post ) {
121
- $this->core->log( "Media Edit > Checking Media #{$post->ID}" );
122
- $success = $this->core->check_media( $post->ID, true );
123
- $this->core->log( "Success $success\n" );
124
- if ( $success ) {
125
- if ( array_key_exists( $this->core->last_analysis, $this->foundTypes ) )
126
- echo $this->foundTypes[ $this->core->last_analysis ];
127
- else
128
- echo "It seems to be used as: " . $this->core->last_analysis;
129
- }
130
- else {
131
- echo "Doesn't seem to be used.";
132
- }
133
- }
134
-
135
- function media_row_actions( $actions, $post ) {
136
- global $current_screen;
137
- if ( 'upload' != $current_screen->id )
138
- return $actions;
139
- global $wpdb;
140
- $table_name = $wpdb->prefix . "mclean_scan";
141
- $res = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE postId = %d", $post->ID ) );
142
- if ( !empty( $res ) && isset( $actions['delete'] ) )
143
- $actions['delete'] = "<a href='?page=media-cleaner&view=deleted'>" .
144
- __( 'Delete with Media Cleaner', 'media-cleaner' ) . "</a>";
145
- if ( !empty( $res ) && isset( $actions['trash'] ) )
146
- $actions['trash'] = "<a href='?page=media-cleaner'>" .
147
- __( 'Trash with Media Cleaner', 'media-cleaner' ) . "</a>";
148
- if ( !empty( $res ) && isset( $actions['untrash'] ) ) {
149
- $actions['untrash'] = "<a href='?page=media-cleaner&view=deleted'>" .
150
- __( 'Restore with Media Cleaner', 'media-cleaner' ) . "</a>";
151
- }
152
- return $actions;
153
- }
154
-
155
- }
 
 
 
 
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
+ "PAGE BUILDER (ID)" => "Found in Page Builder (as an ID).",
14
+ "PAGE BUILDER (URL)" => "Found in Page Builder (as an URL).",
15
+ "GALLERY" => "Found in gallery.",
16
+ "META" => "Found in meta.",
17
+ "META (ID)" => "Found in meta (as an ID).",
18
+ "META (URL)" => "Found in meta (as an URL).",
19
+ "META ACF (ID)" => "Found in meta (as an URL).",
20
+ "META ACF (URL)" => "Found in meta (as an URL).",
21
+ "WIDGET" => "Found in widget.",
22
+ "ACF WIDGET (ID)" => "Found in ACF Widget (as an ID).",
23
+ "ACF WIDGET (URL)" => "Found in ACF Widget (as an URL).",
24
+ "ATTACHMENT (ID)" => "Found in Attachment (as an ID).",
25
+ "METASLIDER (ID)" => "Found in MetaSlider (as an ID).",
26
+ "MY CALENDAR (URL)" => "Found in My Calendar (as an URL).",
27
+ "UBERMENU (URL)" => "Found in UberMenu (as an URL).",
28
+ "MAX MEGA MENU (URL)" => "Found in Max Mega Menu (as an URL).",
29
+ "SITE ICON" => "Found in Site Icon."
30
+ );
31
+
32
+ function __construct( $core, $admin ) {
33
+ $this->core = $core;
34
+ $this->admin = $admin;
35
+ add_action( 'init', array( $this, 'load_textdomain' ) );
36
+ add_action( 'admin_menu', array( $this, 'admin_menu' ) );
37
+ add_action( 'admin_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) );
38
+ add_action( 'admin_print_scripts', array( $this, 'admin_inline_js' ) );
39
+ add_action( 'add_meta_boxes', array( $this, 'add_metabox' ) );
40
+ add_filter( 'media_row_actions', array( $this, 'media_row_actions' ), 10, 2 );
41
+ }
42
+
43
+ /**
44
+ * Renders a view within the views directory.
45
+ * @param string $view The name of the view to render
46
+ * @param array $data
47
+ * An associative array of variables to bind to the view.
48
+ * Each key turns into a variable name.
49
+ * @return string Rendered view
50
+ */
51
+ function render_view( $view, $data = null ) {
52
+ ob_start();
53
+ if ( is_array( $data ) ) extract( $data );
54
+ include( __DIR__ . "/views/$view.php" );
55
+ return ob_get_clean();
56
+ }
57
+
58
+ function load_textdomain() {
59
+ load_plugin_textdomain( 'media-cleaner', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
60
+ }
61
+
62
+ function admin_menu() {
63
+ add_media_page( 'Media Cleaner', 'Cleaner', 'manage_options', 'media-cleaner', array( $this, 'wpmc_screen' ) );
64
+ }
65
+
66
+ function wpmc_screen() {
67
+ global $wpdb, $wplr;
68
+ echo $this->render_view( 'menu-screen', array(
69
+ 'wpdb' => $wpdb,
70
+ 'wplr' => $wplr,
71
+ 'ui' => $this,
72
+ 'core' => $this->core,
73
+ 'admin' => $this->admin
74
+ ) );
75
+ }
76
+
77
+ function wp_enqueue_scripts() {
78
+ wp_enqueue_style( 'wp-jquery-ui-dialog' );
79
+ wp_enqueue_script( 'jquery-ui-dialog' );
80
+ wp_enqueue_style( 'media-cleaner-css', plugins_url( '/scripts/style.css', __FILE__ ) );
81
+
82
+ $screen = get_current_screen();
83
+ global $wpmc_version;
84
+ switch ( $screen->id ) {
85
+ case 'media_page_media-cleaner': // Media > Cleaner
86
+ wp_enqueue_script( 'media-cleaner', plugins_url( '/scripts/dashboard.js', __FILE__ ), array( 'jquery', 'jquery-ui-dialog' ),
87
+ $wpmc_version, true );
88
+ break;
89
+ case 'meow-apps_page_wpmc_settings-menu': // Meow Apps > Media Cleaner (Settings)
90
+ wp_enqueue_script( 'media-cleaner-settings', plugins_url( '/scripts/settings.js', __FILE__ ), array( 'jquery' ),
91
+ $wpmc_version, true );
92
+ break;
93
+ }
94
+ }
95
+
96
+ /**
97
+ *
98
+ * DASHBOARD
99
+ *
100
+ */
101
+
102
+ function admin_inline_js() {
103
+ echo "<script type='text/javascript'>\n";
104
+ echo 'var wpmc_cfg = {
105
+ timeout: ' . ( (int) $this->core->get_max_execution_time() ) * 1000 . ',
106
+ delay: ' . get_option( 'wpmc_delay', 100 ) . ',
107
+ postsBuffer:' . get_option( 'wpmc_posts_buffer', 5 ) . ',
108
+ mediasBuffer:' . get_option( 'wpmc_medias_buffer', 100 ) . ',
109
+ analysisBuffer: ' . get_option( 'wpmc_analysis_buffer', 50 ) . ',
110
+ isPro: ' . ( $this->admin->is_registered() ? '1' : '0') . ',
111
+ scanFiles: ' . ( ( $this->core->current_method == 'files' && $this->admin->is_registered() ) ? '1' : '0' ) . ',
112
+ scanMedia: ' . ( $this->core->current_method == 'media' ? '1' : '0' ) . ' };';
113
+ echo "\n</script>";
114
+ }
115
+
116
+ /*******************************************************************************
117
+ * METABOX FOR USAGE
118
+ ******************************************************************************/
119
+
120
+ function add_metabox() {
121
+ add_meta_box( 'mfrh_media_usage_box', 'Media Cleaner', array( $this, 'display_metabox' ), 'attachment', 'side', 'default' );
122
+ }
123
+
124
+ function display_metabox( $post ) {
125
+ $this->core->log( "Media Edit > Checking Media #{$post->ID}" );
126
+ $success = $this->core->check_media( $post->ID, true );
127
+ $this->core->log( "Success $success\n" );
128
+ if ( $success ) {
129
+ if ( array_key_exists( $this->core->last_analysis, $this->foundTypes ) )
130
+ echo $this->foundTypes[ $this->core->last_analysis ];
131
+ else
132
+ echo "It seems to be used as: " . $this->core->last_analysis;
133
+ }
134
+ else {
135
+ echo "Doesn't seem to be used.";
136
+ }
137
+ }
138
+
139
+ function media_row_actions( $actions, $post ) {
140
+ global $current_screen;
141
+ if ( 'upload' != $current_screen->id )
142
+ return $actions;
143
+ global $wpdb;
144
+ $table_name = $wpdb->prefix . "mclean_scan";
145
+ $res = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE postId = %d", $post->ID ) );
146
+ if ( !empty( $res ) && isset( $actions['delete'] ) )
147
+ $actions['delete'] = "<a href='?page=media-cleaner&view=deleted'>" .
148
+ __( 'Delete with Media Cleaner', 'media-cleaner' ) . "</a>";
149
+ if ( !empty( $res ) && isset( $actions['trash'] ) )
150
+ $actions['trash'] = "<a href='?page=media-cleaner'>" .
151
+ __( 'Trash with Media Cleaner', 'media-cleaner' ) . "</a>";
152
+ if ( !empty( $res ) && isset( $actions['untrash'] ) ) {
153
+ $actions['untrash'] = "<a href='?page=media-cleaner&view=deleted'>" .
154
+ __( 'Restore with Media Cleaner', 'media-cleaner' ) . "</a>";
155
+ }
156
+ return $actions;
157
+ }
158
+
159
+ }
views/menu-screen.php CHANGED
@@ -1,71 +1,82 @@
1
- <div class='wrap'>
2
 
3
  <?php
4
  echo $admin->display_title( "Media Cleaner" );
5
  $posts_per_page = get_option( 'wpmc_results_per_page', 20 );
6
  $view = isset ( $_GET[ 'view' ] ) ? sanitize_text_field( $_GET[ 'view' ] ) : "issues";
7
  $paged = isset ( $_GET[ 'paged' ] ) ? sanitize_text_field( $_GET[ 'paged' ] ) : 1;
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";
15
- $issues_count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name WHERE ignored = 0 AND deleted = 0" );
16
- $total_size = $wpdb->get_var( "SELECT SUM(size) FROM $table_name WHERE ignored = 0 AND deleted = 0" );
17
- $trash_total_size = $wpdb->get_var( "SELECT SUM(size) FROM $table_name WHERE ignored = 0 AND deleted = 1" );
18
- $ignored_count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name WHERE ignored = 1" );
19
- $deleted_count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name WHERE deleted = 1" );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
  if ( $view == 'deleted' ) {
22
  $items_count = $deleted_count;
23
  $items = $wpdb->get_results( $wpdb->prepare( "SELECT id, type, postId, path, size, ignored, deleted, issue
24
- FROM $table_name WHERE ignored = 0 AND deleted = 1 AND path LIKE %s
25
  ORDER BY path, time
26
  DESC LIMIT %d, %d", '%' . $s . '%', ( $paged - 1 ) * $posts_per_page, $posts_per_page ), OBJECT );
27
  }
28
  else if ( $view == 'ignored' ) {
29
  $items_count = $ignored_count;
30
  $items = $wpdb->get_results( $wpdb->prepare( "SELECT id, type, postId, path, size, ignored, deleted, issue
31
- FROM $table_name
32
- WHERE ignored = 1 AND deleted = 0 AND path LIKE %s
33
  ORDER BY path, time
34
  DESC LIMIT %d, %d", '%' . $s . '%', ( $paged - 1 ) * $posts_per_page, $posts_per_page ), OBJECT );
35
  }
36
  else {
37
  $items_count = $issues_count;
38
  $items = $wpdb->get_results( $wpdb->prepare( "SELECT id, type, postId, path, size, ignored, deleted, issue
39
- FROM $table_name
40
- WHERE ignored = 0 AND deleted = 0 AND path LIKE %s
41
  ORDER BY path, time
42
  DESC LIMIT %d, %d", '%' . $s . '%', ( $paged - 1 ) * $posts_per_page, $posts_per_page ), OBJECT );
43
  }
44
  ?>
45
 
46
- <style>
47
- #wpmc-pages {
48
- float: right;
49
- position: relative;
50
- top: 12px;
51
- }
52
-
53
- #wpmc-pages a {
54
- text-decoration: none;
55
- border: 1px solid black;
56
- padding: 2px 5px;
57
- border-radius: 4px;
58
- background: #E9E9E9;
59
- color: lightslategrey;
60
- border-color: #BEBEBE;
61
- }
62
-
63
- #wpmc-pages .current {
64
- font-weight: bold;
65
- }
66
- </style>
67
-
68
- <div id="wpmc_actions" style='margin-top: 0px; background: #FFF; padding: 5px; border-radius: 4px; height: 28px; box-shadow: 0px 0px 6px #C2C2C2;'>
69
 
70
  <!-- SCAN -->
71
  <?php if ( $view != 'deleted' ): ?>
@@ -92,18 +103,13 @@
92
  ?>
93
  </a>
94
 
95
- <!-- RESET -->
96
- <?php if ( $view != 'deleted' ): ?>
97
- <a id='wpmc_reset' href='?page=media-cleaner&reset=1' class='button-primary' style='float: right; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-sos"></span><?php _e("Reset", 'media-cleaner'); ?></a>
98
- <?php endif; ?>
99
-
100
  <!-- DELETE ALL -->
101
  <?php if ( $view == 'deleted' ): // i ?>
102
- <a id='wpmc_recover_all' class='button-primary exclusive' style='float: right; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-repeat"></span><?php _e("Recover all", 'media-cleaner'); ?></a>
103
  <a id='wpmc_empty_trash' class='button button-red exclusive' style='float: right; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-trash"></span><?php _e("Empty trash", 'media-cleaner'); ?></a>
 
104
  <?php else: // i ?>
105
- <?php if ( $s ): // ii ?>
106
- <a id='wpmc_delete_all' class='button button-red exclusive' data-filter="<?php echo esc_attr( $s ); ?>" style='float: right; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-trash"></span><?php _e("Delete all search results", 'media-cleaner'); ?></a>
107
  <?php else: // ii ?>
108
  <a id='wpmc_delete_all' class='button button-red exclusive' style='float: right; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-trash"></span><?php _e("Delete all", 'media-cleaner'); ?></a>
109
  <?php endif; // ii ?>
@@ -111,11 +117,25 @@
111
 
112
  <form id="posts-filter" action="upload.php" method="get" style='float: right;'>
113
  <p class="search-box" style='margin-left: 5px; float: left;'>
114
- <input type="search" name="s" class="exclusive" style="width: 120px;" value="<?php echo $s ? esc_attr( $s ) : ""; ?>">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  <input type="hidden" name="page" value="media-cleaner">
116
  <input type="hidden" name="view" value="<?php echo $view; ?>">
117
  <input type="hidden" name="paged" value="1">
118
- <input type="submit" class="button exclusive" value="<?php _e( 'Search', 'media-cleaner' ) ?>"><span style='border-right: #A2A2A2 solid 1px; margin-left: 5px; margin-right: 3px;'>&nbsp;</span>
119
  </p>
120
  </form>
121
 
@@ -126,36 +146,22 @@
126
 
127
  <p>
128
  <?php
129
- $method = "";
130
- $table_scan = $wpdb->prefix . "mclean_scan";
131
- $table_refs = $wpdb->prefix . "mclean_refs";
132
- $db_init = !(strtolower( $wpdb->get_var( "SHOW TABLES LIKE '$table_scan'" ) ) != strtolower( $table_scan )
133
- ||strtolower( $wpdb->get_var( "SHOW TABLES LIKE '$table_refs'" ) ) != strtolower( $table_refs ));
134
-
135
- // The DB for Media Cleaner does not exist. Let's create it.
136
- if ( !$db_init ) {
137
- wpmc_reset();
138
- $db_init = !(strtolower( $wpdb->get_var( "SHOW TABLES LIKE '$table_scan'" ) ) != strtolower( $table_scan )
139
- || strtolower( $wpdb->get_var( "SHOW TABLES LIKE '$table_refs'" ) ) != strtolower( $table_refs ));
140
- }
141
-
142
- // It still doesn't exist. Weird, something might have happened?
143
- if ( !$db_init ) {
144
- _e( "<div class='notice notice-error'><p><b>The database is not ready for Media Cleaner. The scan will not work.</b> Click on the <b>Reset</b> button, it re-creates the tables required by Media Cleaner. If this message still appear, contact the support.</p></div>", 'media-cleaner' );
145
- }
146
- else {
147
- $method = get_option( 'wpmc_method', 'media' );
148
  if ( !$admin->is_registered() )
149
  $method = 'media';
150
 
151
  $hide_warning = get_option( 'wpmc_hide_warning', false );
152
-
153
  if ( !$hide_warning ) {
154
- _e( "<div class='notice notice-warning'><p><b style='color: red;'>Important.</b> <b>Backup your DB and your /uploads directory before using Media Cleaner. </b> The deleted files will be temporarily moved to the <b>uploads/wpmc-trash</b> directory. After testing your website, you can check the <a href='?page=media-cleaner&s&view=deleted'>trash</a> to either empty it or recover the media and files. The Media Cleaner does its best to be safe to use. However, WordPress being a very dynamic and pluggable system, it is impossible to predict all the situations in which your files are used. <b style='color: red;'>Again, please backup!</b> If you don't know how, give a try to this: <a href='https://meow.click/blogvault' target='_blank'>BlogVault</a>. <br /><br /><b style='color: red;'>Be thoughtful.</b> Don't blame Media Cleaner if it deleted too many or not enough of your files. It makes cleaning possible and this task is only possible this way; don't post a bad review because it broke your install. <b>If you have a proper backup, there is no risk</b>. Sorry for the lengthy message, but better be safe than sorry. You can disable this big warning in the options if you have a Pro license. Make sure you read this warning twice. Media Cleaner is awesome and always getting better so I hope you will enjoy it. Thank you :)</p></div>", 'media-cleaner' );
 
 
155
  }
156
 
157
  if ( !MEDIA_TRASH ) {
158
- _e( "<div class='notice notice-warning'><p>The trash for the Media Library is disabled. Any media removed by the plugin will be <b>permanently deleted</b>. To enable it, modify your wp-config.php file and add this line (preferably at the top): <b>define( 'MEDIA_TRASH', true );</b></p></div>", 'media-cleaner' );
 
 
159
  }
160
  }
161
 
@@ -198,7 +204,7 @@
198
 
199
  if ( class_exists( 'X_Bootstrap' ) )
200
  array_push( $unsupported, 'Theme X' );
201
-
202
  if ( class_exists( 'SiteOrigin_Panels' ) )
203
  array_push( $unsupported, 'SiteOrigin PageBuilder' );
204
 
@@ -217,6 +223,12 @@
217
  if ( defined( 'AV_FRAMEWORK_VERSION' ) )
218
  array_push( $unsupported, 'Avia Framework' );
219
 
 
 
 
 
 
 
220
  if ( !empty( $unsupported ) ) {
221
  echo "<div class='notice notice-error'><p>";
222
  _e( "<b>Important note about the following plugin(s): </b>", 'media-cleaner' );
@@ -224,34 +236,73 @@
224
  _e( "They require additional checks which are implemented in the <a target='_blank' href='//meowapps.com/plugin/media-cleaner'>Media Cleaner Pro</a>.", 'media-cleaner' );
225
  echo "</p></div>";
226
  }
227
-
228
  }
229
 
230
- $anychecks = get_option( 'wpmc_content', true ) || get_option( 'wpmc_posts', false )
231
- || get_option( 'wpmc_postmeta', false ) || get_option( 'wpmc_widgets', false );
232
  $check_library = get_option(' wpmc_media_library', true );
 
 
 
 
 
 
233
 
234
- if ( $method == 'media' ) {
235
- if ( !$anychecks )
236
- _e( "<div class='error'><p>Media Cleaner will analyze your Media Library. However, There is <b>NOTHING MARKED TO BE CHECKED</b> in the Settings. Media Cleaner will therefore run a special scan: <b>only the broken medias will be detected as issues.</b></p></div>", 'media-cleaner' );
237
- else
238
- _e( "<div class='notice notice-success'><p>Media Cleaner will analyze your Media Library.</p></div>", 'media-cleaner' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  }
240
  else if ( $method == 'files' ) {
241
- if ( !$anychecks && !$check_library )
242
- _e( "<div class='error'><p>Media Cleaner will analyze your Filesystem. However, There is <b>NOTHING MARKED TO BE CHECKED</b> in the Settings. If you scan now, all the files will be detected as <b>NOT USED</b>.</p></div>", 'media-cleaner' );
243
- else
244
- _e( "<div class='notice notice-success'><p>Media Cleaner will analyze your Filesystem.</p></div>", 'media-cleaner' );
 
 
 
 
 
245
  }
246
 
247
- echo sprintf( __( 'There are <b>%s issue(s)</b> with your files, accounting for <b>%s MB</b>. Your trash contains <b>%s MB.</b>', 'media-cleaner' ), number_format( $issues_count, 0 ), number_format( $total_size / 1000000, 2 ), number_format( $trash_total_size / 1000000, 2 ) );
 
 
 
 
 
 
248
  ?>
249
  </p>
250
 
251
- <div id='wpmc-pages'>
252
  <?php
253
  echo paginate_links(array(
254
- 'base' => '?page=media-cleaner&s=' . urlencode($s) . '&view=' . $view . '%_%',
255
  'current' => $paged,
256
  'format' => '&paged=%#%',
257
  'total' => ceil( $items_count / $posts_per_page ),
@@ -266,11 +317,13 @@
266
  <li class="all"><a <?php if ( $view == 'deleted' ) echo "class='current'"; ?> href='?page=media-cleaner&s=<?php echo $s; ?>&view=deleted'><?php _e( "Trash", 'media-cleaner' ); ?></a><span class="count">(<?php echo $deleted_count; ?>)</span></li>
267
  </ul>
268
 
269
- <table id='wpmc-table' class='wp-list-table widefat fixed media'>
270
 
271
  <thead>
272
  <tr>
273
- <th scope="col" id="cb" class="manage-column column-cb check-column"><input id="wpmc-cb-select-all" type="checkbox"></th>
 
 
274
  <?php if ( !get_option( 'wpmc_hide_thumbnails', false ) ): ?>
275
  <th style='width: 64px;'><?php _e( 'Thumb', 'media-cleaner' ) ?></th>
276
  <?php endif; ?>
@@ -290,8 +343,10 @@
290
  <tbody>
291
  <?php
292
  foreach ( $items as $issue ) {
293
- $regex = "^(.*)(\\s\\(\\+.*)$";
294
- $issue->path = preg_replace( '/' .$regex . '/i', '$1', $issue->path );
 
 
295
  ?>
296
  <tr>
297
  <td><input type="checkbox" name="id" value="<?php echo $issue->id ?>"></td>
@@ -360,6 +415,18 @@
360
  </tfoot>
361
 
362
  </table>
 
 
 
 
 
 
 
 
 
 
 
 
363
  </div>
364
 
365
  <div id="wpmc-dialog" class="hidden" style="max-width:800px"></div>
1
+ <div class='wrap wrap-media-cleaner'>
2
 
3
  <?php
4
  echo $admin->display_title( "Media Cleaner" );
5
  $posts_per_page = get_option( 'wpmc_results_per_page', 20 );
6
  $view = isset ( $_GET[ 'view' ] ) ? sanitize_text_field( $_GET[ 'view' ] ) : "issues";
7
  $paged = isset ( $_GET[ 'paged' ] ) ? sanitize_text_field( $_GET[ 'paged' ] ) : 1;
 
 
 
 
 
8
  $s = isset ( $_GET[ 's' ] ) ? sanitize_text_field( $_GET[ 's' ] ) : null;
9
+ $f = isset ( $_GET[ 'f' ] ) ? sanitize_text_field( $_GET[ 'f' ] ) : null;
10
+ $table_scan = $wpdb->prefix . "mclean_scan";
11
+ $table_refs = $wpdb->prefix . "mclean_refs";
12
+ $filterByTypeSQL = '';
13
+ if ( !empty( $f ) ) {
14
+ $availableFilters = [ 'NO_CONTENT', 'ORPHAN_FILE', 'ORPHAN_RETINA', 'ORPHAN_WEBP', 'ORPHAN_MEDIA' ];
15
+ if ( in_array( $f, $availableFilters ) )
16
+ $filterByTypeSQL = " AND issue = '$f'";
17
+ else
18
+ $f = null;
19
+ }
20
+
21
+ // Check the DB
22
+ // If does not exist, let's create it.
23
+ // TODO: When PHP 7 only, let's clean this and use anonymous functions.
24
+ $db_init = !( strtolower( $wpdb->get_var( "SHOW TABLES LIKE '$table_scan'" ) ) != strtolower( $table_scan )
25
+ || strtolower( $wpdb->get_var( "SHOW TABLES LIKE '$table_refs'" ) ) != strtolower( $table_refs ) );
26
+ if ( !$db_init ) {
27
+ wpmc_create_database();
28
+ $db_init = !( strtolower( $wpdb->get_var( "SHOW TABLES LIKE '$table_scan'" ) ) != strtolower( $table_scan )
29
+ || strtolower( $wpdb->get_var( "SHOW TABLES LIKE '$table_refs'" ) ) != strtolower( $table_refs ) );
30
+ }
31
+
32
+ // It still doesn't exist. That's not your lucky day :(
33
+ if ( !$db_init ) {
34
+ echo "<div class='notice notice-error'><p>";
35
+ _e( "<b>The database is not ready for Media Cleaner. The scan will not work.</b> Click on the <b>Reset</b> button, it re-creates the tables required by Media Cleaner. If this message still appear, contact the support.", 'media-cleaner' );
36
+ echo "</p></div>";
37
+ }
38
+
39
+ // Check the access rights to the uploads directory
40
+ $upload_folder = wp_upload_dir();
41
+ $basedir = $upload_folder['basedir'];
42
+ if ( !is_writable( $basedir ) ) {
43
+ echo "<div class='notice notice-error'><p>";
44
+ _e( 'The directory for uploads is not writable. Media Cleaner will only be able to scan.', 'media-cleaner' );
45
+ echo "</p></div>";
46
+ }
47
+
48
+ $issues_count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_scan WHERE ignored = 0 AND deleted = 0" . $filterByTypeSQL );
49
+ $total_size = $wpdb->get_var( "SELECT SUM(size) FROM $table_scan WHERE ignored = 0 AND deleted = 0" . $filterByTypeSQL );
50
+ $trash_total_size = $wpdb->get_var( "SELECT SUM(size) FROM $table_scan WHERE ignored = 0 AND deleted = 1" . $filterByTypeSQL );
51
+ $ignored_count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_scan WHERE ignored = 1" . $filterByTypeSQL );
52
+ $deleted_count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_scan WHERE deleted = 1" . $filterByTypeSQL );
53
 
54
  if ( $view == 'deleted' ) {
55
  $items_count = $deleted_count;
56
  $items = $wpdb->get_results( $wpdb->prepare( "SELECT id, type, postId, path, size, ignored, deleted, issue
57
+ FROM $table_scan WHERE ignored = 0 AND deleted = 1 AND path LIKE %s $filterByTypeSQL
58
  ORDER BY path, time
59
  DESC LIMIT %d, %d", '%' . $s . '%', ( $paged - 1 ) * $posts_per_page, $posts_per_page ), OBJECT );
60
  }
61
  else if ( $view == 'ignored' ) {
62
  $items_count = $ignored_count;
63
  $items = $wpdb->get_results( $wpdb->prepare( "SELECT id, type, postId, path, size, ignored, deleted, issue
64
+ FROM $table_scan
65
+ WHERE ignored = 1 AND deleted = 0 AND path LIKE %s $filterByTypeSQL
66
  ORDER BY path, time
67
  DESC LIMIT %d, %d", '%' . $s . '%', ( $paged - 1 ) * $posts_per_page, $posts_per_page ), OBJECT );
68
  }
69
  else {
70
  $items_count = $issues_count;
71
  $items = $wpdb->get_results( $wpdb->prepare( "SELECT id, type, postId, path, size, ignored, deleted, issue
72
+ FROM $table_scan
73
+ WHERE ignored = 0 AND deleted = 0 AND path LIKE %s $filterByTypeSQL
74
  ORDER BY path, time
75
  DESC LIMIT %d, %d", '%' . $s . '%', ( $paged - 1 ) * $posts_per_page, $posts_per_page ), OBJECT );
76
  }
77
  ?>
78
 
79
+ <div id="wpmc_actions">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  <!-- SCAN -->
82
  <?php if ( $view != 'deleted' ): ?>
103
  ?>
104
  </a>
105
 
 
 
 
 
 
106
  <!-- DELETE ALL -->
107
  <?php if ( $view == 'deleted' ): // i ?>
 
108
  <a id='wpmc_empty_trash' class='button button-red exclusive' style='float: right; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-trash"></span><?php _e("Empty trash", 'media-cleaner'); ?></a>
109
+ <a id='wpmc_recover_all' class='button-primary exclusive' style='float: right; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-repeat"></span><?php _e("Recover all", 'media-cleaner'); ?></a>
110
  <?php else: // i ?>
111
+ <?php if ( $f || $s ): // ii ?>
112
+ <a id='wpmc_delete_all' class='button button-red exclusive' data-filter='<?php echo esc_attr( $f ) ?>' data-search='<?php echo esc_attr( $s ) ?>' style='float: right; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-trash"></span><?php _e("Delete these results", 'media-cleaner'); ?></a>
113
  <?php else: // ii ?>
114
  <a id='wpmc_delete_all' class='button button-red exclusive' style='float: right; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-trash"></span><?php _e("Delete all", 'media-cleaner'); ?></a>
115
  <?php endif; // ii ?>
117
 
118
  <form id="posts-filter" action="upload.php" method="get" style='float: right;'>
119
  <p class="search-box" style='margin-left: 5px; float: left;'>
120
+ <input type="search" name="s" placeholder="<?php _e('Search', 'media-cleaner' ); ?>" style="width: 120px;" value="<?php echo $s ? esc_attr( $s ) : ""; ?>">
121
+ <select name="f" id="filter-by-type" style="margin-top: -3px; font-size: 13px;">
122
+ <option <?php echo !$f ? 'selected="selected"' : ''; ?> value="0"><?php
123
+ _e('All Issues', 'media-cleaner' ); ?></option>
124
+ <option <?php echo $f === 'NO_CONTENT' ? 'selected="selected"' : ''; ?> value="NO_CONTENT"><?php
125
+ _e( 'Seems not use', 'media-cleaner' ); ?></option>
126
+ <option <?php echo $f === 'ORPHAN_MEDIA' ? 'selected="selected"' : ''; ?>value="ORPHAN_MEDIA"><?php
127
+ _e( 'No attached file', 'media-cleaner' ); ?></option>
128
+ <option <?php echo $f === 'ORPHAN_FILE' ? 'selected="selected"' : ''; ?>value="ORPHAN_FILE"><?php
129
+ _e( 'Not in Library', 'media-cleaner' ); ?></option>
130
+ <option <?php echo $f === 'ORPHAN_RETINA' ? 'selected="selected"' : ''; ?>value="ORPHAN_RETINA"><?php
131
+ _e( 'Orphan Retina', 'media-cleaner' ); ?></option>
132
+ <option <?php echo $f === 'ORPHAN_WEBP' ? 'selected="selected"' : ''; ?>value="ORPHAN_WEBP"><?php
133
+ _e( 'Orphan WebP', 'media-cleaner' ); ?></option>
134
+ </select>
135
  <input type="hidden" name="page" value="media-cleaner">
136
  <input type="hidden" name="view" value="<?php echo $view; ?>">
137
  <input type="hidden" name="paged" value="1">
138
+ <input type="submit" class="button exclusive" value="<?php _e( 'Search', 'media-cleaner' ); ?>"><span style='border-right: #A2A2A2 solid 1px; margin-left: 5px; margin-right: 3px;'>&nbsp;</span>
139
  </p>
140
  </form>
141
 
146
 
147
  <p>
148
  <?php
149
+ $method = get_option( 'wpmc_method', 'media' );
150
+ if ( $db_init ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  if ( !$admin->is_registered() )
152
  $method = 'media';
153
 
154
  $hide_warning = get_option( 'wpmc_hide_warning', false );
 
155
  if ( !$hide_warning ) {
156
+ echo "<div class='notice notice-warning'><p>";
157
+ _e( "<b style='color: red;'>Important.</b> <b>Backup your DB and your /uploads directory before using Media Cleaner. </b> The deleted files will be temporarily moved to the <b>uploads/wpmc-trash</b> directory. After testing your website, you can check the <a href='?page=media-cleaner&s&view=deleted'>trash</a> to either empty it or recover the media and files. The Media Cleaner does its best to be safe to use. However, WordPress being a very dynamic and pluggable system, it is impossible to predict all the situations in which your files are used. <b style='color: red;'>Again, please backup!</b> If you don't know how, give a try to this: <a href='https://meow.click/blogvault' target='_blank'>BlogVault</a>. <br /><br /><b style='color: red;'>Be thoughtful.</b> Don't blame Media Cleaner if it deleted too many or not enough of your files. It makes cleaning possible and this task is only possible this way; don't post a bad review because it broke your install. <b>If you have a proper backup, there is no risk</b>. Sorry for the lengthy message, but better be safe than sorry. You can disable this big warning in the options if you have a Pro license. Make sure you read this warning twice. Media Cleaner is awesome and always getting better so I hope you will enjoy it. Thank you :)", 'media-cleaner' );
158
+ echo "</p></div>";
159
  }
160
 
161
  if ( !MEDIA_TRASH ) {
162
+ echo "<div class='notice notice-warning'>";
163
+ _e( "<p>The trash for the Media Library is disabled. Any media removed by the plugin will be <b>permanently deleted</b>. To enable it, modify your wp-config.php file and add this line (preferably at the top): <b>define( 'MEDIA_TRASH', true );</b>", 'media-cleaner' );
164
+ echo "</p></div>";
165
  }
166
  }
167
 
204
 
205
  if ( class_exists( 'X_Bootstrap' ) )
206
  array_push( $unsupported, 'Theme X' );
207
+
208
  if ( class_exists( 'SiteOrigin_Panels' ) )
209
  array_push( $unsupported, 'SiteOrigin PageBuilder' );
210
 
223
  if ( defined( 'AV_FRAMEWORK_VERSION' ) )
224
  array_push( $unsupported, 'Avia Framework' );
225
 
226
+ if ( class_exists( 'FAT_Portfolio' ) )
227
+ array_push( $unsupported, 'FAT Portfolio' );
228
+
229
+ if ( class_exists( 'YIKES_Custom_Product_Tabs' ) )
230
+ array_push( $unsupported, 'Yikes Custom Product Tabs' );
231
+
232
  if ( !empty( $unsupported ) ) {
233
  echo "<div class='notice notice-error'><p>";
234
  _e( "<b>Important note about the following plugin(s): </b>", 'media-cleaner' );
236
  _e( "They require additional checks which are implemented in the <a target='_blank' href='//meowapps.com/plugin/media-cleaner'>Media Cleaner Pro</a>.", 'media-cleaner' );
237
  echo "</p></div>";
238
  }
 
239
  }
240
 
241
+ $check_content = get_option( 'wpmc_content', true );
 
242
  $check_library = get_option(' wpmc_media_library', true );
243
+ $live_content = get_option(' wpmc_live_content', true );
244
+
245
+ $access_settings = ' ' . sprintf(
246
+ // translators: %s is URL leading to the plugin settings page
247
+ __( '<a href="%s">Click here</a> to modify the settings.', 'media-cleaner' ),
248
+ 'admin.php?page=wpmc_settings-menu' );
249
 
250
+ if ( $method == 'media' && ( $check_content || $live_content ) ) {
251
+ echo "<div class='notice notice-success'><p>";
252
+ _e( "Media Cleaner will analyze the Media Library for entries which aren't used in the content.", 'media-cleaner' );
253
+ echo $access_settings;
254
+ echo "</p></div>";
255
+ }
256
+ else if ( $method == 'media' ) {
257
+ echo "<div class='notice notice-error'><p>";
258
+ _e( "Media Cleaner will analyze the Media Library. Since <i>Content</i> has not be checked, a special scan will be ran: <u>only broken media entries</u> will be detected.", 'media-cleaner' );
259
+ echo $access_settings;
260
+ echo "</p></div>";
261
+ }
262
+ else if ( $method == 'files' && ( $check_content || $live_content ) && $check_library ) {
263
+ echo "<div class='notice notice-success'><p>";
264
+ _e( "Media Cleaner will analyze the filesystem for files which aren't registered in the Media Library and aren't used in the content.", 'media-cleaner' );
265
+ echo $access_settings;
266
+ echo "</p></div>";
267
+ }
268
+ else if ( $method == 'files' && $check_library ) {
269
+ echo "<div class='notice notice-success'><p>";
270
+ _e( "Media Cleaner will analyze the filesystem for files which aren't registered in the Media Library.", 'media-cleaner' );
271
+ echo $access_settings;
272
+ echo "</p></div>";
273
+ }
274
+ else if ( $method == 'files' && ( $check_content || $live_content ) ) {
275
+ echo "<div class='notice notice-success'><p>";
276
+ _e( "Media Cleaner will analyze the filesystem for files which aren't used in the content.", 'media-cleaner' );
277
+ echo $access_settings;
278
+ echo "</p></div>";
279
  }
280
  else if ( $method == 'files' ) {
281
+ echo "<div class='notice notice-error'><p>";
282
+ _e( "Media Cleaner will analyze the filesystem. <b>Neither <i>Content</i> or <i>Media Library</i> has been checked.</b> <u>Therefore, all the files will be listed as issues</u>.", 'media-cleaner' );
283
+ echo $access_settings;
284
+ echo "</p></div>";
285
+ }
286
+ else {
287
+ echo "<div class='notice notice-error'><p>";
288
+ _e( "This type of scan hasn't been set.", 'media-cleaner' );
289
+ echo "</p></div>";
290
  }
291
 
292
+ echo sprintf(
293
+ // translators: %1$s is a number of found issues, %2$s is a size of detected files, %3$s is a total size of files in trash
294
+ __( 'There are <b>%1$s issue(s)</b> with your files, accounting for <b>%2$s MB</b>. Your trash contains <b>%3$s MB.</b>', 'media-cleaner' ),
295
+ number_format( $issues_count, 0 ),
296
+ number_format( $total_size / 1000000, 2 ),
297
+ number_format( $trash_total_size / 1000000, 2 )
298
+ );
299
  ?>
300
  </p>
301
 
302
+ <div id='wpmc-paging'>
303
  <?php
304
  echo paginate_links(array(
305
+ 'base' => '?page=media-cleaner&s=' . urlencode($s) . '&f=' . urlencode($f) . '&view=' . $view . '%_%',
306
  'current' => $paged,
307
  'format' => '&paged=%#%',
308
  'total' => ceil( $items_count / $posts_per_page ),
317
  <li class="all"><a <?php if ( $view == 'deleted' ) echo "class='current'"; ?> href='?page=media-cleaner&s=<?php echo $s; ?>&view=deleted'><?php _e( "Trash", 'media-cleaner' ); ?></a><span class="count">(<?php echo $deleted_count; ?>)</span></li>
318
  </ul>
319
 
320
+ <table id='wpmc-table' class='wp-list-table widefat fixed striped media'>
321
 
322
  <thead>
323
  <tr>
324
+ <th scope="col" id="cb" class="manage-column column-cb check-column" style="padding: 8px 2px;">
325
+ <input id="wpmc-cb-select-all" type="checkbox">
326
+ </th>
327
  <?php if ( !get_option( 'wpmc_hide_thumbnails', false ) ): ?>
328
  <th style='width: 64px;'><?php _e( 'Thumb', 'media-cleaner' ) ?></th>
329
  <?php endif; ?>
343
  <tbody>
344
  <?php
345
  foreach ( $items as $issue ) {
346
+ if ( $view == 'deleted' ) {
347
+ $regex = "^(.*)(\\s\\(\\+.*)$";
348
+ $issue->path = preg_replace( '/' .$regex . '/i', '$1', $issue->path );
349
+ }
350
  ?>
351
  <tr>
352
  <td><input type="checkbox" name="id" value="<?php echo $issue->id ?>"></td>
415
  </tfoot>
416
 
417
  </table>
418
+
419
+ <div id='wpmc-paging'>
420
+ <?php
421
+ echo paginate_links(array(
422
+ 'base' => '?page=media-cleaner&s=' . urlencode($s) . '&view=' . $view . '%_%',
423
+ 'current' => $paged,
424
+ 'format' => '&paged=%#%',
425
+ 'total' => ceil( $items_count / $posts_per_page ),
426
+ 'prev_next' => false
427
+ ));
428
+ ?>
429
+ </div>
430
  </div>
431
 
432
  <div id="wpmc-dialog" class="hidden" style="max-width:800px"></div>