oont-contents/plugins/wp-rocket/inc/Engine/Optimization/RUCSS/Database/Tables/UsedCSS.php
2025-02-08 15:10:23 +01:00

326 lines
8.5 KiB
PHP

<?php
namespace WP_Rocket\Engine\Optimization\RUCSS\Database\Tables;
use WP_Rocket\Dependencies\Database\Table;
/**
* RUCSS UsedCSS Table.
*/
class UsedCSS extends Table {
/**
* Table name
*
* @var string
*/
protected $name = 'wpr_rucss_used_css';
/**
* Database version key (saved in _options or _sitemeta)
*
* @var string
*/
protected $db_version_key = 'wpr_rucss_used_css_version';
/**
* Database version
*
* @var int
*/
protected $version = 20220926;
/**
* Key => value array of versions => methods.
*
* @var array
*/
protected $upgrades = [
20220121 => 'add_async_rucss_columns',
20220131 => 'make_status_column_index',
20220513 => 'add_hash_column',
20220920 => 'make_status_column_index_instead_queue_name',
20221104 => 'add_error_columns',
];
/**
* Instantiate class.
*/
public function __construct() {
parent::__construct();
add_action( 'admin_init', [ $this, 'maybe_trigger_recreate_table' ], 9 );
add_action( 'init', [ $this, 'maybe_upgrade' ] );
}
/**
* Setup the database schema
*
* @return void
*/
protected function set_schema() {
$this->schema = "
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
url varchar(2000) NOT NULL default '',
css longtext default NULL,
hash varchar(32) default '',
error_code varchar(32) NULL default NULL,
error_message longtext NULL default NULL,
unprocessedcss longtext NULL,
retries tinyint(1) NOT NULL default 1,
is_mobile tinyint(1) NOT NULL default 0,
job_id varchar(255) NOT NULL default '',
queue_name varchar(255) NOT NULL default '',
status varchar(255) NOT NULL default '',
modified timestamp NOT NULL default '0000-00-00 00:00:00',
last_accessed timestamp NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (id),
KEY url (url(150), is_mobile),
KEY modified (modified),
KEY last_accessed (last_accessed),
INDEX `status_index` (`status`(191)),
INDEX `error_code_index` (`error_code`(32)),
KEY hash (hash)";
}
/**
* Delete all used_css which were not accessed in the last month.
*
* @return bool|int
*/
public function delete_old_used_css() {
// Get the database interface.
$db = $this->get_db();
// Bail if no database interface is available.
if ( empty( $db ) ) {
return false;
}
/**
* Filters the old RUCSS deletion interval
*
* @param int $delete_interval Old RUCSS deletion interval in months
*/
$delete_interval = (int) apply_filters( 'rocket_rucss_delete_interval', 1 );
if ( $delete_interval <= 0 ) {
return false;
}
$prefixed_table_name = $this->apply_prefix( $this->table_name );
$query = "DELETE FROM `$prefixed_table_name` WHERE `last_accessed` <= date_sub(now(), interval $delete_interval month)";
$rows_affected = $db->query( $query );
return $rows_affected;
}
/**
* Get all used_css which were not accessed in the last month.
*
* @return array
*/
public function get_old_used_css() : array {
// Get the database interface.
$db = $this->get_db();
// Bail if no database interface is available.
if ( empty( $db ) ) {
return false;
}
$prefixed_table_name = $this->apply_prefix( $this->table_name );
$query = "SELECT * FROM `$prefixed_table_name` WHERE `last_accessed` <= date_sub(now(), interval 1 month)";
$rows_affected = $db->get_results( $query );
return $rows_affected;
}
/**
* Add queue columns.
*
* @return bool
*/
protected function add_async_rucss_columns() {
$jobid_column_exists = $this->column_exists( 'job_id' );
$queuename_column_exists = $this->column_exists( 'queue_name' );
$status_column_exists = $this->column_exists( 'status' );
$created = true;
if ( ! $jobid_column_exists ) {
$created &= $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN job_id VARCHAR(255) NULL default '' AFTER is_mobile " );
}
if ( ! $queuename_column_exists ) {
$created &= $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN queue_name VARCHAR(255) NULL default '' AFTER job_id " );
}
if ( ! $status_column_exists ) {
$created &= $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN status VARCHAR(255) NULL default '' AFTER queue_name " );
}
return $this->is_success( $created );
}
/**
* Make status column as index.
*
* @return bool
*/
protected function make_status_column_index() {
$queuename_column_exists = $this->column_exists( 'queue_name' );
if ( ! $queuename_column_exists ) {
return $this->is_success( false );
}
if ( $this->index_exists( 'queue_name_index' ) ) {
return $this->is_success( true );
}
$index_added = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD INDEX `queue_name_index` (`queue_name`) " );
return $this->is_success( $index_added );
}
/**
* Add hash column and index
*
* @return bool
*/
protected function add_hash_column() {
$hash_column_exists = $this->column_exists( 'hash' );
$created = true;
if ( ! $hash_column_exists ) {
$created &= $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD COLUMN hash VARCHAR(32) NULL default '' AFTER css, ADD KEY hash (hash) " );
}
return $this->is_success( $created );
}
/**
* Make status column as index.
*
* @return bool
*/
protected function make_status_column_index_instead_queue_name() {
$queuename_column_exists = $this->column_exists( 'status' );
if ( ! $queuename_column_exists ) {
return $this->is_success( false );
}
if ( $this->index_exists( 'status_index' ) ) {
return $this->is_success( true );
}
if ( $this->index_exists( 'queue_name_index' ) ) {
if ( ! $this->get_db()->query( "ALTER TABLE {$this->table_name} DROP INDEX `queue_name_index`" ) ) {
return $this->is_success( false );
}
}
$index_added = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD INDEX `status_index` (`status`(191)) " );
return $this->is_success( $index_added );
}
/**
* Remove all completed rows.
*
* @return bool|int
*/
public function remove_all_completed_rows() {
// Get the database interface.
$db = $this->get_db();
// Bail if no database interface is available.
if ( empty( $db ) ) {
return false;
}
$prefixed_table_name = $this->apply_prefix( $this->table_name );
return $db->query( "DELETE FROM `$prefixed_table_name` WHERE status IN ( 'failed', 'completed' )" );
}
/**
* Returns name from table.
*
* @return string
*/
public function get_name() {
return $this->apply_prefix( $this->table_name );
}
/**
* Trigger recreation of cache table if not exist.
*
* @return void
*/
public function maybe_trigger_recreate_table() {
if ( $this->exists() ) {
return;
}
delete_option( $this->db_version_key );
}
/**
* Add error columns
*
* @return bool
*/
protected function add_error_columns() {
return $this->add_error_message_column() && $this->add_error_code_column() && $this->make_error_code_column_index();
}
/**
* Add error_message column and index
*
* @return bool
*/
private function add_error_message_column() {
$error_message_column_exists = $this->column_exists( 'error_message' );
$created = true;
if ( ! $error_message_column_exists ) {
$created &= $this->get_db()->query( "ALTER TABLE `{$this->table_name}` ADD COLUMN error_message longtext NULL default NULL AFTER hash" );
}
return $this->is_success( $created );
}
/**
* Add error_code column and index
*
* @return bool
*/
private function add_error_code_column() {
$error_code_column_exists = $this->column_exists( 'error_code' );
$created = true;
if ( ! $error_code_column_exists ) {
$created &= $this->get_db()->query( "ALTER TABLE `{$this->table_name}` ADD COLUMN error_code VARCHAR(32) NULL default NULL AFTER hash" );
}
return $this->is_success( $created );
}
/**
* Make status column as index.
*
* @return bool
*/
private function make_error_code_column_index() {
$error_code_column_exists = $this->column_exists( 'error_code' );
if ( ! $error_code_column_exists ) {
return $this->is_success( false );
}
if ( $this->index_exists( 'error_code_index' ) ) {
return $this->is_success( true );
}
$index_added = $this->get_db()->query( "ALTER TABLE {$this->table_name} ADD INDEX `error_code_index` (`error_code`) " );
return $this->is_success( $index_added );
}
}