PluginProbe ʕ •ᴥ•ʔ
Advanced Database Cleaner – Optimize & Clean Database to Speed Up Site Performance / 3.0.1
Advanced Database Cleaner – Optimize & Clean Database to Speed Up Site Performance v3.0.1
trunk 1.0.0 1.1.0 1.1.1 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.5 1.3.6 1.3.7 2.0.0 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.1.0 4.1.1
advanced-database-cleaner / includes / functions.php
advanced-database-cleaner / includes Last commit date
custom-clean-view 6 years ago custom-schedule-view 6 years ago license 6 years ago class_clean_cron.php 6 years ago class_clean_options.php 6 years ago class_clean_tables.php 5 years ago class_general_cleanup.php 6 years ago clean_db.php 6 years ago functions.php 5 years ago header_page_filter.php 6 years ago optimize_db.php 6 years ago overview_settings.php 6 years ago premium_page.php 6 years ago sidebar.php 6 years ago
functions.php
1299 lines
1 <?php
2 /** If we are in MU, define the main blog ID. This will be usefull to call get_option correctly when we switch between blogs */
3 /** Used mainly in aDBc_get_keep_last_sql_arg() */
4 if(function_exists('is_multisite') && is_multisite()){
5 if(!defined("ADBC_MAIN_SITE_ID")) define("ADBC_MAIN_SITE_ID", get_current_blog_id());
6 }
7
8 /** Reduces the value of the string in parameter according to max lenght then create a tooltip for it */
9 function aDBc_create_tooltip_for_long_string($string_value, $max_characters){
10 $new_name = esc_html($string_value);
11 if(strlen($new_name) > $max_characters){
12 $new_name = trim(substr($new_name, 0, $max_characters));
13 $new_name = $new_name . " <span class='aDBc-tooltips'>" . "..." . "<span>" . esc_html($string_value) . "</span></span>";
14 }
15 return $new_name;
16 }
17
18 /** Reduces the value of the string in parameter according to max lenght then create a tooltip for it */
19 function aDBc_create_tooltip_by_replace($string_value, $max_characters, $tooltip_content){
20 $new_name = $string_value;
21 if(strlen($new_name) > $max_characters){
22 $new_name = substr($new_name, 0, $max_characters) . " ...";
23 }
24 $new_name = "<span class='aDBc-tooltips'>" . esc_html($new_name) . "<span>" . esc_html($tooltip_content) . "</span></span>";
25 return $new_name;
26 }
27
28 /** Reduces the value of the option value according to max lenght then create a tooltip for it */
29 function aDBc_create_tooltip_for_option_value($string_value, $max_characters){
30
31 $option_content = maybe_unserialize($string_value);
32 if(is_array($option_content)){
33 $new_name = "<i>Array</i>" . " <span class='aDBc-tooltips'>" . "..." . "<span>" . esc_html($string_value) . "</span></span>";
34 }else if(gettype($option_content) == 'object'){
35 $new_name = "<i>Object</i>" . " <span class='aDBc-tooltips'>" . "..." . "<span>" . esc_html($string_value) . "</span></span>";
36 }else{
37 $new_name = esc_html($string_value);
38 if(strlen($new_name) > $max_characters){
39 $new_name = trim(substr($new_name, 0, $max_characters));
40 $new_name = $new_name . " <span class='aDBc-tooltips'>" . "..." . "<span>" . esc_html($string_value) . "</span></span>";
41 }
42 }
43 return $new_name;
44 }
45
46 function aDBc_get_order_by_sql_arg($default_order_by){
47
48 // Prepare ORDER BY and ORDER
49 $order_by = " ORDER BY " . $default_order_by . " ASC";
50 if(!empty($_GET['orderby'])){
51 $order_by = " ORDER BY " . esc_sql($_GET['orderby']);
52 $order_by .= empty($_GET['order']) ? " ASC" : " " . esc_sql($_GET['order']);
53 }
54
55 return $order_by;
56 }
57
58 function aDBc_get_limit_offset_sql_args(){
59
60 // Identify current page for WP_List_Table
61 $page_number = 1;
62 if(!empty($_GET['paged'])){
63 $page_number = absint($_GET['paged']);
64 }
65
66 // Identify items per page to display
67 $per_page = 50;
68 if(!empty($_GET['per_page'])){
69 $per_page = absint($_GET['per_page']);
70 }
71
72 // Prepare LIMIT and OFFSET
73 $offset = ($page_number - 1) * $per_page;
74 $limit_offset = " LIMIT $offset,$per_page";
75
76 return $limit_offset;
77 }
78
79 /** Cleans all elements in the current site and in MU according to the selected type */
80 function aDBc_clean_all_elements_type($type){
81 global $wpdb;
82 if(function_exists('is_multisite') && is_multisite()){
83 $blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
84 foreach($blogs_ids as $blog_id){
85 switch_to_blog($blog_id);
86 aDBc_clean_elements_type($type);
87 restore_current_blog();
88 }
89 }else{
90 aDBc_clean_elements_type($type);
91 }
92 }
93
94 /** Cleans all elements in the current site according to the selected type */
95 function aDBc_clean_elements_type($type){
96
97 global $wpdb;
98
99 switch($type){
100 case "revision":
101 $revision_date = aDBc_get_keep_last_sql_arg('revision','post_modified');
102 $wpdb->query("DELETE FROM $wpdb->posts WHERE post_type = 'revision'" . $revision_date);
103 break;
104 case "auto-draft":
105 $auto_draft_date = aDBc_get_keep_last_sql_arg('auto-draft','post_modified');
106 $wpdb->query("DELETE FROM $wpdb->posts WHERE post_status = 'auto-draft'" . $auto_draft_date);
107 break;
108 case "trash-posts":
109 $trash_post_date = aDBc_get_keep_last_sql_arg('trash-posts','post_modified');
110 $wpdb->query("DELETE FROM $wpdb->posts WHERE post_status = 'trash'" . $trash_post_date);
111 break;
112 case "moderated-comments":
113 $moderated_comment_date = aDBc_get_keep_last_sql_arg('moderated-comments','comment_date');
114 $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_approved = '0'" . $moderated_comment_date);
115 break;
116 case "spam-comments":
117 $spam_comment_date = aDBc_get_keep_last_sql_arg('spam-comments','comment_date');
118 $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_approved = 'spam'" . $spam_comment_date);
119 break;
120 case "trash-comments":
121 $trash_comment_date = aDBc_get_keep_last_sql_arg('trash-comments','comment_date');
122 $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_approved = 'trash'" . $trash_comment_date);
123 break;
124 case "pingbacks":
125 $pingback_date = aDBc_get_keep_last_sql_arg('pingbacks','comment_date');
126 $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_type = 'pingback'" . $pingback_date);
127 break;
128 case "trackbacks":
129 $trackback_date = aDBc_get_keep_last_sql_arg('trackbacks','comment_date');
130 $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_type = 'trackback'" . $trackback_date);
131 break;
132 case "orphan-postmeta":
133 $wpdb->query("DELETE pm FROM $wpdb->postmeta pm LEFT JOIN $wpdb->posts wp ON wp.ID = pm.post_id WHERE wp.ID IS NULL");
134 break;
135 case "orphan-commentmeta":
136 $wpdb->query("DELETE FROM $wpdb->commentmeta WHERE comment_id NOT IN (SELECT comment_id FROM $wpdb->comments)");
137 break;
138 case "orphan-relationships":
139 $wpdb->query("DELETE FROM $wpdb->term_relationships WHERE term_taxonomy_id=1 AND object_id NOT IN (SELECT id FROM $wpdb->posts)");
140 break;
141 case "orphan-usermeta":
142 $wpdb->query("DELETE FROM $wpdb->usermeta WHERE user_id NOT IN (SELECT ID FROM $wpdb->users)");
143 break;
144 case "orphan-termmeta":
145 $wpdb->query("DELETE FROM $wpdb->termmeta WHERE term_id NOT IN (SELECT term_id FROM $wpdb->terms)");
146 break;
147 case "expired-transients":
148 $type_arg = " AND b.option_value < UNIX_TIMESTAMP()";
149 aDBc_clean_all_transients($type_arg);
150 break;
151 //case "transients-with-expiration":
152 // $type_arg = " AND b.option_value > UNIX_TIMESTAMP()";
153 // aDBc_clean_all_transients($type_arg);
154 // break;
155 //case "transients-with-no-expiration":
156 // $type_arg = " AND b.option_value is NULL";
157 // aDBc_clean_all_transients($type_arg);
158 // break;
159 }
160 }
161
162 /** Cleans transients based on the type specified in parameter */
163 function aDBc_clean_all_transients($type_arg){
164
165 global $wpdb;
166
167 $aDBc_transients = $wpdb->get_results("SELECT a.option_name, b.option_value FROM $wpdb->options a LEFT JOIN $wpdb->options b ON b.option_name =
168 CONCAT(
169 CASE WHEN a.option_name LIKE '_site_transient_%'
170 THEN '_site_transient_timeout_'
171 ELSE '_transient_timeout_'
172 END
173 ,
174 SUBSTRING(a.option_name, CHAR_LENGTH(
175 CASE WHEN a.option_name LIKE '_site_transient_%'
176 THEN '_site_transient_'
177 ELSE '_transient_'
178 END
179 ) + 1)
180 )
181 WHERE (a.option_name LIKE '_transient_%' OR a.option_name LIKE '_site_transient_%') AND a.option_name NOT LIKE '%_transient_timeout_%'" . $type_arg);
182
183 foreach($aDBc_transients as $transient){
184 $site_wide = (strpos($transient->option_name, '_site_transient') !== false);
185 $name = str_replace($site_wide ? '_site_transient_' : '_transient_', '', $transient->option_name);
186 if(false !== $site_wide){
187 delete_site_transient($name);
188 }else{
189 delete_transient($name);
190 }
191 }
192 }
193
194 /** Cleans scheduled elements in the current site and in MU (used by the scheduler) */
195 function aDBc_clean_scheduled_elements($schedule_name){
196
197 global $wpdb;
198
199 $schedule_settings = get_option('aDBc_clean_schedule');
200
201 if(is_array($schedule_settings) && array_key_exists($schedule_name, $schedule_settings)){
202
203 $schedule_params = $schedule_settings[$schedule_name];
204 $elements_to_clean = $schedule_params['elements_to_clean'];
205
206 if(function_exists('is_multisite') && is_multisite()){
207 $blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
208 foreach($blogs_ids as $blog_id){
209 switch_to_blog($blog_id);
210 foreach($elements_to_clean as $type){
211 aDBc_clean_elements_type($type);
212 }
213 restore_current_blog();
214 }
215 }else{
216 foreach($elements_to_clean as $type){
217 aDBc_clean_elements_type($type);
218 }
219 }
220
221 // After clean up, verify if the caller is a "ONCE" schedule, if so, change its settings in DB to inactive...
222 if($schedule_params['repeat'] == "once"){
223 $schedule_params['active'] = "0";
224 $schedule_settings[$schedule_name] = $schedule_params;
225 update_option('aDBc_clean_schedule', $schedule_settings, "no");
226 }
227 }
228 }
229
230 /** Optimizes/repairs all tables having lost space or that should be repaired (used by the scheduler) */
231 function aDBc_optimize_scheduled_tables($schedule_name){
232
233 global $wpdb;
234
235 $schedule_settings = get_option('aDBc_optimize_schedule');
236
237 if(is_array($schedule_settings) && array_key_exists($schedule_name, $schedule_settings)){
238
239 $schedule_params = $schedule_settings[$schedule_name];
240 $operations = $schedule_params['operations'];
241
242 // Perform optimize operation
243 if(in_array("optimize", $operations)){
244 $result = $wpdb->get_results("SELECT table_name FROM information_schema.tables WHERE table_schema = '" . DB_NAME ."' and Engine <> 'InnoDB' and data_free > 0");
245 foreach($result as $table){
246
247 // Get table name
248 $table_name = "";
249 // This test to prevent issues in MySQL 8 where tables are not shown
250 // MySQL 5 uses $table->table_name while MySQL 8 uses $table->TABLE_NAME
251 if(property_exists($table, "table_name")){
252 $table_name = $table->table_name;
253 }else if(property_exists($table, "TABLE_NAME")){
254 $table_name = $table->TABLE_NAME;
255 }
256
257 $wpdb->query("OPTIMIZE TABLE " . $table_name);
258 }
259 }
260
261 // Perfom repair operation
262 if(in_array("repair", $operations)){
263 $result = $wpdb->get_results("SELECT table_name FROM information_schema.tables WHERE table_schema = '" . DB_NAME ."' and Engine IN ('CSV', 'MyISAM', 'ARCHIVE')");
264 foreach($result as $table){
265
266 // Get table name
267 $table_name = "";
268 // This test to prevent issues in MySQL 8 where tables are not shown
269 // MySQL 5 uses $table->table_name while MySQL 8 uses $table->TABLE_NAME
270 if(property_exists($table, "table_name")){
271 $table_name = $table->table_name;
272 }else if(property_exists($table, "TABLE_NAME")){
273 $table_name = $table->TABLE_NAME;
274 }
275
276 $query_result = $wpdb->get_results("CHECK TABLE " . $table_name);
277 foreach($query_result as $row){
278 if($row->Msg_type == 'error'){
279 if(preg_match('/corrupt/i', $row->Msg_text)){
280 $wpdb->query("REPAIR TABLE " . $table_name);
281 }
282 }
283 }
284 }
285 }
286
287 // After optimization/repair, verify if the caller is a "ONCE" schedule, if so, change its settings in DB to inactive...
288 if($schedule_params['repeat'] == "once"){
289 $schedule_params['active'] = "0";
290 $schedule_settings[$schedule_name] = $schedule_params;
291 update_option('aDBc_optimize_schedule', $schedule_settings, "no");
292 }
293 }
294 }
295
296 /** Returns an array containing all elements in general cleanup tab with their names used in the code */
297 function aDBc_return_array_all_elements_to_clean(){
298
299 $aDBc_unused["revision"]['name'] = __('Revisions','advanced-database-cleaner');
300 $aDBc_unused["revision"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-revisions-and-how-to-clean-them";
301 $aDBc_unused["auto-draft"]['name'] = __('Auto drafts','advanced-database-cleaner');
302 $aDBc_unused["auto-draft"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-auto-drafts-and-how-to-clean-them";
303 $aDBc_unused["trash-posts"]['name'] = __('Trashed posts','advanced-database-cleaner');
304 $aDBc_unused["trash-posts"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-trash-posts-and-how-to-clean-them";
305
306 $aDBc_unused["moderated-comments"]['name'] = __('Pending comments','advanced-database-cleaner');
307 $aDBc_unused["moderated-comments"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-pending-comments-and-how-to-clean-them";
308 $aDBc_unused["spam-comments"]['name'] = __('Spam comments','advanced-database-cleaner');
309 $aDBc_unused["spam-comments"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-spam-comments-and-how-to-clean-them";
310 $aDBc_unused["trash-comments"]['name'] = __('Trashed comments','advanced-database-cleaner');
311 $aDBc_unused["trash-comments"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-trash-comments-and-how-to-clean-them";
312
313 $aDBc_unused["pingbacks"]['name'] = __('Pingbacks','advanced-database-cleaner');
314 $aDBc_unused["pingbacks"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-pingbacks-and-how-to-clean-them";
315 $aDBc_unused["trackbacks"]['name'] = __('Trackbacks','advanced-database-cleaner');
316 $aDBc_unused["trackbacks"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-trackbacks-and-how-to-clean-them";
317
318 $aDBc_unused["orphan-postmeta"]['name'] = __('Orphaned post meta','advanced-database-cleaner');
319 $aDBc_unused["orphan-postmeta"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-orphan-posts-meta-and-how-to-clean-them";
320 $aDBc_unused["orphan-commentmeta"]['name'] = __('Orphaned comment meta','advanced-database-cleaner');
321 $aDBc_unused["orphan-commentmeta"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-orphan-comments-meta-and-how-to-clean-them";
322 $aDBc_unused["orphan-usermeta"]['name'] = __('Orphaned user meta','advanced-database-cleaner');
323 $aDBc_unused["orphan-usermeta"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-orphaned-user-meta-and-how-to-clean-them";
324 $aDBc_unused["orphan-termmeta"]['name'] = __('Orphaned term meta','advanced-database-cleaner');
325 $aDBc_unused["orphan-termmeta"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-orphaned-term-meta-and-how-to-clean-them";
326
327 $aDBc_unused["orphan-relationships"]['name'] = __('Orphaned relationships','advanced-database-cleaner');
328 $aDBc_unused["orphan-relationships"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-orphan-relationships-and-how-to-clean-them";
329
330 $aDBc_unused["expired-transients"]['name'] = __("Expired transients","advanced-database-cleaner");
331 $aDBc_unused["expired-transients"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-transients";
332
333
334 /*$aDBc_transient_toolip = "<span class='aDBc-tooltips-headers'>
335 <img style='width:12px' class='aDBc-info-image' src='". ADBC_PLUGIN_DIR_PATH . '/images/information2.svg' . "'/>
336 <span>" . __('Do not clean these items unless you know what you are doing!','advanced-database-cleaner') ." </span>
337 </span>";
338
339 $aDBc_unused["transients-with-expiration"]['name'] = __("Transients with an expiration","advanced-database-cleaner") . "<br><span class='aDBc-caution'>" . __("Use with caution!","advanced-database-cleaner") . "</span>" . $aDBc_transient_toolip;
340 $aDBc_unused["transients-with-expiration"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-transients";
341
342 $aDBc_unused["transients-with-no-expiration"]['name'] = __("Transients with no expiration","advanced-database-cleaner") . "<br><span class='aDBc-caution'>" . __("Use with caution!","advanced-database-cleaner") . "</span>" . $aDBc_transient_toolip;
343 $aDBc_unused["transients-with-no-expiration"]['URL_blog'] = "https://sigmaplugin.com/blog/what-are-wordpress-transients";*/
344
345 return $aDBc_unused;
346
347 }
348
349 /** Counts all elements to clean (in the current site or MU) */
350 function aDBc_count_all_elements_to_clean(){
351 global $wpdb;
352 $aDBc_unused = aDBc_return_array_all_elements_to_clean();
353
354 // Initialize counts to 0
355 foreach($aDBc_unused as $aDBc_type => $element_info){
356 $aDBc_unused[$aDBc_type]['count'] = 0;
357 }
358
359 //(for the table usermeta, only one table exists for MU, do not witch over blogs for it)
360 if(function_exists('is_multisite') && is_multisite()){
361 $blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
362 foreach($blogs_ids as $blog_id){
363 switch_to_blog($blog_id);
364 aDBc_count_elements_to_clean($aDBc_unused);
365 restore_current_blog();
366 }
367 }else{
368 aDBc_count_elements_to_clean($aDBc_unused);
369 }
370 return $aDBc_unused;
371 }
372
373 /** Counts elements to clean in the current site */
374 function aDBc_count_elements_to_clean(&$aDBc_unused){
375
376 global $wpdb;
377
378 // Test if there are any keep_last options to count only elements with date < keep_lat to add it to the query
379 $revision_date = aDBc_get_keep_last_sql_arg('revision','post_modified');
380 $auto_draft_date = aDBc_get_keep_last_sql_arg('auto-draft','post_modified');
381 $trash_post_date = aDBc_get_keep_last_sql_arg('trash-posts','post_modified');
382 $moderated_comment_date = aDBc_get_keep_last_sql_arg('moderated-comments','comment_date');
383 $spam_comment_date = aDBc_get_keep_last_sql_arg('spam-comments','comment_date');
384 $trash_comment_date = aDBc_get_keep_last_sql_arg('trash-comments','comment_date');
385 $pingback_date = aDBc_get_keep_last_sql_arg('pingbacks','comment_date');
386 $trackback_date = aDBc_get_keep_last_sql_arg('trackbacks','comment_date');
387
388 // Execute count queries
389 $aDBc_unused["revision"]['count'] += $wpdb->get_var("SELECT COUNT(ID) FROM $wpdb->posts WHERE post_type = 'revision'" . $revision_date);
390 $aDBc_unused["auto-draft"]['count'] += $wpdb->get_var("SELECT COUNT(ID) FROM $wpdb->posts WHERE post_status = 'auto-draft'" . $auto_draft_date);
391 $aDBc_unused["trash-posts"]['count'] += $wpdb->get_var("SELECT COUNT(ID) FROM $wpdb->posts WHERE post_status = 'trash'" . $trash_post_date);
392
393 $aDBc_unused["moderated-comments"]['count'] += $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = '0'" . $moderated_comment_date);
394 $aDBc_unused["spam-comments"]['count'] += $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'" . $spam_comment_date);
395 $aDBc_unused["trash-comments"]['count'] += $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'trash'" . $trash_comment_date);
396 $aDBc_unused["pingbacks"]['count'] += $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_type = 'pingback'" . $pingback_date);
397 $aDBc_unused["trackbacks"]['count'] += $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_type = 'trackback'" . $trackback_date);
398
399 $aDBc_unused["orphan-postmeta"]['count'] += $wpdb->get_var("SELECT COUNT(meta_id) FROM $wpdb->postmeta pm LEFT JOIN $wpdb->posts wp ON wp.ID = pm.post_id WHERE wp.ID IS NULL");
400
401 $aDBc_unused["orphan-commentmeta"]['count'] += $wpdb->get_var("SELECT COUNT(meta_id) FROM $wpdb->commentmeta WHERE comment_id NOT IN (SELECT comment_id FROM $wpdb->comments)");
402
403 // for the table usermeta, only one table exists for MU, do not switch over blogs for it. Get count only in main site
404 if(is_main_site()){
405 $aDBc_unused["orphan-usermeta"]['count'] += $wpdb->get_var("SELECT COUNT(umeta_id) FROM $wpdb->usermeta WHERE user_id NOT IN (SELECT ID FROM $wpdb->users)");
406 }
407
408 $aDBc_unused["orphan-termmeta"]['count'] += $wpdb->get_var("SELECT COUNT(meta_id) FROM $wpdb->termmeta WHERE term_id NOT IN (SELECT term_id FROM $wpdb->terms)");
409
410 $aDBc_unused["orphan-relationships"]['count'] += $wpdb->get_var("SELECT COUNT(object_id) FROM $wpdb->term_relationships WHERE term_taxonomy_id=1 AND object_id NOT IN (SELECT ID FROM $wpdb->posts)");
411
412 // Section for transients
413 //$all_transients_names = $wpdb->get_col("SELECT option_name FROM $wpdb->options where (option_name LIKE '_transient_%' OR option_name LIKE '_site_transient_%') AND option_name NOT LIKE '_transient_timeout_%' AND option_name NOT LIKE '_site_transient_timeout_%'");
414
415 $expired_transient_names = $wpdb->get_col("SELECT REPLACE(option_name, '_timeout', '') FROM $wpdb->options where (option_name LIKE '_transient_timeout_%' OR option_name LIKE '_site_transient_timeout_%') AND option_value < UNIX_TIMESTAMP()");
416
417 //$transient_with_expiration_names = $wpdb->get_col("SELECT REPLACE(option_name, '_timeout', '') FROM $wpdb->options where option_value > UNIX_TIMESTAMP() AND (option_name LIKE '_transient_timeout_%' OR option_name LIKE '_site_transient_timeout_%')");
418
419 // Get transients with no expiration
420 //$transients_with_no_expiration = array_diff($all_transients_names, $expired_transient_names, $transient_with_expiration_names);
421
422 $aDBc_unused["expired-transients"]['count'] += count($expired_transient_names);
423 //$aDBc_unused["transients-with-expiration"]['count'] += count($transient_with_expiration_names);
424 //$aDBc_unused["transients-with-no-expiration"]['count'] += count($transients_with_no_expiration);
425 // End of transients section
426
427 }
428
429 /** Prepare keep_last element if any **/
430 function aDBc_get_keep_last_sql_arg($element_type, $column_name){
431
432 // If we are in MU, we shoul call settings from the main site since here in are inside switch_blog and therefore calling get_option will lead to calling the current blog options
433 if(function_exists('is_multisite') && is_multisite()){
434 $settings = get_blog_option(ADBC_MAIN_SITE_ID, 'aDBc_settings');
435 }else{
436 $settings = get_option('aDBc_settings');
437 }
438 if(!empty($settings['keep_last'])){
439 $keep_setting = $settings['keep_last'];
440 if(!empty($keep_setting[$element_type]))
441 return " and $column_name < NOW() - INTERVAL " . $keep_setting[$element_type] . " DAY";
442 }
443 return "";
444 }
445
446 /**************************************************************************************************
447 * This function filters the array containing results according to users args for the free versions.
448 * Mainly for tables to optimize and repair
449 **************************************************************************************************/
450 function aDBc_filter_results_in_all_items_array_free(&$aDBc_all_items, $aDBc_tables_name_to_optimize, $aDBc_tables_name_to_repair){
451
452 if(function_exists('is_multisite') && is_multisite()){
453
454 // Filter according to tables types (to optimize, to repair...)
455 if(!empty($_GET['t_type']) && $_GET['t_type'] != "all"){
456 $type = esc_sql($_GET['t_type']);
457 if($type == 'optimize'){
458 $array_names = $aDBc_tables_name_to_optimize;
459 }else{
460 $array_names = $aDBc_tables_name_to_repair;
461 }
462 foreach($aDBc_all_items as $item_name => $item_info){
463 foreach($item_info['sites'] as $site_id => $site_item_info){
464 if(!in_array($site_item_info['prefix'] . $item_name, $array_names)){
465 unset($aDBc_all_items[$item_name]['sites'][$site_id]);
466 }
467 }
468 }
469 }
470
471 }else{
472
473 // Prepare an array containing names of items to delete
474 $names_to_delete = array();
475
476 // Filter according to tables types (to optimize, to repair...)
477 $filter_on_t_type = !empty($_GET['t_type']) && $_GET['t_type'] != "all";
478 if($filter_on_t_type){
479 $type = esc_sql($_GET['t_type']);
480 if($type == "optimize"){
481 $array_names = $aDBc_tables_name_to_optimize;
482 }else{
483 $array_names = $aDBc_tables_name_to_repair;
484 }
485 }
486
487 foreach($aDBc_all_items as $item_name => $item_info){
488 if($filter_on_t_type){
489 if(!in_array($item_info['sites'][1]['prefix'] . $item_name, $array_names)){
490 array_push($names_to_delete, $item_name);
491 }
492 }
493 }
494
495 // Loop over the names to delete and delete them for the array
496 foreach($names_to_delete as $name){
497 unset($aDBc_all_items[$name]);
498 }
499
500 }
501
502 }
503
504 /***********************************************************************************
505 *
506 * Common function to: options, tables and scheduled tasks processes
507 *
508 ***********************************************************************************/
509
510 /** Prepares items (options, tables or tasks) to display + message*/
511 function aDBc_prepare_items_to_display(
512 &$items_to_display,
513 &$aDBc_items_categories_info,
514 &$aDBc_which_button_to_show,
515 $aDBc_tables_name_to_optimize,
516 $aDBc_tables_name_to_repair,
517 &$array_belongs_to_counts,
518 &$aDBc_message,
519 &$aDBc_class_message,
520 $items_type){
521
522 // Prepare categories info
523 switch($items_type){
524 case 'tasks' :
525 $aDBc_all_items = aDBc_get_all_scheduled_tasks();
526 $aDBc_items_categories_info = array(
527 'all' => array('name' => __('All', 'advanced-database-cleaner'), 'color' => '#4E515B', 'count' => 0),
528 'u' => array('name' => __('Uncategorized', 'advanced-database-cleaner'), 'color' => 'grey', 'count' => 0),
529 'o' => array('name' => __('Orphans','advanced-database-cleaner'), 'color' => '#E97F31', 'count' => 0),
530 'p' => array('name' => __('Plugins tasks', 'advanced-database-cleaner'), 'color' => '#00BAFF', 'count' => 0),
531 't' => array('name' => __('Themes tasks', 'advanced-database-cleaner'), 'color' => '#45C966', 'count' => 0),
532 'w' => array('name' => __('WP tasks', 'advanced-database-cleaner'), 'color' => '#D091BE', 'count' => 0)
533 );
534 break;
535 case 'options' :
536 $aDBc_all_items = aDBc_get_all_options();
537 $aDBc_items_categories_info = array(
538 'all' => array('name' => __('All', 'advanced-database-cleaner'), 'color' => '#4E515B', 'count' => 0),
539 'u' => array('name' => __('Uncategorized', 'advanced-database-cleaner'), 'color' => 'grey', 'count' => 0),
540 'o' => array('name' => __('Orphans','advanced-database-cleaner'), 'color' => '#E97F31', 'count' => 0),
541 'p' => array('name' => __('Plugins options', 'advanced-database-cleaner'), 'color' => '#00BAFF', 'count' => 0),
542 't' => array('name' => __('Themes options', 'advanced-database-cleaner'), 'color' => '#45C966', 'count' => 0),
543 'w' => array('name' => __('WP options', 'advanced-database-cleaner'), 'color' => '#D091BE', 'count' => 0)
544 );
545 break;
546 case 'tables' :
547 $aDBc_all_items = aDBc_get_all_tables();
548 $aDBc_items_categories_info = array(
549 'all' => array('name' => __('All', 'advanced-database-cleaner'), 'color' => '#4E515B', 'count' => 0),
550 'u' => array('name' => __('Uncategorized', 'advanced-database-cleaner'), 'color' => 'grey', 'count' => 0),
551 'o' => array('name' => __('Orphans','advanced-database-cleaner'), 'color' => '#E97F31', 'count' => 0),
552 'p' => array('name' => __('Plugins tables', 'advanced-database-cleaner'), 'color' => '#00BAFF', 'count' => 0),
553 't' => array('name' => __('Themes tables', 'advanced-database-cleaner'), 'color' => '#45C966', 'count' => 0),
554 'w' => array('name' => __('WP tables', 'advanced-database-cleaner'), 'color' => '#D091BE', 'count' => 0)
555 );
556 break;
557 }
558
559 $aDBc_saved_items_file = "";
560 // xxx change this later, no need for this test in the free verion. Moreover, ADBC_UPLOAD_DIR_PATH_TO_ADBC is not defined here
561 /*if(file_exists(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/" . $items_type . ".txt")){
562 $aDBc_saved_items_file = fopen(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/" . $items_type . ".txt", "r");
563 }*/
564
565 // Affect type and belongs_to to items.
566 if ($aDBc_saved_items_file) {
567 while(($item = fgets($aDBc_saved_items_file)) !== false) {
568 $columns = explode(":", trim($item));
569 // We replace +=+ by : because names that contain : have been transformed to +=+ to prevent problems with split based on :
570 $item_name = str_replace("+=+", ":", $columns[0]);
571 // Prevent adding an item that was cleaned (maybe by other plugins) but not updated in file
572 if(array_key_exists($item_name, $aDBc_all_items) && empty($aDBc_all_items[$item_name]['belongs_to'])) {
573
574 $aDBc_all_items[$item_name]['belongs_to'] = $columns[1];
575 $aDBc_all_items[$item_name]['type'] = $columns[2];
576
577 // Add this belongs_to to array for display in dropdown filter
578 $belongs_to_value = explode("(", $columns[1], 2);
579 $belongs_to_value = trim($belongs_to_value[0]);
580 $belongs_to_value = str_replace(" ", "-", $belongs_to_value);
581 if($items_type == "tasks"){
582 if(!array_key_exists($belongs_to_value, $array_belongs_to_counts)){
583 $array_belongs_to_counts[$belongs_to_value]['type'] = $columns[2];
584 foreach($aDBc_all_items[$item_name]['sites'] as $site => $info){
585 $array_belongs_to_counts[$belongs_to_value]['count'] = count($aDBc_all_items[$item_name]['sites'][$site]['args']);
586 }
587 }else{
588 foreach($aDBc_all_items[$item_name]['sites'] as $site => $info){
589 $array_belongs_to_counts[$belongs_to_value]['count'] += count($aDBc_all_items[$item_name]['sites'][$site]['args']);
590 }
591 }
592 }else{
593 if(!array_key_exists($belongs_to_value, $array_belongs_to_counts)){
594 $array_belongs_to_counts[$belongs_to_value]['type'] = $columns[2];
595 $array_belongs_to_counts[$belongs_to_value]['count'] = count($aDBc_all_items[$item_name]['sites']);
596 }else{
597 $array_belongs_to_counts[$belongs_to_value]['count'] += count($aDBc_all_items[$item_name]['sites']);
598 }
599 }
600 }
601 }
602 fclose($aDBc_saved_items_file);
603 }
604
605 // Filter results according to users choices and args
606 if(ADBC_PLUGIN_F_TYPE == "pro"){
607 aDBc_filter_results_in_all_items_array($aDBc_all_items, $aDBc_tables_name_to_optimize, $aDBc_tables_name_to_repair);
608 }else{
609 aDBc_filter_results_in_all_items_array_free($aDBc_all_items, $aDBc_tables_name_to_optimize, $aDBc_tables_name_to_repair);
610 }
611
612 // Put 'u' type to all uncategorized items and count all items
613 foreach($aDBc_all_items as $item_name => $item_info){
614 // Counting items differ from tasks to options and tables
615 // For tasks, we will counts numbers of args in array, while for options/tables, we will count number of sites
616 if($items_type == "tasks"){
617 foreach($item_info['sites'] as $site => $info){
618 $aDBc_items_categories_info['all']['count'] += count($item_info['sites'][$site]['args']);
619 if(empty($item_info['type'])){
620 $aDBc_all_items[$item_name]['type'] = 'u';
621 $aDBc_items_categories_info['u']['count'] += count($item_info['sites'][$site]['args']);
622 }else{
623 $aDBc_items_categories_info[$item_info['type']]['count'] += count($item_info['sites'][$site]['args']);
624 }
625 }
626 }else{
627 $aDBc_items_categories_info['all']['count'] += count($item_info['sites']);
628 if(empty($item_info['type'])){
629 $aDBc_all_items[$item_name]['type'] = 'u';
630 $aDBc_items_categories_info['u']['count'] += count($item_info['sites']);
631 }else{
632 $aDBc_items_categories_info[$item_info['type']]['count'] += count($item_info['sites']);
633 }
634 }
635 }
636
637 // Prepare items to display
638 $aDBc_not_categorized_toolip = "<span class='aDBc-tooltips-headers'>
639 <img class='aDBc-info-image' src='". ADBC_PLUGIN_DIR_PATH . '/images/information2.svg' . "'/>
640 <span>" . __('This item is not categorized yet! Please click on scan button above to categorize it.','advanced-database-cleaner') ." </span>
641 </span>";
642 foreach($aDBc_all_items as $item_name => $item_info){
643
644 if($_GET['aDBc_cat'] != "all" && $item_info['type'] != $_GET['aDBc_cat']){
645 continue;
646 }
647
648 switch($item_info['type']){
649 case 'u' :
650 if(ADBC_PLUGIN_F_TYPE == "free"){
651 $belongs_to_without_html = __('Available in Pro version!', 'advanced-database-cleaner');
652 $belongs_to = '<span style="color:#999">' . $belongs_to_without_html . '</span>';
653 }else{
654 $belongs_to_without_html = __('Uncategorised!', 'advanced-database-cleaner');
655 $belongs_to = '<span style="color:#999">' . $belongs_to_without_html . '</span>' . $aDBc_not_categorized_toolip;
656 }
657 break;
658 case 'o' :
659 $belongs_to_without_html = __('Orphan!', 'advanced-database-cleaner');
660 $belongs_to = '<span style="color:#E97F31">' . $belongs_to_without_html . '</span>';
661 break;
662 case 'w' :
663 $belongs_to_without_html = __('Wordpress core', 'advanced-database-cleaner');
664 $belongs_to = '<span style="color:#D091BE">' . $belongs_to_without_html;
665 // Add percent % if any
666 $belongs_to .= $item_info['belongs_to'] == "w" ? "" : " ".$item_info['belongs_to'];
667 $belongs_to .= '</span>';
668 break;
669 case 'p' :
670 $belongs_to_without_html = $item_info['belongs_to'];
671 $belongs_to = '<span style="color:#00BAFF">' . $belongs_to_without_html . '</span>';
672 break;
673 case 't' :
674 $belongs_to_without_html = $item_info['belongs_to'];
675 $belongs_to = '<span style="color:#45C966">' . $belongs_to_without_html . '</span>';
676 break;
677 }
678 foreach($item_info['sites'] as $site_id => $site_item_info){
679 switch($items_type){
680 case 'tasks' :
681 foreach($site_item_info['args'] as $args_info){
682 array_push($items_to_display, array(
683 'hook_name' => $item_name,
684 'arguments' => $args_info['arguments'],
685 'site_id' => $site_id,
686 'next_run' => $args_info['next_run'] . ' - ' . $args_info['frequency'],
687 'timestamp' => $args_info['timestamp'],
688 'hook_belongs_to' => $belongs_to
689 ));
690 }
691 break;
692 case 'options' :
693 array_push($items_to_display, array(
694 'option_name' => $item_name,
695 'option_value' => $site_item_info['value'],
696 'option_autoload' => $site_item_info['autoload'],
697 'option_size' => $site_item_info['size'],
698 'site_id' => $site_id,
699 'option_belongs_to' => $belongs_to
700 ));
701 break;
702 case 'tables' :
703 array_push($items_to_display, array(
704 'table_name' => $item_name,
705 'table_prefix' => $site_item_info['prefix'],
706 'table_full_name' => $site_item_info['prefix'].$item_name,
707 'table_rows' => $site_item_info['rows'],
708 'table_size' => $site_item_info['size'],
709 'table_lost' => $site_item_info['lost'],
710 'site_id' => $site_id,
711 'table_belongs_to' => $belongs_to
712 ));
713 break;
714 }
715 }
716 }
717
718 // Sort items if necessary
719 if(!empty($_GET['orderby'])){
720 $order_by = esc_sql($_GET['orderby']);
721 $order = empty($_GET['order']) ? "asc" : esc_sql($_GET['order']);
722
723 if($order_by == "table_name"){
724 $order_by = "table_full_name";
725 }
726
727 $elements = array();
728 foreach($items_to_display as $items){
729 $elements[] = $items[$order_by];
730 }
731
732 if($order_by == "table_size" || $order_by == "option_size" || $order_by == "site_id"){
733 if($order == "asc"){
734 array_multisort($elements, SORT_ASC, $items_to_display, SORT_NUMERIC);
735 }else{
736 array_multisort($elements, SORT_DESC, $items_to_display, SORT_NUMERIC);
737 }
738 }else{
739 if($order == "asc"){
740 array_multisort($elements, SORT_ASC, $items_to_display, SORT_REGULAR);
741 }else{
742 array_multisort($elements, SORT_DESC, $items_to_display, SORT_REGULAR);
743 }
744 }
745 }
746
747 // Select which button to show, is it "new search" or "continue search"?
748 // If $aDBc_saved_items['last_file_path'] contains a path, then we conclude that the last search has failed => display "continue searching" button
749 $new_search = get_option("aDBc_temp_last_iteration_".$items_type);
750 if(empty($new_search)){
751 $aDBc_which_button_to_show = "new_search";
752 }else{
753 $aDBc_which_button_to_show = "continue_search";
754 $aDBc_message .= '<font color="black">';
755 $aDBc_message .= __('This page will reload several times during this scan!', 'advanced-database-cleaner');
756 $aDBc_message .= '</font>';
757 $aDBc_class_message = "notice-info";
758 }
759 }
760
761 /***********************************************************************************
762 *
763 * Function proper to options processes
764 *
765 ***********************************************************************************/
766
767 /** Prepares all options for all sites (if any) in a multidimensional array */
768 function aDBc_get_all_options() {
769 $aDBc_all_options = array();
770 global $wpdb;
771 if(function_exists('is_multisite') && is_multisite()){
772 $blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
773 foreach($blogs_ids as $blog_id){
774 switch_to_blog($blog_id);
775 aDBc_add_options($aDBc_all_options, $blog_id);
776 restore_current_blog();
777 }
778 }else{
779 aDBc_add_options($aDBc_all_options, "1");
780 }
781 return $aDBc_all_options;
782 }
783
784 /** Prepares options for one single site (Used by aDBc_get_all_options() function) */
785 function aDBc_add_options(&$aDBc_all_options, $blog_id){
786 global $wpdb;
787 // Get the list of all options from the current WP database
788 $aDBc_options_in_db = $wpdb->get_results("SELECT option_name, option_value, autoload FROM $wpdb->options WHERE option_name NOT LIKE '%transient%' and option_name NOT LIKE '%session%expire%'");
789 foreach($aDBc_options_in_db as $option){
790 // If the option has not been added yet, add it and initiate its info
791 if(empty($aDBc_all_options[$option->option_name])){
792 $aDBc_all_options[$option->option_name] = array('belongs_to' => '', 'maybe_belongs_to' => '', 'type' => '', 'sites' => array());
793 }
794
795 // Add info of the option according to the current site
796 $aDBc_all_options[$option->option_name]['sites'][$blog_id] = array(
797 'value' => aDBc_create_tooltip_for_option_value($option->option_value, 17),
798 'size' => mb_strlen($option->option_value),
799 'autoload' => $option->autoload
800 );
801 }
802 }
803
804 /***********************************************************************************
805 *
806 * Function proper to tables processes
807 *
808 ***********************************************************************************/
809
810 /** Prepares all tables for all sites (if any) in a multidimensional array */
811 function aDBc_get_all_tables() {
812
813 global $wpdb;
814
815 // First, prepare an array containing rows and sizes of tables
816 $aDBc_tables_rows_sizes = array();
817 $aDBc_result = $wpdb->get_results('SHOW TABLE STATUS FROM `'.DB_NAME.'`');
818 foreach($aDBc_result as $aDBc_row){
819 $aDBc_table_size = $aDBc_row->Data_length + $aDBc_row->Index_length;
820 $aDBc_table_lost = $aDBc_row->Data_free;
821 $aDBc_tables_rows_sizes[$aDBc_row->Name] = array('rows' => $aDBc_row->Rows, 'size' => $aDBc_table_size, 'lost' => $aDBc_table_lost);
822 }
823
824 // Prepare ana array to hold all info about tables
825 $aDBc_all_tables = array();
826 $aDBc_prefix_list = array();
827 // If is Multisite then we retrieve the list of all prefixes
828 if(function_exists('is_multisite') && is_multisite()){
829 $blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
830 foreach($blogs_ids as $blog_id){
831 $aDBc_prefix_list[$wpdb->get_blog_prefix($blog_id)] = $blog_id;
832 }
833 }else{
834 $aDBc_prefix_list[$wpdb->prefix] = "1";
835 }
836 // Get the names of all tables in the database
837 $aDBc_all_tables_names = $wpdb->get_results("SELECT table_name FROM information_schema.tables WHERE table_schema = '" . DB_NAME . "'");
838
839 foreach($aDBc_all_tables_names as $aDBc_table){
840
841 // Get table name
842 $table_name = "";
843 // This test to prevent issues in MySQL 8 where tables are not shown
844 // MySQL 5 uses $aDBc_table->table_name while MySQL 8 uses $aDBc_table->TABLE_NAME
845 if(property_exists($aDBc_table, "table_name")){
846 $table_name = $aDBc_table->table_name;
847 }else if(property_exists($aDBc_table, "TABLE_NAME")){
848 $table_name = $aDBc_table->TABLE_NAME;
849 }
850
851 // Holds the possible prefixes found for the current table
852 $aDBc_found_prefixes = array();
853 // Test if the table name starts with a valid prefix
854 foreach($aDBc_prefix_list as $prefix => $site_id){
855 if(substr($table_name, 0, strlen($prefix)) === $prefix){
856 $aDBc_found_prefixes[$prefix] = $site_id;
857 }
858 }
859 // If the table do not start with any valid prefix, we add it as it is
860 if(count($aDBc_found_prefixes) == 0){
861 $aDBc_table_name_without_prefix = $table_name;
862 $aDBc_table_prefix = "";
863 $aDBc_table_site = "1";
864 }else if(count($aDBc_found_prefixes) == 1){
865 // If the number of possible prefixes found is 1, we add the table name with its data
866 // Get the first element in $aDBc_found_prefixes
867 reset($aDBc_found_prefixes);
868 $aDBc_table_prefix = key($aDBc_found_prefixes);
869 $aDBc_table_site = current($aDBc_found_prefixes);
870 $aDBc_table_name_without_prefix = substr($table_name, strlen($aDBc_table_prefix));
871 }else{
872 // If the number of possible prefixes found >= 2, we choose the longest prefix as valid one
873 $aDBc_table_prefix = "";
874 $aDBc_table_site = "";
875 $aDBc_table_name_without_prefix = "";
876 foreach($aDBc_found_prefixes as $aDBc_prefix => $aDBc_site){
877 if(strlen($aDBc_prefix) >= strlen($aDBc_table_prefix)){
878 $aDBc_table_prefix = $aDBc_prefix;
879 $aDBc_table_site = $aDBc_site;
880 $aDBc_table_name_without_prefix = substr($table_name, strlen($aDBc_table_prefix));
881 }
882 }
883 }
884 // Add table information to the global array
885 // If the table has not been added yet, add it and initiate its info
886 if(empty($aDBc_all_tables[$aDBc_table_name_without_prefix])){
887 $aDBc_all_tables[$aDBc_table_name_without_prefix] = array('belongs_to' => '', 'maybe_belongs_to' => '', 'type' => '', 'sites' => array());
888 }
889 // Add info of the task according to the current site
890 $aDBc_all_tables[$aDBc_table_name_without_prefix]['sites'][$aDBc_table_site] = array('prefix' => $aDBc_table_prefix,
891 'rows' => $aDBc_tables_rows_sizes[$table_name]['rows'],
892 'size' => $aDBc_tables_rows_sizes[$table_name]['size'],
893 'lost' => $aDBc_tables_rows_sizes[$table_name]['lost'],
894 );
895 }
896 return $aDBc_all_tables;
897 }
898
899 /***********************************************************************************
900 *
901 * Function proper to scheduled tasks processes
902 *
903 ***********************************************************************************/
904
905 /** Prepares all scheduled tasks for all sites (if any) in a multidimensional array */
906 function aDBc_get_all_scheduled_tasks() {
907 $aDBc_all_tasks = array();
908 if(function_exists('is_multisite') && is_multisite()){
909 global $wpdb;
910 $blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
911 foreach($blogs_ids as $blog_id){
912 switch_to_blog($blog_id);
913 aDBc_add_scheduled_tasks($aDBc_all_tasks, $blog_id);
914 restore_current_blog();
915 }
916 }else{
917 aDBc_add_scheduled_tasks($aDBc_all_tasks, "1");
918 }
919 return $aDBc_all_tasks;
920 }
921
922 /** Prepares scheduled tasks for one single site (Used by aDBc_get_all_scheduled_tasks() function) */
923 function aDBc_add_scheduled_tasks(&$aDBc_all_tasks, $blog_id) {
924 $cron = _get_cron_array();
925 $schedules = wp_get_schedules();
926 foreach((array) $cron as $timestamp => $cronhooks){
927 foreach( (array) $cronhooks as $hook => $events){
928 foreach( (array) $events as $event){
929 // If the frequency exist
930 if($event['schedule']){
931 if(!empty($schedules[$event['schedule']])){
932 $aDBc_frequency = $schedules[$event['schedule']]['display'];
933 }else{
934 $aDBc_frequency = __('Unknown!', 'advanced-database-cleaner');
935 }
936 }else{
937 $aDBc_frequency = __('Single event', 'advanced-database-cleaner');
938 }
939 // Get arguments
940 $aDBc_args_array = array();
941 if(!empty($event['args'])){
942 $aDBc_args = $event['args'];
943 foreach( (array) $aDBc_args as $id => $arg){
944 array_push($aDBc_args_array, $arg);
945 }
946 }
947 if(empty($aDBc_args_array)){
948 $args_string = "none";
949 }else{
950 $args_string = serialize($aDBc_args_array);
951 }
952 // If the task has not been added yet, add it and initiate its info
953 if(empty($aDBc_all_tasks[$hook])){
954
955 $aDBc_all_tasks[$hook] = array('belongs_to' => '', 'maybe_belongs_to' => '', 'type' => '', 'sites' => array());
956
957 }
958
959 // Initialize args array
960 if(empty($aDBc_all_tasks[$hook]['sites'][$blog_id]['args'])){
961 $aDBc_all_tasks[$hook]['sites'][$blog_id]['args'] = array();
962 }
963
964 array_push($aDBc_all_tasks[$hook]['sites'][$blog_id]['args'], array('frequency' => $aDBc_frequency,
965 'next_run' => get_date_from_gmt(@date('Y-m-d H:i:s', $timestamp), 'M j, Y @ H:i:s'),
966 'timestamp' => $timestamp,
967 'arguments' => $args_string));
968 }
969 }
970 }
971 }
972
973
974 /***********************************************************************************
975 * Transfrom bytes to corresponding best size system: KB, MB or GB
976 ***********************************************************************************/
977 function aDBc_get_size_from_bytes($bytes) {
978 $size = $bytes / 1024;
979 if($size >= 1024){
980 $size = $size / 1024;
981 if($size >= 1024){
982 $size = $size / 1024;
983 $size = round($size, 1) . " GB";
984 }else{
985 $size = round($size, 1) . " MB";
986 }
987 }else{
988 $size = round($size, 1) . " KB";
989 }
990 return $size;
991 }
992
993 /***********************************************************************************
994 * Create the folder plus an index.php for silence is golden
995 ***********************************************************************************/
996 function aDBc_create_folder_plus_index_file($folder) {
997
998 wp_mkdir_p($folder);
999
1000 // Create index file
1001 $myfile = fopen($folder . '/index.php', "w");
1002 if($myfile){
1003 fwrite($myfile, "<?php\n// Silence is golden.");
1004 fclose($myfile);
1005 }
1006
1007 // Create htaccess file
1008 // $myfile = fopen($folder . '/.htaccess', "w");
1009 // if($myfile){
1010 // fwrite($myfile, "Deny from all");
1011 // fclose($myfile);
1012 // }
1013 }
1014
1015 /**************************************************************************************************
1016 * Delete folder with its content
1017 *************************************************************************************************/
1018 function aDBc_delete_folder_with_content($path){
1019
1020 if(!file_exists($path))
1021 return;
1022 $dir = opendir($path);
1023 while(($file = readdir($dir)) !== false){
1024 if ($file != '.' && $file != '..'){
1025 unlink($path . "/" . $file);
1026 }
1027 }
1028 closedir($dir);
1029 rmdir( $path );
1030
1031 }
1032
1033 /**************************************************************************************************
1034 * Uupdate task in db after being deleted
1035 *************************************************************************************************/
1036 function aDBc_update_task_in_db_after_delete($arg_name, $db_option_name){
1037
1038 $clean_schedule_setting = get_option($db_option_name);
1039 // We will proceed only if settings are an array
1040 if(is_array($clean_schedule_setting)){
1041 $schedule = $clean_schedule_setting[$arg_name];
1042 $schedule['active'] = "0";
1043 $clean_schedule_setting[$arg_name] = $schedule;
1044 update_option($db_option_name, $clean_schedule_setting, "no");
1045 }
1046
1047 }
1048
1049 /***********************************************************************************
1050 * Get core tables that are categorized by default
1051 ***********************************************************************************/
1052 function aDBc_get_core_tables() {
1053
1054 /*
1055 * yyy: WP core tables
1056 * Found in wp-admin/includes/schema.php and wp-admin/includes/upgrade.php
1057 * After each release of WP, this list should be updated to add new tables if necessary (to minimize searches in files).
1058 */
1059 $aDBc_wp_core_tables = array(
1060 'terms',
1061 'term_taxonomy',
1062 'term_relationships',
1063 'commentmeta',
1064 'comments',
1065 'links',
1066 'options',
1067 'postmeta',
1068 'posts',
1069 'users',
1070 'usermeta',
1071 // Since 3.0 in wp-admin/includes/upgrade.php
1072 'sitecategories',
1073 // Since 4.4
1074 'termmeta'
1075 );
1076
1077 // If MU, add tables of MU
1078 if(function_exists('is_multisite') && is_multisite()){
1079 array_push($aDBc_wp_core_tables, 'blogs');
1080 array_push($aDBc_wp_core_tables, 'blog_versions');
1081 array_push($aDBc_wp_core_tables, 'blogmeta');
1082 array_push($aDBc_wp_core_tables, 'registration_log');
1083 array_push($aDBc_wp_core_tables, 'site');
1084 array_push($aDBc_wp_core_tables, 'sitemeta');
1085 array_push($aDBc_wp_core_tables, 'signups');
1086 }
1087
1088 return $aDBc_wp_core_tables;
1089 }
1090
1091 /***********************************************************************************
1092 * Get core tasks that are categorized by default
1093 ***********************************************************************************/
1094 function aDBc_get_core_tasks() {
1095
1096 /*
1097 * yyy: WP core tasks
1098 * After each release of WP, this list should be updated to add new tasks if necessary (to minimize searches in files).
1099 */
1100 $aDBc_wp_core_tasks = array(
1101 'wp_version_check',
1102 'wp_update_plugins',
1103 'wp_update_themes',
1104 'wp_maybe_auto_update',
1105 'wp_scheduled_auto_draft_delete',
1106 'wp_scheduled_delete',
1107 'update_network_counts',
1108 'delete_expired_transients',
1109 'wp_privacy_delete_old_export_files',
1110 'recovery_mode_clean_expired_keys'
1111 );
1112
1113 return $aDBc_wp_core_tasks;
1114 }
1115
1116 /***********************************************************************************
1117 * Get core options that are categorized by default
1118 ***********************************************************************************/
1119 function aDBc_get_core_options() {
1120
1121 /*
1122 * yyy: WP core options
1123 * Found in wp-admin/includes/schema.php
1124 * After each release of WP, this list should be updated to add new options if necessary (to minimize searches in files).
1125 */
1126 $aDBc_wp_core_options = array(
1127 'siteurl',
1128 'home',
1129 'blogname',
1130 'blogdescription',
1131 'users_can_register',
1132 'admin_email',
1133 'start_of_week',
1134 'use_balanceTags',
1135 'use_smilies',
1136 'require_name_email',
1137 'comments_notify',
1138 'posts_per_rss',
1139 'rss_use_excerpt',
1140 'mailserver_url',
1141 'mailserver_login',
1142 'mailserver_pass',
1143 'mailserver_port',
1144 'default_category',
1145 'default_comment_status',
1146 'default_ping_status',
1147 'default_pingback_flag',
1148 'posts_per_page',
1149 'date_format',
1150 'time_format',
1151 'links_updated_date_format',
1152 'comment_moderation',
1153 'moderation_notify',
1154 'permalink_structure',
1155 'gzipcompression',
1156 'hack_file',
1157 'blog_charset',
1158 'moderation_keys',
1159 'active_plugins',
1160 'category_base',
1161 'ping_sites',
1162 'advanced_edit',
1163 'comment_max_links',
1164 'gmt_offset',
1165 // 1.5
1166 'default_email_category',
1167 'recently_edited',
1168 'template',
1169 'stylesheet',
1170 'comment_whitelist',
1171 'blacklist_keys',
1172 'comment_registration',
1173 'html_type',
1174 // 1.5.1
1175 'use_trackback',
1176 // 2.0
1177 'default_role',
1178 'db_version',
1179 // 2.0.1
1180 'uploads_use_yearmonth_folders',
1181 'upload_path',
1182 // 2.1
1183 'blog_public',
1184 'default_link_category',
1185 'show_on_front',
1186 // 2.2
1187 'tag_base',
1188 // 2.5
1189 'show_avatars',
1190 'avatar_rating',
1191 'upload_url_path',
1192 'thumbnail_size_w',
1193 'thumbnail_size_h',
1194 'thumbnail_crop',
1195 'medium_size_w',
1196 'medium_size_h',
1197 // 2.6
1198 'avatar_default',
1199 // 2.7
1200 'large_size_w',
1201 'large_size_h',
1202 'image_default_link_type',
1203 'image_default_size',
1204 'image_default_align',
1205 'close_comments_for_old_posts',
1206 'close_comments_days_old',
1207 'thread_comments',
1208 'thread_comments_depth',
1209 'page_comments',
1210 'comments_per_page',
1211 'default_comments_page',
1212 'comment_order',
1213 'sticky_posts',
1214 'widget_categories',
1215 'widget_text',
1216 'widget_rss',
1217 'uninstall_plugins',
1218 // 2.8
1219 'timezone_string',
1220 // 3.0
1221 'page_for_posts',
1222 'page_on_front',
1223 // 3.1
1224 'default_post_format',
1225 // 3.5
1226 'link_manager_enabled',
1227 // 4.3.0
1228 'finished_splitting_shared_terms',
1229 'site_icon',
1230 // 4.4.0
1231 'medium_large_size_w',
1232 'medium_large_size_h',
1233 // 4.9.6
1234 'wp_page_for_privacy_policy',
1235 // 4.9.8
1236 'show_comments_cookies_opt_in',
1237 // Deleted from new versions
1238 'blodotgsping_url', 'bodyterminator', 'emailtestonly', 'phoneemail_separator', 'smilies_directory',
1239 'subjectprefix', 'use_bbcode', 'use_blodotgsping', 'use_phoneemail', 'use_quicktags', 'use_weblogsping',
1240 'weblogs_cache_file', 'use_preview', 'use_htmltrans', 'smilies_directory', 'fileupload_allowedusers',
1241 'use_phoneemail', 'default_post_status', 'default_post_category', 'archive_mode', 'time_difference',
1242 'links_minadminlevel', 'links_use_adminlevels', 'links_rating_type', 'links_rating_char',
1243 'links_rating_ignore_zero', 'links_rating_single_image', 'links_rating_image0', 'links_rating_image1',
1244 'links_rating_image2', 'links_rating_image3', 'links_rating_image4', 'links_rating_image5',
1245 'links_rating_image6', 'links_rating_image7', 'links_rating_image8', 'links_rating_image9',
1246 'links_recently_updated_time', 'links_recently_updated_prepend', 'links_recently_updated_append',
1247 'weblogs_cacheminutes', 'comment_allowed_tags', 'search_engine_friendly_urls', 'default_geourl_lat',
1248 'default_geourl_lon', 'use_default_geourl', 'weblogs_xml_url', 'new_users_can_blog', '_wpnonce',
1249 '_wp_http_referer', 'Update', 'action', 'rich_editing', 'autosave_interval', 'deactivated_plugins',
1250 'can_compress_scripts', 'page_uris', 'update_core', 'update_plugins', 'update_themes', 'doing_cron',
1251 'random_seed', 'rss_excerpt_length', 'secret', 'use_linksupdate', 'default_comment_status_page',
1252 'wporg_popular_tags', 'what_to_show', 'rss_language', 'language', 'enable_xmlrpc', 'enable_app',
1253 'embed_autourls', 'default_post_edit_rows',
1254 //Found in wp-admin/includes/upgrade.php
1255 'widget_search',
1256 'widget_recent-posts',
1257 'widget_recent-comments',
1258 'widget_archives',
1259 'widget_meta',
1260 'sidebars_widgets',
1261 // Found in wp-admin/includes/schema.php but not with the above list
1262 'initial_db_version',
1263 'WPLANG',
1264 // Found in wp-admin/includes/class-wp-plugins-list-table.php
1265 'recently_activated',
1266 // Found in wp-admin/network/site-info.php
1267 'rewrite_rules',
1268 // Found in wp-admin/network.php
1269 'auth_key',
1270 'auth_salt',
1271 'logged_in_key',
1272 'logged_in_salt',
1273 'nonce_key',
1274 'nonce_salt',
1275 // Found in wp-includes/theme.php
1276 'theme_switched',
1277 // Found in wp-includes/class-wp-customize-manager.php
1278 'current_theme',
1279 // Found in wp-includes/cron.php
1280 'cron',
1281 // Unknown : To verify
1282 'user_roles',
1283 'widget_nav_menu',
1284 );
1285
1286 // Before doing anything, we add some special options to the WP core options array
1287 // The 'user_roles' option is added in Multi-site as $prefix.'user_roles'. So for each site we should add this options in that format
1288 if(function_exists('is_multisite') && is_multisite()){
1289 global $wpdb;
1290 $blogs_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
1291 foreach($blogs_ids as $blog_id){
1292 array_push($aDBc_wp_core_options, $wpdb->get_blog_prefix($blog_id).'user_roles');
1293 }
1294 }
1295
1296 return $aDBc_wp_core_options;
1297 }
1298
1299 ?>