*/ class Wp_Database_Tools_Database { /** * The table name. * * @since 1.0.0 * @access protected * @var String $table_name Content cronjobs row and count. */ protected $table_name; /** * The array of the cronjobs. * * @since 1.0.0 * @access protected * @var Wp_Database_Tools_Database_Cronjobs $cronjobs Content cronjobs row and count. */ protected $cronjobs; /** * The array of the cronjobs. * * @since 1.0.0 * @access protected * @var array $cronjobs_data Content cronjobs row and count. */ protected $cronjobs_data; /** * The array of the transients. * * @since 1.0.0 * @access protected * @var Wp_Database_Tools_Database_Transients $transients Content transients row and count. */ protected $transients; /** * The array of the transients_data. * * @since 1.0.0 * @access protected * @var array $transients_data Content transients_data row and count. */ protected $transients_data; /** * The general object. * * @since 1.0.0 * @access protected * @var Wp_Database_Tools_Database_General $general The general object. */ protected $general; /** * The general data of database. * * @since 1.0.0 * @access protected * @var array $general_data The general data of database. */ protected $general_data; /** * The tables object. * * @since 1.0.0 * @access protected * @var Wp_Database_Tools_Database_Tables $tables The general object. */ protected $tables; /** * The tables data of database. * * @since 1.0.0 * @access protected * @var array $tables_data The tables data of database. */ protected $tables_data; /** * The options object. * * @since 1.0.0 * @access protected * @var Wp_Database_Tools_Database_Options $options The general object. */ protected $options; /** * The options data of database. * * @since 1.0.0 * @access protected * @var array $general_data The options data of database. */ protected $options_data; /** * The plugins data. * * @since 1.0.0 * @access protected * @var array $plugins The plugins data. */ protected $plugins; /** * The themes data. * * @since 1.0.0 * @access protected * @var array $themes The themes data. */ protected $themes; /** * The matching obj. * * @since 1.0.0 * @access protected * @var Wp_Database_Tools_Matching $matching The matching obj. */ protected $matching; /** * The general data of database. * * @since 1.0.0 * @access protected * @var array $general_data The general data of database. */ protected $size; /** * The license status. * * @since 1.0.0 * @access protected * @var array $license_status The license status. */ public $license_status; /** * The data loop. * * @since 1.0.0 * @access protected * @var array $data_loop Control loop data. */ public $data_loop; /** * The limit records. * * @since 1.0.0 * @access protected * @var array $limit The limit records. */ protected $limit; /** * The key use of child class. * * @since 1.0.0 * @access protected * @var array $key The key use of child class. */ protected $key; /** * The full data data of database. * * @since 1.0.0 * @access protected * @var array $full_data The full data data of database. */ protected $full_data; /** * The api data of database. * * @since 1.0.0 * @access protected * @var array $api_data The api data of jsons. */ protected $api_data; /** * The feedback data of users selects. * * @since 1.0.0 * @access protected * @var array $feedback The feedback data of users selects. */ protected $feedback; /** * The porcent of loding. * * @since 1.0.0 * @access protected * @var array $current_loading The porcent of loding. */ protected $current_loading; /** * Indicates if record is multiple. * * @since 1.0.0 * @access protected * @var boolean $is_multiple Indicates if record is multiple. */ protected $is_multiple; /** * Property if the scanner must be force. * * @since 1.0.0 * @access protected * @var string $force_execute_scanner Property if the scanner must be force. */ protected $force_execute_scanner; /** * The cache data of records. * * @since 1.0.0 * @access protected * @var array $cache_data The cache data of records. */ protected $cache_data; /** * Initialize the database base. * * @param Wp_Database_Tools_Plugins $plugins obj. * @param Wp_Database_Tools_Themes $themes obj. * @param Wp_Database_Tools_Matching $matching obj. * @param string $license_status The status license. * * @since 1.0.0 */ public function __construct( $plugins, $themes, $matching, $license_status ) { // Dependencies. $this->load_dependencies(); $this->check_database_size(); $this->check_transients(); $this->plugins = $plugins->get_plugins(); $this->themes = $themes->get_themes(); $this->matching = $matching; $this->license_status = $license_status; // General. $this->general = new Wp_Database_Tools_Database_General(); $this->tables = new Wp_Database_Tools_Database_Tables( $this->plugins, $this->themes, $this->matching, $this->license_status ); $this->options = new Wp_Database_Tools_Database_Options( $this->plugins, $this->themes, $this->matching, $this->license_status ); $this->transients = new Wp_Database_Tools_Database_Transients( $this->plugins, $this->themes, $this->matching, $this->license_status ); $this->cronjobs = new Wp_Database_Tools_Database_Cronjobs( $this->plugins, $this->themes, $this->matching, $this->license_status ); } /** * Load dependencies. * Called in the constructor of the child classes. * * @param string $key The key of child. * @since 1.0.0 */ protected function load_dependencies_child( $key ) { require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/data/class-wp-database-tools-database-data.php'; require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/data/class-wp-database-tools-database-data-origin.php'; require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/data/class-wp-database-tools-database-data-author.php'; require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/data/class-wp-database-tools-database-data-marketplace.php'; if ( 'transients' === $key || 'options' === $key ) { require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/data/class-wp-database-tools-database-data-option.php'; } if ( 'cronjobs' === $key ) { require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/data/class-wp-database-tools-database-data-cronjob.php'; } if ( 'tables' === $key ) { require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/data/class-wp-database-tools-database-data-table.php'; } } /** * Collects the json that are stored through the API and stores them in an array. * * @since 1.0.0 * @return array The array with api data. */ protected function get_api_data( $key ) { // API data. $path_api_data = plugin_dir_path( __DIR__ ) . 'data/api/'; $api_data = array( 'source' => json_decode( file_get_contents( $path_api_data . $key . '.json' ) ), 'plugins' => json_decode( file_get_contents( $path_api_data . 'plugins.json' ) ), 'themes' => json_decode( file_get_contents( $path_api_data . 'themes.json' ) ), 'cores' => json_decode( file_get_contents( $path_api_data . 'cores.json' ) ), 'authors' => json_decode( file_get_contents( $path_api_data . 'authors.json' ) ), 'marketplaces' => json_decode( file_get_contents( $path_api_data . 'marketplaces.json' ) ), ); return $api_data; } /** * In some sections, such as options and transients, a calculation of the total number of records is performed. * It is also indicated if the calculated size is considered high or low. * * @since 1.0.0 * @return array The array with size data. */ protected function calculate_data_source_size( $cache_source ) { // Calc size format. $total_sum_value = is_array( $cache_source['size']['total']['value'] ) ? array_sum( $cache_source['size']['total']['value'] ) : $cache_source['size']['total']['value']; $autoload_sum_value = is_array( $cache_source['size']['autoload']['value'] ) ? array_sum( $cache_source['size']['autoload']['value'] ) : $cache_source['size']['autoload']['value']; $cache_source['size']['total']['format'] = $this->get_file_size_info( $total_sum_value ); $cache_source['size']['autoload']['format'] = $this->get_file_size_info( $autoload_sum_value ); $cache_source['size']['autoload']['indicator'] = $this->get_level_size( $autoload_sum_value ); return $cache_source; } /** * Reads from the json the flags that determine whether to perform data * processing or to collect data from the cache files. * * @since 1.0.0 * @return array The array with size data. */ protected function get_data_cache_indicator( $key ) { $cache_path = plugin_dir_path( __DIR__ ) . 'data/cache/' . WPDBT_PREFIX . $key; // Load source. $cache_source = file_get_contents( $cache_path . '_' . $key . '.json' ); if ( false === $cache_source ) { Wp_Database_Tools_Logger::error( 'GET CACHE: source fail' ); } // Load indicators. $cache_indicators = file_get_contents( $cache_path . '_indicators.json' ); if ( false === $cache_indicators ) { Wp_Database_Tools_Logger::error( 'GET CACHE: indicators fail' ); } $cache_source_decode = json_decode( $cache_source, true ); if ( false === $cache_source_decode || null === $cache_source_decode ) { Wp_Database_Tools_Logger::error( 'GET CACHE: fail decoding data ' . $key . ' fail' ); } $cache_indicators_decode = json_decode( $cache_indicators ); if ( false === $cache_indicators_decode || null === $cache_indicators_decode ) { Wp_Database_Tools_Logger::error( 'GET CACHE: fail decoding indicators ' . $key . ' fail' ); } $cache_data = array( 'source' => $cache_source_decode, 'indicators' => $cache_indicators_decode, ); return $cache_data; } /** * Sets the flags that determine whether data processing should be * performed and saves the information in json * * @since 1.0.0 */ protected function set_cache_indicators( $key, $api_data_source, $feedback, $sum_ids ) { $cache_path = plugin_dir_path( __DIR__ ) . 'data/cache/' . WPDBT_PREFIX . $key; $cache_data_indicators = array( 'api' => strlen( wp_json_encode( $api_data_source ) ), 'status' => strlen( wp_json_encode( array( $feedback, $this->license_status ) ) ), 'ids' => $sum_ids, ); file_put_contents( $cache_path . '_indicators.json', json_encode( $cache_data_indicators ) ); } /** * Returns a string depending on whether the size of the records is * considered high, medium or high. * * @since 1.0.0 * @return String The level by the size. */ public function get_level_size( $bytes ) { if ( $bytes <= 2097152 ) { return 'lower'; } if ( $bytes > 2097152 && $bytes < 5242880 ) { return 'medium'; } if ( $bytes >= 5242880 ) { return 'high'; } } /** * Establishes a transient with the state of charge. * * @since 1.0.0 */ protected function set_status_loading( $status, $porcent, $data_loop, $cache ) { $data = array( 'status' => $status, 'porcent' => $porcent, 'data_loop' => $data_loop, 'cache' => $cache, ); set_transient( WPDBT_PREFIX . 'status_loading', $data ); } /** * Returns the transient that stores the load loop data. * * @param string $key The key transient. * @since 1.0.0 * @return array $data_loop Transient data loop. */ public function get_data_loop( $key ) { $data_loop = get_transient( $key . '_data_loop' ); if ( false === $data_loop ) { $data_loop = array( 'offset' => 0, 'is_finish' => false, ); } return $data_loop; } /** * Saves in a transient the loop data of the data load.. * * @param string $limit Query limit. * @param string $offset Query offset. * @param string $total Total records. * @param string $key The key transient. * @since 1.0.0 */ public function set_data_loop( $limit, $offset, $total, $key ) { // Calc vars. $offset += $limit; $loops = ceil( $total / $limit ) === 0 ? 1 : ceil( $total / $limit ); // Set data. $data_loop = array( 'offset' => $offset, 'is_finish' => false, 'total' => $total, 'loops' => $loops, 'current_loop' => ceil( $offset / $limit ), ); $data_loop['is_finish'] = ( $data_loop['loops'] + 1 ) == $data_loop['current_loop']; if ( true === $data_loop['is_finish'] ) { $data_loop['current_loop']--; } // Save transient. set_transient( $key . '_data_loop', $data_loop ); } /** * Remove the transient from loop data * * @param string $key The key transient. * @since 1.0.0 */ public function remove_data_loop( $key ) { if ( empty( $key ) && isset( $_GET['page'] ) ) { $key = $_GET['page']; } delete_transient( $key . '_data_loop' ); } /** * Includes the necessary dependencies. * * @since 1.0.0 */ private function load_dependencies() { if ( ! function_exists( 'wp_get_current_user' ) ) { include ABSPATH . 'wp-includes/pluggable.php'; } /** * WishListMember compatibility * The error occurs when calling get_site_transient, WishListMember registers a filter that includes the current_user_can method */ if ( is_plugin_active( 'wishlist-member/wpm.php' ) ) { if ( ! function_exists( 'wp_get_current_user' ) ) { include ABSPATH . 'wp-includes/pluggable.php'; } } /** * The class responsible for orchestrating the actions and filters of the * core plugin. */ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wp-database-tools-database-general.php'; require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wp-database-tools-database-tables.php'; require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wp-database-tools-database-options.php'; require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wp-database-tools-database-transients.php'; require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wp-database-tools-database-cronjobs.php'; } /** * Calls the method of the general child class. * Executes processing of data received from a form. * * @since 1.0.0 */ public function action_form_general() { $this->general->action_form(); } /** * Calls the method of the tables child class. * Executes processing of data received from a form. * * @since 1.0.0 */ public function action_form_tables() { $this->tables->action_form(); } /** * Calls the method of the options child class. * Executes processing of data received from a form. * * @since 1.0.0 */ public function action_form_options() { $this->options->action_form(); } /** * Calls the method of the transients child class. * Executes processing of data received from a form. * * @since 1.0.0 */ public function action_form_transients() { $this->transients->action_form(); } /** * Calls the method of the cronjobs child class. * Executes processing of data received from a form. * * @since 1.0.0 */ public function action_form_cronjobs() { $this->cronjobs->action_form(); } /** * Returns user feedback data on origins. * This is done so that the user is limited to voting only once. * * @param string $section The key of the array (e.g. tables). * @since 1.0.0 * @return array $feedback meta user. */ public function get_user_feedback( $section ) { $KEY = WPDBT_PREFIX . 'feedback'; $feedback = get_user_meta( get_current_user_id(), $KEY, true ); if ( ! $feedback ) { return false; } if ( isset( $feedback[ $section ] ) ) { $feedback = $feedback[ $section ]; } else { return false; } if ( ! $feedback ) { return false; } return $feedback; } /** * Checks the size of the database and assigns it to the property "size". * * @since 1.0.0 */ public function check_database_size() { $size = array(); global $wpdb; $query = "SELECT (SUM(DATA_LENGTH + INDEX_LENGTH)) as size FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '" . $wpdb->dbname . "'"; $result = $wpdb->get_results( $query ); $size['size'] = $result[0]->size; $size['format'] = $this->get_file_size_info( $size['size'] ); $size['format'] = $size['format']['size'] . '' . $size['format']['type']; $this->size = $size; } /** * Assigns the data to the property through the class method. * * @since 1.0.0 */ public function check_general_data() { $this->general_data = $this->general->get_data(); } /** * Assigns the data to the property through the class method. * * @since 1.0.0 */ public function check_tables_data() { $this->tables_data = $this->tables->get_data(); $this->size = $this->tables->get_size(); } /** * Assigns the data to the property through the class method. * * @since 1.0.0 */ public function check_options_data() { $this->options_data = $this->options->get_data(); } /** * Assigns the data to the property through the class method. * * @since 1.0.0 */ public function check_transients_data() { $this->transients_data = $this->transients->get_data(); } /** * Assigns the data to the property through the class method. * * @since 1.0.0 */ public function check_cronjobs_data() { $this->cronjobs_data = $this->cronjobs->get_data(); } /** * Assigns the data to the property through the class method. * * @since 1.0.0 */ private function check_transients() { global $wpdb; $this->transients['data'] = $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . "options WHERE option_name LIKE ('%\_transient\_%')" ); $this->transients['count'] = count( $this->transients['data'] ); } /** * Returns the size calculated from bits. * * @param int $file_size size on bits. * @since 1.0.0 * @return array $db_size_info database size. */ static function get_file_size_info( $file_size ) { $bytes = array( 'B', 'KB', 'MB', 'GB', 'TB' ); if ( $file_size < 1024 ) { $file_size = 1; } for ( $i = 0; $file_size > 1024; $i++ ) { $file_size /= 1024; } $db_size_info['size'] = round( $file_size, 2 ); $db_size_info['type'] = $bytes[ $i ]; return $db_size_info; } public function init_dashboard() { $cronjobs_obj = $this->get_cronjobs_obj(); $cronjobs_obj->check_data( null ); $this->check_cronjobs_data(); $this->check_transients(); } public function init_general() { $tables_obj = $this->get_general_obj(); $tables_obj->check_data( null ); $this->check_general_data(); } public function init_tables() { $tables_obj = $this->get_tables_obj(); $tables_obj->check_data( null ); $this->check_tables_data(); } public function init_options() { $options_obj = $this->get_options_obj(); $options_obj->check_data( null ); $this->check_options_data(); } public function init_transients() { $transients_obj = $this->get_transients_obj(); $transients_obj->check_data( null ); $this->check_transients_data(); } public function init_cronjobs() { $cronjobs_obj = $this->get_cronjobs_obj(); $cronjobs_obj->check_data( null ); $this->check_cronjobs_data(); } static function set_data_api( $api_data_source, $api_data_plugins, $api_data_themes, $api_data_cores, $api_data_marketplaces, $api_data_authors, $section ) { $MARKETPLACE_CORE_ID = 1; $MARKETPLACE_UNKNOWN_ID = 4; $format_data = array(); $format_data['source'] = $api_data_source; $format_data['origin'] = null; $format_data['marketplace'] = null; $format_data['author'] = null; // Get type if ( $section == 'options' ) { $key_type = 'optionable_type'; $key_id = 'optionable_id'; } if ( $section == 'transients' ) { $key_type = 'transientable_type'; $key_id = 'transientable_id'; } if ( $section == 'tables' ) { $key_type = 'tableable_type'; $key_id = 'tableable_id'; } if ( $section == 'cronjobs' ) { $key_type = 'cronable_type'; $key_id = 'cronable_id'; } $api_data_origin_type = strtolower( str_replace( 'App\Models\\', '', $api_data_source->{$key_type} ) ); $api_data_origin_id = $api_data_source->{$key_id}; // Origin if ( $api_data_origin_type == 'plugin' ) { $key_api_data = array_keys( array_column( $api_data_plugins, 'id' ), $api_data_origin_id ); $key_api_data = $key_api_data[0]; $format_data['origin'] = $api_data_plugins[ $key_api_data ]; } if ( $api_data_origin_type == 'theme' ) { $key_api_data = array_keys( array_column( $api_data_themes, 'id' ), $api_data_origin_id ); $key_api_data = $key_api_data[0]; $format_data['origin'] = $api_data_themes[ $key_api_data ]; } if ( $api_data_origin_type == 'core' ) { $key_api_data = array_keys( array_column( $api_data_cores, 'id' ), $api_data_origin_id ); $key_api_data = $key_api_data[0]; $format_data['origin'] = $api_data_cores[ $key_api_data ]; } // Marketplace $marketplace_id = ( $api_data_origin_type == 'core' ) ? $MARKETPLACE_CORE_ID : $format_data['origin']->marketplace_id; $key_api_data = array_keys( array_column( $api_data_marketplaces, 'id' ), $marketplace_id ); $key_api_data = $key_api_data[0]; $format_data['marketplace'] = $api_data_marketplaces[ $key_api_data ]; // Author $key_api_data = array_keys( array_column( $api_data_authors, 'id' ), $format_data['origin']->author_id ); $key_api_data = $key_api_data[0]; $format_data['author'] = $api_data_authors[ $key_api_data ]; return $format_data; } static function execute_simple_query( $table, $condition, $key, $label, $is_days, $action ) { global $wpdb; $data = array(); $query = $action . ' FROM ' . $wpdb->prefix . $table . ' WHERE ' . $condition; $data[ $key ]['data'] = $wpdb->get_results( $query ); $data[ $key ]['count'] = ( isset( $data[ $key ]['data'][0]->total ) ) ? $data[ $key ]['data'][0]->total : count( $data[ $key ]['data'] ); $data[ $key ]['label'] = $label; $data[ $key ]['is-days'] = $is_days; $data[ $key ]['table'] = $table; return $data; } static function execute_complex_complex_query( $table, $sql, $key, $label, $is_days ) { global $wpdb; $data[ $key ]['data'] = $wpdb->get_results( $sql ); $data[ $key ]['count'] = ( isset( $data[ $key ]['data'][0]->total ) ) ? $data[ $key ]['data'][0]->total : count( $data[ $key ]['data'] ); $data[ $key ]['label'] = $label; $data[ $key ]['is-days'] = $is_days; $data[ $key ]['table'] = $table; return $data; } static function generate_message_success( $type, $indicator, $array_indicator, $action ) { return sprintf( __( 'Records of type %1$s with the %2$s %3$s have been %4$s
', 'wp-database-tools' ), $type, $indicator, join( ', ', $array_indicator ), $action ); } static function generate_message_error( $type, $indicator, $array_indicator, $action ) { return sprintf( __( 'Records of type %1$s with the %2$s %3$s could not be %4$s
', 'wp-database-tools' ), $type, $indicator, join( ', ', $array_indicator ), $action ); } static function generate_message_success_simple( $type, $action ) { return sprintf( __( 'Records of type %1$s have been %2$s
', 'wp-database-tools' ), $type, $action ); } static function generate_message_error_simple( $type, $action ) { return sprintf( __( 'Records of type %1$s could not be %2$s
', 'wp-database-tools' ), $type, $action ); } static function generate_message_associated_success( $type, $associated, $array_ids ) { return sprintf( __( 'Records of type %1$s associated to %2$s with the ids %3$s have been eliminated
', 'wp-database-tools' ), $type, $associated, join( ', ', $array_ids ) ); } static function generate_message_associated_error( $type, $associated, $array_ids ) { return sprintf( __( 'Records of type %1$s associated to %2$s with the ids %3$s could not be removed
', 'wp-database-tools' ), $type, $associated, join( ', ', $array_ids ) ); } /** * Executes the deletion in the general section. * Stores the return message to the user in a transient. * * @since 1.0.0 */ static function execute_delete( $table, $ids_array, $meta_keys_array ) { global $wpdb; $errors_messages = ''; $successes_messages = ''; $MAX_REMOVE_INDIVIDUAL = 15; switch ( $table ) { case 'posts': $ids_array_successes = array(); $ids_array_errors = array(); if ( count( $ids_array ) > $MAX_REMOVE_INDIVIDUAL ) { $sql = $wpdb->prepare( 'DELETE FROM %1s WHERE ID IN (%1s)', $wpdb->posts, join( ', ', $ids_array ) ); $result = $wpdb->query( $sql ); if ( $result == count( $ids_array ) ) { $successes_messages .= self::generate_message_success_simple( 'posts', __( 'removed', WPDBT_SLUG ) ); } else { $errors_messages .= self::generate_message_error_simple( 'posts', __( 'removed', WPDBT_SLUG ) ); } // removed from few records we return the specific ids } else { foreach ( $ids_array as $id ) { $result = wp_delete_post( $id, true ); if ( $result !== false && $result !== null ) { array_push( $ids_array_successes, $id ); } else { array_push( $ids_array_errors, $id ); } } } if ( ! empty( $ids_array_successes ) ) { if ( count( $ids_array_successes ) < $MAX_REMOVE_INDIVIDUAL ) { $successes_messages .= self::generate_message_success( 'posts', 'ids', $ids_array_successes, __( 'removed', WPDBT_SLUG ) ); } else { $successes_messages .= self::generate_message_success_simple( 'posts', __( 'removed', WPDBT_SLUG ) ); } } if ( ! empty( $ids_array_errors ) ) { if ( count( $ids_array_errors ) < $MAX_REMOVE_INDIVIDUAL ) { $errors_messages .= self::generate_message_error( 'posts', 'ids', $ids_array_errors, __( 'removed', WPDBT_SLUG ) ); } else { $errors_messages .= self::generate_message_error_simple( 'posts', __( 'removed', WPDBT_SLUG ) ); } } break; case 'comments': $ids_array_successes = array(); $ids_array_errors = array(); if ( count( $ids_array ) > $MAX_REMOVE_INDIVIDUAL ) { $sql = $wpdb->prepare( 'DELETE FROM %1s WHERE comment_ID IN (%1s)', $wpdb->comments, join( ', ', $ids_array ) ); $result = $wpdb->query( $sql ); if ( $result == count( $ids_array ) ) { $successes_messages .= self::generate_message_success_simple( 'comments', __( 'removed', WPDBT_SLUG ) ); } else { $errors_messages .= self::generate_message_error_simple( 'comments', __( 'removed', WPDBT_SLUG ) ); } // removed from few records we return the specific ids } else { foreach ( $ids_array as $id ) { $result = wp_delete_comment( $id, true ); if ( $result !== false && $result !== null ) { array_push( $ids_array_successes, $id ); } else { array_push( $ids_array_errors, $id ); } } } if ( ! empty( $ids_array_successes ) ) { if ( count( $ids_array_successes ) < $MAX_REMOVE_INDIVIDUAL ) { $successes_messages .= self::generate_message_success( 'comments', 'ids', $ids_array_successes, __( 'removed', WPDBT_SLUG ) ); } else { $successes_messages .= self::generate_message_success_simple( 'comments', __( 'removed', WPDBT_SLUG ) ); } } if ( ! empty( $ids_array_errors ) ) { if ( count( $ids_array_errors ) < $MAX_REMOVE_INDIVIDUAL ) { $errors_messages .= self::generate_message_error( 'comments', 'ids', $ids_array_errors, __( 'removed', WPDBT_SLUG ) ); } else { $errors_messages .= self::generate_message_error_simple( 'comments', __( 'removed', WPDBT_SLUG ) ); } } break; case 'postmeta': $ids_array_successes = array(); $ids_array_errors = array(); if ( count( $ids_array ) > $MAX_REMOVE_INDIVIDUAL ) { $sql = $wpdb->prepare( 'DELETE FROM %1s WHERE meta_id IN (%1s)', $wpdb->postmeta, join( ', ', $ids_array ) ); $result = $wpdb->query( $sql ); if ( $result == count( $ids_array ) ) { $successes_messages .= self::generate_message_success_simple( 'postmeta', __( 'removed', WPDBT_SLUG ) ); } else { $errors_messages .= self::generate_message_error_simple( 'postmeta', __( 'removed', WPDBT_SLUG ) ); } // removed from few records we return the specific ids } else { foreach ( $ids_array as $key => $id ) { // $result = delete_metadata('post', $id, $meta_keys_array[$key]); $result = delete_metadata_by_mid( 'post', $id ); if ( $result !== false && $result !== null ) { array_push( $ids_array_successes, $id ); } else { array_push( $ids_array_errors, $id ); } } } if ( ! empty( $ids_array_successes ) ) { if ( count( $ids_array_successes ) < $MAX_REMOVE_INDIVIDUAL ) { $successes_messages .= self::generate_message_success( 'postmeta', 'ids', $ids_array_successes, __( 'removed', WPDBT_SLUG ) ); } else { $successes_messages .= self::generate_message_success_simple( 'postmeta', __( 'removed', WPDBT_SLUG ) ); } } if ( ! empty( $ids_array_errors ) ) { if ( count( $ids_array_errors ) < $MAX_REMOVE_INDIVIDUAL ) { $errors_messages .= self::generate_message_error( 'postmeta', 'ids', $ids_array_errors, __( 'removed', WPDBT_SLUG ) ); } else { $errors_messages .= self::generate_message_error_simple( 'postmeta', __( 'removed', WPDBT_SLUG ) ); } } break; case 'commentmeta': $ids_array_successes = array(); $ids_array_errors = array(); if ( count( $ids_array ) > $MAX_REMOVE_INDIVIDUAL ) { $sql = $wpdb->prepare( 'DELETE FROM %1s WHERE meta_id IN (%1s)', $wpdb->commentmeta, join( ', ', $ids_array ) ); $result = $wpdb->query( $sql ); if ( $result == count( $ids_array ) ) { $successes_messages .= self::generate_message_success_simple( 'commentmeta', __( 'removed', WPDBT_SLUG ) ); } else { $errors_messages .= self::generate_message_error_simple( 'commentmeta', __( 'removed', WPDBT_SLUG ) ); } // removed from few records we return the specific ids } else { foreach ( $ids_array as $key => $id ) { // $result = delete_metadata('comment', $id, $meta_keys_array[$key]); $result = delete_metadata_by_mid( 'comment', $id ); if ( $result !== false && $result !== null ) { array_push( $ids_array_successes, $id ); } else { array_push( $ids_array_errors, $id ); } } } if ( ! empty( $ids_array_successes ) ) { if ( count( $ids_array_successes ) < $MAX_REMOVE_INDIVIDUAL ) { $successes_messages .= self::generate_message_success( 'commentmeta', 'ids', $ids_array_successes, __( 'removed', WPDBT_SLUG ) ); } else { $successes_messages .= self::generate_message_success_simple( 'commentmeta', __( 'removed', WPDBT_SLUG ) ); } } if ( ! empty( $ids_array_errors ) ) { if ( count( $ids_array_errors ) < $MAX_REMOVE_INDIVIDUAL ) { $errors_messages .= self::generate_message_error( 'commentmeta', 'ids', $ids_array_errors, __( 'removed', WPDBT_SLUG ) ); } else { $errors_messages .= self::generate_message_error_simple( 'commentmeta', __( 'removed', WPDBT_SLUG ) ); } } break; case 'usermeta': $ids_array_successes = array(); $ids_array_errors = array(); if ( count( $ids_array ) > $MAX_REMOVE_INDIVIDUAL ) { $sql = $wpdb->prepare( 'DELETE FROM %1s WHERE umeta_id IN (%1s)', $wpdb->usermeta, join( ', ', $ids_array ) ); $result = $wpdb->query( $sql ); if ( $result == count( $ids_array ) ) { $successes_messages .= self::generate_message_success_simple( 'usermeta', __( 'removed', WPDBT_SLUG ) ); } else { $errors_messages .= self::generate_message_error_simple( 'usermeta', __( 'removed', WPDBT_SLUG ) ); } // removed from few records we return the specific ids } else { foreach ( $ids_array as $key => $id ) { // $result = delete_metadata('user', $id, $meta_keys_array[$key]); $result = delete_metadata_by_mid( 'user', $id ); if ( $result !== false && $result !== null ) { array_push( $ids_array_successes, $id ); } else { array_push( $ids_array_errors, $id ); } } } if ( ! empty( $ids_array_successes ) ) { if ( count( $ids_array_successes ) < $MAX_REMOVE_INDIVIDUAL ) { $successes_messages .= self::generate_message_associated_success( 'usermeta', 'users', $ids_array_successes ); } else { $successes_messages .= self::generate_message_success_simple( 'usermeta', __( 'removed', WPDBT_SLUG ) ); } } if ( ! empty( $ids_array_errors ) ) { if ( count( $ids_array_errors ) < $MAX_REMOVE_INDIVIDUAL ) { $errors_messages .= self::generate_message_associated_error( 'usermeta', 'users', $ids_array_errors ); } else { $errors_messages .= self::generate_message_error_simple( 'usermeta', __( 'removed', WPDBT_SLUG ) ); } } break; case 'termmeta': $ids_array_successes = array(); $ids_array_errors = array(); if ( count( $ids_array ) > $MAX_REMOVE_INDIVIDUAL ) { $sql = $wpdb->prepare( 'DELETE FROM %1s WHERE meta_id IN (%1s)', $wpdb->termmeta, join( ', ', $ids_array ) ); $result = $wpdb->query( $sql ); if ( $result == count( $ids_array ) ) { $successes_messages .= self::generate_message_success_simple( 'termmeta', __( 'removed', WPDBT_SLUG ) ); } else { $errors_messages .= self::generate_message_error_simple( 'termmeta', __( 'removed', WPDBT_SLUG ) ); } // removed from few records we return the specific ids } else { foreach ( $ids_array as $key => $id ) { // $result = delete_metadata('term', $id, $meta_keys_array[$key]); $result = delete_metadata_by_mid( 'term', $id ); if ( $result !== false && $result !== null ) { array_push( $ids_array_successes, $id ); } else { array_push( $ids_array_errors, $id ); } } } if ( ! empty( $ids_array_successes ) ) { if ( count( $ids_array_successes ) < $MAX_REMOVE_INDIVIDUAL ) { $successes_messages .= self::generate_message_associated_success( 'termmeta', 'terms', $ids_array_successes ); } else { $successes_messages .= self::generate_message_success_simple( 'termmeta', __( 'removed', WPDBT_SLUG ) ); } } if ( ! empty( $ids_array_errors ) ) { if ( count( $ids_array_errors ) < $MAX_REMOVE_INDIVIDUAL ) { $errors_messages .= self::generate_message_associated_error( 'termmeta', 'terms', $ids_array_errors ); } else { $errors_messages .= self::generate_message_error_simple( 'termmeta', __( 'removed', WPDBT_SLUG ) ); } } break; case 'term_relationships': $sql = $wpdb->prepare( 'DELETE FROM %1s WHERE term_taxonomy_id = 1 AND object_id NOT IN (SELECT id FROM %1s )', $wpdb->prefix . $table, $wpdb->prefix . 'posts' ); $result = $wpdb->query( $sql ); if ( $result !== false && $result !== null ) { $successes_messages .= self::generate_message_success_simple( 'term_relationships', __( 'removed', WPDBT_SLUG ) ); } else { $errors_messages .= self::generate_message_error_simple( 'term_relationships', __( 'removed', WPDBT_SLUG ) ); } break; case 'options': $sql = $wpdb->prepare( 'DELETE FROM %1s WHERE option_id IN (%1s)', $wpdb->options, join( ', ', $ids_array ) ); $result = $wpdb->query( $sql ); if ( $result == count( $ids_array ) ) { $successes_messages .= self::generate_message_success_simple( 'options', __( 'removed', WPDBT_SLUG ) ); } else { $errors_messages .= self::generate_message_error_simple( 'options', __( 'removed', WPDBT_SLUG ) ); } break; } if ( ! empty( get_transient( WPDBT_PREFIX . 'errors' ) ) ) { $errors_messages .= get_transient( WPDBT_PREFIX . 'errors' ); } if ( ! empty( get_transient( WPDBT_PREFIX . 'successes' ) ) ) { $successes_messages .= get_transient( WPDBT_PREFIX . 'successes' ); } set_transient( WPDBT_PREFIX . 'errors', $errors_messages ); set_transient( WPDBT_PREFIX . 'successes', $successes_messages ); } /** * Checks if the records fall within the date range so that they can be deleted or not. * * @since 1.0.0 * @return boolean It is possible to delete the record. */ static function can_delete( $is_days, $table, $action_key, $row ) { $can_delete = true; if ( $is_days ) { $current_options = get_option( WPDBT_PREFIX . 'user_options_general' ); $user_selected_day = $current_options[ $action_key ]['days']; $user_selected_day = ( $user_selected_day == null ) ? 0 : $user_selected_day; switch ( $table ) { case 'posts': $diff_days = self::get_dates_between_dates( $row->post_date ); $can_delete = $diff_days >= $user_selected_day; break; case 'comments': $diff_days = self::get_dates_between_dates( $row->comment_date ); $can_delete = $diff_days >= $user_selected_day; break; } } return $can_delete; } static function get_ID( $table, $row ) { switch ( $table ) { case 'posts': return $row->ID; break; case 'comments': return $row->comment_ID; break; case 'postmeta': return $row->meta_id; break; case 'commentmeta': return $row->meta_id; break; case 'usermeta': return $row->umeta_id; break; case 'termmeta': return $row->meta_id; break; case 'term_relationships': return null; break; case 'options': return $row->option_id; break; } } static function get_dates_between_dates( $date ) { $now = time(); $date_compare = strtotime( $date ); $datediff = abs( $now - $date_compare ); return floor( $datediff / ( 60 * 60 * 24 ) ); } public function get_table_titles( $table ) { $info_tables_tittles = array(); switch ( true ) { case ( $table == 'posts' ): $info_tables_tittles = array( 'ID', 'Tittle', 'Content', 'Date', 'Actions', ); break; case ( $table == 'comments' ): $info_tables_tittles = array( 'ID', 'Author', 'Content', 'Date', 'Actions', ); break; case ( $table == 'postmeta' || $table == 'commentmeta' || $table == 'usermeta' || $table == 'termmeta' ): $info_tables_tittles = array( 'ID', 'Meta Key', 'Meta value', 'Actions', ); break; case ( $table == 'term_relationships' ): $info_tables_tittles = array( 'ID', 'Term taxonomy id', 'Term order', 'Actions', ); break; case ( $table == 'options' ): $info_tables_tittles = array( 'ID', 'Name', 'Value', 'Autoload', 'Actions', ); break; } return $info_tables_tittles; } public function get_info_tables( $table, $row ) { $info_tables = array(); switch ( true ) { case ( $table == 'posts' ): $info_tables = array( 'id' => $row->ID, 'title' => $row->post_title, 'content' => $row->post_content, 'date' => $row->post_date, ); break; case ( $table == 'comments' ): $info_tables = array( 'id' => $row->comment_ID, 'author' => get_comment_author( $row->comment_ID ), 'content' => $row->comment_content, 'date' => $row->comment_date, ); break; case ( $table == 'postmeta' || $table == 'commentmeta' || $table == 'usermeta' || $table == 'termmeta' ): $id_key = $table != 'usermeta' ? $row->meta_id : $row->umeta_id; $info_tables = array( 'id' => $id_key, 'meta-key' => $row->meta_key, 'meta-value' => $row->meta_value, ); break; case ( $table == 'term_relationships' ): $info_tables = array( 'id' => $row->object_id, 'meta-key' => $row->term_taxonomy_id, 'meta-value' => $row->term_order, ); break; case ( $table == 'options' ): $info_tables = array( 'id' => $row->option_id, 'option-name' => $row->option_name, 'option-value' => $row->option_value, 'autoload' => $row->autoload, ); break; } return $info_tables; } /** * Initializes the array of all data that will be returned for display in the js. * Call in the child classes. * * @since 1.0.0 * @return array The origin data. */ protected function init_full_data() { $full_data = array(); $full_data['data'] = array(); $full_data['size'] = array( 'autoload' => array( 'value' => 0, 'format' => '', ), 'total' => array( 'value' => 0, 'format' => '', ), ); $full_data['origins'] = $this->init_choices_data(); return $full_data; } /** * Initializes in an array the basic data used by the choices library. Used in child classes * * @since 1.0.0 * @return array The array with default data. */ protected function init_choices_data() { $choices = array( array( 'label' => __( 'WordPress Core', 'wp-database-tools' ), 'id' => 1, 'disabled' => false, 'choices' => array( array( 'value' => __( 'WordPress Core', 'wp-database-tools' ), 'label' => __( 'WordPress Core', 'wp-database-tools' ), 'selected' => false, ), ), ), array( 'label' => __( 'Plugins', 'wp-database-tools' ), 'id' => 2, 'disabled' => false, 'choices' => array(), ), array( 'label' => __( 'Themes', 'wp-database-tools' ), 'id' => 3, 'disabled' => false, 'choices' => array(), ), array( 'label' => __( 'Multiple', 'wp-database-tools' ), 'id' => 4, 'disabled' => false, 'choices' => array( array( 'value' => __( 'Multiple', 'wp-database-tools' ), 'label' => __( 'Multiple', 'wp-database-tools' ), 'selected' => false, ), ), ), ); return $choices; } /** * The total size of database. * * @since 1.0.0 * @return array The size of the database. */ public function get_size() { return $this->size; } /** * The array of cronjobs. * * @since 1.0.0 * @return Obj The obj of cronjobs. */ public function get_cronjobs_obj() { return $this->cronjobs; } /** * The array of cronjobs. * * @since 1.0.0 * @return array The data of cronjobs. */ public function get_cronjobs_data() { return $this->cronjobs_data; } /** * The array of transients. * * @since 1.0.0 * @return array The array of transients. */ public function get_transients() { return $this->transients; } /** * The array of transients. * * @since 1.0.0 * @return array The array of transients. */ public function get_general_data() { return $this->general_data; } /** * The array of transients. * * @since 1.0.0 * @return array The array of transients. */ public function get_tables_data() { return $this->tables_data; } /** * The Obj of transients. * * @since 1.0.0 * @return Obj The Obj of transients. */ public function get_tables_obj() { return $this->tables; } /** * The Obj of transients. * * @since 1.0.0 * @return Obj The Obj of transients. */ public function get_options_obj() { return $this->options; } /** * The Obj of transients. * * @since 1.0.0 * @return Obj The Obj of transients. */ public function get_transients_obj() { return $this->transients; } /** * The Obj of transients. * * @since 1.0.0 * @return Obj The Obj of transients. */ public function get_general_obj() { return $this->general; } /** * The array of transients. * * @since 1.0.0 * @return array The array of transients. */ public function get_options_data() { return $this->options_data; } /** * The array of transients. * * @since 1.0.0 * @return array The array of transients. */ public function get_transients_data() { return $this->transients_data; } /** * The array of plugins. * * @since 1.0.0 * @return array The array of plugins. */ public function get_plugins() { return $this->plugins; } /** * The array of themes. * * @since 1.0.0 * @return array The array of themes. */ public function get_themes() { return $this->themes; } }