- 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>
495 lines
15 KiB
PHP
Executable File
495 lines
15 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_Cronjobs extends Wp_Database_Tools_Database {
|
|
|
|
|
|
/**
|
|
* All the information processed from the cronjobs
|
|
*
|
|
* @since 1.0.0
|
|
* @access protected
|
|
* @var array $data Cronjobs 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();
|
|
}
|
|
|
|
/**
|
|
* Prepare data to loop over records
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
private function prepare_data() {
|
|
// Custom key.
|
|
$this->key = 'cronjobs';
|
|
// 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 );
|
|
}
|
|
|
|
/**
|
|
* Sets the total number of records
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function check_count() {
|
|
$this->count = count( _get_cron_array() );
|
|
}
|
|
|
|
public function check_data() {
|
|
|
|
// TODO: Better way, loop json encode.
|
|
ini_set( 'memory_limit', '-1' );
|
|
set_time_limit( 0 );
|
|
|
|
$this->prepare_data();
|
|
|
|
// Cronjobs data.
|
|
global $wpdb;
|
|
$rows = _get_cron_array();
|
|
$sum_ids = array_sum( array_keys( $rows ) );
|
|
// Pagination.
|
|
$rows = array_slice( $rows, $this->data_loop['offset'], $this->limit, true );
|
|
$max_loading = count( $rows );
|
|
|
|
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'] ) ) {
|
|
|
|
if ( $this->license_status ) {
|
|
Wp_Database_Tools_Logger::info( 'CRONJOBS: load data by cache' );
|
|
// 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 );
|
|
$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.
|
|
if ( isset( $this->cache_data['source']['data'] ) ) {
|
|
/*
|
|
TODO: The data retrieved from the row as an array is different from what
|
|
is currently stored in the cache. A common data must be fetched in order to be able to compare the load.
|
|
*/
|
|
$sum_ids_cache = array_sum( array_keys( $rows ) );
|
|
$sum_ids_cache = ( $this->cache_data['indicators']->ids < $sum_ids ) ? $sum_ids_cache + $this->cache_data['indicators']->ids : $this->cache_data['indicators']->ids;
|
|
} else {
|
|
$sum_ids_cache = 0;
|
|
}
|
|
|
|
parent::set_cache_indicators( $this->key, $this->api_data['source'], $this->feedback, $sum_ids_cache + $this->cache_data['indicators']->ids );
|
|
}
|
|
|
|
Wp_Database_Tools_Logger::info( 'CRONJOBS: starting to process data' );
|
|
// Specific attributes.
|
|
$schedules = wp_get_schedules();
|
|
// 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( 'CRONJOBS: ending to process data ' . count( $this->cache_data['source'] ) );
|
|
|
|
// Get source data and calculate finihs size.
|
|
$this->data = $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 $timestamp => $events ) {
|
|
|
|
foreach ( $events as $event_hook => $event_args ) {
|
|
|
|
foreach ( $event_args as $event ) {
|
|
|
|
$cronjob = new Wp_Database_Tools_Database_Data_Cronjob( $schedules, $timestamp, $event_hook, $events, $event, $this->feedback );
|
|
$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( (array) $this->api_data['source'], 'name' ), $cronjob->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;
|
|
|
|
// Multiples values.
|
|
if ( $this->is_multiple ) {
|
|
|
|
$cronjob->set_multiple( true );
|
|
$cronjob->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, 'cronjobs' );
|
|
// 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( $cronjob->get_name() );
|
|
$this->full_data['origins'] = $origin->check_choices( $this->full_data['origins'] );
|
|
array_push( $cronjob->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
|
|
);
|
|
|
|
$cronjob->origin->set_origin_by_api( $api_data, 'cronjobs' );
|
|
$cronjob->origin->set_question( $cronjob->get_name() );
|
|
$cronjob->origin->set_status( $this->plugins, $this->themes );
|
|
}
|
|
} else {
|
|
|
|
$this->is_multiple = false;
|
|
|
|
if ( $this->force_execute_scanner == 'NO' ) {
|
|
|
|
$data_algorithm = $cronjob->get_matching_data( $this->matching, $this->plugins, $this->themes, $cronjob->get_name() );
|
|
|
|
if ( ! is_null( $data_algorithm ) ) {
|
|
$cronjob->set_data_by_algorithm( $data_algorithm );
|
|
$cronjob->origin->set_status( $this->plugins, $this->themes );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( ! $this->is_multiple ) {
|
|
$this->full_data['origins'] = $cronjob->origin->check_choices( $this->full_data['origins'] );
|
|
// Marketplace.
|
|
$marketplace = $cronjob->origin->get_marketplace();
|
|
$cronjob->origin->set_marketplace( $marketplace->return_object_vars() );
|
|
// Auhor.
|
|
$author = $cronjob->origin->get_author();
|
|
$cronjob->origin->set_author( $author->return_object_vars() );
|
|
// Origin.
|
|
$cronjob->set_origin( $cronjob->origin->return_object_vars() );
|
|
}
|
|
|
|
$cronjob_array = $cronjob->return_object_vars( $cronjob );
|
|
|
|
// Prevent encoding.
|
|
if ( ! mb_check_encoding( $cronjob_array ) ) {
|
|
Wp_Database_Tools_Logger::error( 'CRONJOBS: error encoding ' . $cronjob_array['name'] );
|
|
continue;
|
|
}
|
|
|
|
if ( is_array( $cronjob_array ) ) {
|
|
array_push( $this->full_data['data'], $cronjob_array );
|
|
} else {
|
|
Wp_Database_Tools_Logger::error( 'CRONJOBS: error add ' . $cronjob_array['name'] );
|
|
continue;
|
|
}
|
|
|
|
parent::set_status_loading( 'loading', 100 * $this->current_loading / $max_loading, $this->data_loop, false );
|
|
$this->current_loading++;
|
|
}
|
|
}
|
|
|
|
// Memory optimization.
|
|
unset( $events );
|
|
}
|
|
|
|
$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( 'CRONJOBS: error data new cache not found' );
|
|
}
|
|
|
|
if ( ! isset( $current_cache['data'] ) ) {
|
|
Wp_Database_Tools_Logger::error( 'CRONJOBS: error data current cache not found' );
|
|
}
|
|
|
|
if ( mb_check_encoding( $this->full_data ) ) {
|
|
|
|
Wp_Database_Tools_Logger::info( 'CRONJOBS: available encoding' );
|
|
|
|
try {
|
|
$new_cache = mb_convert_encoding( $this->full_data, 'UTF-8' );
|
|
} catch ( Exception $e ) {
|
|
$new_cache = $this->full_data;
|
|
Wp_Database_Tools_Logger::error( 'CRONJOBS: the data cache has not been encoded properly' );
|
|
}
|
|
|
|
if ( $new_cache === null || ! isset( $new_cache['data'] ) ) {
|
|
Wp_Database_Tools_Logger::error( 'CRONJOBS: the data cache has not been encoded properly' );
|
|
$new_cache = $this->full_data;
|
|
}
|
|
}
|
|
|
|
if ( ! isset( $new_cache['data'] ) ) {
|
|
Wp_Database_Tools_Logger::error( 'CRONJOBS: error data new cache after encoding' );
|
|
}
|
|
|
|
if ( ! isset( $current_cache['data'] ) ) {
|
|
Wp_Database_Tools_Logger::error( 'CRONJOBS: 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( 'CRONJOBS: error merge cronjobs 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( 'CRONJOBS: error save json' );
|
|
}
|
|
}
|
|
|
|
// Loading status.
|
|
parent::set_status_loading( 'loading', 0, $this->data_loop, false );
|
|
|
|
// Memory optimization.
|
|
unset( $this->full_data );
|
|
unset( $this->api_data );
|
|
unset( $this->cache_data );
|
|
unset( $new_cache );
|
|
unset( $current_cache );
|
|
gc_collect_cycles();
|
|
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
wp_redirect( $_POST['current-url'] . '&' . WPDBT_PREFIX . 'notice=cronjobs' );
|
|
}
|
|
|
|
|
|
/**
|
|
* 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.
|
|
$action_keys = $_POST['action-keys'];
|
|
$action_keys = explode( '↕', $action_keys );
|
|
|
|
$errors_messages = '';
|
|
$successes_messages = '';
|
|
$hooks_array_successes = array();
|
|
$hooks_array_errors = array();
|
|
|
|
foreach ( $action_keys as $option_key ) {
|
|
|
|
$cronjob = explode( '↔', $option_key );
|
|
$hook = $cronjob[0];
|
|
$args = json_decode( html_entity_decode( $cronjob[1] ), true );
|
|
$timestamp = $cronjob[2];
|
|
|
|
$unscheduled = wp_unschedule_event( $timestamp, $hook, $args );
|
|
|
|
if ( is_wp_error( $unscheduled ) ) {
|
|
array_push( $hooks_array_errors, $hook );
|
|
} else {
|
|
array_push( $hooks_array_successes, $hook );
|
|
}
|
|
}
|
|
|
|
if ( ! empty( $hooks_array_successes ) ) {
|
|
$successes_messages .= parent::generate_message_success( 'cronjobs', 'hook_names', $hooks_array_successes, __( 'removed', 'wp-database-tools' ) );
|
|
set_transient( WPDBT_PREFIX . 'successes', $successes_messages );
|
|
}
|
|
|
|
if ( ! empty( $hooks_array_errors ) ) {
|
|
$errors_messages .= parent::generate_message_error( 'cronjobs', 'hook_names', $hooks_array_errors, __( 'removed', 'wp-database-tools' ) );
|
|
set_transient( WPDBT_PREFIX . 'errors', $errors_messages );
|
|
}
|
|
|
|
parent::set_cache_indicators( 'cronjobs', 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( 'CRONJOBS: 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;
|
|
}
|
|
}
|