203 lines
5.6 KiB
PHP
203 lines
5.6 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Class file for EWWWIO_Relative_Migration
|
||
|
*
|
||
|
* Performs the migration from storing absolute paths to using relative paths in the ewwwio_images table.
|
||
|
*
|
||
|
* @link https://ewww.io
|
||
|
* @package EWWW_Image_Optimizer
|
||
|
* @since 4.5.2
|
||
|
*/
|
||
|
|
||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||
|
exit;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Migrates absolute paths to relative paths (once).
|
||
|
*/
|
||
|
class EWWWIO_Relative_Migration {
|
||
|
|
||
|
/**
|
||
|
* The offset/position in the database.
|
||
|
*
|
||
|
* @var int $id
|
||
|
*/
|
||
|
private $offset = 0;
|
||
|
|
||
|
/**
|
||
|
* The time when we started processing.
|
||
|
*
|
||
|
* @var int $started
|
||
|
*/
|
||
|
private $started;
|
||
|
|
||
|
/**
|
||
|
* Sets up the the migration.
|
||
|
*/
|
||
|
public function __construct() {
|
||
|
if ( 'done' === get_option( 'ewww_image_optimizer_relative_migration_status' ) ) {
|
||
|
return;
|
||
|
}
|
||
|
if ( ! $this->table_exists() ) {
|
||
|
$this->unschedule();
|
||
|
update_option( 'ewww_image_optimizer_relative_migration_status', 'done' );
|
||
|
delete_option( 'ewww_image_optimizer_relative_migration_offset' );
|
||
|
}
|
||
|
if ( ! get_option( 'ewww_image_optimizer_relative_migration_status' ) ) {
|
||
|
update_option( 'ewww_image_optimizer_relative_migration_status', 'started' );
|
||
|
}
|
||
|
$this->maybe_schedule();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check to see if the ewwwio_images table actually exists.
|
||
|
*
|
||
|
* @return bool True if does, false if it don't.
|
||
|
*/
|
||
|
private function table_exists() {
|
||
|
global $wpdb;
|
||
|
return $wpdb->get_var( "SHOW TABLES LIKE '$wpdb->ewwwio_images'" ) === $wpdb->ewwwio_images;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Retrieves a batch of records based on the current offset.
|
||
|
*/
|
||
|
private function get_records() {
|
||
|
ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
|
||
|
global $wpdb;
|
||
|
if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
|
||
|
ewww_image_optimizer_db_init();
|
||
|
global $ewwwdb;
|
||
|
} else {
|
||
|
$ewwwdb = $wpdb;
|
||
|
}
|
||
|
$query = "SELECT id,path,updated FROM $ewwwdb->ewwwio_images WHERE pending=0 AND image_size > 0 ORDER BY id DESC LIMIT $this->offset,500";
|
||
|
$records = $ewwwdb->get_results( $query, ARRAY_A );
|
||
|
|
||
|
$this->offset += 500;
|
||
|
if ( is_array( $records ) ) {
|
||
|
return $records;
|
||
|
}
|
||
|
return array();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Called via wp_cron to initiate the migration effort.
|
||
|
*/
|
||
|
public function migrate() {
|
||
|
ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
|
||
|
$this->started = time();
|
||
|
$this->offset = (int) get_option( 'ewww_image_optimizer_relative_migration_offset' );
|
||
|
$records = $this->get_records();
|
||
|
ewwwio_debug_message( 'starting at ' . gmdate( 'Y-m-d H:i:s', $this->started ) . " with offset $this->offset" );
|
||
|
while ( ! empty( $records ) ) {
|
||
|
foreach ( $records as $record ) {
|
||
|
if ( $this->already_migrated( $record['path'] ) ) {
|
||
|
ewwwio_debug_message( 'already migrated' );
|
||
|
continue;
|
||
|
}
|
||
|
// Relativize the path, and store it back in the db.
|
||
|
$relative_path = ewww_image_optimizer_relativize_path( $record['path'] );
|
||
|
if ( $record['path'] !== $relative_path ) {
|
||
|
$record['path'] = $relative_path;
|
||
|
$this->update_relative_record( $record );
|
||
|
}
|
||
|
}
|
||
|
if ( time() - $this->started > 20 ) {
|
||
|
update_option( 'ewww_image_optimizer_relative_migration_offset', $this->offset, false );
|
||
|
return;
|
||
|
}
|
||
|
$records = $this->get_records();
|
||
|
}
|
||
|
$this->unschedule();
|
||
|
update_option( 'ewww_image_optimizer_relative_migration_status', 'done' );
|
||
|
delete_option( 'ewww_image_optimizer_relative_migration_offset' );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Checks to see if the record already has been migrated.
|
||
|
*
|
||
|
* @param string $path Path of file as retrieved from database.
|
||
|
*/
|
||
|
private function already_migrated( $path ) {
|
||
|
if ( strpos( $path, 'EWWW_IMAGE_OPTIMIZER_RELATIVE_FOLDER' ) === 0 ) {
|
||
|
return true;
|
||
|
}
|
||
|
if ( strpos( $path, 'ABSPATH' ) === 0 ) {
|
||
|
return true;
|
||
|
}
|
||
|
if ( strpos( $path, 'WP_CONTENT_DIR' ) === 0 ) {
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Updates the db record with the relativized path.
|
||
|
*
|
||
|
* @param array $record Includes a relative path, the ID, and the updated timestamp.
|
||
|
*/
|
||
|
private function update_relative_record( $record ) {
|
||
|
ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
|
||
|
global $wpdb;
|
||
|
if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
|
||
|
ewww_image_optimizer_db_init();
|
||
|
global $ewwwdb;
|
||
|
} else {
|
||
|
$ewwwdb = $wpdb;
|
||
|
}
|
||
|
$ewwwdb->update(
|
||
|
$ewwwdb->ewwwio_images,
|
||
|
array(
|
||
|
'path' => $record['path'],
|
||
|
'updated' => $record['updated'],
|
||
|
),
|
||
|
array(
|
||
|
'id' => $record['id'],
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Schedule the migration.
|
||
|
*/
|
||
|
private function maybe_schedule() {
|
||
|
ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
|
||
|
// Create 5 minute wp_cron schedule.
|
||
|
add_filter( 'cron_schedules', array( $this, 'add_migration_schedule' ) );
|
||
|
add_action( 'ewww_image_optimizer_relative_migration', array( $this, 'migrate' ) );
|
||
|
// Schedule migration function.
|
||
|
if ( ! wp_next_scheduled( 'ewww_image_optimizer_relative_migration' ) ) {
|
||
|
ewwwio_debug_message( 'scheduling migration' );
|
||
|
wp_schedule_event( time(), 'ewwwio_relative_migration_interval', 'ewww_image_optimizer_relative_migration' );
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* Clean up the scheduled event.
|
||
|
*/
|
||
|
private function unschedule() {
|
||
|
ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
|
||
|
$timestamp = wp_next_scheduled( 'ewww_image_optimizer_relative_migration' );
|
||
|
if ( $timestamp ) {
|
||
|
wp_unschedule_event( $timestamp, 'ewww_image_optimizer_relative_migration' );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Adds a custom cron schedule: every 5 minutes.
|
||
|
*
|
||
|
* @param array $schedules An array of custom cron schedules.
|
||
|
*/
|
||
|
public function add_migration_schedule( $schedules ) {
|
||
|
ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
|
||
|
$schedules['ewwwio_relative_migration_interval'] = array(
|
||
|
'interval' => MINUTE_IN_SECONDS * 5,
|
||
|
'display' => 'Every 5 Minutes until complete',
|
||
|
);
|
||
|
return $schedules;
|
||
|
}
|
||
|
}
|
||
|
new EWWWIO_Relative_Migration();
|