Media Cleaner - Version 3.8.0

Version Description

  • Update: Core was re-organized and cleaned. Ready for nice updates.
Download this release

Release Info

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

Code changes from version 3.7.0 to 3.8.0

common/admin.php CHANGED
@@ -5,11 +5,15 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
5
  class MeowApps_Admin {
6
 
7
  public static $loaded = false;
8
- public static $version = "1.0";
9
 
10
- public $prefix;
 
 
11
 
12
- public function __construct( $prefix = null ) {
 
 
13
  if ( !MeowApps_Admin::$loaded ) {
14
  if ( is_admin() ) {
15
  add_action( 'admin_menu', array( $this, 'admin_menu_start' ) );
@@ -18,7 +22,38 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
18
  }
19
  MeowApps_Admin::$loaded = true;
20
  }
 
 
21
  $this->prefix = $prefix;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  }
23
 
24
  function display_ads() {
@@ -110,19 +145,32 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
110
  }
111
 
112
  function check_install( $plugin ) {
113
- $pluginpath = get_home_path() . 'wp-content/plugins/' . $plugin;
 
114
  if ( !file_exists( $pluginpath ) ) {
115
- $url = wp_nonce_url( "update.php?action=install-plugin&plugin=$plugin", "install-plugin_$plugin" );
116
- return "<a href='$url'><small><span class='' style='float: right;'>install</span></small></a>";
 
 
 
 
 
 
 
117
  }
 
118
  $plugin_file = $plugin . '/' . $plugin . '.php';
119
- if ( is_plugin_active( $plugin_file ) )
120
- return "<small><span style='float: right; color: green;'><span class='dashicons dashicons-yes'></span></span></small>";
 
 
 
 
121
  else {
122
  $url = wp_nonce_url( self_admin_url( 'plugins.php?action=activate&plugin=' . $plugin_file ),
123
  'activate-plugin_' . $plugin_file );
124
- return '<small><span style="color: orange; float: right;">off
125
- (<a style="color: rgba(30,140,190,.8); text-decoration: none;" href="' .
126
  $url . '">enable</a>)</span></small>';
127
  }
128
  }
@@ -181,7 +229,7 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
181
  ?>
182
  <?php $this->display_title(); ?>
183
  <p>
184
- <?php _e( 'Meow Apps is run by <a href="http://jordymeow.com">Jordy Meow</a>, a photographer and software developer based in Japan. When he realized that WordPress was an environment not so friendly to photographers, Meow Apps was born. It is a suite of plugins dedicate to make the blogging life of image lovers easy and pretty. Meow Apps also teams up with the best players in the community (other themes or plugins developers). For more information, please check <a href="http://meowapps.com" target="_blank">Meow Apps</a>.', 'meowapps' )
185
  ?>
186
  </p>
187
  <div class="meow-row">
@@ -204,9 +252,9 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
204
  <li><b>Media File Renamer</b> <?php echo $this->check_install( 'media-file-renamer' ) ?><br />
205
  Nicer filenames and better SEO, automatically.</li>
206
  <li><b>Media Cleaner</b> <?php echo $this->check_install( 'media-cleaner' ) ?><br />
207
- Detect the files you are not using to clean your system.</li>
208
  <li><b>WP Retina 2x</b> <?php echo $this->check_install( 'wp-retina-2x' ) ?><br />
209
- Make your website perfect for retina devices.</li>
210
  <li><b>WP Category Permalink</b> <?php echo $this->check_install( 'wp-category-permalink' ) ?><br />
211
  Allows you to select a main category (or taxonomy) for nicer permalinks.</li>
212
  </ul>
@@ -240,7 +288,7 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
240
 
241
  }
242
 
243
- echo "<br /><small style='color: lightgray;'>Meow Admin " . MeowApps_Admin::$version . "</small></div>";
244
  }
245
 
246
  // HELPERS
5
  class MeowApps_Admin {
6
 
7
  public static $loaded = false;
8
+ public static $admin_version = "1.2";
9
 
10
+ public $prefix; // prefix used for actions, filters (mfrh)
11
+ public $mainfile; // plugin main file (media-file-renamer.php)
12
+ public $domain; // domain used for translation (media-file-renamer)
13
 
14
+ public function __construct( $prefix, $mainfile, $domain ) {
15
+
16
+ // Core Admin (used by all Meow Apps plugins)
17
  if ( !MeowApps_Admin::$loaded ) {
18
  if ( is_admin() ) {
19
  add_action( 'admin_menu', array( $this, 'admin_menu_start' ) );
22
  }
23
  MeowApps_Admin::$loaded = true;
24
  }
25
+
26
+ // Variables for this plugin
27
  $this->prefix = $prefix;
28
+ $this->mainfile = $mainfile;
29
+ $this->domain = $domain;
30
+
31
+ // Check if the free version is installed but there is license
32
+ // TODO: In the future, this should be removed ideally
33
+ if ( is_admin() ) {
34
+ $license = get_option( $this->prefix . '_license', "" );
35
+ if ( ( !empty( $license ) ) && !file_exists( plugin_dir_path( __FILE__ ) . '/meowapps/admin.php' ) ) {
36
+ add_action( 'admin_notices', array( $this, 'admin_notices_licensed_free' ) );
37
+ }
38
+ }
39
+ }
40
+
41
+ function admin_notices_licensed_free() {
42
+ if ( isset( $_POST[$this->prefix . '_reset_sub'] ) ) {
43
+ delete_option( $this->prefix . '_pro_serial' );
44
+ delete_option( $this->prefix . '_license' );
45
+ return;
46
+ }
47
+ echo '<div class="error">';
48
+ echo '<p>It looks like you are using the free version of the plugin (<b>' . $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.';
49
+ echo '<p>
50
+ <form method="post" action="">
51
+ <input type="hidden" name="' . $this->prefix . '_reset_sub" value="true">
52
+ <input type="submit" name="submit" id="submit" class="button" value="Remove the license">
53
+ </form>
54
+ </p>
55
+ ';
56
+ echo '</div>';
57
  }
58
 
59
  function display_ads() {
145
  }
146
 
147
  function check_install( $plugin ) {
148
+ $pro = false;
149
+ $pluginpath = get_home_path() . 'wp-content/plugins/' . $plugin . '-pro';
150
  if ( !file_exists( $pluginpath ) ) {
151
+ $pluginpath = get_home_path() . 'wp-content/plugins/' . $plugin;
152
+ if ( !file_exists( $pluginpath ) ) {
153
+ $url = wp_nonce_url( "update.php?action=install-plugin&plugin=$plugin", "install-plugin_$plugin" );
154
+ return "<a href='$url'><small><span class='' style='float: right;'>install</span></small></a>";
155
+ }
156
+ }
157
+ else {
158
+ $pro = true;
159
+ $plugin = $plugin . "-pro";
160
  }
161
+
162
  $plugin_file = $plugin . '/' . $plugin . '.php';
163
+ if ( is_plugin_active( $plugin_file ) ) {
164
+ if ( $pro )
165
+ return "<small><span style='float: right;'><span class='dashicons dashicons-heart' style='color: rgba(255, 63, 0, 1); font-size: 30px !important; margin-right: 10px;'></span></span></small>";
166
+ else
167
+ return "<small><span style='float: right;'><span class='dashicons dashicons-yes' style='color: #00b4ff; font-size: 30px !important; margin-right: 10px;'></span></span></small>";
168
+ }
169
  else {
170
  $url = wp_nonce_url( self_admin_url( 'plugins.php?action=activate&plugin=' . $plugin_file ),
171
  'activate-plugin_' . $plugin_file );
172
+ return '<small><span style="color: black; float: right;">off
173
+ (<a style="color: rgba(30,140,190,1); text-decoration: none;" href="' .
174
  $url . '">enable</a>)</span></small>';
175
  }
176
  }
229
  ?>
230
  <?php $this->display_title(); ?>
231
  <p>
232
+ <?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>.', 'meowapps' )
233
  ?>
234
  </p>
235
  <div class="meow-row">
252
  <li><b>Media File Renamer</b> <?php echo $this->check_install( 'media-file-renamer' ) ?><br />
253
  Nicer filenames and better SEO, automatically.</li>
254
  <li><b>Media Cleaner</b> <?php echo $this->check_install( 'media-cleaner' ) ?><br />
255
+ Detect the files which are not in use.</li>
256
  <li><b>WP Retina 2x</b> <?php echo $this->check_install( 'wp-retina-2x' ) ?><br />
257
+ The famous plugin that adds Retina support.</li>
258
  <li><b>WP Category Permalink</b> <?php echo $this->check_install( 'wp-category-permalink' ) ?><br />
259
  Allows you to select a main category (or taxonomy) for nicer permalinks.</li>
260
  </ul>
288
 
289
  }
290
 
291
+ echo "<br /><small style='color: lightgray;'>Meow Admin " . MeowApps_Admin::$admin_version . "</small></div>";
292
  }
293
 
294
  // HELPERS
