File "bulk-optimization.php"
Full Path: /home/adniftyx/public_html/wp-content/plugins/image-optimization/modules/optimization/components/bulk-optimization.php
File size: 7.41 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace ImageOptimization\Modules\Optimization\Components;
use ImageOptimization\Classes\Async_Operation\{
Async_Operation,
Async_Operation_Hook,
Async_Operation_Queue,
};
use ImageOptimization\Classes\Image\{
Image_Meta,
Image_Status
};
use ImageOptimization\Modules\Optimization\{
Classes\Exceptions\Bulk_Token_Expired_Error,
Classes\Optimize_Image,
Classes\Bulk_Optimization\Bulk_Optimization_Queue,
Classes\Bulk_Optimization\Bulk_Optimization_Queue_Status,
Classes\Bulk_Optimization\Bulk_Optimization_Queue_Type,
Classes\Bulk_Optimization\Bulk_Optimization_Token_Manager,
};
use ImageOptimization\Classes\Logger;
use ImageOptimization\Classes\Utils;
use ImageOptimization\Classes\Exceptions\Quota_Exceeded_Error;
use Throwable;
// @codeCoverageIgnoreStart
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
// @codeCoverageIgnoreEnd
class Bulk_Optimization {
/** @async */
public function optimize_bulk() {
$queue = new Bulk_Optimization_Queue( Bulk_Optimization_Queue_Type::OPTIMIZATION );
if ( ! $queue->exists() ) {
Logger::debug( 'Bulk optimization queue did not found' );
return;
}
if ( ! $queue->has_more_images() ) {
Logger::debug( 'No more pending images, deleting queue' );
$queue->delete();
return;
}
if ( $queue->should_refresh_token() ) {
Logger::debug( 'Refreshing bulk token' );
try {
$token_data = Bulk_Optimization_Token_Manager::obtain_token(
$queue->get_stats()[ Bulk_Optimization_Queue_Status::PENDING ],
$queue->get_max_batch_size()
);
$queue
->set_bulk_token(
$token_data['token'],
time() + HOUR_IN_SECONDS,
$token_data['batch_size']
)
->save();
} catch ( Throwable $t ) {
Logger::info( 'Failed to obtain a bulk token: ' . $t->getMessage() );
foreach ( $queue->get_images_by_status( Bulk_Optimization_Queue_Status::PENDING ) as $image ) {
( new Image_Meta( $image['id'] ) )
->set_status( Image_Status::NOT_OPTIMIZED )
->save();
}
$queue->delete();
return;
}
}
$image_id = $queue->get_next_image();
Logger::debug( 'Processing image: ' . $image_id );
if ( ! $image_id ) {
Logger::debug( 'No image to process, deleting queue' );
$queue->delete();
return;
}
$queue
->set_current_image_id( $image_id )
->save();
try {
$oi = new Optimize_Image(
$image_id,
'bulk',
$queue->get_bulk_token()
);
$oi->optimize();
$queue
->mark_image_completed( $image_id )
->increment_optimized_counter()
->save();
} catch ( Bulk_Token_Expired_Error $btee ) {
$queue->mark_image_failed( $image_id )->save();
Logger::info( "Token expired while optimizing image {$image_id}" );
} catch ( Quota_Exceeded_Error $qee ) {
$queue->mark_image_failed( $image_id )->save();
Logger::info( "Quota exceeded while optimizing image {$image_id}" );
} catch ( Throwable $e ) {
$queue->mark_image_failed( $image_id )->save();
Logger::info( "Failed to optimize image {$image_id}: " . $e->getMessage() );
}
$queue
->set_current_image_id( null )
->save();
try {
if ( $queue->has_more_images() ) {
Async_Operation::create(
Async_Operation_Hook::OPTIMIZE_BULK,
[ 'operation_id' => $queue->get_operation_id() ],
Async_Operation_Queue::OPTIMIZE
);
Logger::debug( 'Async operation created' );
} else {
Logger::debug( 'All images were optimized, deleting queue' );
$queue->delete();
}
} catch ( Throwable $t ) {
Logger::error( "Failed to create next async operation or delete queue: " . $t->getMessage() );
}
}
/** @async */
public function reoptimize_bulk() {
$queue = new Bulk_Optimization_Queue( Bulk_Optimization_Queue_Type::REOPTIMIZATION );
if ( ! $queue->exists() ) {
return;
}
if ( ! $queue->has_more_images() ) {
$queue->delete();
return;
}
if ( $queue->should_refresh_token() ) {
try {
$token_data = Bulk_Optimization_Token_Manager::obtain_token(
$queue->get_stats()[ Bulk_Optimization_Queue_Status::PENDING ],
$queue->get_max_batch_size()
);
$queue
->set_bulk_token(
$token_data['token'],
time() + HOUR_IN_SECONDS,
$token_data['batch_size']
)
->save();
} catch ( Throwable $t ) {
Logger::info( 'Failed to obtain bulk token: ' . $t->getMessage() );
foreach ( $queue->get_images_by_status( Bulk_Optimization_Queue_Status::PENDING ) as $image ) {
( new Image_Meta( $image['id'] ) )
->set_status( Image_Status::OPTIMIZATION_FAILED )
->save();
}
$queue->delete();
return;
}
}
$image_id = $queue->get_next_image();
if ( ! $image_id ) {
$queue
->set_status( Bulk_Optimization_Queue_Status::COMPLETED )
->save();
return;
}
$queue
->set_current_image_id( $image_id )
->save();
try {
$oi = new Optimize_Image(
$image_id,
'bulk-reoptimize',
$queue->get_bulk_token(),
true
);
$oi->optimize();
$queue
->mark_image_completed( $image_id )
->increment_optimized_counter()
->save();
} catch ( Bulk_Token_Expired_Error $btee ) {
$queue->mark_image_failed( $image_id )->save();
Logger::info( "Token expired while reoptimizing image {$image_id}" );
} catch ( Quota_Exceeded_Error $qee ) {
$queue->mark_image_failed( $image_id )->save();
foreach ( $queue->get_images_by_status( Bulk_Optimization_Queue_Status::PENDING ) as $image ) {
( new Image_Meta( $image['id'] ) )
->set_status( Image_Status::OPTIMIZATION_FAILED )
->save();
}
$queue->delete();
Logger::info( "Quota exceeded while reoptimizing image {$image_id}" );
return;
} catch ( Throwable $e ) {
$queue->mark_image_failed( $image_id )->save();
Logger::info( "Failed to reoptimize image {$image_id}: " . $e->getMessage() );
}
$queue
->set_current_image_id( null )
->save();
try {
if ( $queue->has_more_images() ) {
Async_Operation::create(
Async_Operation_Hook::REOPTIMIZE_BULK,
[ 'operation_id' => $queue->get_operation_id() ],
Async_Operation_Queue::OPTIMIZE
);
} else {
$queue->delete();
}
} catch ( Throwable $t ) {
Logger::error( "Failed to create next async operation or delete queue: " . $t->getMessage() );
}
}
/**
* Renders the bulk optimization notice
*
* @return void
*/
public function render_bulk_optimization_notice() {
$queue = new Bulk_Optimization_Queue( Bulk_Optimization_Queue_Type::OPTIMIZATION );
$is_in_progress = $queue->exists();
?>
<div class="notice notice-info notice image-optimizer__notice image-optimizer__notice--info image-optimizer__notice--bulk-tip"
style="display: <?php echo $is_in_progress ? 'block' : 'none'; ?>">
<p>
<b>
<?php esc_html_e(
'Heads up!',
'image-optimization'
); ?>
</b>
<span>
<?php esc_html_e(
'Bulk optimizing may take a lot of processing and server time, depending on the number of images. Your site will still work smoothly until the processing is all done, without any downtime.',
'image-optimization'
); ?>
</span>
</p>
</div>
<?php
}
public function __construct() {
add_action( Async_Operation_Hook::OPTIMIZE_BULK, [ $this, 'optimize_bulk' ] );
add_action( Async_Operation_Hook::REOPTIMIZE_BULK, [ $this, 'reoptimize_bulk' ] );
add_action( 'current_screen', function () {
if ( Utils::is_bulk_optimization_page() ) {
add_filter( 'admin_footer_text', [ $this, 'render_bulk_optimization_notice' ] );
}
} );
}
}