__('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_permission_adbc_folder_msg . '