core.php ADDED
@@ -0,0 +1,1034 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Meow_WPMC_Core {
4
+
5
+ public $checkers = null;
6
+ public $admin = null;
7
+ public $debug = false;
8
+
9
+ public function __construct( $admin ) {
10
+ $this->admin = $admin;
11
+ add_action( 'admin_notices', array( $this, 'admin_notices' ) );
12
+ add_action( 'admin_menu', array( $this, 'admin_menu' ) );
13
+ add_action( 'admin_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) );
14
+ add_action( 'admin_print_scripts', array( $this, 'admin_inline_js' ) );
15
+ add_action( 'wp_ajax_wpmc_scan', array( $this, 'wp_ajax_wpmc_scan' ) );
16
+ add_action( 'wp_ajax_wpmc_get_all_issues', array( $this, 'wp_ajax_wpmc_get_all_issues' ) );
17
+ add_action( 'wp_ajax_wpmc_get_all_deleted', array( $this, 'wp_ajax_wpmc_get_all_deleted' ) );
18
+ add_action( 'wp_ajax_wpmc_scan_do', array( $this, 'wp_ajax_wpmc_scan_do' ) );
19
+ add_action( 'wp_ajax_wpmc_delete_do', array( $this, 'wp_ajax_wpmc_delete_do' ) );
20
+ add_action( 'wp_ajax_wpmc_ignore_do', array( $this, 'wp_ajax_wpmc_ignore_do' ) );
21
+ add_action( 'wp_ajax_wpmc_recover_do', array( $this, 'wp_ajax_wpmc_recover_do' ) );
22
+ add_filter( 'media_row_actions', array( $this, 'media_row_actions' ), 10, 2 );
23
+
24
+ // Checkers
25
+ require( 'wpmc_checkers.php' );
26
+ $this->checkers = new Meow_WPMC_Checkers( $this );
27
+ }
28
+
29
+ /*******************************************************************************
30
+ * ASYNCHRONOUS AJAX FUNCTIONS
31
+ ******************************************************************************/
32
+
33
+ function wp_ajax_wpmc_delete_do () {
34
+ ob_start();
35
+ $data = $_POST['data'];
36
+ $success = 0;
37
+ foreach ( $data as $piece ) {
38
+ $success += ( $this->wpmc_delete( $piece ) ? 1 : 0 );
39
+ }
40
+ ob_end_clean();
41
+ echo json_encode(
42
+ array(
43
+ 'success' => true,
44
+ 'result' => array( 'data' => $data, 'success' => $success ),
45
+ 'message' => __( "Status unknown.", 'media-cleaner' )
46
+ )
47
+ );
48
+ die();
49
+ }
50
+
51
+ function wp_ajax_wpmc_ignore_do () {
52
+ ob_start();
53
+ $data = $_POST['data'];
54
+ $success = 0;
55
+ foreach ( $data as $piece ) {
56
+ $success += ( $this->wpmc_ignore( $piece ) ? 1 : 0 );
57
+ }
58
+ ob_end_clean();
59
+ echo json_encode(
60
+ array(
61
+ 'success' => true,
62
+ 'result' => array( 'data' => $data, 'success' => $success ),
63
+ 'message' => __( "Status unknown.", 'media-cleaner' )
64
+ )
65
+ );
66
+ die();
67
+ }
68
+
69
+ function wp_ajax_wpmc_recover_do () {
70
+ ob_start();
71
+ $data = $_POST['data'];
72
+ $success = 0;
73
+ foreach ( $data as $piece ) {
74
+ $success += ( $this->wpmc_recover( $piece ) ? 1 : 0 );
75
+ }
76
+ ob_end_clean();
77
+ echo json_encode(
78
+ array(
79
+ 'success' => true,
80
+ 'result' => array( 'data' => $data, 'success' => $success ),
81
+ 'message' => __( "Status unknown.", 'media-cleaner' )
82
+ )
83
+ );
84
+ die();
85
+ }
86
+
87
+ function wp_ajax_wpmc_scan_do () {
88
+ ob_start();
89
+ $type = $_POST['type'];
90
+ $data = $_POST['data'];
91
+ $success = 0;
92
+ foreach ( $data as $piece ) {
93
+ if ( $type == 'file' ) {
94
+ if ( $this->debug )
95
+ error_log( "Check File: {$piece}" );
96
+ $success += ( apply_filters( 'wpmc_check_file', true, $piece ) ? 1 : 0 );
97
+ if ( $this->debug )
98
+ error_log( "Success " . $success . "\n" );
99
+ } elseif ( $type == 'media' ) {
100
+ if ( $this->debug )
101
+ error_log( "Check Media: {$piece}" );
102
+ $success += ( $this->wpmc_check_media( $piece ) ? 1 : 0 );
103
+ if ( $this->debug )
104
+ error_log( "Success " . $success . "\n" );
105
+ }
106
+ }
107
+ ob_end_clean();
108
+ echo json_encode(
109
+ array(
110
+ 'success' => true,
111
+ 'result' => array( 'type' => $type, 'data' => $data, 'success' => $success ),
112
+ 'message' => __( "Items checked.", 'media-cleaner' )
113
+ )
114
+ );
115
+ die();
116
+ }
117
+
118
+ function wp_ajax_wpmc_get_all_deleted () {
119
+ global $wpdb;
120
+ $table_name = $wpdb->prefix . "wpmcleaner";
121
+ $ids = $wpdb->get_col( "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = 1" );
122
+ echo json_encode(
123
+ array(
124
+ 'results' => array( 'ids' => $ids ),
125
+ 'success' => true,
126
+ 'message' => __( "List generated.", 'media-cleaner' )
127
+ )
128
+ );
129
+ die;
130
+ }
131
+
132
+ function wp_ajax_wpmc_get_all_issues () {
133
+ global $wpdb;
134
+ $isTrash = ( isset( $_POST['isTrash'] ) && $_POST['isTrash'] == 1 ) ? true : false;
135
+ $table_name = $wpdb->prefix . "wpmcleaner";
136
+ if ( $isTrash )
137
+ $ids = $wpdb->get_col( "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = 1" );
138
+ else
139
+ $ids = $wpdb->get_col( "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = 0" );
140
+ echo json_encode(
141
+ array(
142
+ 'results' => array( 'ids' => $ids ),
143
+ 'success' => true,
144
+ 'message' => __( "List generated.", 'media-cleaner' )
145
+ )
146
+ );
147
+ die;
148
+ }
149
+
150
+ function wpmc_get_galleries_images( $force = false ) {
151
+ if ( $force ) {
152
+ delete_transient( "wpmc_galleries_images" );
153
+ $galleries_images = null;
154
+ }
155
+ else {
156
+ $galleries_images = get_transient("wpmc_galleries_images");
157
+ }
158
+ if ( !$galleries_images ) {
159
+ global $wpdb;
160
+ $galleries_images = array();
161
+ $posts = $wpdb->get_col( "SELECT id FROM $wpdb->posts WHERE post_type != 'attachment' AND post_status != 'inherit'" );
162
+ foreach( $posts as $post ) {
163
+ $galleries = get_post_galleries_images( $post );
164
+ foreach( $galleries as $gallery ) {
165
+ foreach( $gallery as $image ) {
166
+ array_push( $galleries_images, $image );
167
+ }
168
+ }
169
+ }
170
+
171
+ $post_galleries = get_posts( array(
172
+ 'tax_query' => array(
173
+ array(
174
+ 'taxonomy' => 'post_format',
175
+ 'field' => 'slug',
176
+ 'terms' => array( 'post-format-gallery' ),
177
+ 'operator' => 'IN'
178
+ )
179
+ )
180
+ ) );
181
+
182
+ foreach( (array) $post_galleries as $gallery_post ) {
183
+ $arrImages = get_children( 'post_type=attachment&post_mime_type=image&post_parent=' . $gallery_post->ID );
184
+ if ( $arrImages ) {
185
+ foreach( (array) $arrImages as $image_post ) {
186
+ array_push( $galleries_images, $image_post->guid );
187
+ }
188
+ }
189
+ }
190
+ wp_reset_postdata();
191
+
192
+ set_transient( "wpmc_galleries_images", $galleries_images, 60 * 60 * 2 );
193
+ }
194
+ return $galleries_images;
195
+ }
196
+
197
+ function wp_ajax_wpmc_scan() {
198
+ global $wpdb;
199
+
200
+ $method = get_option( 'wpmc_method', 'media' );
201
+ if ( !$this->admin->is_registered() )
202
+ $method = 'media';
203
+ $path = isset( $_POST['path'] ) ? $_POST['path'] : null;
204
+ $limit = isset( $_POST['limit'] ) ? $_POST['limit'] : 0;
205
+ $limitsize = 100;
206
+
207
+ if ( ( $method == 'media' && empty( $limit ) ) || ( $method == 'files' && empty( $path ) ) ) {
208
+ // Reset and prepare all the Attachment IDs of all the galleries
209
+ $this->wpmc_reset_issues();
210
+ delete_transient( 'wpmc_posts_with_shortcode' );
211
+ $this->wpmc_get_galleries_images( true );
212
+ }
213
+
214
+ if ( $method == 'files' ) {
215
+ $output = apply_filters( 'wpmc_list_uploaded_files', array(
216
+ 'results' => array(), 'success' => false, 'message' => __( "Unavailable.", 'media-cleaner' )
217
+ ), $path );
218
+ echo json_encode( $output );
219
+ die();
220
+ }
221
+
222
+ if ( $method == 'media' ) {
223
+ // Prevent double scanning by removing filesystem entries that we have DB entries for
224
+ $results = $wpdb->get_col( $wpdb->prepare( "SELECT p.ID FROM $wpdb->posts p
225
+ WHERE p.post_status = 'inherit'
226
+ AND p.post_type = 'attachment'
227
+ LIMIT %d, %d", $limit, $limitsize
228
+ )
229
+ );
230
+ $finished = count( $results ) < $limitsize;
231
+ echo json_encode(
232
+ array(
233
+ 'results' => $results,
234
+ 'success' => true,
235
+ 'finished' => $finished,
236
+ 'limit' => $limit + $limitsize,
237
+ 'message' => __( "Medias retrieved.", 'media-cleaner' ) )
238
+ );
239
+ die();
240
+ }
241
+
242
+ // No task.
243
+ echo json_encode( array( 'success' => false, 'message' => __( "No task.", 'media-cleaner' ) ) );
244
+ die();
245
+ }
246
+
247
+ /**
248
+ *
249
+ * HELPERS
250
+ *
251
+ */
252
+
253
+ function wpmc_trashdir() {
254
+ $upload_folder = wp_upload_dir();
255
+ return trailingslashit( $upload_folder['basedir'] ) . 'wpmc-trash';
256
+ }
257
+
258
+ /**
259
+ *
260
+ * DELETE / SCANNING / RESET
261
+ *
262
+ */
263
+
264
+ function wpmc_recover_file( $path ) {
265
+ $basedir = wp_upload_dir();
266
+ $originalPath = trailingslashit( $basedir['basedir'] ) . $path;
267
+ $trashPath = trailingslashit( $this->wpmc_trashdir() ) . $path;
268
+ $path_parts = pathinfo( $originalPath );
269
+ if ( !file_exists( $path_parts['dirname'] ) && !wp_mkdir_p( $path_parts['dirname'] ) ) {
270
+ die( 'Failed to create folder.' );
271
+ }
272
+ if ( !file_exists( $trashPath ) ) {
273
+ if ( $this->debug )
274
+ error_log( "The file $originalPath actually does not exist in the trash." );
275
+ return true;
276
+ }
277
+ if ( !rename( $trashPath, $originalPath ) ) {
278
+ die( 'Failed to move the file.' );
279
+ }
280
+ return true;
281
+ }
282
+
283
+ function wpmc_recover( $id ) {
284
+ global $wpdb;
285
+ $table_name = $wpdb->prefix . "wpmcleaner";
286
+ $issue = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $id ), OBJECT );
287
+ $issue->path = stripslashes( $issue->path );
288
+
289
+ // Files
290
+ if ( $issue->type == 0 ) {
291
+ $this->wpmc_recover_file( $issue->path );
292
+ $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 0 WHERE id = %d", $id ) );
293
+ return true;
294
+ }
295
+ // Media
296
+ else if ( $issue->type == 1 ) {
297
+
298
+ // Copy the main file back
299
+ $fullpath = get_attached_file( $issue->postId );
300
+ $mainfile = $this->wpmc_clean_uploaded_filename( $fullpath );
301
+ $baseUp = pathinfo( $mainfile );
302
+ $baseUp = $baseUp['dirname'];
303
+ $file = $this->wpmc_clean_uploaded_filename( $fullpath );
304
+ if ( !$this->wpmc_recover_file( $file ) )
305
+ error_log( "Could not recover $file." );
306
+
307
+ // If images, copy the other files as well
308
+ $meta = wp_get_attachment_metadata( $issue->postId );
309
+ $isImage = isset( $meta, $meta['width'], $meta['height'] );
310
+ $sizes = $this->wpmc_get_image_sizes();
311
+ if ( $isImage && isset( $meta['sizes'] ) ) {
312
+ foreach ( $meta['sizes'] as $name => $attr ) {
313
+ if ( isset( $attr['file'] ) ) {
314
+ $filepath = wp_upload_dir();
315
+ $filepath = $filepath['basedir'];
316
+ $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
317
+ $file = $this->wpmc_clean_uploaded_filename( $filepath );
318
+ if ( !$this->wpmc_recover_file( $file ) )
319
+ error_log( "Could not recover $file." );
320
+ }
321
+ }
322
+ }
323
+ if ( !wp_untrash_post( $issue->postId ) )
324
+ die( "Failed to untrash Media {$issue->postId}." );
325
+ $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 0 WHERE id = %d", $id ) );
326
+ return true;
327
+ }
328
+ }
329
+
330
+ function wpmc_trash_file( $fileIssuePath ) {
331
+ global $wpdb;
332
+ $basedir = wp_upload_dir();
333
+ $originalPath = trailingslashit( $basedir['basedir'] ) . $fileIssuePath;
334
+ $trashPath = trailingslashit( $this->wpmc_trashdir() ) . $fileIssuePath;
335
+ $path_parts = pathinfo( $trashPath );
336
+
337
+ try {
338
+ if ( !file_exists( $path_parts['dirname'] ) && !wp_mkdir_p( $path_parts['dirname'] ) ) {
339
+ return false;
340
+ }
341
+ // Rename the file (move). 'is_dir' is just there for security (no way we should move a whole directory)
342
+ if ( is_dir( $originalPath ) ) {
343
+ error_log( "Attempted to delete a directory instead of a file ($originalPath). Can't do that." );
344
+ return false;
345
+ }
346
+ if ( !file_exists( $originalPath ) ) {
347
+ if ( $this->debug )
348
+ error_log( "The file $originalPath actually does not exist." );
349
+ return true;
350
+ }
351
+ if ( !rename( $originalPath, $trashPath ) ) {
352
+ return false;
353
+ }
354
+ }
355
+ catch ( Exception $e ) {
356
+ return false;
357
+ }
358
+ $this->wpmc_clean_dir( dirname( $originalPath ) );
359
+ return true;
360
+ }
361
+
362
+ function wpmc_ignore( $id ) {
363
+ global $wpdb;
364
+ $table_name = $wpdb->prefix . "wpmcleaner";
365
+ $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET ignored = 1 WHERE id = %d", $id ) );
366
+ return true;
367
+ }
368
+
369
+ function wpmc_endsWith( $haystack, $needle )
370
+ {
371
+ $length = strlen( $needle );
372
+ if ( $length == 0 )
373
+ return true;
374
+ return ( substr( $haystack, -$length ) === $needle );
375
+ }
376
+
377
+ function wpmc_clean_dir( $dir ) {
378
+ if ( !file_exists( $dir ) )
379
+ return;
380
+ else if ( $this->wpmc_endsWith( $dir, 'uploads' ) )
381
+ return;
382
+ $found = array_diff( scandir( $dir ), array( '.', '..' ) );
383
+ if ( count( $found ) < 1 ) {
384
+ if ( rmdir( $dir ) ) {
385
+ $this->wpmc_clean_dir( dirname( $dir ) );
386
+ }
387
+ }
388
+ }
389
+
390
+ function wpmc_delete( $id ) {
391
+ global $wpdb;
392
+ $table_name = $wpdb->prefix . "wpmcleaner";
393
+ $issue = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $id ), OBJECT );
394
+ $regex = "^(.*)(\\s\\(\\+.*)$";
395
+ $issue->path = preg_replace('/'.$regex.'/i', '$1', $issue->path); // remove " (+ 6 files)" from path
396
+
397
+ // Make sure there isn't a media DB entry
398
+ if ( $issue->type == 0 ) {
399
+ $attachmentid = $this->wpmc_find_attachment_id_by_file( $issue->path );
400
+ if ( $attachmentid ) {
401
+ error_log( "File Cleaner: Issue listed as filesystem but Media {$attachmentid} exists." );
402
+ }
403
+ }
404
+
405
+ if ( $issue->type == 0 ) {
406
+
407
+ if ( $issue->deleted == 0 ) {
408
+ // Move file to the trash
409
+ if ( $this->wpmc_trash_file( $issue->path ) )
410
+ $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 1 WHERE id = %d", $id ) );
411
+ return true;
412
+ }
413
+ else {
414
+ // Delete file from the trash
415
+ $trashPath = trailingslashit( $this->wpmc_trashdir() ) . $issue->path;
416
+ if ( !unlink( $trashPath ) )
417
+ error_log( 'Failed to delete the file.' );
418
+ $wpdb->query( $wpdb->prepare( "DELETE FROM $table_name WHERE id = %d", $id ) );
419
+ $this->wpmc_clean_dir( dirname( $trashPath ) );
420
+ return true;
421
+ }
422
+ }
423
+
424
+ if ( $issue->type == 1 ) {
425
+ if ( $issue->deleted == 0 && MEDIA_TRASH ) {
426
+ // Move Media to trash
427
+ // Let's copy the images to the trash so that it can be recovered.
428
+ $fullpath = get_attached_file( $issue->postId );
429
+ $mainfile = $this->wpmc_clean_uploaded_filename( $fullpath );
430
+ $baseUp = pathinfo( $mainfile );
431
+ $baseUp = $baseUp['dirname'];
432
+ $file = $this->wpmc_clean_uploaded_filename( $fullpath );
433
+ if ( !$this->wpmc_trash_file( $file ) )
434
+ error_log( "Could not trash $file." );
435
+
436
+ // If images, check the other files as well
437
+ $meta = wp_get_attachment_metadata( $issue->postId );
438
+ $isImage = isset( $meta, $meta['width'], $meta['height'] );
439
+ $sizes = $this->wpmc_get_image_sizes();
440
+ if ( $isImage && isset( $meta['sizes'] ) ) {
441
+ foreach ( $meta['sizes'] as $name => $attr ) {
442
+ if ( isset( $attr['file'] ) ) {
443
+ $filepath = wp_upload_dir();
444
+ $filepath = $filepath['basedir'];
445
+ $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
446
+ $file = $this->wpmc_clean_uploaded_filename( $filepath );
447
+ if ( !$this->wpmc_trash_file( $file ) )
448
+ error_log( "Could not trash $file." );
449
+ }
450
+ }
451
+ }
452
+ wp_delete_attachment( $issue->postId, false );
453
+ $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 1 WHERE id = %d", $id ) );
454
+ return true;
455
+ }
456
+ else {
457
+ // Trash Media definitely by recovering it (to be like a normal Media) and remove it through the
458
+ // standard WordPress workflow
459
+ if ( MEDIA_TRASH )
460
+ $this->wpmc_recover( $id );
461
+ wp_delete_attachment( $issue->postId, true );
462
+ $wpdb->query( $wpdb->prepare( "DELETE FROM $table_name WHERE id = %d", $id ) );
463
+ return true;
464
+ }
465
+ }
466
+ return false;
467
+ }
468
+
469
+ /**
470
+ *
471
+ * SCANNING / RESET
472
+ *
473
+ */
474
+
475
+ function wpmc_check_is_ignore( $file ) {
476
+ global $wpdb;
477
+ $table_name = $wpdb->prefix . "wpmcleaner";
478
+ $count = $wpdb->get_var( "SELECT COUNT(*)
479
+ FROM $table_name
480
+ WHERE deleted = 0
481
+ AND path LIKE '%". esc_sql( $wpdb->esc_like( $file ) ) . "%'" );
482
+ if ( $this->debug && $count > 0 )
483
+ error_log("{$file} found in IGNORE");
484
+ return ($count > 0);
485
+ }
486
+
487
+ function wpmc_find_attachment_id_by_file ($file) {
488
+ global $wpdb;
489
+ $postmeta_table_name = $wpdb->prefix . 'postmeta';
490
+ $file = $this->wpmc_clean_uploaded_filename( $file );
491
+ $sql = $wpdb->prepare( "SELECT post_id
492
+ FROM {$postmeta_table_name}
493
+ WHERE meta_key = '_wp_attached_file'
494
+ AND meta_value = %s", $file
495
+ );
496
+ $ret = $wpdb->get_var( $sql );
497
+ if ( $this->debug && empty( $ret ) )
498
+ error_log( "File $file not found as _wp_attached_file (Library)." );
499
+ else if ( $this->debug ) {
500
+ error_log( "File $file found as Media $ret." );
501
+ }
502
+ return $ret;
503
+ }
504
+
505
+ function wpmc_get_image_sizes() {
506
+ $sizes = array();
507
+ global $_wp_additional_image_sizes;
508
+ foreach ( get_intermediate_image_sizes() as $s ) {
509
+ $crop = false;
510
+ if ( isset( $_wp_additional_image_sizes[$s] ) ) {
511
+ $width = intval( $_wp_additional_image_sizes[$s]['width'] );
512
+ $height = intval( $_wp_additional_image_sizes[$s]['height'] );
513
+ $crop = $_wp_additional_image_sizes[$s]['crop'];
514
+ } else {
515
+ $width = get_option( $s.'_size_w' );
516
+ $height = get_option( $s.'_size_h' );
517
+ $crop = get_option( $s.'_crop' );
518
+ }
519
+ $sizes[$s] = array( 'width' => $width, 'height' => $height, 'crop' => $crop );
520
+ }
521
+ return $sizes;
522
+ }
523
+
524
+
525
+ // From a fullpath to the shortened and cleaned path (for example '2013/02/file.png')
526
+ function wpmc_clean_uploaded_filename( $fullpath ) {
527
+ $upload_folder = wp_upload_dir();
528
+ $basedir = $upload_folder['basedir'];
529
+ $file = str_replace( $basedir, '', $fullpath );
530
+ $file = trim( $file, "/" );
531
+ return $file;
532
+ }
533
+
534
+ function wpmc_check_media( $attachmentId ) {
535
+
536
+ // Is it an image?
537
+ $meta = wp_get_attachment_metadata( $attachmentId );
538
+ $isImage = isset( $meta, $meta['width'], $meta['height'] );
539
+
540
+ // Get the main file
541
+ global $wpdb;
542
+ $fullpath = get_attached_file( $attachmentId );
543
+ $mainfile = $this->wpmc_clean_uploaded_filename( $fullpath );
544
+ $baseUp = pathinfo( $mainfile );
545
+ $baseUp = $baseUp['dirname'];
546
+ $size = 0;
547
+ $countfiles = 0;
548
+ $issue = 'NO_CONTENT';
549
+ if ( file_exists( $fullpath ) ) {
550
+ $size = filesize( $fullpath );
551
+
552
+ if ( $this->wpmc_check_is_ignore( $mainfile )
553
+ || $this->checkers->wpmc_check_db_has_background_or_header( $mainfile )
554
+ || $this->checkers->wpmc_check_db_has_content( $mainfile, $attachmentId )
555
+ || $this->checkers->wpmc_check_in_gallery( $mainfile )
556
+ || $this->checkers->wpmc_check_db_has_meta( $mainfile, $attachmentId ) )
557
+ return true;
558
+
559
+ // If images, check the other files as well
560
+ $countfiles = 0;
561
+ $sizes = $this->wpmc_get_image_sizes();
562
+ if ( $isImage && isset( $meta['sizes'] ) ) {
563
+ foreach ( $meta['sizes'] as $name => $attr ) {
564
+ if ( isset( $attr['file'] ) ) {
565
+ $filepath = wp_upload_dir();
566
+ $filepath = $filepath['basedir'];
567
+ $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
568
+ if ( file_exists( $filepath ) ) {
569
+ $size += filesize( $filepath );
570
+ }
571
+ $file = $this->wpmc_clean_uploaded_filename( $attr['file'] );
572
+ $countfiles++;
573
+ if ($this->debug) error_log("checking MEDIA-IMAGE {$filepath}");
574
+ if ( $this->checkers->wpmc_check_in_gallery( $filepath )
575
+ || $this->checkers->wpmc_check_db_has_background_or_header( $filepath )
576
+ || $this->checkers->wpmc_check_db_has_meta( $filepath, $attachmentId ) )
577
+ return true;
578
+ }
579
+ }
580
+ }
581
+ } else {
582
+ $issue = 'ORPHAN_MEDIA';
583
+ }
584
+
585
+ $table_name = $wpdb->prefix . "wpmcleaner";
586
+ $wpdb->insert( $table_name,
587
+ array(
588
+ 'time' => current_time('mysql'),
589
+ 'type' => 1,
590
+ 'size' => $size,
591
+ 'path' => $mainfile . ( $countfiles > 0 ? ( " (+ " . $countfiles . " files)" ) : "" ),
592
+ 'postId' => $attachmentId,
593
+ 'issue' => $issue
594
+ )
595
+ );
596
+ return false;
597
+ }
598
+
599
+ // Delete all issues
600
+ function wpmc_reset_issues( $includingIgnored = false ) {
601
+ global $wpdb;
602
+ $table_name = $wpdb->prefix . "wpmcleaner";
603
+ if ( $includingIgnored ) {
604
+ $wpdb->query( "DELETE FROM $table_name WHERE deleted = 0" );
605
+ }
606
+ else {
607
+ $wpdb->query( "DELETE FROM $table_name WHERE ignored = 0 AND deleted = 0" );
608
+ }
609
+ }
610
+
611
+ /**
612
+ *
613
+ * DASHBOARD
614
+ *
615
+ */
616
+
617
+ function admin_inline_js() {
618
+ echo "<script type='text/javascript'>\n";
619
+ echo 'var wpmc_cfg = { isPro: ' . ( $this->admin->is_registered() ? '1' : '0') . ', scanFiles: ' . ( ( get_option( 'wpmc_method', 'media' ) == 'files' && $this->admin->is_registered() ) ? '1' : '0' ) . ', scanMedia: ' . ( get_option( 'wpmc_method', 'media' ) == 'media' ? '1' : '0' ) . ' };';
620
+ echo "\n</script>";
621
+ }
622
+
623
+ function echo_issue( $issue ) {
624
+ if ( $issue == 'NO_CONTENT' ) {
625
+ _e( "Seems not in use.", 'media-cleaner' );
626
+ }
627
+ else if ( $issue == 'NO_MEDIA' ) {
628
+ _e( "Not in Media Library.", 'media-cleaner' );
629
+ }
630
+ else if ( $issue == 'ORPHAN_RETINA' ) {
631
+ _e( "Orphan retina.", 'media-cleaner' );
632
+ }
633
+ else if ( $issue == 'ORPHAN_MEDIA' ) {
634
+ _e( "File not found.", 'media-cleaner' );
635
+ }
636
+ else {
637
+ echo $issue;
638
+ }
639
+ }
640
+
641
+ function media_row_actions( $actions, $post ) {
642
+ global $current_screen;
643
+ if ( 'upload' != $current_screen->id )
644
+ return $actions;
645
+ global $wpdb;
646
+ $table_name = $wpdb->prefix . "wpmcleaner";
647
+ $res = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE postId = %d", $post->ID ) );
648
+ if ( !empty( $res ) && isset( $actions['delete'] ) )
649
+ $actions['delete'] = "<a href='?page=media-cleaner&view=deleted'>Delete with Media Cleaner</a>";
650
+ if ( !empty( $res ) && isset( $actions['trash'] ) )
651
+ $actions['trash'] = "<a href='?page=media-cleaner'>Trash with Media Cleaner</a>";
652
+ if ( !empty( $res ) && isset( $actions['untrash'] ) ) {
653
+ $actions['untrash'] = "<a href='?page=media-cleaner&view=deleted'>Restore with Media Cleaner</a>";
654
+ }
655
+ return $actions;
656
+ }
657
+
658
+ function wpmc_screen() {
659
+ global $wplr;
660
+ ?>
661
+ <div class='wrap'>
662
+
663
+ <?php
664
+ echo $this->admin->display_title( "Media Cleaner" );
665
+ global $wpdb;
666
+ $posts_per_page = get_user_meta( get_current_user_id(), 'upload_per_page', true );
667
+ if ( empty( $posts_per_page ) )
668
+ $posts_per_page = 20;
669
+ $view = isset ( $_GET[ 'view' ] ) ? sanitize_text_field( $_GET[ 'view' ] ) : "issues";
670
+ $paged = isset ( $_GET[ 'paged' ] ) ? sanitize_text_field( $_GET[ 'paged' ] ) : 1;
671
+ $reset = isset ( $_GET[ 'reset' ] ) ? $_GET[ 'reset' ] : 0;
672
+ if ( $reset ) {
673
+ wpmc_reset();
674
+ }
675
+ $s = isset ( $_GET[ 's' ] ) ? sanitize_text_field( $_GET[ 's' ] ) : null;
676
+ $table_name = $wpdb->prefix . "wpmcleaner";
677
+ $issues_count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name WHERE ignored = 0 AND deleted = 0" );
678
+ $total_size = $wpdb->get_var( "SELECT SUM(size) FROM $table_name WHERE ignored = 0 AND deleted = 0" );
679
+ $trash_total_size = $wpdb->get_var( "SELECT SUM(size) FROM $table_name WHERE ignored = 0 AND deleted = 1" );
680
+ $ignored_count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name WHERE ignored = 1" );
681
+ $deleted_count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name WHERE deleted = 1" );
682
+
683
+ if ( $view == 'deleted' ) {
684
+ $items_count = $deleted_count;
685
+ $items = $wpdb->get_results( $wpdb->prepare( "SELECT id, type, postId, path, size, ignored, deleted, issue
686
+ FROM $table_name WHERE ignored = 0 AND deleted = 1 AND path LIKE %s
687
+ ORDER BY time
688
+ DESC LIMIT %d, %d", '%' . $s . '%', ( $paged - 1 ) * $posts_per_page, $posts_per_page ), OBJECT );
689
+ }
690
+ else if ( $view == 'ignored' ) {
691
+ $items_count = $ignored_count;
692
+ $items = $wpdb->get_results( $wpdb->prepare( "SELECT id, type, postId, path, size, ignored, deleted, issue
693
+ FROM $table_name
694
+ WHERE ignored = 1 AND deleted = 0 AND path LIKE %s
695
+ ORDER BY time
696
+ DESC LIMIT %d, %d", '%' . $s . '%', ( $paged - 1 ) * $posts_per_page, $posts_per_page ), OBJECT );
697
+ }
698
+ else {
699
+ $items_count = $issues_count;
700
+ $items = $wpdb->get_results( $wpdb->prepare( "SELECT id, type, postId, path, size, ignored, deleted, issue
701
+ FROM $table_name
702
+ WHERE ignored = 0 AND deleted = 0 AND path LIKE %s
703
+ ORDER BY time
704
+ DESC LIMIT %d, %d", '%' . $s . '%', ( $paged - 1 ) * $posts_per_page, $posts_per_page ), OBJECT );
705
+ }
706
+ ?>
707
+
708
+ <style>
709
+ #wpmc-pages {
710
+ float: right;
711
+ position: relative;
712
+ top: 12px;
713
+ }
714
+
715
+ #wpmc-pages a {
716
+ text-decoration: none;
717
+ border: 1px solid black;
718
+ padding: 2px 5px;
719
+ border-radius: 4px;
720
+ background: #E9E9E9;
721
+ color: lightslategrey;
722
+ border-color: #BEBEBE;
723
+ }
724
+
725
+ #wpmc-pages .current {
726
+ font-weight: bold;
727
+ }
728
+ </style>
729
+
730
+ <div style='margin-top: 0px; background: #FFF; padding: 5px; border-radius: 4px; height: 28px; box-shadow: 0px 0px 6px #C2C2C2;'>
731
+
732
+ <!-- SCAN -->
733
+ <?php if ( $view != 'deleted' ) { ?>
734
+ <a id='wpmc_scan' onclick='wpmc_scan()' class='button-primary' style='float: left;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-search"></span><?php _e("Scan", 'media-cleaner'); ?></a>
735
+ <?php } ?>
736
+
737
+ <!-- DELETE SELECTED -->
738
+ <a id='wpmc_delete' onclick='wpmc_delete()' class='button' style='float: left; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-no"></span><?php _e("Delete", 'media-cleaner'); ?></a>
739
+ <?php if ( $view == 'deleted' ) { ?>
740
+ <a id='wpmc_recover' onclick='wpmc_recover()' class='button-secondary' style='float: left; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-repeat"></span><?php _e( "Recover", 'media-cleaner' ); ?></a>
741
+ <?php } ?>
742
+
743
+ <!-- IGNORE SELECTED -->
744
+ <a id='wpmc_ignore' onclick='wpmc_ignore()' class='button' style='float: left; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-yes"></span><?php _e("Ignore", 'media-cleaner'); ?></a>
745
+
746
+ <!-- RESET -->
747
+ <?php if ( $view != 'deleted' ) { ?>
748
+ <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>
749
+ <?php } ?>
750
+
751
+ <!-- DELETE ALL -->
752
+ <?php if ( $view == 'deleted' ) { ?>
753
+ <a id='wpmc_recover_all' onclick='wpmc_recover_all()' class='button-primary' 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>
754
+ <a id='wpmc_delete_all' onclick='wpmc_delete_all(true)' class='button button-red' 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>
755
+ <?php } else { ?>
756
+ <a id='wpmc_delete_all' onclick='wpmc_delete_all()' class='button button-red' 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>
757
+ <?php } ?>
758
+
759
+ <form id="posts-filter" action="upload.php" method="get" style='float: right;'>
760
+ <p class="search-box" style='margin-left: 5px; float: left;'>
761
+ <input type="search" name="s" style="width: 120px;" value="<?php echo $s ? $s : ""; ?>">
762
+ <input type="hidden" name="page" value="media-cleaner">
763
+ <input type="hidden" name="view" value="<?php echo $view; ?>">
764
+ <input type="hidden" name="paged" value="<?php echo $paged; ?>">
765
+ <input type="submit" class="button" value="<?php _e( 'Search', 'media-cleaner' ) ?>"><span style='border-right: #A2A2A2 solid 1px; margin-left: 5px; margin-right: 3px;'>&nbsp;</span>
766
+ </p>
767
+ </form>
768
+
769
+ <!-- PROGRESS -->
770
+ <span style='margin-left: 12px; font-size: 15px; top: 5px; position: relative; color: #747474;' id='wpmc_progression'></span>
771
+
772
+ </div>
773
+
774
+ <p>
775
+ <?php
776
+ $method = get_option( 'wpmc_method', 'media' );
777
+ if ( !$this->admin->is_registered() )
778
+ $method = 'media';
779
+
780
+ $hide_warning = get_option( 'wpmc_hide_warning', false );
781
+
782
+ if ( !$hide_warning ) {
783
+ _e( "<div class='notice notice-error'><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> <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' );
784
+ }
785
+
786
+ if ( !MEDIA_TRASH ) {
787
+ _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:<br /><b>define( 'MEDIA_TRASH', true );</b></p></div>" );
788
+ }
789
+
790
+ if ( !$this->admin->is_registered() ) {
791
+ echo "<div class='notice notice-info'><p>";
792
+ _e( "<b>This version is not Pro.</b> This plugin is a lot of work so please consider in getting the Pro version in order to receive support and to help the plugin to evolve. Also, the Pro version will also give you the option <b>to scan the <u>physical files</u> in your /uploads folder</b>. You can <a target='_blank' href='http://meowapps.com/media-cleaner'>get a serial for the Pro version here</a></b>.", 'media-cleaner' );
793
+ echo "</p></div>";
794
+ }
795
+
796
+ $anychecks = get_option(' wpmc_posts', false ) || get_option(' wpmc_galleries', false ) || get_option(' wpmc_postmeta', false );
797
+ $check_library = get_option(' wpmc_media_library', false );
798
+
799
+ if ( $method == 'media' ) {
800
+ if ( !$anychecks )
801
+ _e( "<div class='error'><p>Media Cleaner will analyze your Media Library. There is however <b>nothing marked to be check</b> in the Settings.</p></div>", 'media-cleaner' );
802
+ else
803
+ _e( "<div class='notice notice-success'><p>Media Cleaner will analyze your Media Library.</p></div>", 'media-cleaner' );
804
+ }
805
+ else if ( $method == 'files' ) {
806
+ if ( !$anychecks && !$check_library )
807
+ _e( "<div class='error'><p>Media Cleaner will analyze your Filesystem. There is however <b>nothing marked to be check</b> in the Settings.</p></div>", 'media-cleaner' );
808
+ else
809
+ _e( "<div class='notice notice-success'><p>Media Cleaner will analyze your Filesystem.</p></div>", 'media-cleaner' );
810
+ }
811
+
812
+ 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 ) );
813
+ ?>
814
+ </p>
815
+
816
+ <div id='wpmc-pages'>
817
+ <?php
818
+ echo paginate_links(array(
819
+ 'base' => '?page=media-cleaner&s=' . urlencode($s) . '&view=' . $view . '%_%',
820
+ 'current' => $paged,
821
+ 'format' => '&paged=%#%',
822
+ 'total' => ceil( $items_count / $posts_per_page ),
823
+ 'prev_next' => false
824
+ ));
825
+ ?>
826
+ </div>
827
+
828
+ <ul class="subsubsub">
829
+ <li class="all"><a <?php if ( $view == 'issues' ) echo "class='current'"; ?> href='?page=media-cleaner&s=<?php echo $s; ?>&view=issues'><?php _e( "Issues", 'media-cleaner' ); ?></a><span class="count">(<?php echo $issues_count; ?>)</span></li> |
830
+ <li class="all"><a <?php if ( $view == 'ignored' ) echo "class='current'"; ?> href='?page=media-cleaner&s=<?php echo $s; ?>&view=ignored'><?php _e( "Ignored", 'media-cleaner' ); ?></a><span class="count">(<?php echo $ignored_count; ?>)</span></li> |
831
+ <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>
832
+ </ul>
833
+
834
+ <table id='wpmc-table' class='wp-list-table widefat fixed media'>
835
+
836
+ <thead>
837
+ <tr>
838
+ <th scope="col" id="cb" class="manage-column column-cb check-column"><input id="wpmc-cb-select-all" type="checkbox"></th>
839
+ <?php if ( !get_option( 'wpmc_hide_thumbnails', false ) ): ?>
840
+ <th style='width: 64px;'><?php _e( 'Thumb', 'media-cleaner' ) ?></th>
841
+ <?php endif; ?>
842
+ <th style='width: 50px;'><?php _e( 'Type', 'media-cleaner' ) ?></th>
843
+ <th style='width: 80px;'><?php _e( 'Origin', 'media-cleaner' ) ?></th>
844
+
845
+ <?php if ( !empty( $wplr ) ): ?>
846
+ <th style='width: 70px;'><?php _e( 'LR ID', 'media-cleaner' ) ?></th>
847
+ <?php endif; ?>
848
+
849
+ <th><?php _e( 'Path', 'media-cleaner' ) ?></th>
850
+ <th style='width: 220px;'><?php _e( 'Issue', 'media-cleaner' ) ?></th>
851
+ <th style='width: 80px; text-align: right;'><?php _e( 'Size', 'media-cleaner' ) ?></th>
852
+ </tr>
853
+ </thead>
854
+
855
+ <tbody>
856
+ <?php
857
+ foreach ( $items as $issue ) {
858
+ $regex = "^(.*)(\\s\\(\\+.*)$";
859
+ $issue->path = preg_replace( '/' .$regex . '/i', '$1', $issue->path );
860
+ ?>
861
+ <tr>
862
+ <td><input type="checkbox" name="id" value="<?php echo $issue->id ?>"></td>
863
+ <?php if ( !get_option( 'wpmc_hide_thumbnails', false ) ): ?>
864
+ <td>
865
+ <?php
866
+ if ( $issue->deleted == 0 ) {
867
+ if ( $issue ->type == 0 ) {
868
+ // FILE
869
+ $upload_dir = wp_upload_dir();
870
+ $url = htmlspecialchars( $upload_dir['baseurl'] . '/' . $issue->path, ENT_QUOTES );
871
+ echo "<a target='_blank' href='" . $url .
872
+ "'><img style='max-width: 48px; max-height: 48px;' src='" . $url . "' /></a>";
873
+ }
874
+ else {
875
+ // MEDIA
876
+ $attachmentsrc = wp_get_attachment_image_src( $issue->postId, 'thumbnail' );
877
+ $attachmentsrc_clean = htmlspecialchars( $attachmentsrc[0], ENT_QUOTES );
878
+ echo "<a target='_blank' href='" . $attachmentsrc_clean .
879
+ "'><img style='max-width: 48px; max-height: 48px;' src='" .
880
+ $attachmentsrc_clean . "' />";
881
+ }
882
+ }
883
+ if ( $issue->deleted == 1 ) {
884
+ $upload_dir = wp_upload_dir();
885
+ $url = htmlspecialchars( $upload_dir['baseurl'] . '/wpmc-trash/' . $issue->path, ENT_QUOTES );
886
+ echo "<a target='_blank' href='" . $url .
887
+ "'><img style='max-width: 48px; max-height: 48px;' src='" . $url . "' /></a>";
888
+ }
889
+ ?>
890
+ </td>
891
+ <?php endif; ?>
892
+ <td><?php echo $issue->type == 0 ? 'FILE' : 'MEDIA'; ?></td>
893
+ <td><?php echo $issue->type == 0 ? 'Filesystem' : ("<a href='post.php?post=" .
894
+ $issue->postId . "&action=edit'>ID " . $issue->postId . "</a>"); ?></td>
895
+ <?php if ( !empty( $wplr ) ) { $info = $wplr->get_sync_info( $issue->postId ); ?>
896
+ <td style='width: 70px;'><?php echo ( !empty( $info ) && $info->lr_id ? $info->lr_id : "" ); ?></td>
897
+ <?php } ?>
898
+ <td><?php echo stripslashes( $issue->path ); ?></td>
899
+ <td><?php $this->echo_issue( $issue->issue ); ?></td>
900
+ <td style='text-align: right;'><?php echo number_format( $issue->size / 1000, 2 ); ?> KB</td>
901
+ </tr>
902
+ <?php } ?>
903
+ </tbody>
904
+
905
+ <tfoot>
906
+ <tr><th></th>
907
+ <?php if ( !get_option( 'hide_thumbnails', false ) ): ?>
908
+ <th></th>
909
+ <?php endif; ?>
910
+ <th><?php _e( 'Type', 'media-cleaner' ) ?></th><th><?php _e( 'Origin', 'media-cleaner' ) ?></th>
911
+ <?php if ( !empty( $wplr ) ): ?>
912
+ <th style='width: 70px;'><?php _e( 'LR ID', 'media-cleaner' ) ?></th>
913
+ <?php endif; ?>
914
+ <th><?php _e( 'Path', 'media-cleaner' ) ?></th><th><?php _e( 'Issue', 'media-cleaner' ) ?></th><th style='width: 80px; text-align: right;'><?php _e( 'Size', 'media-cleaner' ) ?></th></tr>
915
+ </tfoot>
916
+
917
+ </table>
918
+ </wrap>
919
+
920
+ <?php
921
+ }
922
+
923
+ function admin_menu() {
924
+ //load_plugin_textdomain( 'media-cleaner', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
925
+ add_media_page( 'Media Cleaner', 'Cleaner', 'manage_options', 'media-cleaner', array( $this, 'wpmc_screen' ) );
926
+ }
927
+
928
+ function wp_enqueue_scripts () {
929
+ wp_enqueue_style( 'media-cleaner-css', plugins_url( '/media-cleaner.css', __FILE__ ) );
930
+ wp_enqueue_script( 'media-cleaner', plugins_url( '/media-cleaner.js', __FILE__ ), array( 'jquery' ), "3.7.0", true );
931
+ }
932
+
933
+ /*******************************************************************************
934
+ * OLD PRO / TODO: THIS FUNCTION SHOULD BE REMOVED IN THE FUTURE
935
+ ******************************************************************************/
936
+
937
+ function admin_notices() {
938
+ if ( isset( $_POST['wpmc_reset_sub'] ) ) {
939
+ delete_transient( 'wpmc_validated' );
940
+ delete_option( 'wpmc_pro_serial' );
941
+ delete_option( 'wpmc_pro_status' );
942
+ }
943
+ $validated = get_transient( 'wpmc_validated' );
944
+ $subscr_id = get_option( 'wpmc_pro_serial', "" );
945
+ if ( empty( $subscr_id ) || empty( $validated ) )
946
+ return;
947
+ $forever = strpos( $subscr_id, 'F-' ) !== false;
948
+ $yearly = strpos( $subscr_id, 'I-' ) !== false;
949
+ ?>
950
+ <div class="error">
951
+ <p>
952
+ <b>IMPORTANT MESSAGE ABOUT MEDIA CLEANER.</b>
953
+ In order to comply with WordPress.org rules, changes in the code and how the plugin was sold had to be made. The plugin now requires to be bought through <a target='_blank' href="https://store.meowapps.com">https://store.meowapps.com</a>. You will be able to download the Pro version there (and it will be kept updated), manage your keys and websites. Only the free version can be hosted by WordPress.org, so this is the one you have now. To ease this upgrade, I made the price of my standard licenses cheaper.<br /><br />
954
+ Your license is <b><?php echo $subscr_id ?></b>.
955
+ <?php
956
+ if ( $forever ) {
957
+ echo "You have a Forever license. If you got this license less than 120 days ago, reply to the welcome e-mail (after buying a new license) with your previous license key ($subscr_id) and the e-mail you are using in Paypal. I will refund the previous payment. Otherwise, we are out of luck :( So here is a discount instead, of <b>90% off</b>, for any license you like: <b>UPGRADE90MEDIACLEANER</b>.";
958
+ }
959
+ else if ( $yearly ) {
960
+ echo "You have a Yearly license. If you got this license less than 120 days ago, reply to the welcome e-mail (after buying a new license) with your previous license key ($subscr_id) and the e-mail you are using in Paypal. I will refund the previous payment. If it is more than 120 days ago, we are out of luck :) So here is a discount of <b>50% off</b>, for any license you like: <b>UPGRADEMEDIACLEANER50</b>. Also, don't forget to cancel your current subscription in Paypal (<a target='_blank' href='https://www.paypal.com/us/selfhelp/article/How-do-I-cancel-an-automatic-payment-I-have-with-a-merchant-FAQ2058'>click here</a> if you don't know how to do this).";
961
+ }
962
+ else {
963
+ echo "Your license is special, so please contact me.";
964
+ }
965
+ ?>
966
+ If you absolutely need to use the plugin as it was before, with your current license key, please download it again here: <a target='_blank' href="https://meowapps.com/previous-versions/">Previous Versions</a>. I will keep the old system up for a while, but no updates will be possible, and better to enjoy the discount codes.
967
+ <br /><br />Also note that I also have now an <a target='_blank' href='https://store.meowapps.com/affiliate-area/'>Affiliate Program</a> in that store, don't hesitate to register for it. Thanks a lot for your comprehension and sorry for the troubles. Not easy for anyone but it had to be done and I think you will really enjoy the new store more than the previous clunky system.
968
+ </p>
969
+ <p>
970
+ <form method="post" action="">
971
+ <input type="hidden" name="wpmc_reset_sub" value="true">
972
+ <input type="submit" name="submit" id="submit" class="button" value="Got it. Understood!">
973
+ <br /><small>Make sure you got a new license and all before clicking this button. It will also clean your install from the old key data.</small>
974
+ </form>
975
+ </p>
976
+ </div>
977
+ <?php
978
+ }
979
+
980
+ }
981
+
982
+
983
+ /*
984
+ INSTALL / UNINSTALL
985
+ */
986
+
987
+ register_activation_hook( __FILE__, 'wpmc_activate' );
988
+ register_deactivation_hook( __FILE__, 'wpmc_uninstall' );
989
+ register_uninstall_hook( __FILE__, 'wpmc_uninstall' );
990
+
991
+ function wpmc_check_db() {
992
+ global $wpdb;
993
+ $tbl_m = $wpdb->prefix . 'wpmcleaner';
994
+ if ( !$wpdb->get_var( $wpdb->prepare( "SELECT COUNT(1) FROM information_schema.tables WHERE table_schema = '%s' AND table_name = '%s';", $wpdb->dbname, $tbl_m ) ) ) {
995
+ wpmc_activate();
996
+ }
997
+ }
998
+
999
+ function wpmc_reset () {
1000
+ wpmc_uninstall();
1001
+ wpmc_activate();
1002
+ }
1003
+
1004
+ function wpmc_activate () {
1005
+ global $wpdb;
1006
+ $table_name = $wpdb->prefix . "wpmcleaner";
1007
+ $charset_collate = $wpdb->get_charset_collate();
1008
+ $sql = "CREATE TABLE $table_name (
1009
+ id BIGINT(20) NOT NULL AUTO_INCREMENT,
1010
+ time DATETIME DEFAULT '0000-00-00 00:00:00' NOT NULL,
1011
+ type TINYINT(1) NOT NULL,
1012
+ postId BIGINT(20) NULL,
1013
+ path TINYTEXT NULL,
1014
+ size INT(9) NULL,
1015
+ ignored TINYINT(1) NOT NULL DEFAULT 0,
1016
+ deleted TINYINT(1) NOT NULL DEFAULT 0,
1017
+ issue TINYTEXT NOT NULL,
1018
+ UNIQUE KEY id (id)
1019
+ ) " . $charset_collate . ";";
1020
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
1021
+ dbDelta( $sql );
1022
+
1023
+ $upload_folder = wp_upload_dir();
1024
+ $basedir = $upload_folder['basedir'];
1025
+ if ( !is_writable( $basedir ) ) {
1026
+ echo '<div class="error"><p>' . __( 'The directory for uploads is not writable. Media Cleaner will only be able to scan.', 'media-cleaner' ) . '</p></div>';
1027
+ }
1028
+ }
1029
+
1030
+ function wpmc_uninstall () {
1031
+ global $wpdb;
1032
+ $table_name = $wpdb->prefix . "wpmcleaner";
1033
+ $wpdb->query("DROP TABLE IF EXISTS $table_name");
1034
+ }
languages/media-file-cleaner-fr_FR.mo DELETED
Binary file
languages/media-file-cleaner-fr_FR.po DELETED
@@ -1,453 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: WP Media Cleaner\n"
4
- "POT-Creation-Date: 2015-08-25 11:33+0900\n"
5
- "PO-Revision-Date: 2015-08-25 11:34+0900\n"
6
- "Last-Translator: Jordy Meow <jordy@meow.fr>\n"
7
- "Language-Team: Meow.fr <apps@meow.fr>\n"
8
- "Language: fr_FR\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.8.1\n"
13
- "X-Poedit-KeywordsList: _e;__\n"
14
- "X-Poedit-Basepath: ..\n"
15
- "X-Poedit-SourceCharset: UTF-8\n"
16
- "Plural-Forms: nplurals=2; plural=(n > 1);\n"
17
- "X-Poedit-SearchPath-0: .\n"
18
-
19
- #: media-file-cleaner.php:55 media-file-cleaner.php:73
20
- #: media-file-cleaner.php:91
21
- msgid "Status unknown."
22
- msgstr "Statut inconnu"
23
-
24
- #: media-file-cleaner.php:118
25
- msgid "Items checked."
26
- msgstr "Fichiers vérifiés"
27
-
28
- #: media-file-cleaner.php:132 media-file-cleaner.php:150
29
- msgid "List generated."
30
- msgstr "Liste générée"
31
-
32
- #: media-file-cleaner.php:262
33
- msgid "Files retrieved."
34
- msgstr "Fichiers récupérés"
35
-
36
- #: media-file-cleaner.php:272
37
- msgid "Medias retrieved."
38
- msgstr "Images récupérées"
39
-
40
- #: media-file-cleaner.php:278
41
- msgid "No task."
42
- msgstr "Aucune opération"
43
-
44
- #: media-file-cleaner.php:906
45
- msgid "Seems not in use."
46
- msgstr "Ne semble pas en cours d'utilisation"
47
-
48
- #: media-file-cleaner.php:909
49
- msgid "Not in Media Library."
50
- msgstr "Pas dans la bibliothèque multimédia"
51
-
52
- #: media-file-cleaner.php:912
53
- msgid "Orphan retina."
54
- msgstr "Retina orphelin"
55
-
56
- #: media-file-cleaner.php:915
57
- msgid "File not found."
58
- msgstr "Fichier introuvable"
59
-
60
- #: media-file-cleaner.php:996
61
- msgid "Scan"
62
- msgstr "Scanner"
63
-
64
- #: media-file-cleaner.php:1000
65
- msgid "Delete"
66
- msgstr "Supprimer"
67
-
68
- #: media-file-cleaner.php:1002
69
- msgid "Recover"
70
- msgstr "Récupérer"
71
-
72
- #: media-file-cleaner.php:1006
73
- msgid "Ignore"
74
- msgstr "Ignorer"
75
-
76
- #: media-file-cleaner.php:1010
77
- msgid "Reset"
78
- msgstr "Reset"
79
-
80
- #: media-file-cleaner.php:1015
81
- msgid "Recover all"
82
- msgstr "Tout récupérer"
83
-
84
- #: media-file-cleaner.php:1016
85
- msgid "Empty trash"
86
- msgstr "Vider la corbeille"
87
-
88
- #: media-file-cleaner.php:1018
89
- msgid "Delete all"
90
- msgstr "Tout supprimer"
91
-
92
- #: media-file-cleaner.php:1027
93
- msgid "Search"
94
- msgstr "Chercher"
95
-
96
- #: media-file-cleaner.php:1042
97
- msgid ""
98
- "<b>Backup your database and files before delete! This is important.</b> The "
99
- "files deleted by the plugin will be moved to the 'uploads/wpmc-trash' "
100
- "directory and you can trash them later. I am trying my best to make this "
101
- "plugin safe but since it deletes files on a very dynamic system (= "
102
- "WordPress), it is impossible to predict every single situation. Be careful."
103
- msgstr ""
104
- "<p style=\"text-align: justify;\"><strong>Note importante </strong>: Avant "
105
- "de lancer la scan, je vous remercie de <strong>sauvegarder vos fichiers et "
106
- "votre base de données</strong> parce que les éléments supprimés par le "
107
- "plugin WP Media Cleaner seront déplacés dans le répertoire \"uploads/wpmc-"
108
- "trash\" de votre client FTP.</p>"
109
-
110
- #: media-file-cleaner.php:1044
111
- msgid ""
112
- " If you delete an item of the type MEDIA, the database entry for it (Media "
113
- "Library) will be deleted permanently."
114
- msgstr ""
115
- "<p style=\"text-align: justify;\">Si vous supprimez un média de votre "
116
- "bibliothèque WordPress à l'issue d'un scan, le plugin WP Media Cleaner le "
117
- "supprimera de celle-ci.</p>"
118
-
119
- #: media-file-cleaner.php:1049
120
- msgid ""
121
- "Scan is not enabled for neither the files or for the medias. The plugin is "
122
- "basically disabled. <b>Please check Settings > Media Cleaner</b>."
123
- msgstr ""
124
- "<p style=\"text-align: justify;\">Vous ne pouvez pas utiliser WP Media "
125
- "Cleaner, et scanner vos fichiers et vos médias tant que vous n'aurez pas "
126
- "<strong>vérifier les paramètres</strong> (Réglages > Media Cleaner)</"
127
- "strong>. Il faut ainsi que vous cochiez le scan de la bibliothèque et/ou le "
128
- "scan des fichiers pour que l'extension fonctionne.</p>"
129
-
130
- #: media-file-cleaner.php:1054
131
- msgid ""
132
- "<b>This version is not Pro.</b> It will only let you delete the files "
133
- "<u><b>one by one</b></u>, for your safety. <b>If the plugin works perfectly "
134
- "for deleting the files one by one then you can <a href='http://apps.meow.fr/"
135
- "media-file-cleaner'>get the PRO version</a></b>. It will let you delete all "
136
- "the files in one click."
137
- msgstr ""
138
- "<p style=\"text-align: justify;\">Vous utilisez la version gratuite de WP "
139
- "Media Cleaner qui vous autorise à scanner votre bibliothèque de médias et à "
140
- "supprimer les fichiers un par un.</p>\n"
141
- "<p style=\"text-align: justify;\"> Une version payante de WP Media Cleaner "
142
- "est disponible sur <a href='http://apps.meow.fr/wp-media-cleaner'>le site de "
143
- "son auteur</a> afin que vous l'utilisiez avec toutes ses fonctionnalités "
144
- "(suppression de tous les fichiers).</p>"
145
-
146
- #: media-file-cleaner.php:1058
147
- #, php-format
148
- msgid ""
149
- "There are <b>%d issue(s)</b> with your files, accounting for <b>%d MB</b>. "
150
- "Your trash contains <b>%d MB.</b>"
151
- msgstr ""
152
- "Il y a <strong>%d fichier(s) inutilisé(s)</strong> qui représente un total "
153
- "de <strong>%d MB</strong>. Votre corbeille contient <strong>%d MB</strong>."
154
-
155
- #: media-file-cleaner.php:1075
156
- msgid "Issues"
157
- msgstr "Fichiers inutilisés"
158
-
159
- #: media-file-cleaner.php:1076
160
- msgid "Ignored"
161
- msgstr "Fichiers ignorés"
162
-
163
- #: media-file-cleaner.php:1077
164
- msgid "Trash"
165
- msgstr "Corbeille"
166
-
167
- #: media-file-cleaner.php:1086
168
- msgid "Thumb"
169
- msgstr "Aperçu"
170
-
171
- #: media-file-cleaner.php:1088 media-file-cleaner.php:1132
172
- msgid "Type"
173
- msgstr "Type"
174
-
175
- #: media-file-cleaner.php:1089 media-file-cleaner.php:1132
176
- msgid "Origin"
177
- msgstr "Origine"
178
-
179
- #: media-file-cleaner.php:1090 media-file-cleaner.php:1132
180
- msgid "Path"
181
- msgstr "Fichier"
182
-
183
- #: media-file-cleaner.php:1091 media-file-cleaner.php:1132
184
- msgid "Issue"
185
- msgstr "Problème"
186
-
187
- #: media-file-cleaner.php:1092 media-file-cleaner.php:1132
188
- msgid "Size"
189
- msgstr "Taille"
190
-
191
- #: media-file-cleaner.php:1181
192
- msgid "Your serial does not seem right."
193
- msgstr "Votre numéro de série ne semble pas être correct."
194
-
195
- #: media-file-cleaner.php:1184
196
- msgid "Your subscription is not active."
197
- msgstr "Votre abonnement n'est pas actif."
198
-
199
- #: media-file-cleaner.php:1187
200
- msgid "Too many URLs are linked to your subscription."
201
- msgstr "Il y a trop d'adresse URL qui sont liées à votre abonnement."
202
-
203
- #: media-file-cleaner.php:1190
204
- msgid "There is a problem with your subscription."
205
- msgstr "Il y a un problème avec votre abonnement."
206
-
207
- #: media-file-cleaner.php:1199
208
- msgid "Your subscription is enabled."
209
- msgstr "Votre abonnement est actif."
210
-
211
- #: media-file-cleaner.php:1249
212
- msgid ""
213
- "The directory for uploads is not writable. Media File Cleaner will only be "
214
- "able to scan."
215
- msgstr ""
216
- "Le répertoire pour les téléchargements (/uploads) n'est pas accessible en "
217
- "écriture. WP Media Cleaner ne pourra seulement que scanner vos fichiers. "
218
- "Pour résoudre le problème, merci de contacter votre hébergeur Internet."
219
-
220
- #: meow_footer.php:22
221
- msgid ""
222
- "Developed by <a style=\"text-decoration: none;\" href=\"http://www.meow.fr\" "
223
- "target=\"_blank\">Jordy Meow</a>"
224
- msgstr ""
225
- "Développé par <a style=\"text-decoration: none;\" href=\"http://www.meow.fr"
226
- "\">Jordy Meow</a>."
227
-
228
- #: meow_footer.php:34
229
- msgid ""
230
- "I love and strongly recommend WP Engine. My plugins are all tested with it."
231
- msgstr "J'utilise WP Engine pour tester mes plugins et je le recommande."
232
-
233
- #: meow_footer.php:45
234
- msgid ""
235
- "<b>This plugin is actively developed and maintained by <a href=\"http://www."
236
- "meow.fr\">Jordy Meow</a></b>.<br />More of my tools are available here: <a "
237
- "href=\"http://apps.meow.fr\">Meow Apps</a>. I am also a photographer in "
238
- "Japan: <a href=\"http://www.totorotimes.com\">Totoro Times</a>."
239
- msgstr ""
240
- "<strong>Le plugin est développé et maintenu par <a href=\"http://www.meow.fr"
241
- "\">Jordy Meow</a></strong>.<br />Mes outils et mes plugins sont disponibles "
242
- "dans les pages de mon site <a href=\"http://apps.meow.fr\">Meow Apps</a>. </"
243
- "br />Je suis également photographe au Japon et mes travaux sont disponibles "
244
- "sur mon autre site : <a href=\"http://www.totorotimes.fr\">Totoro Times</a>."
245
-
246
- #: meow_footer.php:48
247
- #, php-format
248
- msgid "Donation link: %sPaypal%s. Thanks! ^^"
249
- msgstr ""
250
- "Don Paypal : %sPaypal%s. Merci de soutenir l'auteur du plugin WP Media "
251
- "Cleaner."
252
-
253
- #: wpmc_settings.php:48
254
- msgid "Options"
255
- msgstr "Options"
256
-
257
- #: wpmc_settings.php:52
258
- msgid "Serial Key (Pro)"
259
- msgstr "Numéro de série (Pro)"
260
-
261
- #: wpmc_settings.php:67
262
- msgid "Scan Media"
263
- msgstr "Scan de la bibliothèque"
264
-
265
- #: wpmc_settings.php:68
266
- msgid ""
267
- "The Media Library will be scanned.<br /><small>The medias from Media Library "
268
- "which seem not being used in your WordPress will be marked as to be deleted."
269
- "</small>"
270
- msgstr ""
271
- "<p style=\"text-align: justify;\">La bibliothèque de médias sera scannée.</"
272
- "p>\n"
273
- "<p style=\"text-align: justify;\"><small>Les fichiers situés dans votre "
274
- "bibliothèque de médias qui seront inutilisés par vos billets, seront listés "
275
- "dans l'onglet \"Fichiers inutilisés\" (Médias > Media Cleaner)</small>.</p>"
276
-
277
- #: wpmc_settings.php:74
278
- msgid "Scan Files"
279
- msgstr "Scan des fichiers"
280
-
281
- #: wpmc_settings.php:75
282
- msgid ""
283
- "The Uploads folder will be scanned.<br /><small>The files in your /uploads "
284
- "folder that don't seem being used in your WordPress will be marked as to be "
285
- "deleted. <b>If they are found in your Media Library, they will be considered "
286
- "as fine.</b></small>"
287
- msgstr ""
288
- "<p style=\"text-align: justify;\">Le dossier uploads du FTP sera scanné.</"
289
- "p>\n"
290
- "<p style=\"text-align: justify;\"><small>Les fichiers du dossier uploads qui "
291
- "seront inutilisés par vos billets, seront listés dans l'onglet \"Fichiers "
292
- "inutilisés\" (Médias > Media Cleaner). Si ils se trouvent dans votre "
293
- "bibliothèque de médias, les fichiers seront valides.<small></p>"
294
-
295
- #: wpmc_settings.php:81
296
- msgid "Resolve Shortcode"
297
- msgstr "Gestion des shortcodes"
298
-
299
- #: wpmc_settings.php:82
300
- #, php-format
301
- msgid ""
302
- "The shortcodes you are using in your posts and widgets will be resolved and "
303
- "checked.<br /><small>This process takes more resources. If the scanning "
304
- "suddenly stops, this might be the cause. Here is the list of the shortcodes "
305
- "enabled on your WordPress that you might be using: <b>%s</b>. Please note "
306
- "that the gallery shortcode is checked by the normal process. You don't need "
307
- "to have this option enabled for the WP gallery.</small>"
308
- msgstr ""
309
- "<p style=\"text-align: justify;\">WP Media Cleaner vérifiera les shortcodes "
310
- "que vous utilisez dans vos articles, dans vos pages et dans vos widgets. Ce "
311
- "processus de vérification nécessitera un peu plus de ressources que "
312
- "d'habitude. Si le scan s'arrête soudainement, merci de décocher cette "
313
- "option, d’enregistrer le paramètre et de relancer le processus.</p>\n"
314
- "<p style=\"text-align: justify;\"><small>Je vous présente la liste non-"
315
- "exhaustive des shortcodes qui pourraient être utilisés sur votre WordPress : "
316
- "%s.</small></p>\n"
317
- "<p style=\"text-align: justify;\"><small>A noter également qu'il est inutile "
318
- "de cocher cette option pour vérifier uniquement le shortcode \"gallery\" de "
319
- "WordPress.</small></p>"
320
-
321
- #: wpmc_settings.php:88
322
- msgid "UTF-8 Support"
323
- msgstr "Gestion de l'UTF-8"
324
-
325
- #: wpmc_settings.php:89
326
- msgid ""
327
- "The filenames in UTF-8 will not be skipped.<br /><small>PHP does not always "
328
- "work well with UTF-8 on all systems (Windows?). If the scanning suddenly "
329
- "stops, this might be the cause.</small>"
330
- msgstr ""
331
- "<p style=\"text-align: justify;\">Les noms de fichiers encodés en UTF-8 ne "
332
- "seront pas ignorés.</p>\n"
333
- "<p style=\"text-align: justify;\"><small>Le PHP ne fonctionne pas toujours "
334
- "correctement avec ce type d'encodage et le système Windows. Si le scan des "
335
- "fichiers s'arrête soudainement, cela signifierait qu'il y a un soucis avec "
336
- "le mode UTF-8 et que vous devez décocher cette option.</small></p>"
337
-
338
- #: wpmc_settings.php:95
339
- msgid "Hide Thumbnails"
340
- msgstr "Désactiver les miniatures"
341
-
342
- #: wpmc_settings.php:96
343
- msgid ""
344
- "Hide the thumbnails column.<br /><small>Useful if your WordPress if filled-"
345
- "up with huge images.</small>"
346
- msgstr ""
347
- "<p style=\"text-align: justify;\">Cacher la colonne des miniatures.</p>\n"
348
- "<p style=\"text-align: justify;\"><small>Cette option est utile si la taille "
349
- "de vos images est importante.</small></p>"
350
-
351
- #: wpmc_settings.php:105
352
- #, php-format
353
- msgid "Status: %s"
354
- msgstr "Statut : %s"
355
-
356
- #: wpmc_settings.php:110
357
- msgid "Serial"
358
- msgstr "Numéro de série"
359
-
360
- #: wpmc_settings.php:111
361
- msgid ""
362
- "<br />Enter your serial or subscription ID here. If you don't have one yet, "
363
- "get one <a target=\"_blank\" href=\"http://apps.meow.fr/wp-media-cleaner/"
364
- "\">right here</a>."
365
- msgstr ""
366
- "<p style=\"text-align: justify;\">Saisissez votre numéro de série dans la "
367
- "zone de texte située ci-dessus. Si vous ne possédez pas de clé de licence, "
368
- "merci de vous rendre sur <a href=\"http://apps.meow.fr/wp-media-cleaner/"
369
- "\">le site de l'auteur</a>.</p>"
370
-
371
- #~ msgid ""
372
- #~ "<b>This version is not Pro.</b> It will only let you delete the files "
373
- #~ "<u><b>one by one</b></u>, for your safety. <b>If the plugin works "
374
- #~ "perfectly for deleting the files one by one then you can <a href='http://"
375
- #~ "apps.meow.fr/wp-media-cleaner'>get the PRO version</a></b>. It will let "
376
- #~ "you delete all the files in one click."
377
- #~ msgstr ""
378
- #~ "<p style=\"text-align: justify;\">Vous utilisez la version gratuite de WP "
379
- #~ "Media Cleaner qui vous autorise à scanner votre bibliothèque de médias et "
380
- #~ "à supprimer les fichiers un par un.</p>\n"
381
- #~ "<p style=\"text-align: justify;\"> Une version payante de WP Media "
382
- #~ "Cleaner est disponible sur <a href='http://apps.meow.fr/wp-media-"
383
- #~ "cleaner'>le site de son auteur</a> afin que vous l'utilisiez avec toutes "
384
- #~ "ses fonctionnalités (suppression de tous les fichiers).</p>"
385
-
386
- #~ msgid ""
387
- #~ "The directory for uploads is not writable. WP Media Cleaner will only be "
388
- #~ "able to scan."
389
- #~ msgstr ""
390
- #~ "Le répertoire pour les téléchargements (/uploads) n'est pas accessible en "
391
- #~ "écriture. WP Media Cleaner ne pourra seulement que scanner vos fichiers. "
392
- #~ "Pour résoudre le problème, merci de contacter votre hébergeur Internet."
393
-
394
- #~ msgid ""
395
- #~ "Scan is not enabled for neither the files or for the medias. The plugin "
396
- #~ "is basically disabled.<br /><b>Please check Settings > Media Cleaner</b>."
397
- #~ msgstr ""
398
- #~ "<p style=\"text-align: justify;\">Le scan n'est activé ni pour les "
399
- #~ "fichiers ni pour les médias. <strong>Merci de vérifier les paramètres de "
400
- #~ "WP Media Cleaner dans les options générales de WordPress (Réglages > "
401
- #~ "Media Cleaner)</strong>.</p>"
402
-
403
- #~ msgid "Basics"
404
- #~ msgstr "Options"
405
-
406
- #~ msgid "Pro"
407
- #~ msgstr "Pro"
408
-
409
- #~ msgid "Lists generated."
410
- #~ msgstr "Listes générées."
411
-
412
- #~ msgid "Related content or media not found."
413
- #~ msgstr "Pas de media associé, ni contenu."
414
-
415
- #~ msgid ""
416
- #~ "Be aware that a media will be considered <b>NOT</b> an issue <b>ONLY IF</"
417
- #~ "b> it is found in the Posts or Pages, and not in a Gallery. The deletion "
418
- #~ "of a media is also <b>PERMANENT</b>."
419
- #~ msgstr ""
420
- #~ "Attention, un media ne sera pas considéré comme un problème <b>seulement "
421
- #~ "dans le cas où</b> il est présent dans les Posts ou les Pages, mais pas "
422
- #~ "dans les Galleries ! La suppression des médias est aussi <b>irrémédiable</"
423
- #~ "b>."
424
-
425
- #~ msgid "The Media Library will be scanned."
426
- #~ msgstr "La Bibliothèque sera scannée."
427
-
428
- #~ msgid "The Uploads folder will be scanned."
429
- #~ msgstr "Les fichiers uploadés seront scannés."
430
-
431
- #~ msgid "The categories are both the same. Mmm. Please be careful!"
432
- #~ msgstr "Les catégories sont identiques... ohlala, faites-attention !"
433
-
434
- #~ msgid ""
435
- #~ "This plugin switches category 2 by 2. Doing that, you can change the way "
436
- #~ "WordPress picks the default category. This is particularly useful when a "
437
- #~ "post belongs to 2 or more categories. This plugin modifies directly the "
438
- #~ "ID's, which means you can uninstall it when you are done."
439
- #~ msgstr ""
440
- #~ "Ce plugin échange les ids des catégories deux par deux. Vous pourrez "
441
- #~ "ainsi changer la façon dont WordPress choisi les catégories par défaut "
442
- #~ "(très utile quand les posts appartiennent à deux catégories ou plus). Ce "
443
- #~ "plugin modifie les ids directement, il peut donc être désinstallé une "
444
- #~ "fois que l'opération est terminée."
445
-
446
- #~ msgid "Please backup your database before switching."
447
- #~ msgstr "Sauvegardez votre base de donnée avant d'utiliser cette fonction."
448
-
449
- #~ msgid "Categories (ordered by id's)"
450
- #~ msgstr "Catégories (triées par id)"
451
-
452
- #~ msgid "Switch:"
453
- #~ msgstr "Échanger :"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
media-cleaner.php CHANGED
@@ -3,11 +3,10 @@
3
  Plugin Name: Media Cleaner
4
  Plugin URI: http://meowapps.com
5
  Description: Clean your Media Library, many options, trash system.
6
- Version: 3.7.0
7
  Author: Jordy Meow
8
  Author URI: http://meowapps.com
9
  Text Domain: media-cleaner
10
- Domain Path: /languages
11
 
12
  Big thanks to Matt (http://www.twistedtek.net/) for all his
13
  contributions made to the plugin.
@@ -17,1048 +16,18 @@ Originally developed for two of my websites:
17
  - Haikyo (http://www.haikyo.org)
18
  */
19
 
20
- add_action( 'admin_notices', 'wpmc_admin_notices' );
21
- add_action( 'admin_menu', 'wpmc_admin_menu' );
22
- add_action( 'admin_enqueue_scripts', 'wpmc_wp_enqueue_scripts' );
23
- add_action( 'admin_print_scripts', 'wpmc_admin_inline_js' );
24
- add_action( 'wp_ajax_wpmc_scan', 'wpmc_wp_ajax_wpmc_scan' );
25
- add_action( 'wp_ajax_wpmc_get_all_issues', 'wpmc_wp_ajax_wpmc_get_all_issues' );
26
- add_action( 'wp_ajax_wpmc_get_all_deleted', 'wpmc_wp_ajax_wpmc_get_all_deleted' );
27
- add_action( 'wp_ajax_wpmc_scan_do', 'wpmc_wp_ajax_wpmc_scan_do' );
28
- add_action( 'wp_ajax_wpmc_delete_do', 'wpmc_wp_ajax_wpmc_delete_do' );
29
- add_action( 'wp_ajax_wpmc_ignore_do', 'wpmc_wp_ajax_wpmc_ignore_do' );
30
- add_action( 'wp_ajax_wpmc_recover_do', 'wpmc_wp_ajax_wpmc_recover_do' );
31
- add_filter( 'media_row_actions', 'wpmc_media_row_actions', 10, 2 );
32
 
33
- register_activation_hook( __FILE__, 'wpmc_activate' );
34
- register_deactivation_hook( __FILE__, 'wpmc_uninstall' );
35
- register_uninstall_hook( __FILE__, 'wpmc_uninstall' );
36
 
37
- require( 'wpmc_admin.php' );
 
 
38
 
39
- global $wpmc_admin, $wpmc_debug, $wpmc_exclude_dir, $wpmc_version;
40
- $wpmc_version = '3.7.0';
41
- $wpmc_debug = false;
42
- $disable_meowapps = false;
43
- $wpmc_admin = new Meow_MediaCleaner_Admin();
44
- $wpmc_exclude_dir = array( ".", "..", "wpmc-trash", ".htaccess",
45
- "ptetmp", "profiles", "sites", "bws_captcha_images",
46
- "woocommerce_uploads", "wc-logs" );
47
-
48
- /*******************************************************************************
49
- * ASYNCHRONOUS AJAX FUNCTIONS
50
- ******************************************************************************/
51
-
52
- function wpmc_wp_ajax_wpmc_delete_do () {
53
- ob_start();
54
- $data = $_POST['data'];
55
- $success = 0;
56
- foreach ( $data as $piece ) {
57
- $success += ( wpmc_delete( $piece ) ? 1 : 0 );
58
- }
59
- ob_end_clean();
60
- echo json_encode(
61
- array(
62
- 'success' => true,
63
- 'result' => array( 'data' => $data, 'success' => $success ),
64
- 'message' => __( "Status unknown.", 'media-cleaner' )
65
- )
66
- );
67
- die();
68
- }
69
-
70
- function wpmc_wp_ajax_wpmc_ignore_do () {
71
- ob_start();
72
- $data = $_POST['data'];
73
- $success = 0;
74
- foreach ( $data as $piece ) {
75
- $success += ( wpmc_ignore( $piece ) ? 1 : 0 );
76
- }
77
- ob_end_clean();
78
- echo json_encode(
79
- array(
80
- 'success' => true,
81
- 'result' => array( 'data' => $data, 'success' => $success ),
82
- 'message' => __( "Status unknown.", 'media-cleaner' )
83
- )
84
- );
85
- die();
86
- }
87
-
88
- function wpmc_wp_ajax_wpmc_recover_do () {
89
- ob_start();
90
- $data = $_POST['data'];
91
- $success = 0;
92
- foreach ( $data as $piece ) {
93
- $success += ( wpmc_recover( $piece ) ? 1 : 0 );
94
- }
95
- ob_end_clean();
96
- echo json_encode(
97
- array(
98
- 'success' => true,
99
- 'result' => array( 'data' => $data, 'success' => $success ),
100
- 'message' => __( "Status unknown.", 'media-cleaner' )
101
- )
102
- );
103
- die();
104
- }
105
-
106
- function wpmc_wp_ajax_wpmc_scan_do () {
107
- global $wpmc_debug;
108
- ob_start();
109
- $type = $_POST['type'];
110
- $data = $_POST['data'];
111
- $success = 0;
112
- foreach ( $data as $piece ) {
113
- if ( $type == 'file' ) {
114
- if ( $wpmc_debug )
115
- error_log( "Check File: {$piece}" );
116
- $success += ( wpmc_check_file( $piece ) ? 1 : 0 );
117
- if ( $wpmc_debug )
118
- error_log( "Success " . $success . "\n" );
119
- } elseif ( $type == 'media' ) {
120
- if ( $wpmc_debug )
121
- error_log( "Check Media: {$piece}" );
122
- $success += ( wpmc_check_media( $piece ) ? 1 : 0 );
123
- if ( $wpmc_debug )
124
- error_log( "Success " . $success . "\n" );
125
- }
126
- }
127
- ob_end_clean();
128
- echo json_encode(
129
- array(
130
- 'success' => true,
131
- 'result' => array( 'type' => $type, 'data' => $data, 'success' => $success ),
132
- 'message' => __( "Items checked.", 'media-cleaner' )
133
- )
134
- );
135
- die();
136
- }
137
-
138
- function wpmc_wp_ajax_wpmc_get_all_deleted () {
139
- global $wpdb;
140
- $table_name = $wpdb->prefix . "wpmcleaner";
141
- $ids = $wpdb->get_col( "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = 1" );
142
- echo json_encode(
143
- array(
144
- 'results' => array( 'ids' => $ids ),
145
- 'success' => true,
146
- 'message' => __( "List generated.", 'media-cleaner' )
147
- )
148
- );
149
- die;
150
- }
151
-
152
- function wpmc_wp_ajax_wpmc_get_all_issues () {
153
- global $wpdb;
154
- $isTrash = ( isset( $_POST['isTrash'] ) && $_POST['isTrash'] == 1 ) ? true : false;
155
- $table_name = $wpdb->prefix . "wpmcleaner";
156
- if ( $isTrash )
157
- $ids = $wpdb->get_col( "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = 1" );
158
- else
159
- $ids = $wpdb->get_col( "SELECT id FROM $table_name WHERE ignored = 0 AND deleted = 0" );
160
- echo json_encode(
161
- array(
162
- 'results' => array( 'ids' => $ids ),
163
- 'success' => true,
164
- 'message' => __( "List generated.", 'media-cleaner' )
165
- )
166
- );
167
- die;
168
- }
169
-
170
- function wpmc_get_galleries_images( $force = false ) {
171
- if ( $force ) {
172
- delete_transient( "wpmc_galleries_images" );
173
- $galleries_images = null;
174
- }
175
- else {
176
- $galleries_images = get_transient("wpmc_galleries_images");
177
- }
178
- if ( !$galleries_images ) {
179
- global $wpdb;
180
- $galleries_images = array();
181
- $posts = $wpdb->get_col( "SELECT id FROM $wpdb->posts WHERE post_type != 'attachment' AND post_status != 'inherit'" );
182
- foreach( $posts as $post ) {
183
- $galleries = get_post_galleries_images( $post );
184
- foreach( $galleries as $gallery ) {
185
- foreach( $gallery as $image ) {
186
- array_push( $galleries_images, $image );
187
- }
188
- }
189
- }
190
-
191
- $post_galleries = get_posts( array(
192
- 'tax_query' => array(
193
- array(
194
- 'taxonomy' => 'post_format',
195
- 'field' => 'slug',
196
- 'terms' => array( 'post-format-gallery' ),
197
- 'operator' => 'IN'
198
- )
199
- )
200
- ) );
201
-
202
- foreach( (array) $post_galleries as $gallery_post ) {
203
- $arrImages = get_children( 'post_type=attachment&post_mime_type=image&post_parent=' . $gallery_post->ID );
204
- if ( $arrImages ) {
205
- foreach( (array) $arrImages as $image_post ) {
206
- array_push( $galleries_images, $image_post->guid );
207
- }
208
- }
209
- }
210
- wp_reset_postdata();
211
-
212
- set_transient( "wpmc_galleries_images", $galleries_images, 60 * 60 * 2 );
213
- }
214
- return $galleries_images;
215
  }
216
 
217
- function wpmc_wp_ajax_wpmc_scan() {
218
- global $wpdb;
219
- global $wpmc_admin;
220
-
221
- $method = get_option( 'wpmc_method', 'media' );
222
- if ( !$wpmc_admin->is_registered() )
223
- $method = 'media';
224
- $path = isset( $_POST['path'] ) ? $_POST['path'] : null;
225
- $limit = isset( $_POST['limit'] ) ? $_POST['limit'] : 0;
226
- $limitsize = 100;
227
- $upload_folder = wp_upload_dir();
228
-
229
- if ( ( $method == 'media' && empty( $limit ) ) || ( $method == 'files' && empty( $path ) ) ) {
230
- // Reset and prepare all the Attachment IDs of all the galleries
231
- wpmc_reset_issues();
232
- delete_transient( 'wpmc_posts_with_shortcode' );
233
- wpmc_get_galleries_images( true );
234
- }
235
-
236
- if ( $method == 'files' ) {
237
- $files = wpmc_list_uploaded_files( $path ? ( trailingslashit( $upload_folder['basedir'] ) . $path ) : $upload_folder['basedir'] );
238
- echo json_encode(
239
- array(
240
- 'results' => $files, 'success' => true, 'message' => __( "Files retrieved.", 'media-cleaner' )
241
- )
242
- );
243
- die();
244
- }
245
-
246
- if ( $method == 'media' ) {
247
- // Prevent double scanning by removing filesystem entries that we have DB entries for
248
- $results = $wpdb->get_col( $wpdb->prepare( "SELECT p.ID FROM $wpdb->posts p
249
- WHERE p.post_status = 'inherit'
250
- AND p.post_type = 'attachment'
251
- LIMIT %d, %d", $limit, $limitsize
252
- )
253
- );
254
- $finished = count( $results ) < $limitsize;
255
- echo json_encode(
256
- array(
257
- 'results' => $results,
258
- 'success' => true,
259
- 'finished' => $finished,
260
- 'limit' => $limit + $limitsize,
261
- 'message' => __( "Medias retrieved.", 'media-cleaner' ) )
262
- );
263
- die();
264
- }
265
-
266
- // No task.
267
- echo json_encode( array( 'success' => false, 'message' => __( "No task.", 'media-cleaner' ) ) );
268
- die();
269
- }
270
-
271
- /**
272
- *
273
- * HELPERS
274
- *
275
- */
276
-
277
- function wpmc_trashdir() {
278
- $upload_folder = wp_upload_dir();
279
- return trailingslashit( $upload_folder['basedir'] ) . 'wpmc-trash';
280
- }
281
-
282
- /**
283
- *
284
- * DELETE / SCANNING / RESET
285
- *
286
- */
287
-
288
- function wpmc_recover_file( $path ) {
289
- $basedir = wp_upload_dir();
290
- $originalPath = trailingslashit( $basedir['basedir'] ) . $path;
291
- $trashPath = trailingslashit( wpmc_trashdir() ) . $path;
292
- $path_parts = pathinfo( $originalPath );
293
- if ( !file_exists( $path_parts['dirname'] ) && !wp_mkdir_p( $path_parts['dirname'] ) ) {
294
- die( 'Failed to create folder.' );
295
- }
296
- if ( !file_exists( $trashPath ) ) {
297
- global $wpmc_debug;
298
- if ( $wpmc_debug )
299
- error_log( "The file $originalPath actually does not exist in the trash." );
300
- return true;
301
- }
302
- if ( !rename( $trashPath, $originalPath ) ) {
303
- die( 'Failed to move the file.' );
304
- }
305
- return true;
306
- }
307
-
308
- function wpmc_recover( $id ) {
309
- global $wpdb;
310
- $table_name = $wpdb->prefix . "wpmcleaner";
311
- $issue = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $id ), OBJECT );
312
- $issue->path = stripslashes( $issue->path );
313
-
314
- // Files
315
- if ( $issue->type == 0 ) {
316
- wpmc_recover_file( $issue->path );
317
- $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 0 WHERE id = %d", $id ) );
318
- return true;
319
- }
320
- // Media
321
- else if ( $issue->type == 1 ) {
322
-
323
- // Copy the main file back
324
- $fullpath = get_attached_file( $issue->postId );
325
- $mainfile = wpmc_clean_uploaded_filename( $fullpath );
326
- $baseUp = pathinfo( $mainfile );
327
- $baseUp = $baseUp['dirname'];
328
- $file = wpmc_clean_uploaded_filename( $fullpath );
329
- if ( !wpmc_recover_file( $file ) )
330
- error_log( "Could not recover $file." );
331
-
332
- // If images, copy the other files as well
333
- $meta = wp_get_attachment_metadata( $issue->postId );
334
- $isImage = isset( $meta, $meta['width'], $meta['height'] );
335
- $sizes = wpmc_get_image_sizes();
336
- if ( $isImage && isset( $meta['sizes'] ) ) {
337
- foreach ( $meta['sizes'] as $name => $attr ) {
338
- if ( isset( $attr['file'] ) ) {
339
- $filepath = wp_upload_dir();
340
- $filepath = $filepath['basedir'];
341
- $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
342
- $file = wpmc_clean_uploaded_filename( $filepath );
343
- if ( !wpmc_recover_file( $file ) )
344
- error_log( "Could not recover $file." );
345
- }
346
- }
347
- }
348
- if ( !wp_untrash_post( $issue->postId ) )
349
- die( "Failed to untrash Media {$issue->postId}." );
350
- $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 0 WHERE id = %d", $id ) );
351
- return true;
352
- }
353
- }
354
-
355
- function wpmc_trash_file( $fileIssuePath ) {
356
- global $wpdb;
357
- $basedir = wp_upload_dir();
358
- $originalPath = trailingslashit( $basedir['basedir'] ) . $fileIssuePath;
359
- $trashPath = trailingslashit( wpmc_trashdir() ) . $fileIssuePath;
360
- $path_parts = pathinfo( $trashPath );
361
-
362
- try {
363
- if ( !file_exists( $path_parts['dirname'] ) && !wp_mkdir_p( $path_parts['dirname'] ) ) {
364
- return false;
365
- }
366
- // Rename the file (move). 'is_dir' is just there for security (no way we should move a whole directory)
367
- if ( is_dir( $originalPath ) ) {
368
- error_log( "Attempted to delete a directory instead of a file ($originalPath). Can't do that." );
369
- return false;
370
- }
371
- if ( !file_exists( $originalPath ) ) {
372
- global $wpmc_debug;
373
- if ( $wpmc_debug )
374
- error_log( "The file $originalPath actually does not exist." );
375
- return true;
376
- }
377
- if ( !rename( $originalPath, $trashPath ) ) {
378
- return false;
379
- }
380
- }
381
- catch ( Exception $e ) {
382
- return false;
383
- }
384
- wpmc_clean_dir( dirname( $originalPath ) );
385
- return true;
386
- }
387
-
388
- function wpmc_ignore( $id ) {
389
- global $wpdb;
390
- $table_name = $wpdb->prefix . "wpmcleaner";
391
- $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET ignored = 1 WHERE id = %d", $id ) );
392
- return true;
393
- }
394
-
395
- function wpmc_endsWith( $haystack, $needle )
396
- {
397
- $length = strlen( $needle );
398
- if ( $length == 0 )
399
- return true;
400
- return ( substr( $haystack, -$length ) === $needle );
401
- }
402
-
403
- function wpmc_clean_dir( $dir ) {
404
- if ( !file_exists( $dir ) )
405
- return;
406
- else if ( wpmc_endsWith( $dir, 'uploads' ) )
407
- return;
408
- $found = array_diff( scandir( $dir ), array( '.', '..' ) );
409
- if ( count( $found ) < 1 ) {
410
- if ( rmdir( $dir ) ) {
411
- wpmc_clean_dir( dirname( $dir ) );
412
- }
413
- }
414
- }
415
-
416
- function wpmc_delete( $id ) {
417
- global $wpdb;
418
- $table_name = $wpdb->prefix . "wpmcleaner";
419
- $issue = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $id ), OBJECT );
420
- $regex = "^(.*)(\\s\\(\\+.*)$";
421
- $issue->path = preg_replace('/'.$regex.'/i', '$1', $issue->path); // remove " (+ 6 files)" from path
422
-
423
- // Make sure there isn't a media DB entry
424
- if ( $issue->type == 0 ) {
425
- $attachmentid = wpmc_find_attachment_id_by_file( $issue->path );
426
- if ( $attachmentid ) {
427
- error_log( "File Cleaner: Issue listed as filesystem but Media {$attachmentid} exists." );
428
- }
429
- }
430
-
431
- if ( $issue->type == 0 ) {
432
-
433
- if ( $issue->deleted == 0 ) {
434
- // Move file to the trash
435
- if ( wpmc_trash_file( $issue->path ) )
436
- $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 1 WHERE id = %d", $id ) );
437
- return true;
438
- }
439
- else {
440
- // Delete file from the trash
441
- $trashPath = trailingslashit( wpmc_trashdir() ) . $issue->path;
442
- if ( !unlink( $trashPath ) )
443
- error_log( 'Failed to delete the file.' );
444
- $wpdb->query( $wpdb->prepare( "DELETE FROM $table_name WHERE id = %d", $id ) );
445
- wpmc_clean_dir( dirname( $trashPath ) );
446
- return true;
447
- }
448
- }
449
-
450
- if ( $issue->type == 1 ) {
451
- if ( $issue->deleted == 0 && MEDIA_TRASH ) {
452
- // Move Media to trash
453
- // Let's copy the images to the trash so that it can be recovered.
454
- $fullpath = get_attached_file( $issue->postId );
455
- $mainfile = wpmc_clean_uploaded_filename( $fullpath );
456
- $baseUp = pathinfo( $mainfile );
457
- $baseUp = $baseUp['dirname'];
458
- $file = wpmc_clean_uploaded_filename( $fullpath );
459
- if ( !wpmc_trash_file( $file ) )
460
- error_log( "Could not trash $file." );
461
-
462
- // If images, check the other files as well
463
- $meta = wp_get_attachment_metadata( $issue->postId );
464
- $isImage = isset( $meta, $meta['width'], $meta['height'] );
465
- $sizes = wpmc_get_image_sizes();
466
- if ( $isImage && isset( $meta['sizes'] ) ) {
467
- foreach ( $meta['sizes'] as $name => $attr ) {
468
- if ( isset( $attr['file'] ) ) {
469
- $filepath = wp_upload_dir();
470
- $filepath = $filepath['basedir'];
471
- $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
472
- $file = wpmc_clean_uploaded_filename( $filepath );
473
- if ( !wpmc_trash_file( $file ) )
474
- error_log( "Could not trash $file." );
475
- }
476
- }
477
- }
478
- wp_delete_attachment( $issue->postId, false );
479
- $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET deleted = 1 WHERE id = %d", $id ) );
480
- return true;
481
- }
482
- else {
483
- // Trash Media definitely by recovering it (to be like a normal Media) and remove it through the
484
- // standard WordPress workflow
485
- if ( MEDIA_TRASH )
486
- wpmc_recover( $id );
487
- wp_delete_attachment( $issue->postId, true );
488
- $wpdb->query( $wpdb->prepare( "DELETE FROM $table_name WHERE id = %d", $id ) );
489
- return true;
490
- }
491
- }
492
- return false;
493
- }
494
-
495
- /**
496
- *
497
- * SCANNING / RESET
498
- *
499
- */
500
-
501
- function wpmc_check_is_ignore( $file ) {
502
- global $wpdb, $wpmc_debug;
503
- $table_name = $wpdb->prefix . "wpmcleaner";
504
- $count = $wpdb->get_var( "SELECT COUNT(*)
505
- FROM $table_name
506
- WHERE deleted = 0
507
- AND path LIKE '%". esc_sql( $wpdb->esc_like( $file ) ) . "%'" );
508
- if ( $wpmc_debug && $count > 0 )
509
- error_log("{$file} found in IGNORE");
510
- return ($count > 0);
511
- }
512
-
513
-
514
-
515
- function wpmc_find_attachment_id_by_file ($file) {
516
- global $wpdb, $wpmc_debug;
517
- $postmeta_table_name = $wpdb->prefix . 'postmeta';
518
- $file = wpmc_clean_uploaded_filename( $file );
519
- $sql = $wpdb->prepare( "SELECT post_id
520
- FROM {$postmeta_table_name}
521
- WHERE meta_key = '_wp_attached_file'
522
- AND meta_value = %s", $file
523
- );
524
- $ret = $wpdb->get_var( $sql );
525
- if ( $wpmc_debug && empty( $ret ) )
526
- error_log( "File $file not found as _wp_attached_file (Library)." );
527
- else if ( $wpmc_debug ) {
528
- error_log( "File $file found as Media $ret." );
529
- }
530
- return $ret;
531
- }
532
-
533
- function wpmc_get_image_sizes() {
534
- $sizes = array();
535
- global $_wp_additional_image_sizes;
536
- foreach ( get_intermediate_image_sizes() as $s ) {
537
- $crop = false;
538
- if ( isset( $_wp_additional_image_sizes[$s] ) ) {
539
- $width = intval( $_wp_additional_image_sizes[$s]['width'] );
540
- $height = intval( $_wp_additional_image_sizes[$s]['height'] );
541
- $crop = $_wp_additional_image_sizes[$s]['crop'];
542
- } else {
543
- $width = get_option( $s.'_size_w' );
544
- $height = get_option( $s.'_size_h' );
545
- $crop = get_option( $s.'_crop' );
546
- }
547
- $sizes[$s] = array( 'width' => $width, 'height' => $height, 'crop' => $crop );
548
- }
549
- return $sizes;
550
- }
551
-
552
-
553
- // From a fullpath to the shortened and cleaned path (for example '2013/02/file.png')
554
- function wpmc_clean_uploaded_filename( $fullpath ) {
555
- $upload_folder = wp_upload_dir();
556
- $basedir = $upload_folder['basedir'];
557
- $file = str_replace( $basedir, '', $fullpath );
558
- $file = trim( $file, "/" );
559
- return $file;
560
- }
561
-
562
- function wpmc_check_media( $attachmentId ) {
563
-
564
- // Is it an image?
565
- $meta = wp_get_attachment_metadata( $attachmentId );
566
- $isImage = isset( $meta, $meta['width'], $meta['height'] );
567
-
568
- // Get the main file
569
- global $wpdb, $wpmc_debug;
570
- $fullpath = get_attached_file( $attachmentId );
571
- $mainfile = wpmc_clean_uploaded_filename( $fullpath );
572
- $baseUp = pathinfo( $mainfile );
573
- $baseUp = $baseUp['dirname'];
574
- $size = 0;
575
- $countfiles = 0;
576
- $issue = 'NO_CONTENT';
577
- if ( file_exists( $fullpath ) ) {
578
- $size = filesize( $fullpath );
579
-
580
- if ( wpmc_check_is_ignore( $mainfile )
581
- || wpmc_check_db_has_background_or_header( $mainfile )
582
- || wpmc_check_db_has_content( $mainfile, $attachmentId )
583
- || wpmc_check_in_gallery( $mainfile )
584
- || wpmc_check_db_has_meta( $mainfile, $attachmentId ) )
585
- return true;
586
-
587
- // If images, check the other files as well
588
- $countfiles = 0;
589
- $sizes = wpmc_get_image_sizes();
590
- if ( $isImage && isset( $meta['sizes'] ) ) {
591
- foreach ( $meta['sizes'] as $name => $attr ) {
592
- if ( isset( $attr['file'] ) ) {
593
- $filepath = wp_upload_dir();
594
- $filepath = $filepath['basedir'];
595
- $filepath = trailingslashit( $filepath ) . trailingslashit( $baseUp ) . $attr['file'];
596
- if ( file_exists( $filepath ) ) {
597
- $size += filesize( $filepath );
598
- }
599
- $file = wpmc_clean_uploaded_filename( $attr['file'] );
600
- $countfiles++;
601
- if ($wpmc_debug) error_log("checking MEDIA-IMAGE {$filepath}");
602
- if ( wpmc_check_in_gallery( $filepath )
603
- || wpmc_check_db_has_background_or_header( $filepath )
604
- || wpmc_check_db_has_meta( $filepath, $attachmentId ) )
605
- return true;
606
- }
607
- }
608
- }
609
- } else {
610
- $issue = 'ORPHAN_MEDIA';
611
- }
612
-
613
- $table_name = $wpdb->prefix . "wpmcleaner";
614
- $wpdb->insert( $table_name,
615
- array(
616
- 'time' => current_time('mysql'),
617
- 'type' => 1,
618
- 'size' => $size,
619
- 'path' => $mainfile . ( $countfiles > 0 ? ( " (+ " . $countfiles . " files)" ) : "" ),
620
- 'postId' => $attachmentId,
621
- 'issue' => $issue
622
- )
623
- );
624
- return false;
625
- }
626
-
627
- // Delete all issues
628
- function wpmc_reset_issues( $includingIgnored = false ) {
629
- global $wpdb;
630
- $table_name = $wpdb->prefix . "wpmcleaner";
631
- if ( $includingIgnored ) {
632
- $wpdb->query( "DELETE FROM $table_name WHERE deleted = 0" );
633
- }
634
- else {
635
- $wpdb->query( "DELETE FROM $table_name WHERE ignored = 0 AND deleted = 0" );
636
- }
637
- }
638
-
639
- /**
640
- *
641
- * DASHBOARD
642
- *
643
- */
644
-
645
- function wpmc_admin_inline_js() {
646
- global $wpmc_admin;
647
- echo "<script type='text/javascript'>\n";
648
- echo 'var wpmc_cfg = { isPro: ' . ( $wpmc_admin->is_registered() ? '1' : '0') . ', scanFiles: ' . ( ( get_option( 'wpmc_method', 'media' ) == 'files' && $wpmc_admin->is_registered() ) ? '1' : '0' ) . ', scanMedia: ' . ( get_option( 'wpmc_method', 'media' ) == 'media' ? '1' : '0' ) . ' };';
649
- echo "\n</script>";
650
- }
651
-
652
- function echo_issue( $issue ) {
653
- if ( $issue == 'NO_CONTENT' ) {
654
- _e( "Seems not in use.", 'media-cleaner' );
655
- }
656
- else if ( $issue == 'NO_MEDIA' ) {
657
- _e( "Not in Media Library.", 'media-cleaner' );
658
- }
659
- else if ( $issue == 'ORPHAN_RETINA' ) {
660
- _e( "Orphan retina.", 'media-cleaner' );
661
- }
662
- else if ( $issue == 'ORPHAN_MEDIA' ) {
663
- _e( "File not found.", 'media-cleaner' );
664
- }
665
- else {
666
- echo $issue;
667
- }
668
- }
669
-
670
- function wpmc_media_row_actions( $actions, $post ) {
671
- global $current_screen;
672
- if ( 'upload' != $current_screen->id )
673
- return $actions;
674
- global $wpdb;
675
- $table_name = $wpdb->prefix . "wpmcleaner";
676
- $res = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE postId = %d", $post->ID ) );
677
- if ( !empty( $res ) && isset( $actions['delete'] ) )
678
- $actions['delete'] = "<a href='?page=media-cleaner&view=deleted'>Delete with Media Cleaner</a>";
679
- if ( !empty( $res ) && isset( $actions['trash'] ) )
680
- $actions['trash'] = "<a href='?page=media-cleaner'>Trash with Media Cleaner</a>";
681
- if ( !empty( $res ) && isset( $actions['untrash'] ) ) {
682
- $actions['untrash'] = "<a href='?page=media-cleaner&view=deleted'>Restore with Media Cleaner</a>";
683
- }
684
- return $actions;
685
- }
686
-
687
- function wpmc_screen() {
688
- global $wpmc_admin;
689
- global $wplr;
690
- ?>
691
- <div class='wrap'>
692
-
693
- <?php
694
- echo $wpmc_admin->display_title( "Media Cleaner" );
695
- global $wpdb;
696
- $posts_per_page = get_user_meta( get_current_user_id(), 'upload_per_page', true );
697
- if ( empty( $posts_per_page ) )
698
- $posts_per_page = 20;
699
- $view = isset ( $_GET[ 'view' ] ) ? sanitize_text_field( $_GET[ 'view' ] ) : "issues";
700
- $paged = isset ( $_GET[ 'paged' ] ) ? sanitize_text_field( $_GET[ 'paged' ] ) : 1;
701
- $reset = isset ( $_GET[ 'reset' ] ) ? $_GET[ 'reset' ] : 0;
702
- if ( $reset ) {
703
- wpmc_reset();
704
- }
705
- $s = isset ( $_GET[ 's' ] ) ? sanitize_text_field( $_GET[ 's' ] ) : null;
706
- $table_name = $wpdb->prefix . "wpmcleaner";
707
- $issues_count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name WHERE ignored = 0 AND deleted = 0" );
708
- $total_size = $wpdb->get_var( "SELECT SUM(size) FROM $table_name WHERE ignored = 0 AND deleted = 0" );
709
- $trash_total_size = $wpdb->get_var( "SELECT SUM(size) FROM $table_name WHERE ignored = 0 AND deleted = 1" );
710
- $ignored_count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name WHERE ignored = 1" );
711
- $deleted_count = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name WHERE deleted = 1" );
712
-
713
- if ( $view == 'deleted' ) {
714
- $items_count = $deleted_count;
715
- $items = $wpdb->get_results( $wpdb->prepare( "SELECT id, type, postId, path, size, ignored, deleted, issue
716
- FROM $table_name WHERE ignored = 0 AND deleted = 1 AND path LIKE %s
717
- ORDER BY time
718
- DESC LIMIT %d, %d", '%' . $s . '%', ( $paged - 1 ) * $posts_per_page, $posts_per_page ), OBJECT );
719
- }
720
- else if ( $view == 'ignored' ) {
721
- $items_count = $ignored_count;
722
- $items = $wpdb->get_results( $wpdb->prepare( "SELECT id, type, postId, path, size, ignored, deleted, issue
723
- FROM $table_name
724
- WHERE ignored = 1 AND deleted = 0 AND path LIKE %s
725
- ORDER BY time
726
- DESC LIMIT %d, %d", '%' . $s . '%', ( $paged - 1 ) * $posts_per_page, $posts_per_page ), OBJECT );
727
- }
728
- else {
729
- $items_count = $issues_count;
730
- $items = $wpdb->get_results( $wpdb->prepare( "SELECT id, type, postId, path, size, ignored, deleted, issue
731
- FROM $table_name
732
- WHERE ignored = 0 AND deleted = 0 AND path LIKE %s
733
- ORDER BY time
734
- DESC LIMIT %d, %d", '%' . $s . '%', ( $paged - 1 ) * $posts_per_page, $posts_per_page ), OBJECT );
735
- }
736
- ?>
737
-
738
- <style>
739
- #wpmc-pages {
740
- float: right;
741
- position: relative;
742
- top: 12px;
743
- }
744
-
745
- #wpmc-pages a {
746
- text-decoration: none;
747
- border: 1px solid black;
748
- padding: 2px 5px;
749
- border-radius: 4px;
750
- background: #E9E9E9;
751
- color: lightslategrey;
752
- border-color: #BEBEBE;
753
- }
754
-
755
- #wpmc-pages .current {
756
- font-weight: bold;
757
- }
758
- </style>
759
-
760
- <div style='margin-top: 0px; background: #FFF; padding: 5px; border-radius: 4px; height: 28px; box-shadow: 0px 0px 6px #C2C2C2;'>
761
-
762
- <!-- SCAN -->
763
- <?php if ( $view != 'deleted' ) { ?>
764
- <a id='wpmc_scan' onclick='wpmc_scan()' class='button-primary' style='float: left;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-search"></span><?php _e("Scan", 'media-cleaner'); ?></a>
765
- <?php } ?>
766
-
767
- <!-- DELETE SELECTED -->
768
- <a id='wpmc_delete' onclick='wpmc_delete()' class='button' style='float: left; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-no"></span><?php _e("Delete", 'media-cleaner'); ?></a>
769
- <?php if ( $view == 'deleted' ) { ?>
770
- <a id='wpmc_recover' onclick='wpmc_recover()' class='button-secondary' style='float: left; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-repeat"></span><?php _e( "Recover", 'media-cleaner' ); ?></a>
771
- <?php } ?>
772
-
773
- <!-- IGNORE SELECTED -->
774
- <a id='wpmc_ignore' onclick='wpmc_ignore()' class='button' style='float: left; margin-left: 5px;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-yes"></span><?php _e("Ignore", 'media-cleaner'); ?></a>
775
-
776
- <!-- RESET -->
777
- <?php if ( $view != 'deleted' ) { ?>
778
- <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>
779
- <?php } ?>
780
-
781
- <!-- DELETE ALL -->
782
- <?php if ( $view == 'deleted' ) { ?>
783
- <a id='wpmc_recover_all' onclick='wpmc_recover_all()' class='button-primary' 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>
784
- <a id='wpmc_delete_all' onclick='wpmc_delete_all(true)' class='button button-red' 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>
785
- <?php } else { ?>
786
- <a id='wpmc_delete_all' onclick='wpmc_delete_all()' class='button button-red' 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>
787
- <?php } ?>
788
-
789
- <form id="posts-filter" action="upload.php" method="get" style='float: right;'>
790
- <p class="search-box" style='margin-left: 5px; float: left;'>
791
- <input type="search" name="s" style="width: 120px;" value="<?php echo $s ? $s : ""; ?>">
792
- <input type="hidden" name="page" value="media-cleaner">
793
- <input type="hidden" name="view" value="<?php echo $view; ?>">
794
- <input type="hidden" name="paged" value="<?php echo $paged; ?>">
795
- <input type="submit" class="button" value="<?php _e( 'Search', 'media-cleaner' ) ?>"><span style='border-right: #A2A2A2 solid 1px; margin-left: 5px; margin-right: 3px;'>&nbsp;</span>
796
- </p>
797
- </form>
798
-
799
- <!-- PROGRESS -->
800
- <span style='margin-left: 12px; font-size: 15px; top: 5px; position: relative; color: #747474;' id='wpmc_progression'></span>
801
-
802
- </div>
803
-
804
- <p>
805
- <?php
806
- $method = get_option( 'wpmc_method', 'media' );
807
- if ( !$wpmc_admin->is_registered() )
808
- $method = 'media';
809
-
810
- $hide_warning = get_option( 'wpmc_hide_warning', false );
811
-
812
- if ( !$hide_warning ) {
813
- _e( "<div class='notice notice-error'><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> <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' );
814
- }
815
-
816
- if ( !MEDIA_TRASH ) {
817
- _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:<br /><b>define( 'MEDIA_TRASH', true );</b></p></div>" );
818
- }
819
-
820
- if ( !$wpmc_admin->is_registered() ) {
821
- echo "<div class='notice notice-info'><p>";
822
- _e( "<b>This version is not Pro.</b> This plugin is a lot of work so please consider in getting the Pro version in order to receive support and to help the plugin to evolve. Also, the Pro version will also give you the option <b>to scan the <u>physical files</u> in your /uploads folder</b>. You can <a target='_blank' href='http://meowapps.com/media-cleaner'>get a serial for the Pro version here</a></b>.", 'media-cleaner' );
823
- echo "</p></div>";
824
- }
825
-
826
- $anychecks = get_option(' wpmc_posts', false ) || get_option(' wpmc_galleries', false ) || get_option(' wpmc_postmeta', false );
827
- $check_library = get_option(' wpmc_media_library', false );
828
-
829
- if ( $method == 'media' ) {
830
- if ( !$anychecks )
831
- _e( "<div class='error'><p>Media Cleaner will analyze your Media Library. There is however <b>nothing marked to be check</b> in the Settings.</p></div>", 'media-cleaner' );
832
- else
833
- _e( "<div class='notice notice-success'><p>Media Cleaner will analyze your Media Library.</p></div>", 'media-cleaner' );
834
- }
835
- else if ( $method == 'files' ) {
836
- if ( !$anychecks && !$check_library )
837
- _e( "<div class='error'><p>Media Cleaner will analyze your Filesystem. There is however <b>nothing marked to be check</b> in the Settings.</p></div>", 'media-cleaner' );
838
- else
839
- _e( "<div class='notice notice-success'><p>Media Cleaner will analyze your Filesystem.</p></div>", 'media-cleaner' );
840
- }
841
-
842
- 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 ) );
843
- ?>
844
- </p>
845
-
846
- <div id='wpmc-pages'>
847
- <?php
848
- echo paginate_links(array(
849
- 'base' => '?page=media-cleaner&s=' . urlencode($s) . '&view=' . $view . '%_%',
850
- 'current' => $paged,
851
- 'format' => '&paged=%#%',
852
- 'total' => ceil( $items_count / $posts_per_page ),
853
- 'prev_next' => false
854
- ));
855
- ?>
856
- </div>
857
-
858
- <ul class="subsubsub">
859
- <li class="all"><a <?php if ( $view == 'issues' ) echo "class='current'"; ?> href='?page=media-cleaner&s=<?php echo $s; ?>&view=issues'><?php _e( "Issues", 'media-cleaner' ); ?></a><span class="count">(<?php echo $issues_count; ?>)</span></li> |
860
- <li class="all"><a <?php if ( $view == 'ignored' ) echo "class='current'"; ?> href='?page=media-cleaner&s=<?php echo $s; ?>&view=ignored'><?php _e( "Ignored", 'media-cleaner' ); ?></a><span class="count">(<?php echo $ignored_count; ?>)</span></li> |
861
- <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>
862
- </ul>
863
-
864
- <table id='wpmc-table' class='wp-list-table widefat fixed media'>
865
-
866
- <thead>
867
- <tr>
868
- <th scope="col" id="cb" class="manage-column column-cb check-column"><input id="wpmc-cb-select-all" type="checkbox"></th>
869
- <?php if ( !get_option( 'wpmc_hide_thumbnails', false ) ): ?>
870
- <th style='width: 64px;'><?php _e( 'Thumb', 'media-cleaner' ) ?></th>
871
- <?php endif; ?>
872
- <th style='width: 50px;'><?php _e( 'Type', 'media-cleaner' ) ?></th>
873
- <th style='width: 80px;'><?php _e( 'Origin', 'media-cleaner' ) ?></th>
874
-
875
- <?php if ( !empty( $wplr ) ): ?>
876
- <th style='width: 70px;'><?php _e( 'LR ID', 'media-cleaner' ) ?></th>
877
- <?php endif; ?>
878
-
879
- <th><?php _e( 'Path', 'media-cleaner' ) ?></th>
880
- <th style='width: 220px;'><?php _e( 'Issue', 'media-cleaner' ) ?></th>
881
- <th style='width: 80px; text-align: right;'><?php _e( 'Size', 'media-cleaner' ) ?></th>
882
- </tr>
883
- </thead>
884
-
885
- <tbody>
886
- <?php
887
- foreach ( $items as $issue ) {
888
- $regex = "^(.*)(\\s\\(\\+.*)$";
889
- $issue->path = preg_replace( '/' .$regex . '/i', '$1', $issue->path );
890
- ?>
891
- <tr>
892
- <td><input type="checkbox" name="id" value="<?php echo $issue->id ?>"></td>
893
- <?php if ( !get_option( 'wpmc_hide_thumbnails', false ) ): ?>
894
- <td>
895
- <?php
896
- if ( $issue->deleted == 0 ) {
897
- if ( $issue ->type == 0 ) {
898
- // FILE
899
- $upload_dir = wp_upload_dir();
900
- $url = htmlspecialchars( $upload_dir['baseurl'] . '/' . $issue->path, ENT_QUOTES );
901
- echo "<a target='_blank' href='" . $url .
902
- "'><img style='max-width: 48px; max-height: 48px;' src='" . $url . "' /></a>";
903
- }
904
- else {
905
- // MEDIA
906
- $attachmentsrc = wp_get_attachment_image_src( $issue->postId, 'thumbnail' );
907
- $attachmentsrc_clean = htmlspecialchars( $attachmentsrc[0], ENT_QUOTES );
908
- echo "<a target='_blank' href='" . $attachmentsrc_clean .
909
- "'><img style='max-width: 48px; max-height: 48px;' src='" .
910
- $attachmentsrc_clean . "' />";
911
- }
912
- }
913
- if ( $issue->deleted == 1 ) {
914
- $upload_dir = wp_upload_dir();
915
- $url = htmlspecialchars( $upload_dir['baseurl'] . '/wpmc-trash/' . $issue->path, ENT_QUOTES );
916
- echo "<a target='_blank' href='" . $url .
917
- "'><img style='max-width: 48px; max-height: 48px;' src='" . $url . "' /></a>";
918
- }
919
- ?>
920
- </td>
921
- <?php endif; ?>
922
- <td><?php echo $issue->type == 0 ? 'FILE' : 'MEDIA'; ?></td>
923
- <td><?php echo $issue->type == 0 ? 'Filesystem' : ("<a href='post.php?post=" .
924
- $issue->postId . "&action=edit'>ID " . $issue->postId . "</a>"); ?></td>
925
- <?php if ( !empty( $wplr ) ) { $info = $wplr->get_sync_info( $issue->postId ); ?>
926
- <td style='width: 70px;'><?php echo ( !empty( $info ) && $info->lr_id ? $info->lr_id : "" ); ?></td>
927
- <?php } ?>
928
- <td><?php echo stripslashes( $issue->path ); ?></td>
929
- <td><?php echo_issue( $issue->issue ); ?></td>
930
- <td style='text-align: right;'><?php echo number_format( $issue->size / 1000, 2 ); ?> KB</td>
931
- </tr>
932
- <?php } ?>
933
- </tbody>
934
-
935
- <tfoot>
936
- <tr><th></th>
937
- <?php if ( !get_option( 'hide_thumbnails', false ) ): ?>
938
- <th></th>
939
- <?php endif; ?>
940
- <th><?php _e( 'Type', 'media-cleaner' ) ?></th><th><?php _e( 'Origin', 'media-cleaner' ) ?></th><th><?php _e( 'Path', 'media-cleaner' ) ?></th><th><?php _e( 'Issue', 'media-cleaner' ) ?></th><th style='width: 80px; text-align: right;'><?php _e( 'Size', 'media-cleaner' ) ?></th></tr>
941
- </tfoot>
942
-
943
- </table>
944
- </wrap>
945
-
946
- <?php
947
- }
948
-
949
- /**
950
- *
951
- * PLUGIN INSTALL / UNINSTALL / SCRIPTS
952
- *
953
- */
954
-
955
- function wpmc_check_db() {
956
- global $wpdb;
957
- $tbl_m = $wpdb->prefix . 'wpmcleaner';
958
- if ( !$wpdb->get_var( $wpdb->prepare( "SELECT COUNT(1) FROM information_schema.tables WHERE table_schema = '%s' AND table_name = '%s';", $wpdb->dbname, $tbl_m ) ) ) {
959
- wpmc_activate();
960
- }
961
- }
962
-
963
- function wpmc_admin_menu() {
964
- load_plugin_textdomain( 'media-cleaner', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
965
- add_media_page( 'Media Cleaner', 'Cleaner', 'manage_options', 'media-cleaner', 'wpmc_screen' );
966
- }
967
-
968
- function wpmc_reset () {
969
- wpmc_uninstall();
970
- wpmc_activate();
971
- }
972
-
973
- function wpmc_activate () {
974
- global $wpdb;
975
- $table_name = $wpdb->prefix . "wpmcleaner";
976
- $charset_collate = $wpdb->get_charset_collate();
977
- $sql = "CREATE TABLE $table_name (
978
- id BIGINT(20) NOT NULL AUTO_INCREMENT,
979
- time DATETIME DEFAULT '0000-00-00 00:00:00' NOT NULL,
980
- type TINYINT(1) NOT NULL,
981
- postId BIGINT(20) NULL,
982
- path TINYTEXT NULL,
983
- size INT(9) NULL,
984
- ignored TINYINT(1) NOT NULL DEFAULT 0,
985
- deleted TINYINT(1) NOT NULL DEFAULT 0,
986
- issue TINYTEXT NOT NULL,
987
- UNIQUE KEY id (id)
988
- ) " . $charset_collate . ";";
989
- require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
990
- dbDelta( $sql );
991
-
992
- $upload_folder = wp_upload_dir();
993
- $basedir = $upload_folder['basedir'];
994
- if ( !is_writable( $basedir ) ) {
995
- echo '<div class="error"><p>' . __( 'The directory for uploads is not writable. Media Cleaner will only be able to scan.', 'media-cleaner' ) . '</p></div>';
996
- }
997
- }
998
-
999
- function wpmc_uninstall () {
1000
- global $wpdb;
1001
- $table_name = $wpdb->prefix . "wpmcleaner";
1002
- $wpdb->query("DROP TABLE IF EXISTS $table_name");
1003
- }
1004
-
1005
- function wpmc_wp_enqueue_scripts () {
1006
- wp_enqueue_style( 'media-cleaner-css', plugins_url( '/media-cleaner.css', __FILE__ ) );
1007
- wp_enqueue_script( 'media-cleaner', plugins_url( '/media-cleaner.js', __FILE__ ), array( 'jquery' ), "3.7.0", true );
1008
- }
1009
-
1010
- /*******************************************************************************
1011
- * OLD PRO / TODO: THIS FUNCTION SHOULD BE REMOVED IN THE FUTURE
1012
- ******************************************************************************/
1013
-
1014
- function wpmc_admin_notices() {
1015
- if ( isset( $_POST['wpmc_reset_sub'] ) ) {
1016
- delete_transient( 'wpmc_validated' );
1017
- delete_option( 'wpmc_pro_serial' );
1018
- delete_option( 'wpmc_pro_status' );
1019
- }
1020
- $validated = get_transient( 'wpmc_validated' );
1021
- $subscr_id = get_option( 'wpmc_pro_serial', "" );
1022
- if ( empty( $subscr_id ) || empty( $validated ) )
1023
- return;
1024
- $forever = strpos( $subscr_id, 'F-' ) !== false;
1025
- $yearly = strpos( $subscr_id, 'I-' ) !== false;
1026
- ?>
1027
- <div class="error">
1028
- <p>
1029
- <b>IMPORTANT MESSAGE ABOUT MEDIA CLEANER.</b>
1030
- In order to comply with WordPress.org rules, changes in the code and how the plugin was sold had to be made. The plugin now requires to be bought through <a target='_blank' href="https://store.meowapps.com">https://store.meowapps.com</a>. You will be able to download the Pro version there (and it will be kept updated), manage your keys and websites. Only the free version can be hosted by WordPress.org, so this is the one you have now. To ease this upgrade, I made the price of my standard licenses cheaper.<br /><br />
1031
- Your license is <b><?php echo $subscr_id ?></b>.
1032
- <?php
1033
- if ( $forever ) {
1034
- echo "You have a Forever license. If you got this license less than 120 days ago, reply to the welcome e-mail (after buying a new license) with your previous license key ($subscr_id) and the e-mail you are using in Paypal. I will refund the previous payment. Otherwise, we are out of luck :( So here is a discount instead, of <b>90% off</b>, for any license you like: <b>UPGRADE90MEDIACLEANER</b>.";
1035
- }
1036
- else if ( $yearly ) {
1037
- echo "You have a Yearly license. If you got this license less than 120 days ago, reply to the welcome e-mail (after buying a new license) with your previous license key ($subscr_id) and the e-mail you are using in Paypal. I will refund the previous payment. If it is more than 120 days ago, we are out of luck :) So here is a discount of <b>50% off</b>, for any license you like: <b>UPGRADEMEDIACLEANER50</b>. Also, don't forget to cancel your current subscription in Paypal (<a target='_blank' href='https://www.paypal.com/us/selfhelp/article/How-do-I-cancel-an-automatic-payment-I-have-with-a-merchant-FAQ2058'>click here</a> if you don't know how to do this).";
1038
- }
1039
- else {
1040
- echo "Your license is special, so please contact me.";
1041
- }
1042
- ?>
1043
- If you absolutely need to use the plugin as it was before, with your current license key, please download it again here: <a target='_blank' href="https://meowapps.com/previous-versions/">Previous Versions</a>. I will keep the old system up for a while, but no updates will be possible, and better to enjoy the discount codes.
1044
- <br /><br />Also note that I also have now an <a target='_blank' href='https://store.meowapps.com/affiliate-area/'>Affiliate Program</a> in that store, don't hesitate to register for it. Thanks a lot for your comprehension and sorry for the troubles. Not easy for anyone but it had to be done and I think you will really enjoy the new store more than the previous clunky system.
1045
- </p>
1046
- <p>
1047
- <form method="post" action="">
1048
- <input type="hidden" name="wpmc_reset_sub" value="true">
1049
- <input type="submit" name="submit" id="submit" class="button" value="Got it. Understood!">
1050
- <br /><small>Make sure you got a new license and all before clicking this button. It will also clean your install from the old key data.</small>
1051
- </form>
1052
- </p>
1053
- </div>
1054
- <?php
1055
- }
1056
-
1057
- if ( file_exists( plugin_dir_path( __FILE__ ) . 'wpmc_checkers.php' ) ) {
1058
- require( 'wpmc_checkers.php' );
1059
- }
1060
-
1061
- if ( !$disable_meowapps && file_exists( plugin_dir_path( __FILE__ ) . '/meowapps/core.php' ) ) {
1062
- require( 'meowapps/core.php' );
1063
- new MeowApps_MediaCleaner_Core( __FILE__ );
1064
- }
3
  Plugin Name: Media Cleaner
4
  Plugin URI: http://meowapps.com
5
  Description: Clean your Media Library, many options, trash system.
6
+ Version: 3.8.0
7
  Author: Jordy Meow
8
  Author URI: http://meowapps.com
9
  Text Domain: media-cleaner
 
10
 
11
  Big thanks to Matt (http://www.twistedtek.net/) for all his
12
  contributions made to the plugin.
16
  - Haikyo (http://www.haikyo.org)
17
  */
18
 
19
+ if ( is_admin() ) {
 
 
 
 
 
 
 
 
 
 
 
20
 
21
+ global $wpmc_version;
22
+ $wpmc_version = '3.8.0';
 
23
 
24
+ // Admin
25
+ require( 'wpmc_admin.php' );
26
+ $wpmc_admin = new Meow_WPMC_Admin( 'wpmc', __FILE__, 'media-cleaner' );
27
 
28
+ // Core
29
+ require( 'core.php' );
30
+ new Meow_WPMC_Core( $wpmc_admin );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  }
32
 
33
+ ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
4
  Tags: management, admin, file, files, images, image, media, library, upload, clean, cleaning
5
  Requires at least: 4.2
6
  Tested up to: 4.7
7
- Stable tag: 3.7.0
8
 
9
  Clean your Media Library and Uploads directory. It has an internal trash and recovery features.
10
 
@@ -26,8 +26,6 @@ Clean your Media Library from the media which aren't used in any of your posts,
26
 
27
  It has been tested with WP Retina 2x and WPML.
28
 
29
- Languages: English, French.
30
-
31
  == Installation ==
32
 
33
  1. Upload `media-file-cleaner` to the `/wp-content/plugins/` directory
@@ -53,6 +51,9 @@ It re-creates the Media Cleaner table in the database. You will need to re-run t
53
 
54
  == Changelog ==
55
 
 
 
 
56
  = 3.7.0 =
57
  * Fix: Little issue when inserting the serial key for the first time.
58
  * Update: Compliance with the WordPress.org rules, new licensing system.
4
  Tags: management, admin, file, files, images, image, media, library, upload, clean, cleaning
5
  Requires at least: 4.2
6
  Tested up to: 4.7
7
+ Stable tag: 3.8.0
8
 
9
  Clean your Media Library and Uploads directory. It has an internal trash and recovery features.
10
 
26
 
27
  It has been tested with WP Retina 2x and WPML.
28
 
 
 
29
  == Installation ==
30
 
31
  1. Upload `media-file-cleaner` to the `/wp-content/plugins/` directory
51
 
52
  == Changelog ==
53
 
54
+ = 3.8.0 =
55
+ * Update: Core was re-organized and cleaned. Ready for nice updates.
56
+
57
  = 3.7.0 =
58
  * Fix: Little issue when inserting the serial key for the first time.
59
  * Update: Compliance with the WordPress.org rules, new licensing system.
wpmc_admin.php CHANGED
@@ -2,10 +2,10 @@
2
 
3
  include "common/admin.php";
4
 
5
- class Meow_MediaCleaner_Admin extends MeowApps_Admin {
6
 
7
- public function __construct() {
8
- parent::__construct( 'wpmc' );
9
  add_action( 'admin_menu', array( $this, 'app_menu' ) );
10
  add_action( 'admin_notices', array( $this, 'admin_notices' ) );
11
  $method = get_option( 'wpmc_method', 666 );
2
 
3
  include "common/admin.php";
4
 
5
+ class Meow_WPMC_Admin extends MeowApps_Admin {
6
 
7
+ public function __construct( $prefix, $mainfile, $domain ) {
8
+ parent::__construct( $prefix, $mainfile, $domain );
9
  add_action( 'admin_menu', array( $this, 'app_menu' ) );
10
  add_action( 'admin_notices', array( $this, 'admin_notices' ) );
11
  $method = get_option( 'wpmc_method', 666 );
wpmc_checkers.php CHANGED
@@ -3,206 +3,215 @@
3
  // This file will contains all the CORE checkers of the Media Cleaner system.
4
  // Each 'checker' checks the usage of the file by a certain feature of WordPress.
5
 
6
- function wpmc_check_db_has_background_or_header( $file ) {
7
- global $wpmc_debug;
8
- if ( current_theme_supports( 'custom-header' ) ) {
9
- $custom_header = get_custom_header();
10
- if ( $custom_header && $custom_header->url ) {
11
- if ( strpos( $custom_header->url, $file ) !== false )
12
- if ($wpmc_debug) error_log("{$file} found in header");
13
- return true;
14
- }
15
  }
16
 
17
- if ( current_theme_supports( 'custom-background' ) ) {
18
- $custom_background = get_theme_mod('background_image');
19
- if ( $custom_background ) {
20
- if ( strpos( $custom_background, $file ) !== false )
21
- if ($wpmc_debug) error_log("{$file} found in background");
22
- return true;
 
 
 
 
 
 
 
 
 
 
 
23
  }
 
 
24
  }
25
 
26
- return false;
27
- }
28
 
29
- function wpmc_check_in_gallery( $file ) {
 
30
 
31
- if ( !get_option( 'wpmc_galleries', false ) )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  return false;
33
-
34
- global $wpmc_debug;
35
- $file = wpmc_clean_uploaded_filename( $file );
36
- $uploads = wp_upload_dir();
37
- $parsedURL = parse_url( $uploads['baseurl'] );
38
- $regex_match_file = '(' . preg_quote( $file ) . ')';
39
- $regex = addcslashes( '(?:(?:http(?:s)?\\:)?//' .
40
- preg_quote( $parsedURL['host'] ).')?' .
41
- preg_quote( $parsedURL['path'] ) . '/' . $regex_match_file, '/');
42
- $images = wpmc_get_galleries_images();
43
- foreach ( $images as $image ) {
44
- $found = preg_match('/'.$regex.'/i', $image);
45
- if ( $wpmc_debug && $found )
46
- error_log("{$file} found in a galllery");
47
- if ( $found )
48
- return true;
49
  }
50
- return false;
51
- }
52
 
53
- function wpmc_check_db_has_meta( $file, $attachment_id = 0 ) {
54
 
55
- if ( !get_option( 'wpmc_postmeta', false ) )
56
- return false;
57
 
58
- global $wpdb, $wpmc_debug;
59
- $uploads = wp_upload_dir();
60
- $parsedURL = parse_url( $uploads['baseurl'] );
61
- $file = wpmc_clean_uploaded_filename( $file );
62
- $regex_match_file = '(' . preg_quote( $file ) . ')';
63
- $regex = addcslashes( '(?:(?:(?:http(?:s)?\\:)?//' .
64
- preg_quote( $parsedURL['host']) . ')?(?:' .
65
- preg_quote( $parsedURL['path']) . '/)|^)' . $regex_match_file, '/');
66
- $regex_mysql = str_replace( '(?:', '(', $regex );
67
- if ( $attachment_id > 0 ) {
68
- $mediaCount = $wpdb->get_var(
69
- $wpdb->prepare( "SELECT COUNT(*)
70
- FROM $wpdb->postmeta
71
- WHERE post_id != %d
72
- AND meta_key != '_wp_attached_file'
73
- AND (meta_value REGEXP %s OR meta_value = %d)",
74
- $attachment_id, $regex_mysql, $attachment_id
75
- )
76
- );
77
- } else {
78
- $mediaCount = $wpdb->get_var(
79
- $wpdb->prepare( "SELECT COUNT(*)
80
- FROM $wpdb->postmeta
81
- WHERE meta_key != '_wp_attached_file'
82
- AND meta_value REGEXP %s",
83
- $regex_mysql
84
- )
85
- );
 
 
 
 
86
  }
87
- if ( $wpmc_debug && $mediaCount > 0 )
88
- error_log("{$file} found in POSTMETA");
89
- return $mediaCount > 0;
90
- }
91
 
92
 
93
- function wpmc_check_db_has_content( $file, $mediaId = null ) {
94
 
95
- global $wpdb, $wpmc_debug;
96
- $shortcode_support = get_option( 'wpmc_shortcode', false );
97
 
98
- // Check in Posts Content
99
- if ( get_option( 'wpmc_posts', false ) ) {
100
- $file = wpmc_clean_uploaded_filename( $file );
101
- $uploads = wp_upload_dir();
102
- $parsedURL = parse_url( $uploads['baseurl'] );
103
- $pinfo = pathinfo( $file );
104
- $regex_match_file = '(' . $pinfo['dirname'] . '/' . $pinfo['filename'] . "(\\-[0-9]{1,8}x[0-9]{1,8})?\\." . $pinfo['extension'] . ')';
105
-
106
- // SUPER STRICT MODE
107
- // $regex = addcslashes('=[\'"](?:(?:http(?:s)?\\:)?//'
108
- // . preg_quote( $parsedURL['host'] ) . ')?'
109
- // . preg_quote( $parsedURL['path'] ) . '/'
110
- // . $regex_match_file . '(?:\\?[^\'"]*)*[\'"]', '/' );
111
-
112
- // NORMAL REGEX
113
- $regex = addcslashes( preg_quote( $parsedURL['path']) . '/' . $regex_match_file . '(?:\\?[^\'"]*)*[\'"]', '/' );
114
- $regex_mysql = str_replace('(?:', '(', $regex);
115
- $sql = $wpdb->prepare( "SELECT COUNT(*)
116
- FROM $wpdb->posts
117
- WHERE post_type <> 'revision'
118
- AND post_type <> 'attachment'
119
- AND post_content REGEXP %s", $regex_mysql );
120
- $mediaCount = $wpdb->get_var( $sql );
121
- if ( $wpmc_debug && $mediaCount > 0 )
122
- error_log( "File {$file} found in post_content, $mediaCount time(s)" );
123
- if ( $mediaCount > 0 )
124
- return true;
125
-
126
- if ( !empty( $mediaId ) ) {
127
  $sql = $wpdb->prepare( "SELECT COUNT(*)
128
  FROM $wpdb->posts
129
  WHERE post_type <> 'revision'
130
  AND post_type <> 'attachment'
131
- AND post_content LIKE %s", "%wp-image-$mediaId%" );
132
  $mediaCount = $wpdb->get_var( $sql );
133
- if ( $wpmc_debug && $mediaCount > 0 )
134
- error_log( "Media {$mediaId} found in post_content, $mediaCount time(s)" );
135
  if ( $mediaCount > 0 )
136
  return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  }
138
- }
139
 
140
- // Shortcode analysis
141
- global $shortcode_tags;
142
- $active_tags = array_keys( $shortcode_tags );
143
- if ( !empty( $active_tags ) ) {
144
- $post_contents = get_transient( 'wpmc_posts_with_shortcode' );
145
- if ( $post_contents === false ) {
146
-
147
- $post_contents = array();
148
-
149
- // Resolve shortcodes from posts
150
- if ( $shortcode_support ) {
151
- $query = array();
152
- $query[] = "SELECT ID, post_content FROM {$wpdb->posts}";
153
- $query[] = "WHERE post_type <> 'revision' AND post_type <> 'attachment'";
154
- $sub_query = array();
155
- foreach ( $active_tags as $tag ) {
156
- $sub_query[] = "post_content LIKE '%[" . esc_sql( $wpdb->esc_like( $tag ) ) . "%'";
157
- }
158
- $query[] = "AND (" . implode ( " OR ", $sub_query ) . ")";
159
- $sql = join( ' ', $query );
160
- $results = $wpdb->get_results( $sql );
161
- foreach ( $results as $key => $data ) {
162
- $post_contents['post_' . $data->ID] = do_shortcode( $data->post_content );
 
163
  }
164
- }
165
 
166
- // Read Widgets
167
- if ( get_option( 'wpmc_widgets', false ) ) {
168
- global $wp_registered_widgets;
169
- $active_widgets = get_option( 'sidebars_widgets' );
170
- foreach ( $active_widgets as $sidebar_name => $sidebar_widgets ) {
171
- if ( $sidebar_name != 'wp_inactive_widgets' && !empty( $sidebar_widgets ) && is_array( $sidebar_widgets ) ) {
172
- $i = 0;
173
- foreach ( $sidebar_widgets as $widget_instance ) {
174
- $widget_class = $wp_registered_widgets[$widget_instance]['callback'][0]->option_name;
175
- $instance_id = $wp_registered_widgets[$widget_instance]['params'][0]['number'];
176
- $widget_data = get_option($widget_class);
177
- if ( !empty( $widget_data[$instance_id]['text'] ) ) {
178
-
179
- // Resolve Widgets or just get them
180
- if ( $shortcode_support )
181
- $post_contents['widget_' . $i] = do_shortcode( $widget_data[$instance_id]['text'] );
182
- else
183
- $post_contents['widget_' . $i] = $widget_data[$instance_id]['text'];
 
 
184
  }
185
- $i++;
186
  }
187
  }
188
  }
189
- }
190
 
191
- if ( !empty( $post_contents ) )
192
- set_transient( 'wpmc_posts_with_shortcode', $post_contents, 2 * 60 * 60 );
193
- }
194
 
195
- if ( !empty( $post_contents ) ) {
196
- foreach ( $post_contents as $key => $content ) {
197
- $found = preg_match( '/' . $regex . '/i', $content );
198
- if ( $wpmc_debug && $found )
199
- error_log( "File Cleaner: {$file} found in {$key} shortcode or widget" );
200
- if ( $found )
201
- return true;
 
202
  }
203
  }
 
204
  }
205
- return false;
206
  }
207
 
208
  ?>
3
  // This file will contains all the CORE checkers of the Media Cleaner system.
4
  // Each 'checker' checks the usage of the file by a certain feature of WordPress.
5
 
6
+ class Meow_WPMC_Checkers {
7
+
8
+ private $core;
9
+
10
+ public function __construct( $core ) {
11
+ $this->core = $core;
 
 
 
12
  }
13
 
14
+ function wpmc_check_db_has_background_or_header( $file ) {
15
+ if ( current_theme_supports( 'custom-header' ) ) {
16
+ $custom_header = get_custom_header();
17
+ if ( $custom_header && $custom_header->url ) {
18
+ if ( strpos( $custom_header->url, $file ) !== false )
19
+ if ($this->core->debug) error_log("{$file} found in header");
20
+ return true;
21
+ }
22
+ }
23
+
24
+ if ( current_theme_supports( 'custom-background' ) ) {
25
+ $custom_background = get_theme_mod('background_image');
26
+ if ( $custom_background ) {
27
+ if ( strpos( $custom_background, $file ) !== false )
28
+ if ($this->core->debug) error_log("{$file} found in background");
29
+ return true;
30
+ }
31
  }
32
+
33
+ return false;
34
  }
35
 
36
+ function wpmc_check_in_gallery( $file ) {
 
37
 
38
+ if ( !get_option( 'wpmc_galleries', false ) )
39
+ return false;
40
 
41
+ $file = $this->core->wpmc_clean_uploaded_filename( $file );
42
+ $uploads = wp_upload_dir();
43
+ $parsedURL = parse_url( $uploads['baseurl'] );
44
+ $regex_match_file = '(' . preg_quote( $file ) . ')';
45
+ $regex = addcslashes( '(?:(?:http(?:s)?\\:)?//' .
46
+ preg_quote( $parsedURL['host'] ).')?' .
47
+ preg_quote( $parsedURL['path'] ) . '/' . $regex_match_file, '/');
48
+ $images = $this->core->wpmc_get_galleries_images();
49
+ foreach ( $images as $image ) {
50
+ $found = preg_match('/'.$regex.'/i', $image);
51
+ if ( $this->core->debug && $found )
52
+ error_log("{$file} found in a galllery");
53
+ if ( $found )
54
+ return true;
55
+ }
56
  return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  }
 
 
58
 
59
+ function wpmc_check_db_has_meta( $file, $attachment_id = 0 ) {
60
 
61
+ if ( !get_option( 'wpmc_postmeta', false ) )
62
+ return false;
63
 
64
+ global $wpdb;
65
+ $uploads = wp_upload_dir();
66
+ $parsedURL = parse_url( $uploads['baseurl'] );
67
+ $file = $this->core->wpmc_clean_uploaded_filename( $file );
68
+ $regex_match_file = '(' . preg_quote( $file ) . ')';
69
+ $regex = addcslashes( '(?:(?:(?:http(?:s)?\\:)?//' .
70
+ preg_quote( $parsedURL['host']) . ')?(?:' .
71
+ preg_quote( $parsedURL['path']) . '/)|^)' . $regex_match_file, '/');
72
+ $regex_mysql = str_replace( '(?:', '(', $regex );
73
+ if ( $attachment_id > 0 ) {
74
+ $mediaCount = $wpdb->get_var(
75
+ $wpdb->prepare( "SELECT COUNT(*)
76
+ FROM $wpdb->postmeta
77
+ WHERE post_id != %d
78
+ AND meta_key != '_wp_attached_file'
79
+ AND (meta_value REGEXP %s OR meta_value = %d)",
80
+ $attachment_id, $regex_mysql, $attachment_id
81
+ )
82
+ );
83
+ } else {
84
+ $mediaCount = $wpdb->get_var(
85
+ $wpdb->prepare( "SELECT COUNT(*)
86
+ FROM $wpdb->postmeta
87
+ WHERE meta_key != '_wp_attached_file'
88
+ AND meta_value REGEXP %s",
89
+ $regex_mysql
90
+ )
91
+ );
92
+ }
93
+ if ( $this->core->debug && $mediaCount > 0 )
94
+ error_log("{$file} found in POSTMETA");
95
+ return $mediaCount > 0;
96
  }
 
 
 
 
97
 
98
 
99
+ function wpmc_check_db_has_content( $file, $mediaId = null ) {
100
 
101
+ global $wpdb;
102
+ $shortcode_support = get_option( 'wpmc_shortcode', false );
103
 
104
+ // Check in Posts Content
105
+ if ( get_option( 'wpmc_posts', false ) ) {
106
+ $file = $this->core->wpmc_clean_uploaded_filename( $file );
107
+ $uploads = wp_upload_dir();
108
+ $parsedURL = parse_url( $uploads['baseurl'] );
109
+ $pinfo = pathinfo( $file );
110
+ $regex_match_file = '(' . $pinfo['dirname'] . '/' . $pinfo['filename'] . "(\\-[0-9]{1,8}x[0-9]{1,8})?\\." .
111
+ ( isset( $pinfo['extension'] ) ? $pinfo['extension'] : '' ) . ')';
112
+
113
+ // SUPER STRICT MODE
114
+ // $regex = addcslashes('=[\'"](?:(?:http(?:s)?\\:)?//'
115
+ // . preg_quote( $parsedURL['host'] ) . ')?'
116
+ // . preg_quote( $parsedURL['path'] ) . '/'
117
+ // . $regex_match_file . '(?:\\?[^\'"]*)*[\'"]', '/' );
118
+
119
+ // NORMAL REGEX
120
+ $regex = addcslashes( preg_quote( $parsedURL['path']) . '/' . $regex_match_file . '(?:\\?[^\'"]*)*[\'"]', '/' );
121
+ $regex_mysql = str_replace('(?:', '(', $regex);
 
 
 
 
 
 
 
 
 
 
 
122
  $sql = $wpdb->prepare( "SELECT COUNT(*)
123
  FROM $wpdb->posts
124
  WHERE post_type <> 'revision'
125
  AND post_type <> 'attachment'
126
+ AND post_content REGEXP %s", $regex_mysql );
127
  $mediaCount = $wpdb->get_var( $sql );
128
+ if ( $this->core->debug && $mediaCount > 0 )
129
+ error_log( "File {$file} found in post_content, $mediaCount time(s)" );
130
  if ( $mediaCount > 0 )
131
  return true;
132
+
133
+ if ( !empty( $mediaId ) ) {
134
+ $sql = $wpdb->prepare( "SELECT COUNT(*)
135
+ FROM $wpdb->posts
136
+ WHERE post_type <> 'revision'
137
+ AND post_type <> 'attachment'
138
+ AND post_content LIKE %s", "%wp-image-$mediaId%" );
139
+ $mediaCount = $wpdb->get_var( $sql );
140
+ if ( $this->core->debug && $mediaCount > 0 )
141
+ error_log( "Media {$mediaId} found in post_content, $mediaCount time(s)" );
142
+ if ( $mediaCount > 0 )
143
+ return true;
144
+ }
145
  }
 
146
 
147
+ // Shortcode analysis
148
+ global $shortcode_tags;
149
+ $active_tags = array_keys( $shortcode_tags );
150
+ if ( !empty( $active_tags ) ) {
151
+ $post_contents = get_transient( 'wpmc_posts_with_shortcode' );
152
+ if ( $post_contents === false ) {
153
+
154
+ $post_contents = array();
155
+
156
+ // Resolve shortcodes from posts
157
+ if ( $shortcode_support ) {
158
+ $query = array();
159
+ $query[] = "SELECT ID, post_content FROM {$wpdb->posts}";
160
+ $query[] = "WHERE post_type <> 'revision' AND post_type <> 'attachment'";
161
+ $sub_query = array();
162
+ foreach ( $active_tags as $tag ) {
163
+ $sub_query[] = "post_content LIKE '%[" . esc_sql( $wpdb->esc_like( $tag ) ) . "%'";
164
+ }
165
+ $query[] = "AND (" . implode ( " OR ", $sub_query ) . ")";
166
+ $sql = join( ' ', $query );
167
+ $results = $wpdb->get_results( $sql );
168
+ foreach ( $results as $key => $data ) {
169
+ $post_contents['post_' . $data->ID] = do_shortcode( $data->post_content );
170
+ }
171
  }
 
172
 
173
+ // Read Widgets
174
+ if ( get_option( 'wpmc_widgets', false ) ) {
175
+ global $wp_registered_widgets;
176
+ $active_widgets = get_option( 'sidebars_widgets' );
177
+ foreach ( $active_widgets as $sidebar_name => $sidebar_widgets ) {
178
+ if ( $sidebar_name != 'wp_inactive_widgets' && !empty( $sidebar_widgets ) && is_array( $sidebar_widgets ) ) {
179
+ $i = 0;
180
+ foreach ( $sidebar_widgets as $widget_instance ) {
181
+ $widget_class = $wp_registered_widgets[$widget_instance]['callback'][0]->option_name;
182
+ $instance_id = $wp_registered_widgets[$widget_instance]['params'][0]['number'];
183
+ $widget_data = get_option($widget_class);
184
+ if ( !empty( $widget_data[$instance_id]['text'] ) ) {
185
+
186
+ // Resolve Widgets or just get them
187
+ if ( $shortcode_support )
188
+ $post_contents['widget_' . $i] = do_shortcode( $widget_data[$instance_id]['text'] );
189
+ else
190
+ $post_contents['widget_' . $i] = $widget_data[$instance_id]['text'];
191
+ }
192
+ $i++;
193
  }
 
194
  }
195
  }
196
  }
 
197
 
198
+ if ( !empty( $post_contents ) )
199
+ set_transient( 'wpmc_posts_with_shortcode', $post_contents, 2 * 60 * 60 );
200
+ }
201
 
202
+ if ( !empty( $post_contents ) ) {
203
+ foreach ( $post_contents as $key => $content ) {
204
+ $found = preg_match( '/' . $regex . '/i', $content );
205
+ if ( $this->core->debug && $found )
206
+ error_log( "File Cleaner: {$file} found in {$key} shortcode or widget" );
207
+ if ( $found )
208
+ return true;
209
+ }
210
  }
211
  }
212
+ return false;
213
  }
214
+
215
  }
216
 
217
  ?>