Files
roi-theme/wp-content/plugins/wp-database-tools/includes/class-wp-database-tools-database-tables.php
root a22573bf0b Commit inicial - WordPress Análisis de Precios Unitarios
- WordPress core y plugins
- Tema Twenty Twenty-Four configurado
- Plugin allow-unfiltered-html.php simplificado
- .gitignore configurado para excluir wp-config.php y uploads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 21:04:30 -06:00

621 lines
19 KiB
PHP
Executable File

<?php
/**
* Database functions
*
* @link https://raiolanetworks.es
* @since 1.0.0
*
* @package Wp_Database_Tools
* @subpackage Wp_Database_Tools/includes
*/
/**
* Contains the functionalities related to database management.
*
* This class defines all code necessary to manage the database functionalities.
*
* @since 1.0.0
* @package Wp_Database_Tools
* @subpackage Wp_Database_Tools/includes
* @author Raiola Networks <info@raiolanetworks.es>
*/
class Wp_Database_Tools_Database_Tables extends Wp_Database_Tools_Database {
/**
* All the information processed from the tables
*
* @since 1.0.0
* @access protected
* @var array $data Tables data.
*/
protected $data;
/**
* The general data of database.
*
* @since 1.0.0
* @access protected
* @var array $data The general data of database.
*/
protected $size;
/**
* The general data of database.
*
* @since 1.0.0
* @access protected
* @var array $data The general data of database.
*/
protected $count;
public function __construct( $plugins, $themes, $matching, $license_status ) {
$this->plugins = $plugins;
$this->themes = $themes;
$this->matching = $matching;
$this->license_status = $license_status;
// Set total count.
$this->check_count();
}
public function check_count() {
global $wpdb;
$num_rows = $wpdb->get_var( "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '" . $wpdb->dbname . "'" );
$this->count = $num_rows;
}
/**
* Prepare data to loop over records
*
* @since 1.0.4
*/
private function prepare_data() {
// Custom key.
$this->key = 'tables';
// Limit to query.
$this->limit = 1000;
// Multiples origins.
$this->is_multiple = false;
// Loading ajax call.
$this->current_loading = 0;
// Prepare data.
$this->full_data = parent::init_full_data();
// API data.
$this->api_data = parent::get_api_data( $this->key );
// Data loop transient.
$this->data_loop = parent::get_data_loop( $this->key );
// Feedback.
$this->feedback = parent::get_user_feedback( $this->key );
// Cache files.
$this->cache_data = parent::get_data_cache_indicator( $this->key );
// Force scanner active.
$this->force_execute_scanner = get_option( WPDBT_PREFIX . 'force_execute_scanner' );
// Load dependencies.
parent::load_dependencies_child( $this->key );
// Set transient loading.
parent::set_status_loading( 'loading', $this->current_loading, $this->data_loop, false );
}
public function check_data() {
// TODO: Better way, loop json encode.
ini_set( 'memory_limit', '-1' );
set_time_limit( 0 );
$this->prepare_data();
// Tables data.
global $wpdb;
$rows = $wpdb->get_results( 'SHOW table STATUS' );
// Loading ajax call.
$max_loading = count( $rows );
$sum_ids = $max_loading;
// Custom atributtes.
$db_size = 0;
if (
$sum_ids === $this->cache_data['indicators']->ids &&
$this->cache_data['indicators']->api === strlen( wp_json_encode( $this->api_data['source'] ) ) &&
$this->cache_data['indicators']->status === strlen( wp_json_encode( array( $this->feedback, $this->license_status ) ) )
) {
if ( ! empty( $this->cache_data['source'] ) && ! is_null( $this->cache_data['source'] ) ) {
Wp_Database_Tools_Logger::info( 'TABLES: cache data is ok' );
if ( $this->license_status ) {
Wp_Database_Tools_Logger::info( 'TABLES: license valid' );
// Set data loop (total).
parent::set_data_loop( $this->limit, $this->data_loop['offset'], $this->count, $this->key );
$this->data_loop = parent::get_data_loop( $this->key );
// Log cache.
$count_data = is_array( $this->cache_data['source'] ) ? count( $this->cache_data['source']['data'] ) : 'null';
Wp_Database_Tools_Logger::info( 'TABLES: return data cache ' . $count_data );
$this->data = $this->cache_data['source'];
// Set status loading.
parent::set_status_loading( 'success', 100, $this->data_loop, true );
return;
}
}
} elseif ( false === $this->data_loop['is_finish'] ) {
// Count ids from cache.
// In tables we only give a single loop.
$sum_ids_cache = $sum_ids;
parent::set_cache_indicators( $this->key, $this->api_data['source'], $this->feedback, $sum_ids_cache );
}
// TODO: Pass cache management to other class
$cache_path = plugin_dir_path( __DIR__ ) . 'data/cache/' . WPDBT_PREFIX . $this->key;
// IF first loop reset cache file.
if ( 0 === $this->data_loop['offset'] ) {
$success_cache = file_put_contents( $cache_path . '_' . $this->key . '.json', wp_json_encode( mb_convert_encoding( array(), 'UTF-8' ) ) );
}
// Set data loop.
parent::set_data_loop( $this->limit, $this->data_loop['offset'], $this->count, $this->key );
// Get if finish.
$this->data_loop = parent::get_data_loop( $this->key );
// Si ha finalizado establecesmos la data.
if ( true === $this->data_loop['is_finish'] ) {
// Get cache.
$this->cache_data['source'] = json_decode( file_get_contents( $cache_path . '_' . $this->key . '.json' ), true );
Wp_Database_Tools_Logger::info( 'TABLES: ending to process data ' . count( $this->cache_data['source'] ) );
// Get source data and calculate finihs size.
$this->data = parent::calculate_data_source_size( $this->cache_data['source'] );
// Set status loading.
parent::set_status_loading( 'success', 100, $this->data_loop, false );
// Reset values loop.
parent::remove_data_loop( $this->key );
return;
}
foreach ( $rows as $row_table ) {
$table = new Wp_Database_Tools_Database_Data_Table( $row_table, $this->feedback );
$db_size += $table->get_size();
$key_api_data = false;
// If license is valid.
if ( $this->license_status ) {
// Prepare origin.
if ( null !== $this->api_data['source'] ) {
$key_api_data = array_keys( array_column( $this->api_data['source'], 'name' ), $table->get_name() );
}
// If key found.
if ( false !== $key_api_data && ! empty( $key_api_data ) ) {
// Check multiple only for verified registers.
$key_api_data_verified = $key_api_data;
foreach ( $key_api_data_verified as $index => $key ) {
if ( $this->api_data['source'][ $key ]->verified !== 1 ) {
unset( $key_api_data_verified[ $index ] );
}
}
$this->is_multiple = count( $key_api_data_verified ) > 1;
$this->is_multiple = false;
// Multiples values.
if ( $this->is_multiple ) {
$table->set_multiple( true );
$table->origin = array();
foreach ( $key_api_data_verified as $key ) {
$api_data = parent::set_data_api(
$this->api_data['source'][ $key ],
$this->api_data['plugins'],
$this->api_data['themes'],
$this->api_data['cores'],
$this->api_data['marketplaces'],
$this->api_data['authors'],
$this->key
);
$origin = new Wp_Database_Tools_Database_Data_Origin();
$origin->set_origin_by_api( $api_data, $this->key );
// Marketplace.
$marketplace = $origin->get_marketplace();
$origin->set_marketplace( $marketplace->return_object_vars() );
// Auhor.
$author = $origin->get_author();
$origin->set_author( $author->return_object_vars() );
// Origin.
$origin->set_status( $this->plugins, $this->themes );
$origin->set_question( $table->get_name() );
$this->full_data['origins'] = $origin->check_choices( $this->full_data['origins'] );
array_push( $table->origin, $origin->return_object_vars() );
}
// Simple values.
} else {
$this->is_multiple = false;
$key_api_data = $key_api_data[0];
$api_data = parent::set_data_api(
$this->api_data['source'][ $key_api_data ],
$this->api_data['plugins'],
$this->api_data['themes'],
$this->api_data['cores'],
$this->api_data['marketplaces'],
$this->api_data['authors'],
$this->key
);
$table->origin->set_origin_by_api( $api_data, $this->key );
$table->origin->set_question( $table->get_name() );
$table->origin->set_status( $this->plugins, $this->themes );
}
} else {
$this->is_multiple = false;
if ( 'NO' === $this->force_execute_scanner ) {
$data_algorithm = $table->get_matching_data( $this->matching, $this->plugins, $this->themes, $table->get_name_without_prefix() );
if ( ! is_null( $data_algorithm ) ) {
$table->set_data_by_algorithm( $data_algorithm );
$table->origin->set_status( $this->plugins, $this->themes );
}
}
}
}
if ( ! $this->is_multiple ) {
$this->full_data['origins'] = $table->origin->check_choices( $this->full_data['origins'] );
// Marketplace.
$marketplace = $table->origin->get_marketplace();
$table->origin->set_marketplace( $marketplace->return_object_vars() );
// Auhor.
$author = $table->origin->get_author();
$table->origin->set_author( $author->return_object_vars() );
// Origin.
$table->set_origin( $table->origin->return_object_vars() );
}
// Return object vars.
$table_array = $table->return_object_vars( $table );
// Prevent encoding.
if ( ! mb_check_encoding( $table_array ) ) {
Wp_Database_Tools_Logger::error( 'TABLES: error encoding ' . $table_array['name'] );
continue;
}
if ( is_array( $table_array ) ) {
array_push( $this->full_data['data'], $table_array );
} else {
Wp_Database_Tools_Logger::error( 'TABLES: error add ' . $table_array['name'] );
continue;
}
parent::set_status_loading( 'loading', 100 * $this->current_loading / $max_loading, $this->data_loop, false );
$this->current_loading++;
// Memory optimization.
unset( $row_table );
}
if ( ! isset( $this->full_data['data'] ) ) {
Wp_Database_Tools_Logger::error( 'TABLES: error tables data empty' );
}
$this->full_data['plugins'] = $this->plugins;
$this->full_data['themes'] = $this->themes;
// If it is finished we establish the data.
if ( false === $this->data_loop['is_finish'] ) {
// Get cache data.
$current_cache = json_decode( file_get_contents( $cache_path . '_' . $this->key . '.json' ), true );
// Encoding current data.
$new_cache = $this->full_data;
if ( ! isset( $new_cache['data'] ) ) {
Wp_Database_Tools_Logger::error( 'TABLES: error data new cache not found' );
}
if ( ! isset( $current_cache['data'] ) ) {
Wp_Database_Tools_Logger::error( 'TABLES: error data current cache not found' );
}
if ( mb_check_encoding( $new_cache ) ) {
try {
$new_cache = mb_convert_encoding( $this->full_data, 'UTF-8' );
} catch ( Exception $e ) {
$new_cache = $this->full_data;
Wp_Database_Tools_Logger::error( 'TABLES: the data cache has not been encoded properly' );
}
if ( $new_cache === null || ! isset( $new_cache['data'] ) ) {
Wp_Database_Tools_Logger::error( 'TABLES: the data cache has not been encoded properly' );
$new_cache = $this->full_data;
}
}
if ( ! isset( $new_cache['data'] ) ) {
Wp_Database_Tools_Logger::error( 'TABLES: error data new cache after encoding' );
}
if ( ! isset( $current_cache['data'] ) ) {
Wp_Database_Tools_Logger::error( 'TABLES: error data current cache after encoding' );
}
// Merge data.
$current_cache = array_merge_recursive( $current_cache, $new_cache );
if ( ! isset( $current_cache['data'] ) ) {
Wp_Database_Tools_Logger::error( 'TABLES: error merge tables data' );
}
// Save data cache.
$current_cache = wp_json_encode( $current_cache );
$save_cache = file_put_contents( $cache_path . '_' . $this->key . '.json', $current_cache );
if ( false === $save_cache ) {
Wp_Database_Tools_Logger::error( 'TABLES: error save json' );
}
}
unset( $new_cache );
unset( $current_cache );
// Loading status.
parent::set_status_loading( 'loading', 0, $this->data_loop, false );
}
/**
* Call a specific method depending on the action to be performed.
*
* @since 1.0.0
*/
public function action_form() {
// TODO: nonce verification.
switch ( $_POST['action-type'] ) {
case 'delete':
$this->delete();
break;
case 'empty':
$this->empty();
break;
case 'optimize':
$this->optimize();
break;
case 'repair':
$this->repair();
break;
}
wp_redirect( $_POST['current-url'] . '&' . WPDBT_PREFIX . 'notice=tables' );
}
/**
* Deletes the records that are indicated in $POST through keys.
* These keys are used in a query. The result is stored in a transient,
* which is then returned as a warning to the user..
*
* @since 1.0.0
*/
public function delete() {
// TODO: nonce verification.
global $wpdb;
$action_keys = $_POST['action-keys'];
$action_keys = explode( '↕', $action_keys );
$action_prefix = $_POST['action-prefix'];
$action_prefix = explode( '↕', $action_prefix );
$errors_messages = '';
$successes_messages = '';
$tables_array_successes = array();
$tables_array_errors = array();
foreach ( $action_keys as $key => $table_name ) {
if ( $action_prefix[ $key ] == 'true' ) {
$table_name = $wpdb->prefix . $table_name;
}
$sql = $wpdb->prepare( 'DROP TABLE IF EXISTS %1s', $table_name );
$result = $wpdb->query( $sql );
if ( $result === false ) {
array_push( $tables_array_errors, $table_name );
} else {
array_push( $tables_array_successes, $table_name );
}
}
if ( ! empty( $tables_array_successes ) ) {
$successes_messages .= parent::generate_message_success( $this->key, 'names', $tables_array_successes, __( 'removed', 'wp-database-tools' ) );
set_transient( WPDBT_PREFIX . 'successes', $successes_messages );
}
if ( ! empty( $tables_array_errors ) ) {
$errors_messages .= parent::generate_message_error( $this->key, 'names', $tables_array_errors, __( 'removed', 'wp-database-tools' ) );
set_transient( WPDBT_PREFIX . 'errors', $errors_messages );
}
parent::set_cache_indicators( 'tables', 0, 0, 0 );
}
/**
* Edit the records that are indicated in $POST through keys.
* These keys are used in a query. The result is stored in a transient,
* which is then returned as a warning to the user..
*
* @since 1.0.0
*/
public function empty() {
// TODO: nonce verification.
global $wpdb;
$action_keys = $_POST['action-keys'];
$action_keys = explode( '↕', $action_keys );
$action_prefix = $_POST['action-prefix'];
$action_prefix = explode( '↕', $action_prefix );
$errors_messages = '';
$successes_messages = '';
$tables_array_successes = array();
$tables_array_errors = array();
foreach ( $action_keys as $key => $table_name ) {
if ( $action_prefix[ $key ] == 'true' ) {
$table_name = $wpdb->prefix . $table_name;
}
$sql = $wpdb->prepare( 'TRUNCATE TABLE %1s', $table_name );
$result = $wpdb->query( $sql );
if ( $result === false ) {
array_push( $tables_array_errors, $table_name );
} else {
array_push( $tables_array_successes, $table_name );
}
}
if ( ! empty( $tables_array_successes ) ) {
$successes_messages .= parent::generate_message_success( $this->key, 'names', $tables_array_successes, __( 'emptied', 'wp-database-tools' ) );
set_transient( WPDBT_PREFIX . 'successes', $successes_messages );
}
if ( ! empty( $tables_array_errors ) ) {
$errors_messages .= parent::generate_message_error( $this->key, 'names', $tables_array_errors, __( 'emptied', 'wp-database-tools' ) );
set_transient( WPDBT_PREFIX . 'errors', $errors_messages );
}
parent::set_cache_indicators( 'tables', 0, 0, 0 );
}
public function optimize() {
global $wpdb;
$action_keys = $_POST['action-keys'];
$action_keys = explode( '↕', $action_keys );
$action_prefix = $_POST['action-prefix'];
$action_prefix = explode( '↕', $action_prefix );
$errors_messages = '';
$successes_messages = '';
$tables_array_successes = array();
$tables_array_errors = array();
foreach ( $action_keys as $key => $table_name ) {
if ( $action_prefix[ $key ] == 'true' ) {
$table_name = $wpdb->prefix . $table_name;
}
$sql = $wpdb->prepare( 'OPTIMIZE TABLE %1s', $table_name );
$results = $wpdb->get_results( $sql );
if ( str_contains( json_encode( $results ), 'Operation failed' ) ) {
array_push( $tables_array_errors, $table_name );
} else {
array_push( $tables_array_successes, $table_name );
}
}
if ( ! empty( $tables_array_successes ) ) {
$successes_messages .= parent::generate_message_success( $this->key, 'names', $tables_array_successes, __( 'optimized', 'wp-database-tools' ) );
set_transient( WPDBT_PREFIX . 'successes', $successes_messages );
}
if ( ! empty( $tables_array_errors ) ) {
$errors_messages .= parent::generate_message_error( $this->key, 'names', $tables_array_errors, __( 'optimized', 'wp-database-tools' ) );
set_transient( WPDBT_PREFIX . 'errors', $errors_messages );
}
parent::set_cache_indicators( 'tables', 0, 0, 0 );
}
public function repair() {
global $wpdb;
$action_keys = $_POST['action-keys'];
$action_keys = explode( '↕', $action_keys );
$action_prefix = $_POST['action-prefix'];
$action_prefix = explode( '↕', $action_prefix );
$errors_messages = '';
$successes_messages = '';
$tables_array_successes = array();
$tables_array_errors = array();
foreach ( $action_keys as $key => $table_name ) {
if ( $action_prefix[ $key ] == 'true' ) {
$table_name = $wpdb->prefix . $table_name;
}
$sql = $wpdb->prepare( 'REPAIR TABLE %1s', $table_name );
$results = $wpdb->get_results( $sql );
if ( str_contains( json_encode( $results ), 'Operation failed' ) ) {
array_push( $tables_array_errors, $table_name );
} else {
array_push( $tables_array_successes, $table_name );
}
}
if ( ! empty( $tables_array_successes ) ) {
$successes_messages .= parent::generate_message_success( $this->key, 'names', $tables_array_successes, __( 'repaired', 'wp-database-tools' ) );
set_transient( WPDBT_PREFIX . 'successes', $successes_messages );
}
if ( ! empty( $tables_array_errors ) ) {
$errors_messages .= parent::generate_message_error( $this->key, 'names', $tables_array_errors, __( 'repaired', 'wp-database-tools' ) );
set_transient( WPDBT_PREFIX . 'errors', $errors_messages );
}
parent::set_cache_indicators( 'tables', 0, 0, 0 );
}
/**
* The array of data of general database.
*
* @since 1.0.0
* @return array The array of data.
*/
public function get_data() {
$count_data = is_array( $this->data ) ? count( $this->data['data'] ) : 'null';
Wp_Database_Tools_Logger::info( 'TABLES: return data ' . $count_data );
return $this->data;
}
/**
* The array of data of general database.
*
* @since 1.0.0
* @return array The array of data.
*/
public function get_size() {
return $this->size;
}
/**
* The array of data of general database.
*
* @since 1.0.0
* @return array The array of data.
*/
public function get_count() {
return $this->count;
}
}