File "class-media-item-optimizer.php"
Full Path: /home/digimqhe/flashdigi.uk/list/media/class-media-item-optimizer.php
File size: 10.44 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace Smush\Core\Media;
use Smush\Core\Backups\Backups;
use Smush\Core\Helper;
use Smush\Core\Smush\Smush_Optimization;
use Smush\Core\Stats\Global_Stats;
use WDEV_Logger;
use WP_Error;
class Media_Item_Optimizer {
const ERROR_META_KEY = 'wp-smush-optimization-errors';
/**
* @var Media_Item_Optimization[]
*/
private $optimizations;
/**
* @var Media_Item
*/
private $media_item;
/**
* @var Backups
*/
private $backups;
/**
* @var WDEV_Logger
*/
private $logger;
/**
* @var Global_Stats
*/
private $global_stats;
/**
* @var WP_Error
*/
private $errors;
public function __construct( $media_item ) {
$this->media_item = $media_item;
$this->backups = new Backups();
$this->logger = Helper::logger();
$this->global_stats = Global_Stats::get();
}
/**
* @return Media_Item_Optimization[]
*/
public function get_optimizations() {
if ( is_null( $this->optimizations ) ) {
$this->optimizations = $this->initialize_optimizations();
}
return $this->optimizations;
}
public function set_optimizations( $optimizations ) {
$this->optimizations = $optimizations;
}
private function initialize_optimizations() {
return apply_filters( 'wp_smush_optimizations', array(), $this->media_item );
}
/**
* TODO: check the uses for this method to make sure they are prepared to receive null
*
* @param $key
*
* @return Media_Item_Optimization|null
*/
public function get_optimization( $key ) {
return $this->get_array_value( $this->get_optimizations(), $key );
}
/**
* @param $key
*
* @return Media_Item_Stats
*/
public function get_stats( $key ) {
$optimization = $this->get_optimization( $key );
if ( $optimization ) {
return $optimization->get_stats();
}
return new Media_Item_Stats();
}
public function get_total_stats() {
$total_stats = new Media_Item_Stats();
foreach ( $this->get_optimizations() as $optimization ) {
$total_stats->add( $optimization->get_stats() );
}
return $total_stats;
}
/**
* @param $optimization_key
* @param $size_key
*
* @return Media_Item_Stats
*/
public function get_size_stats( $optimization_key, $size_key ) {
$optimization = $this->get_optimization( $optimization_key );
if ( $optimization ) {
return $optimization->get_size_stats( $size_key );
}
return new Media_Item_Stats();
}
public function get_total_size_stats( $size_key ) {
$total_stats = new Media_Item_Stats();
foreach ( $this->get_optimizations() as $optimization ) {
$total_stats->add( $optimization->get_size_stats( $size_key ) );
}
return $total_stats;
}
public function get_optimized_sizes_count() {
$size_count = 0;
foreach ( $this->get_optimizations() as $optimization ) {
$optimized_sizes_count = $optimization->get_optimized_sizes_count();
if ( $optimized_sizes_count > $size_count ) {
$size_count = $optimized_sizes_count;
}
}
return $size_count;
}
/**
* Whether the media item was optimized at some point. It may need to be reoptimized.
*
* @return bool
*/
public function is_optimized() {
foreach ( $this->get_optimizations() as $optimization ) {
if ( $optimization->is_optimized() ) {
return true;
}
}
return false;
}
public function should_optimize() {
foreach ( $this->get_optimizations() as $optimization ) {
if ( $optimization->should_optimize() ) {
return true;
}
}
return false;
}
public function should_reoptimize() {
$should_reoptimize = false;
foreach ( $this->get_optimizations() as $optimization ) {
if ( $optimization->should_reoptimize() ) {
$should_reoptimize = true;
}
}
return apply_filters( 'wp_smush_should_resmush', $should_reoptimize, $this->media_item->get_id() );
}
public function optimize() {
if ( $this->restore_in_progress() ) {
$this->logger->log( 'Prevented auto-smush during restore.' );
return false;
}
if ( $this->in_progress() ) {
$this->handle_error( 'in_progress', 'Smush already in progress' );
return false;
}
$media_item = $this->media_item;
do_action(
'wp_smush_before_smush_attempt',
$media_item->get_id(),
$media_item->get_wp_metadata()
);
if ( $media_item->has_errors() || $media_item->is_skipped() ) {
$this->adjust_global_stats_lists();
return false;
}
do_action(
'wp_smush_before_smush_file',
$media_item->get_id(),
$media_item->get_wp_metadata()
);
$this->set_in_progress_transient();
$this->backups->maybe_create_backup( $media_item, $this );
$optimized = $this->run_optimizations();
do_action(
'wp_smush_after_smush_file',
$media_item->get_id(),
$media_item->get_wp_metadata(),
$optimized ? array() : $this->get_errors()
);
if ( $optimized ) {
do_action(
'wp_smush_after_smush_successful',
$media_item->get_id(),
$media_item->get_wp_metadata()
);
$this->delete_previous_optimization_errors();
} else {
$this->handle_optimization_errors();
}
$this->delete_in_progress_transient();
return $optimized;
}
public function restore() {
if ( $this->in_progress() || $this->restore_in_progress() ) {
return false;
}
$this->set_restore_in_progress_transient();
$restoration_attempted = false;
$restored = false;
// First, allow one of the optimizations to handle the restoration process
foreach ( $this->get_optimizations() as $optimization ) {
if ( $optimization->can_restore() ) {
$restoration_attempted = true;
$restored = $optimization->restore();
break;
}
}
if ( ! $restoration_attempted ) {
// Try the standard restoration
$restored = $this->backups->restore_backup( $this->media_item );
}
if ( $restored ) {
// Before deleting all data subtract the stats
$this->global_stats->subtract_item_stats( $this->media_item );
$this->global_stats->subtract_optimized_images_count( $this->get_optimized_sizes_count() );
// Delete all the optimization data
$this->delete_data();
// Delete optimization errors.
$this->delete_previous_optimization_errors();
// Once all data has been deleted, adjust the lists
$this->global_stats->adjust_lists_for_media_item( $this->media_item );
}
$this->delete_restore_in_progress_transient();
return $restored;
}
public function save() {
foreach ( $this->get_optimizations() as $optimization ) {
$optimization->save();
}
}
private function get_array_value( $array, $key ) {
return $array && isset( $array[ $key ] )
? $array[ $key ]
: null;
}
/**
* @param Media_Item_Size $full_size
*
* @return boolean
*/
public function should_optimize_size( $full_size ) {
$should_optimize_size = false;
foreach ( $this->get_optimizations() as $optimization ) {
if ( $optimization->should_optimize_size( $full_size ) ) {
$should_optimize_size = true;
break;
}
}
return $should_optimize_size;
}
public function delete_data() {
foreach ( $this->get_optimizations() as $optimization ) {
$optimization->delete_data();
}
}
/**
* @return bool
*/
private function run_optimizations() {
$all_optimized = true;
foreach ( $this->get_optimizations() as $optimization ) {
if ( $optimization->should_optimize() ) {
$current_optimized = $optimization->optimize();
$all_optimized = $all_optimized && $current_optimized;
}
}
return $all_optimized;
}
private function adjust_global_stats_lists() {
$this->global_stats->adjust_lists_for_media_item( $this->media_item );
}
private function set_in_progress_transient() {
set_transient( $this->in_progress_transient_key(), 1, HOUR_IN_SECONDS );
}
private function delete_in_progress_transient() {
delete_transient( $this->in_progress_transient_key() );
}
public function in_progress() {
return (bool) get_transient( $this->in_progress_transient_key() );
}
private function in_progress_transient_key() {
return 'smush-in-progress-' . $this->media_item->get_id();
}
private function set_restore_in_progress_transient() {
set_transient( $this->restore_in_progress_transient_key(), 1, HOUR_IN_SECONDS );
}
private function delete_restore_in_progress_transient() {
delete_transient( $this->restore_in_progress_transient_key() );
}
public function restore_in_progress() {
return (bool) get_transient( $this->restore_in_progress_transient_key() );
}
private function restore_in_progress_transient_key() {
return 'wp-smush-restore-' . $this->media_item->get_id();
}
/**
* @param $code
* @param $error_message
*
* @return void
*/
private function handle_error( $code, $error_message ) {
$this->logger->error( $error_message );
$this->set_errors( new WP_Error( $code, $error_message ) );
$this->update_errors_meta();
}
public function get_errors() {
if ( is_null( $this->errors ) ) {
$this->errors = $this->fetch_errors_from_meta();
}
return $this->errors;
}
private function set_errors( $errors ) {
$this->errors = $errors;
}
public function has_errors() {
return $this->get_errors()->has_errors();
}
private function set_optimization_errors() {
$errors = new WP_Error();
// Add optimization errors
foreach ( $this->get_optimizations() as $optimization ) {
if ( $optimization->has_errors() ) {
$errors->merge_from( $optimization->get_errors() );
}
}
$this->set_errors( $errors );
}
private function fetch_errors_from_meta() {
$wp_error = new WP_Error();
$errors = get_post_meta( $this->media_item->get_id(), self::ERROR_META_KEY, true );
if ( empty( $errors ) || ! is_array( $errors ) ) {
return $wp_error;
}
foreach ( $errors as $error_code => $error_message ) {
if ( empty( $error_message ) ) {
continue;
}
if ( is_array( $error_message ) ) {
foreach ( $error_message as $error ) {
$wp_error->add( $error_code, $error );
}
} else {
$wp_error->add( $error_code, $error_message );
}
}
return $wp_error;
}
private function update_errors_meta() {
$errors_array = array();
foreach ( $this->errors->get_error_codes() as $error_code ) {
$errors_array[ $error_code ] = $this->errors->get_error_messages( $error_code );
}
if ( ! empty( $errors_array ) ) {
update_post_meta( $this->media_item->get_id(), self::ERROR_META_KEY, $errors_array );
}
}
/**
* @return void
*/
private function handle_optimization_errors() {
$this->set_optimization_errors();
$this->update_errors_meta();
}
private function delete_previous_optimization_errors() {
if ( $this->has_errors() ) {
delete_post_meta( $this->media_item->get_id(), self::ERROR_META_KEY );
$this->set_errors( null );
}
}
}