__('Table', 'advanced-database-cleaner'), 'plural' => __('Tables', 'advanced-database-cleaner'), 'ajax' => false )); $this->aDBc_prepare_and_count_tables(); $this->aDBc_print_page_content(); } /** Prepare items */ function aDBc_prepare_and_count_tables() { if ( ADBC_PLUGIN_PLAN == "pro" ) { // Verify if the adbc_uploads cannot be created $adbc_folder_permission = get_option( "aDBc_permission_adbc_folder_needed" ); if ( ! empty( $adbc_folder_permission ) ) { $this->aDBc_permission_adbc_folder_msg = sprintf( __( 'The plugin needs to create the following directory "%1$s" to save the scan results but this was not possible automatically. Please create that directory manually and set correct permissions so it can be writable by the plugin.','advanced-database-cleaner' ), ADBC_UPLOAD_DIR_PATH_TO_ADBC ); // Once we display the msg, we delete that option from DB delete_option( "aDBc_permission_adbc_folder_needed" ); } } // Test if user wants to delete a scheduled task if(isset($_POST['aDBc_delete_schedule'])){ //Quick nonce security check! if(!check_admin_referer('delete_optimize_schedule_nonce', 'delete_optimize_schedule_nonce')) return; //get out if we didn't click the delete link // We delete the schedule $aDBc_sanitized_schedule_name = sanitize_html_class($_POST['aDBc_delete_schedule']); wp_clear_scheduled_hook('aDBc_optimize_scheduler', array($aDBc_sanitized_schedule_name)); // We delete the item from database $aDBc_schedules = get_option('aDBc_optimize_schedule'); unset($aDBc_schedules[$aDBc_sanitized_schedule_name]); update_option('aDBc_optimize_schedule', $aDBc_schedules, "no"); $this->aDBc_message = __('The clean-up schedule deleted successfully!', 'advanced-database-cleaner'); } // Verify if the user wants to edit the categorization of a table. This block test comes from edit_item_categorization.php if ( ADBC_PLUGIN_PLAN == "pro" ) { if ( isset( $_POST['aDBc_cancel'] ) ) { // If the user cancels the edit, remove the temp file if ( file_exists( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tables_manually_correction_temp.txt" ) ) unlink( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tables_manually_correction_temp.txt" ); } else if ( isset( $_POST['aDBc_correct'] ) ) { // Get the new belongs to of items $new_belongs_to = $_POST['new_belongs_to']; // Get value of checkbox to see if user wants to send correction to the server if ( isset( $_POST['aDBc_send_correction_to_server'] ) ) { $this->aDBc_message = aDBc_edit_categorization_of_items( "tables", $new_belongs_to, 1 ); } else { $this->aDBc_message = aDBc_edit_categorization_of_items( "tables", $new_belongs_to, 0 ); } // Remove the temp file if ( file_exists( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tables_manually_correction_temp.txt" ) ) unlink( ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tables_manually_correction_temp.txt" ); } } // Process bulk action if any before preparing tables to display $this->process_bulk_action(); // Get the names of all tables that should be optimized and count them to print it in the right side of the page global $wpdb; $aDBc_tables_to_optimize = $wpdb->get_results("SELECT table_name, data_free FROM information_schema.tables WHERE table_schema = '" . DB_NAME ."' and Engine <> 'InnoDB' and data_free > 0"); $this->aDBc_total_tables_to_optimize = count($aDBc_tables_to_optimize); foreach($aDBc_tables_to_optimize as $table){ // Get table name $table_name = ""; // This test to prevent issues in MySQL 8 where tables are not shown // MySQL 5 uses $table->table_name while MySQL 8 uses $table->TABLE_NAME if(property_exists($table, "table_name")){ $table_name = $table->table_name; }else if(property_exists($table, "TABLE_NAME")){ $table_name = $table->TABLE_NAME; } array_push($this->aDBc_tables_name_to_optimize, $table_name); if(property_exists($table, "data_free")){ $this->aDBc_total_lost += $table->data_free; } } // Get the names of all tables that should be repaired and count them to print it in the right side of the page $aDBc_tables_maybe_repair = $wpdb->get_results("SELECT table_name FROM information_schema.tables WHERE table_schema = '" . DB_NAME ."' and Engine IN ('CSV', 'MyISAM', 'ARCHIVE')"); foreach($aDBc_tables_maybe_repair as $table){ // Get table name $table_name = ""; // This test to prevent issues in MySQL 8 where tables are not shown // MySQL 5 uses $table->table_name while MySQL 8 uses $table->TABLE_NAME if(property_exists($table, "table_name")){ $table_name = $table->table_name; }else if(property_exists($table, "TABLE_NAME")){ $table_name = $table->TABLE_NAME; } $query_result = $wpdb->get_results("CHECK TABLE `" . $table_name. "`"); foreach($query_result as $row){ if($row->Msg_type == 'error'){ if(preg_match('/corrupt/i', $row->Msg_text)){ array_push($this->aDBc_tables_name_to_repair, $table_name); } } } } $this->aDBc_total_tables_to_repair = count($this->aDBc_tables_name_to_repair); // Prepare data aDBc_prepare_items_to_display( $this->aDBc_tables_to_display, $this->aDBc_tables_categories_info, $this->aDBc_which_button_to_show, $this->aDBc_tables_name_to_optimize, $this->aDBc_tables_name_to_repair, $this->array_belongs_to_counts, $this->aDBc_message, $this->aDBc_class_message, "tables" ); // Call WP prepare_items function $this->prepare_items(); } /** WP: Get columns */ function get_columns(){ $aDBc_belongs_to_toolip = " " . __('Indicates the creator of the table: either a plugin, a theme or WordPress itself. If not sure about the creator, an estimation (%) will be displayed. The higher the percentage is, the more likely that the table belongs to that creator.','advanced-database-cleaner') ." "; $columns = array( 'cb' => '', 'table_name' => __('Table name','advanced-database-cleaner'), 'table_prefix' => __('Prefix','advanced-database-cleaner'), 'table_rows' => __('Rows','advanced-database-cleaner'), 'table_size' => __('Size','advanced-database-cleaner'), 'table_lost' => __('Lost','advanced-database-cleaner'), 'site_id' => __('Site','advanced-database-cleaner'), 'table_belongs_to' => __('Belongs to','advanced-database-cleaner') . $aDBc_belongs_to_toolip ); return $columns; } function get_sortable_columns() { $sortable_columns = array( 'table_name' => array( 'table_name', false ), 'table_rows' => array( 'table_rows', false ), 'table_size' => array( 'table_size', false ), 'site_id' => array( 'site_id', false ) ); return $sortable_columns; } /** WP: Prepare items to display */ function prepare_items() { $columns = $this->get_columns(); $hidden = $this->get_hidden_columns(); $sortable = $this->get_sortable_columns(); $this->_column_headers = array($columns, $hidden, $sortable); $per_page = 50; if(!empty($_GET['per_page'])){ $per_page = absint($_GET['per_page']); } $current_page = $this->get_pagenum(); // Prepare sequence of tables to display $display_data = array_slice($this->aDBc_tables_to_display,(($current_page-1) * $per_page), $per_page); $this->set_pagination_args( array( 'total_items' => count($this->aDBc_tables_to_display), 'per_page' => $per_page )); $this->items = $display_data; } /** WP: Get columns that should be hidden */ function get_hidden_columns() { // If MU, nothing to hide, else hide Side ID column if ( function_exists( 'is_multisite' ) && is_multisite() ) { return array( 'table_prefix', 'table_lost' ); } else { return array( 'table_prefix', 'table_lost', 'site_id' ); } } /** WP: Column default */ function column_default( $item, $column_name ) { switch ( $column_name ) { case 'table_name': $prefix_and_name = $item['table_prefix'] . $item[$column_name]; $return_name = "" . esc_html($item['table_prefix']) . "" . esc_html($item[$column_name]); if ( $item['table_lost'] > 0 && in_array( $prefix_and_name, $this->aDBc_tables_name_to_optimize ) ) { $lost = aDBc_get_size_from_bytes( $item['table_lost'] ); $return_name .= "
"; $return_name .= "" . __( 'Lost space', 'advanced-database-cleaner' ) . ""; $return_name .= " : " . $lost . ""; $return_name .= " (" . __( 'to optimize', 'advanced-database-cleaner' ) . ")"; } if ( in_array( $prefix_and_name, $this->aDBc_tables_name_to_repair ) ) { $return_name .= "
"; $return_name .= "" . __( 'Corrupted!', 'advanced-database-cleaner' ) . ""; $return_name .= " (" . __( 'to repair', 'advanced-database-cleaner' ) . ")"; } return $return_name; break; case 'table_size': return aDBc_get_size_from_bytes( $item['table_size'] ); break; case 'table_lost': return aDBc_get_size_from_bytes( $item['table_lost'] ); break; case 'table_prefix': case 'table_rows': case 'site_id': case 'table_belongs_to': return $item[$column_name]; default: return print_r( $item, true ) ; //Show the whole array for troubleshooting purposes } } /** WP: Column cb for check box */ function column_cb( $item ) { $value = $item['table_prefix'] . "|" . $item['table_name']; return sprintf( '', esc_attr($value) ); } /** WP: Get bulk actions */ function get_bulk_actions() { $actions = array( 'scan_selected' => __( 'Scan selected tables', 'advanced-database-cleaner' ), 'edit_categorization' => __( 'Edit categorization', 'advanced-database-cleaner' ), 'optimize' => __( 'Optimize', 'advanced-database-cleaner' ), 'repair' => __( 'Repair', 'advanced-database-cleaner' ), 'empty' => __( 'Empty rows', 'advanced-database-cleaner' ), 'delete' => __( 'Delete', 'advanced-database-cleaner' ) ); if ( ADBC_PLUGIN_PLAN == "free" ) { unset( $actions['scan_selected'] ); unset( $actions['edit_categorization'] ); } return $actions; } /** WP: Message to display when no items found */ function no_items() { _e( 'No tables found!', 'advanced-database-cleaner' ); } /** WP: Process bulk actions */ public function process_bulk_action() { // Detect when a bulk action is being triggered. $action = $this->current_action(); if ( ! $action ) return; // security check! check_admin_referer( 'bulk-' . $this->_args['plural'] ); // Check role if ( ! current_user_can( 'administrator' ) ) wp_die( 'Security check failed!' ); // Get the list of all tables names to validate selected tables global $wpdb; $sql_rows = "SELECT `TABLE_NAME` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = '" . DB_NAME . "';"; $valid_tables_names = $wpdb->get_col( $sql_rows ); if ( $action == 'delete' ) { // Prepare an array containing names of tables deleted $names_deleted = array(); // If the user wants to clean the tables he/she selected if(isset($_POST['aDBc_elements_to_process'])){ foreach($_POST['aDBc_elements_to_process'] as $table){ $table_info = explode("|", $table, 2); $table_prefix = $table_info[0]; $table_name = wp_unslash($table_info[1]); // Because WP adds slashes to the name in the POST request $full_table_name = $table_prefix . $table_name; // Validate table name before deleting if ( in_array( $full_table_name, $valid_tables_names ) ) { if($wpdb->query("DROP TABLE `" . $full_table_name . "`")){ array_push($names_deleted, $table_name); } } } // After deleting tables, delete names also from file categorization // xxx (should I add this as well to options & crons?) if ( ADBC_PLUGIN_PLAN == "pro" ) { aDBc_refresh_categorization_file_after_delete($names_deleted, 'tables'); } // Update the message to show to the user $this->aDBc_message = __('Selected tables cleaned successfully!', 'advanced-database-cleaner'); } }else if($action == 'optimize'){ // If the user wants to optimize the tables he/she selected if(isset($_POST['aDBc_elements_to_process'])){ foreach($_POST['aDBc_elements_to_process'] as $table) { $table_info = explode("|", $table, 2); $table_prefix = $table_info[0]; $table_name = wp_unslash($table_info[1]); // Because WP adds slashes to the name in the POST request $full_table_name = $table_prefix . $table_name; // Validate table name before optimizing if ( in_array( $full_table_name, $valid_tables_names ) ) { $wpdb->query("OPTIMIZE TABLE `" . $full_table_name . "`"); // run analyze sql query to force updating the table statistics $wpdb->query("ANALYZE TABLE `" . $full_table_name . "`"); } } // Update the message to show to the user $this->aDBc_message = __('Selected tables optimized successfully!', 'advanced-database-cleaner'); } }else if($action == 'empty'){ // If the user wants to empty the tables he/she selected if(isset($_POST['aDBc_elements_to_process'])){ foreach($_POST['aDBc_elements_to_process'] as $table) { $table_info = explode("|", $table, 2); $table_prefix = $table_info[0]; $table_name = wp_unslash($table_info[1]); // Because WP adds slashes to the name in the POST request $full_table_name = $table_prefix . $table_name; // Validate table name before emptying if ( in_array( $full_table_name, $valid_tables_names ) ) { $wpdb->query("TRUNCATE TABLE `" . $full_table_name . "`"); // run analyze sql query to force updating the table statistics $wpdb->query("ANALYZE TABLE `" . $full_table_name . "`"); } } // Update the message to show to the user $this->aDBc_message = __('Selected tables emptied successfully!', 'advanced-database-cleaner'); } }else if($action == 'repair'){ // If the user wants to repair the tables he/she selected if(isset($_POST['aDBc_elements_to_process'])){ $cannot_repair = 0; foreach($_POST['aDBc_elements_to_process'] as $table) { $table_info = explode("|", $table, 2); $table_prefix = $table_info[0]; $table_name = wp_unslash($table_info[1]); // Because WP adds slashes to the name in the POST request $full_table_name = $table_prefix . $table_name; // Validate table name before repairing if ( in_array( $full_table_name, $valid_tables_names ) ) { $query_result = $wpdb->get_results("REPAIR TABLE `" . $full_table_name . "`"); foreach($query_result as $row){ if($row->Msg_type == 'error'){ if(preg_match('/corrupt/i', $row->Msg_text)){ $cannot_repair++; } } else { // run analyze sql query to force updating the table statistics $wpdb->query("ANALYZE TABLE `" . $full_table_name . "`"); } } } } // Update the message to show to the user if($cannot_repair == 0){ $this->aDBc_message = __('Selected tables repaired successfully!', 'advanced-database-cleaner'); }else{ $this->aDBc_class_message = "error"; $this->aDBc_message = __('Some of your tables cannot be repaired!', 'advanced-database-cleaner'); } } }else if($action == 'edit_categorization'){ // If the user wants to edit categorization of the tables he/she selected if(isset($_POST['aDBc_elements_to_process'])){ // Create a temp file containing tables names to change categorization for $aDBc_path_items = @fopen(ADBC_UPLOAD_DIR_PATH_TO_ADBC . "/tables_manually_correction_temp.txt", "w"); if($aDBc_path_items){ foreach($_POST['aDBc_elements_to_process'] as $table) { $table_info = explode("|", $table, 2); $table_prefix = $table_info[0]; $table_name = wp_unslash($table_info[1]); // Because WP adds slashes to the name in the POST request $full_table_name = $table_prefix . $table_name; // Validate table name before adding it to the file if ( in_array( $full_table_name, $valid_tables_names ) ) { fwrite($aDBc_path_items, $table_name . "\n"); } } fclose($aDBc_path_items); } } } } /** Print the page content */ function aDBc_print_page_content(){ // Print a message if any if($this->aDBc_message != ""){ echo '

' . $this->aDBc_message . '

'; } // If the folder adbc_uploads cannot be created, show a msg to users if(!empty($this->aDBc_permission_adbc_folder_msg)){ echo '

' . $this->aDBc_permission_adbc_folder_msg . '

'; } ?>
aDBc_tables_categories_info['o']['count'] > 0){ echo '
' . __('Tables below seem to be orphan! However, please delete only those you are sure to be orphan!','advanced-database-cleaner') . '
'; }else if(($_GET['aDBc_cat'] == 'all' || $_GET['aDBc_cat'] == 'u') && $this->aDBc_tables_categories_info['u']['count'] > 0){ $aDBc_settings = get_option('aDBc_settings'); $hide_not_categorized_msg = empty($aDBc_settings['hide_not_categorized_yet_msg']) ? "" : $aDBc_settings['hide_not_categorized_yet_msg']; if ( $hide_not_categorized_msg != "yes" ) { echo '
' . '
' . __('Some of your tables are not categorized yet! Please click on the button below to categorize them!','advanced-database-cleaner') . '
' . '
' . '
'; } } } ?>
aDBc_which_button_to_show == "new_search" ) { $aDBc_search_text = __( 'Scan tables', 'advanced-database-cleaner' ); } else { $aDBc_search_text = __( 'Continue scanning ...', 'advanced-database-cleaner' ); } ?>
upgrade to Pro to categorize and detect orphaned tables','advanced-database-cleaner') ?>
aDBc_tables_categories_info as $abreviation => $category_info ) { $aDBc_new_URI = add_query_arg( 'aDBc_cat', $abreviation, $aDBc_new_URI ); $selected_color = $abreviation == $_GET['aDBc_cat'] ? $category_info['color'] : '#eee'; $aDBc_link_style = "color:" . $category_info['color']; $aDBc_count = $category_info['count']; if ( ADBC_PLUGIN_PLAN == "free" && $abreviation != "all" && $abreviation != "u" ) { $aDBc_new_URI = ""; $aDBc_link_style = $aDBc_link_style . ";cursor:default;pointer-events:none"; $aDBc_count = "-"; } ?>
display(); ?>
aDBc_total_tables_to_optimize == 0 && $this->aDBc_total_tables_to_repair == 0 ) { ?>
aDBc_total_tables_to_optimize > 0 ) { $aDBc_new_URI = add_query_arg( 't_type', 'optimize', $aDBc_new_URI ); ?>
aDBc_total_lost ); echo __( 'You can save around', 'advanced-database-cleaner' ) . " : " . $aDBc_table_size; ?>
aDBc_total_tables_to_repair > 0 ) { $aDBc_new_URI = add_query_arg( 't_type', 'repair', $aDBc_new_URI ); $to_repair_css = $this->aDBc_total_tables_to_optimize > 0 ? "aDBc-to-repair-section" : ""; ?>
" . $count_schedules ." " .__('optimize schedule(s) set','advanced-database-cleaner') . "
"; ?>
$hook_params ) { echo "
"; echo "" . __( 'Name', 'advanced-database-cleaner' ) . " : " . $hook_name; echo "
"; // We convert hook name to a string because the arg maybe only a digit! $timestamp = wp_next_scheduled( "aDBc_optimize_scheduler", array( $hook_name . '' ) ); if($timestamp){ $next_run = get_date_from_gmt(date('Y-m-d H:i:s', (int) $timestamp), 'M j, Y - H:i'); }else{ $next_run = "---"; } echo "".__('Next run','advanced-database-cleaner') . " : " . $next_run . "
"; $operation1 = in_array('optimize', $hook_params['operations']) ? __('Optimize','advanced-database-cleaner') : ''; $operation2 = in_array('repair', $hook_params['operations']) ? __('Repair','advanced-database-cleaner') : ''; $plus = !empty($operation1) && !empty($operation2) ? " + " : ""; echo "".__('Perform','advanced-database-cleaner') . " : " . $operation1 . $plus . $operation2 . "
"; $repeat = $hook_params['repeat']; switch($repeat){ case "once" : $repeat = __('Once','advanced-database-cleaner'); break; case "hourly" : $repeat = __('Hourly','advanced-database-cleaner'); break; case "twicedaily" : $repeat = __('Twice a day','advanced-database-cleaner'); break; case "daily" : $repeat = __('Daily','advanced-database-cleaner'); break; case "weekly" : $repeat = __('Weekly','advanced-database-cleaner'); break; case "monthly" : $repeat = __('Monthly','advanced-database-cleaner'); break; } echo "".__('Frequency','advanced-database-cleaner') . " : " . $repeat . "
"; echo $hook_params['active'] == "1" ? "" : ""; $aDBc_new_URI = $_SERVER['REQUEST_URI']; $aDBc_new_URI = add_query_arg('aDBc_view', 'edit_optimize_schedule', $aDBc_new_URI); $aDBc_new_URI = add_query_arg('hook_name', $hook_name, $aDBc_new_URI); ?> |