Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
File Manager
/
wp-content
/
plugins
/
image-optimization
/
modules
/
optimization
/
classes
/
bulk-optimization
:
bulk-optimization-controller.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php namespace ImageOptimization\Modules\Optimization\Classes\Bulk_Optimization; use ImageOptimization\Classes\Async_Operation\{ Async_Operation, Async_Operation_Hook, Async_Operation_Queue, Exceptions\Async_Operation_Exception, Queries\Image_Optimization_Operation_Query }; use ImageOptimization\Classes\Image\{ Exceptions\Invalid_Image_Exception, Image, Image_Meta, Image_Optimization_Error_Type, Image_Query_Builder, Image_Status }; use ImageOptimization\Classes\Exceptions\Quota_Exceeded_Error; use ImageOptimization\Classes\Logger; use ImageOptimization\Modules\Stats\Classes\Optimization_Stats; use Throwable; // @codeCoverageIgnoreStart if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } // @codeCoverageIgnoreEnd final class Bulk_Optimization_Controller { /** * Cancels pending bulk optimization operations. * * @return void * @throws Async_Operation_Exception */ public static function delete_bulk_optimization(): void { $queue = new Bulk_Optimization_Queue( Bulk_Optimization_Queue_Type::OPTIMIZATION ); if ( $queue->exists() ) { foreach ( $queue->get_image_ids() as $image_id ) { $meta = new Image_Meta( $image_id ); $status = $meta->get_status(); if ( Image_Status::OPTIMIZATION_IN_PROGRESS === $status ) { $meta->delete(); } } $queue->delete(); } $query = ( new Image_Optimization_Operation_Query() ) ->set_hook( Async_Operation_Hook::OPTIMIZE_BULK ) ->set_status( [ Async_Operation::OPERATION_STATUS_PENDING, Async_Operation::OPERATION_STATUS_RUNNING ] ) ->set_limit( 1 ); $operation = Async_Operation::get( $query ); if ( ! empty( $operation ) ) { Async_Operation::remove( [ $operation[0]->get_id() ] ); } } /** * Creates a queue for bulk optimization and schedules the processor. * * @return void * @throws Quota_Exceeded_Error|Invalid_Image_Exception|Async_Operation_Exception */ public static function create_optimization_queue(): void { $images = Bulk_Optimization_Image_Query::find_images( ( new Image_Query_Builder() ) ->return_not_optimized_images(), true ); Logger::debug( 'Non-optimized images found: ' . $images['total_images_count'] ); if ( ! $images['total_images_count'] ) { $not_fully_optimized_images = Bulk_Optimization_Image_Query::find_images( Bulk_Optimization_Image_Query::query_not_fully_optimized_images(), true ); Logger::debug( 'Non fully optimized images found: ' . $images['total_images_count'] ); if ( ! $not_fully_optimized_images['total_images_count'] ) { Logger::debug( 'Bulk optimization not started' ); return; } $images = $not_fully_optimized_images; } $token_data = Bulk_Optimization_Token_Manager::obtain_token( $images['total_images_count'] ); $queue = new Bulk_Optimization_Queue( Bulk_Optimization_Queue_Type::OPTIMIZATION ); Logger::debug( "Bulk token obtained for {$token_data['batch_size']} images" ); $queue ->set_bulk_token( $token_data['token'], time() + HOUR_IN_SECONDS, $token_data['batch_size'] ) ->set_status( Bulk_Optimization_Queue_Status::PROCESSING ) ->add_images( $images['attachments_in_quota'] ) ->save(); Logger::info( "New queue {$queue->get_operation_id()} created" ); Async_Operation::create( Async_Operation_Hook::OPTIMIZE_BULK, [ 'operation_id' => $queue->get_operation_id() ], Async_Operation_Queue::OPTIMIZE ); Logger::debug( 'Async operation created' ); foreach ( $images['attachments_in_quota'] as $image_id ) { ( new Image_Meta( $image_id ) ) ->set_status( Image_Status::OPTIMIZATION_IN_PROGRESS ) ->set_retry_count( 0 ) ->set_error_type( null ) ->save(); } } /** * Creates a queue for bulk reoptimization and schedules the processor. * * @return void * @throws Quota_Exceeded_Error|Invalid_Image_Exception|Async_Operation_Exception */ public static function create_reoptimization_queue(): void { $images = Bulk_Optimization_Image_Query::find_images( ( new Image_Query_Builder() ) ->return_optimized_images() ); if ( ! $images['total_images_count'] ) { return; } $token_data = Bulk_Optimization_Token_Manager::obtain_token( $images['total_images_count'] ); $queue = new Bulk_Optimization_Queue( Bulk_Optimization_Queue_Type::REOPTIMIZATION ); $queue ->set_bulk_token( $token_data['token'], time() + HOUR_IN_SECONDS, $token_data['batch_size'] ) ->set_status( Bulk_Optimization_Queue_Status::PROCESSING ) ->add_images( $images['attachments_in_quota'] ) ->save(); Async_Operation::create( Async_Operation_Hook::REOPTIMIZE_BULK, [ 'operation_id' => $queue->get_operation_id() ], Async_Operation_Queue::OPTIMIZE ); foreach ( $images['attachments_in_quota'] as $image_id ) { ( new Image_Meta( $image_id ) ) ->set_status( Image_Status::REOPTIMIZING_IN_PROGRESS ) ->set_retry_count( 0 ) ->set_error_type( null ) ->save(); } // Handle images out of quota foreach ( $images['attachments_out_of_quota'] as $image_id ) { ( new Image_Meta( $image_id ) ) ->set_status( Image_Status::REOPTIMIZING_FAILED ) ->set_error_type( Image_Optimization_Error_Type::QUOTA_EXCEEDED ) ->save(); } } /** * Checks if there is a bulk optimization operation in progress. * If there is at least a single active bulk optimization operation it returns true, otherwise false. * * @return bool */ public static function is_optimization_in_progress(): bool { $queue = new Bulk_Optimization_Queue( Bulk_Optimization_Queue_Type::OPTIMIZATION ); return $queue->exists() && Bulk_Optimization_Queue_Status::PROCESSING === $queue->get_status(); } /** * Checks if there is a bulk re-optimization operation in progress. * If there is at least a single active bulk re-optimization operation it returns true, otherwise false. * * @return bool */ public static function is_reoptimization_in_progress(): bool { $queue = new Bulk_Optimization_Queue( Bulk_Optimization_Queue_Type::REOPTIMIZATION ); return $queue->exists() && Bulk_Optimization_Queue_Status::PROCESSING === $queue->get_status(); } /** * Retrieves the bulk optimization process status. * * @return array{status: string, stats: array} */ public static function get_status(): array { $stats = Optimization_Stats::get_image_stats(); $percentage = 0; if ( $stats['total_image_count'] > 0 ) { $percentage = round( $stats['optimized_image_count'] / $stats['total_image_count'] * 100 ); } $output = [ 'status' => 'not-started', 'percentage' => $percentage, ]; $queue = new Bulk_Optimization_Queue( Bulk_Optimization_Queue_Type::OPTIMIZATION ); if ( ! $queue->exists() ) { return $output; } $output['status'] = 'in-progress'; return $output; } /** * Returns latest operations for the bulk optimization screen. * * @return array */ public static function get_processed_images(): array { $output = []; $queue = new Bulk_Optimization_Queue( Bulk_Optimization_Queue_Type::OPTIMIZATION ); if ( ! $queue->exists() ) { return $output; } $images = $queue->get_images(); $images = array_slice( $images, 0, 50 ); foreach ( $images as $queue_image ) { $image_id = $queue_image['id']; try { $image = new Image( $image_id ); $stats = Optimization_Stats::get_image_stats( $image_id ); } catch ( Throwable $t ) { continue; } $meta = new Image_Meta( $image_id ); $output[] = [ 'id' => $image_id, 'status' => $meta->get_status(), 'image_name' => $image->get_attachment_object()->post_title, 'image_id' => $image_id, 'thumbnail_url' => $image->get_url( 'thumbnail' ), 'original_file_size' => $stats['initial_image_size'], 'current_file_size' => $stats['current_image_size'], ]; } return $output; } }