This commit is contained in:
2024-05-20 15:37:46 +03:00
commit 00b7dbd0b7
10404 changed files with 3285853 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
<?php
namespace Smush\Core\Media;
use WP_Smush;
/**
* TODO: maybe reset the media item when:
* - a new size is added
*/
class Media_Item_Cache {
const CACHE_GROUP = 'wp-smushit';
/**
* Static instance
*
* @var self
*/
private static $instance;
/**
* @var Media_Item[]
*/
private $media_items;
/**
* Static instance getter
*/
public static function get_instance() {
if ( empty( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
public function has( $id ) {
$media_item = $this->get_from_cache( $id );
return ! empty( $media_item );
}
/**
* @param $id
*
* @return Media_Item|null
*/
public function get( $id ) {
$media_item = $this->get_from_cache( $id );
if ( ! $media_item ) {
$media_item = new Media_Item( $id );
$this->save_to_cache( $id, $media_item );
}
return $media_item;
}
/**
* @param $id
*
* @return Media_Item|null
*/
private function get_from_cache( $id ) {
return $this->get_array_value(
$this->media_items,
$this->make_key( $id )
);
}
private function make_key( $id ) {
$membership_type_postfix = WP_Smush::is_pro() ? 'pro' : 'free';
return "wp-smush-$membership_type_postfix-media-item-$id";
}
private function save_to_cache( $id, $media_item ) {
$this->media_items[ $this->make_key( $id ) ] = $media_item;
}
public function remove( $id ) {
unset( $this->media_items[ $this->make_key( $id ) ] );
}
private function get_array_value( $array, $key ) {
return $array && isset( $array[ $key ] )
? $array[ $key ]
: null;
}
}

View File

@@ -0,0 +1,108 @@
<?php
namespace Smush\Core\Media;
use Smush\Core\Controller;
use Smush\Core\Error_Handler;
use Smush\Core\Helper;
use Smush\Core\Stats\Global_Stats;
use WP_Smush;
/**
* Performs operations on the media item
*/
class Media_Item_Controller extends Controller {
public function __construct() {
$this->register_action( 'wp_ajax_ignore_bulk_image', array( $this, 'ignore_bulk_image' ) );
$this->register_action( 'wp_ajax_remove_from_skip_list', array( $this, 'remove_from_skip_list' ) );
$this->register_action( 'wp_ajax_wp_smush_ignore_all_failed_items', array(
$this,
'ignore_all_failed_items',
) );
}
public function remove_from_skip_list() {
check_ajax_referer( 'wp-smush-remove-skipped' );
if ( ! Helper::is_user_allowed( 'upload_files' ) ) {
wp_send_json_error( array(
'error_message' => esc_html__( "You don't have permission to work with uploaded files.", 'wp-smushit' ),
), 403 );
}
if ( ! isset( $_POST['id'] ) ) {
wp_send_json_error();
}
$attachment_id = absint( $_POST['id'] );
$changed = $this->change_attachment_ignored_status( $attachment_id, false );
if ( ! $changed ) {
wp_send_json_error();
}
wp_send_json_success(
array(
'html' => WP_Smush::get_instance()->library()->generate_markup( $attachment_id ),
)
);
}
public function ignore_bulk_image() {
check_ajax_referer( 'wp-smush-ajax' );
if ( ! Helper::is_user_allowed( 'upload_files' ) ) {
wp_send_json_error( array(
'error_msg' => esc_html__( "You don't have permission to work with uploaded files.", 'wp-smushit' ),
), 403 );
}
if ( ! isset( $_POST['id'] ) ) {
wp_send_json_error();
}
$attachment_id = absint( $_POST['id'] );
$changed = $this->change_attachment_ignored_status( $attachment_id, true );
if ( ! $changed ) {
wp_send_json_error();
}
wp_send_json_success( array(
'html' => WP_Smush::get_instance()->library()->generate_markup( $attachment_id ),
) );
}
public function ignore_all_failed_items() {
check_ajax_referer( 'wp-smush-ajax' );
if ( ! Helper::is_user_allowed() ) {
wp_send_json_error( array(
'message' => __( "You don't have permission to do this.", 'wp-smushit' ),
), 403 );
}
$failed_images = Error_Handler::get_all_failed_images();
if ( empty( $failed_images ) ) {
wp_send_json_error( array( 'message' => __( 'Not found any failed items.', 'wp-smushit' ) ) );
}
foreach ( $failed_images as $failed_image_id ) {
$this->change_attachment_ignored_status( $failed_image_id, true );
}
wp_send_json_success();
}
private function change_attachment_ignored_status( $attachment_id, $new_status ) {
$media_item = Media_Item_Cache::get_instance()->get( $attachment_id );
if ( ! $media_item->is_mime_type_supported() ) {
return false;
}
$media_item->set_ignored( $new_status );
$media_item->save();
do_action( 'wp_smush_attachment_ignored_status_changed', $attachment_id, $new_status );
return true;
}
}

View File

@@ -0,0 +1,161 @@
<?php
namespace Smush\Core\Media;
use Smush\Core\Array_Utils;
class Media_Item_Optimization_Global_Stats extends Media_Item_Stats {
/**
* @var int How many media *items* are included in this instance.
*/
private $count = 0;
/**
* @var int[] Ids of the attachments included in this instance.
*/
private $attachment_ids = array();
private $array_utils;
public function __construct() {
$this->array_utils = new Array_Utils();
}
public function to_array() {
$array = parent::to_array();
$array['count'] = $this->get_count();
$array['attachment_ids'] = join( ',', $this->get_attachment_ids() );
return $array;
}
public function from_array( $array ) {
parent::from_array( $array );
$this->set_count( (int) $this->get_array_value( $array, 'count' ) );
$attachment_ids = $this->get_array_value( $array, 'attachment_ids' );
$attachment_ids = empty( $attachment_ids ) ? array() : explode( ',', $attachment_ids );
$this->set_attachment_ids( $attachment_ids );
}
/**
* @param $attachment_id int
* @param $item_stats Media_Item_Stats
*
* @return boolean
*/
public function add_item_stats( $attachment_id, $item_stats ) {
if ( $this->has_attachment_id( $attachment_id ) ) {
return false;
} else {
parent::add( $item_stats );
$this->set_count( $this->get_count() + 1 );
$this->add_attachment_id( $attachment_id );
return true;
}
}
/**
* @param $attachment_id int
* @param $item_stats Media_Item_Stats
*
* @return boolean
*/
public function subtract_item_stats( $attachment_id, $item_stats ) {
if ( $this->has_attachment_id( $attachment_id ) ) {
parent::subtract( $item_stats );
$this->set_count( $this->get_count() - 1 );
$this->remove_attachment_id( $attachment_id );
return true;
} else {
return false;
}
}
/**
* @param $addend Media_Item_Optimization_Global_Stats
*
* @return void
*/
public function add( $addend ) {
parent::add( $addend );
$this->set_count( $this->get_count() + $addend->get_count() );
$this->set_attachment_ids(
$this->array_utils->fast_array_unique( array_merge(
$this->get_attachment_ids(),
$addend->get_attachment_ids()
) )
);
}
/**
* @param $subtrahend Media_Item_Optimization_Global_Stats
*
* @return void
*/
public function subtract( $subtrahend ) {
parent::subtract( $subtrahend );
$this->set_count( max( $this->get_count() - $subtrahend->get_count(), 0 ) );
$this->set_attachment_ids(
array_diff(
$this->get_attachment_ids(),
$subtrahend->get_attachment_ids()
)
);
}
/**
* @return mixed
*/
public function get_count() {
return $this->count;
}
/**
* @param mixed $count
*
* @return Media_Item_Optimization_Global_Stats
*/
public function set_count( $count ) {
$this->count = $count;
return $this;
}
private function add_attachment_id( $attachment_id ) {
$this->attachment_ids[] = $attachment_id;
}
private function remove_attachment_id( $attachment_id ) {
$attachment_ids = $this->get_attachment_ids();
$index = array_search( $attachment_id, $attachment_ids );
if ( $index !== false ) {
unset( $attachment_ids[ $index ] );
$this->set_attachment_ids( $attachment_ids );
}
}
public function has_attachment_id( $attachment_id ) {
return in_array( $attachment_id, $this->get_attachment_ids() );
}
private function get_attachment_ids() {
$attachment_ids = $this->attachment_ids;
return empty( $attachment_ids ) || ! is_array( $attachment_ids )
? array()
: $attachment_ids;
}
private function set_attachment_ids( $attachment_ids ) {
$this->attachment_ids = empty( $attachment_ids ) || ! is_array( $attachment_ids )
? array()
: $attachment_ids;
}
}

View File

@@ -0,0 +1,70 @@
<?php
namespace Smush\Core\Media;
use WP_Error;
abstract class Media_Item_Optimization {
/**
* @param $media_item Media_Item
*/
abstract public function __construct( $media_item );
abstract public function get_key();
/**
* @return Media_Item_Stats
*/
abstract public function get_stats();
/**
* @return Media_Item_Stats
*/
abstract public function get_size_stats( $size_key );
abstract public function get_optimized_sizes_count();
abstract public function save();
abstract public function is_optimized();
abstract public function should_optimize();
abstract public function should_reoptimize();
/**
* @param $size Media_Item_Size
*/
abstract public function should_optimize_size( $size );
/**
* @return mixed
*/
abstract public function delete_data();
/**
* @return boolean
*/
abstract public function optimize();
public function can_restore() {
return false;
}
public function restore() {
return false;
}
public function has_errors() {
$wp_error = $this->get_errors();
return $wp_error
&& is_a( $wp_error, '\WP_Error' )
&& $wp_error->has_errors();
}
/**
* @return WP_Error
*/
abstract public function get_errors();
}

View File

@@ -0,0 +1,450 @@
<?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_file',
$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;
}
$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 );
}
}
}

View File

@@ -0,0 +1,134 @@
<?php
namespace Smush\Core\Media;
use Smush\Core\Smush\Smush_Optimization;
use Smush\Core\Smush_File;
class Media_Item_Query {
public function fetch( $offset = 0, $limit = - 1 ) {
global $wpdb;
$query = $this->make_query( 'ID', $offset, $limit );
return $wpdb->get_col( $query );
}
public function fetch_slice_post_meta( $slice, $slice_size ) {
global $wpdb;
$offset = $this->get_offset( $slice, $slice_size );
$limit = (int) $slice_size;
$ids_query = $this->make_query( 'ID', $offset, $limit );
$query = "SELECT CONCAT(post_id, '-', meta_key), post_id, meta_key, meta_value FROM $wpdb->postmeta WHERE post_id IN (SELECT * FROM ($ids_query) AS slice_ids);";
return $wpdb->get_results( $query, OBJECT_K );
}
public function fetch_slice_posts( $slice, $slice_size ) {
global $wpdb;
$offset = $this->get_offset( $slice, $slice_size );
$limit = (int) $slice_size;
$posts_query = $this->make_query( '*', $offset, $limit );
return $wpdb->get_results( $posts_query, OBJECT_K );
}
public function fetch_slice_ids( $slice, $slice_size ) {
$offset = $this->get_offset( $slice, $slice_size );
$limit = (int) $slice_size;
return $this->fetch( $offset, $limit );
}
public function get_slice_count( $slice_size ) {
if ( empty( $slice_size ) ) {
return 0;
}
$image_attachment_count = $this->get_image_attachment_count();
return (int) ceil( $image_attachment_count / $slice_size );
}
public function get_image_attachment_count() {
global $wpdb;
$query = $this->make_query( 'COUNT(*)' );
return (int) $wpdb->get_var( $query );
}
/**
* @param $select
* @param $offset
* @param $limit
*
* @return string|null
*/
private function make_query( $select, $offset = 0, $limit = - 1 ) {
global $wpdb;
$mime_types = ( new Smush_File() )->get_supported_mime_types();
$placeholders = implode( ',', array_fill( 0, count( $mime_types ), '%s' ) );
$column = $select;
$query = "SELECT %s FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type IN (%s)";
$query = sprintf( $query, $column, $placeholders );
$args = $mime_types;
if ( $limit > 0 ) {
$query = "$query LIMIT %d";
$args[] = $limit;
if ( $offset >= 0 ) {
$query = "$query OFFSET %d";
$args[] = $offset;
}
}
return $wpdb->prepare( $query, $args );
}
public function get_lossy_count() {
global $wpdb;
$query = $wpdb->prepare( "SELECT COUNT(DISTINCT post_id) FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = 1", Smush_Optimization::LOSSY_META_KEY );
return $wpdb->get_var( $query );
}
public function get_smushed_count() {
global $wpdb;
$query = $wpdb->prepare(
"SELECT COUNT(DISTINCT post_meta_optimized.post_id) FROM $wpdb->postmeta as post_meta_optimized
LEFT JOIN $wpdb->postmeta as post_meta_ignored ON post_meta_optimized.post_id = post_meta_ignored.post_id AND post_meta_ignored.meta_key= %s
WHERE post_meta_optimized.meta_key = %s AND post_meta_ignored.meta_value IS NULL",
Media_Item::IGNORED_META_KEY,
Smush_Optimization::SMUSH_META_KEY
);
return $wpdb->get_var( $query );
}
public function get_ignored_count() {
global $wpdb;
$query = $wpdb->prepare( "SELECT COUNT(DISTINCT post_id) FROM $wpdb->postmeta WHERE meta_key = %s", Media_Item::IGNORED_META_KEY );
return $wpdb->get_var( $query );
}
/**
* @param $slice
* @param $slice_size
*
* @return float|int
*/
private function get_offset( $slice, $slice_size ) {
$slice = (int) $slice;
$slice_size = (int) $slice_size;
return ( $slice - 1 ) * $slice_size;
}
}

View File

@@ -0,0 +1,263 @@
<?php
namespace Smush\Core\Media;
use Smush\Core\File_System;
use Smush\Core\Settings;
use WP_Smush;
class Media_Item_Size {
/**
* @var string
*/
private $key;
/**
* @var string
*/
private $file_name;
/**
* @var int
*/
private $width;
/**
* @var int
*/
private $height;
/**
* @var string
*/
private $mime_type;
/**
* @var int
*/
private $filesize;
/**
* @var int
*/
private $attachment_id;
/**
* @var Settings
*/
private $settings;
/**
* @var array
*/
private $wp_metadata;
/**
* @var int
*/
private $size_limit;
/**
* @var string
*/
private $dir;
/**
* @var string
*/
private $base_url;
/**
* @var string
*/
private $extension;
/**
* @var File_System
*/
private $fs;
/**
* @param $key string
* @param $attachment_id int
* @param $wp_size_metadata array
*/
public function __construct( $key, $attachment_id, $dir, $base_url, $wp_size_metadata ) {
$this->key = $key;
$this->attachment_id = $attachment_id;
$this->dir = $dir;
$this->base_url = $base_url;
$this->wp_metadata = $wp_size_metadata;
$this->fs = new File_System();
$this->size_limit = WP_Smush::is_pro()
? WP_SMUSH_PREMIUM_MAX_BYTES
: WP_SMUSH_MAX_BYTES;
$this->settings = Settings::get_instance();
$this->from_array( $wp_size_metadata );
}
/**
* @param $size_data array Typically an item from 'sizes' array returned by wp_get_attachment_metadata
*
* @return void
*/
private function from_array( $size_data ) {
$this->set_file_name( (string) $this->get_array_value( $size_data, 'file' ) );
$this->set_width( (int) $this->get_array_value( $size_data, 'width' ) );
$this->set_height( (int) $this->get_array_value( $size_data, 'height' ) );
$this->set_mime_type( (string) $this->get_array_value( $size_data, 'mime-type' ) );
$this->set_filesize( (int) $this->get_array_value( $size_data, 'filesize' ) );
}
private function get_array_value( $array, $key ) {
return isset( $array[ $key ] ) ? $array[ $key ] : null;
}
public function get_file_name_without_extension() {
return mb_substr( $this->get_file_name(), 0, mb_strlen( $this->get_file_name() ) - mb_strlen( '.' . $this->get_extension() ) );
}
public function get_file_name() {
return $this->file_name;
}
public function set_file_name( $file_name ) {
$this->file_name = $file_name;
}
/**
* @return string
*/
public function get_file_path() {
return path_join( $this->dir, $this->get_file_name() );
}
public function get_file_url() {
$base_url = $this->base_url;
$file_name = $this->get_file_name();
return "$base_url$file_name";
}
/**
* @return int
*/
public function get_width() {
return $this->width;
}
/**
* @param int $width
*/
public function set_width( $width ) {
$this->width = $width;
}
/**
* @return int
*/
public function get_height() {
return $this->height;
}
/**
* @param int $height
*/
public function set_height( $height ) {
$this->height = $height;
}
/**
* @return string
*/
public function get_mime_type() {
return $this->mime_type;
}
/**
* @param string $mime_type
*/
public function set_mime_type( $mime_type ) {
$this->mime_type = $mime_type;
}
/**
* @return int
*/
public function get_filesize() {
return $this->filesize;
}
/**
* @param int $filesize
*/
public function set_filesize( $filesize ) {
$this->filesize = $filesize;
}
/**
* @return string
*/
public function get_key() {
return $this->key;
}
public function has_wp_metadata() {
return ! empty( $this->wp_metadata );
}
public function is_smushable() {
return $this->is_size_selected_in_settings() &&
$this->media_image_filter();
}
public function exceeds_size_limit() {
return $this->get_filesize() > $this->size_limit;
}
private function media_image_filter() {
return apply_filters( 'wp_smush_media_image', true, $this->get_key(), $this->get_file_path(), $this->get_attachment_id() );
}
public function file_exists() {
return $this->fs->file_exists( $this->get_file_path() );
}
private function is_size_selected_in_settings() {
if ( $this->get_key() === 'full' ) {
return $this->settings->get( 'original' );
}
$selected = $this->settings->get_setting( 'wp-smush-image_sizes' );
if ( empty( $selected ) || ! is_array( $selected ) ) {
return true;
}
return in_array( $this->get_key(), $selected );
}
/**
* @return int
*/
public function get_size_limit() {
return $this->size_limit;
}
/**
* @param int $size_limit
*/
public function set_size_limit( $size_limit ) {
$this->size_limit = $size_limit;
}
public function get_dir() {
return $this->dir;
}
public function get_extension() {
if ( is_null( $this->extension ) ) {
$this->extension = $this->prepare_extension();
}
return $this->extension;
}
public function prepare_extension() {
return pathinfo( $this->get_file_path(), PATHINFO_EXTENSION );
}
/**
* @return int
*/
public function get_attachment_id() {
return $this->attachment_id;
}
}

View File

@@ -0,0 +1,182 @@
<?php
namespace Smush\Core\Media;
class Media_Item_Stats {
/**
* @var int
*/
private $size_before = 0;
/**
* @var int
*/
private $size_after = 0;
/**
* @var float
*/
private $time = 0.0;
/**
* @return float
*/
public function get_percent() {
return $this->calculate_percentage(
$this->get_size_before(),
$this->get_size_after()
);
}
public function get_human_bytes() {
$bytes = $this->get_bytes();
return size_format(
$bytes,
$bytes >= 1024 ? 1 : 0
);
}
/**
* @return int
*/
public function get_bytes() {
$size_before = $this->get_size_before();
$size_after = $this->get_size_after();
return $size_before > $size_after
? $size_before - $size_after
: 0;
}
/**
* @return int
*/
public function get_size_before() {
return $this->size_before;
}
/**
* @param int $size_before
*/
public function set_size_before( $size_before ) {
$this->size_before = (int) $size_before;
}
/**
* @return int
*/
public function get_size_after() {
return $this->size_after;
}
/**
* @param int $size_after
*/
public function set_size_after( $size_after ) {
$this->size_after = (int) $size_after;
}
/**
* @return float
*/
public function get_time() {
return $this->time;
}
/**
* @param float $time
*/
public function set_time( $time ) {
$this->time = (float) $time;
}
public function from_array( $array ) {
$this->set_time( (float) $this->get_array_value( $array, 'time' ) );
$this->set_size_before( (int) $this->get_array_value( $array, 'size_before' ) );
$this->set_size_after( (int) $this->get_array_value( $array, 'size_after' ) );
}
public function is_empty() {
return empty( $this->get_size_before() ) && empty( $this->get_size_after() );
}
public function to_array() {
return array(
'time' => $this->get_time(),
'bytes' => $this->get_bytes(),
'percent' => $this->get_percent(),
'size_before' => $this->get_size_before(),
'size_after' => $this->get_size_after(),
);
}
protected function get_array_value( $array, $key ) {
return isset( $array[ $key ] ) ? $array[ $key ] : null;
}
/**
* Add values from the passed stats object to the current object
*
* @param $addend Media_Item_Stats
*
* @return void
*/
public function add( $addend ) {
$new_size_before = $this->get_size_before() + $addend->get_size_before();
$new_size_after = $this->get_size_after() + $addend->get_size_after();
$new_time = $this->get_time() + $addend->get_time();
// Update with new values
$this->set_time( $new_time );
$this->set_size_before( $new_size_before );
$this->set_size_after( $new_size_after );
}
/**
* @param $subtrahend Media_Item_Stats
*
* @return void
*/
public function subtract( $subtrahend ) {
$new_size_before = $this->get_size_before() - $subtrahend->get_size_before();
$new_size_after = $this->get_size_after() - $subtrahend->get_size_after();
$new_time = $this->get_time() - $subtrahend->get_time();
// Update with new values
$this->set_time( max( $new_time, 0 ) );
$this->set_size_before( max( $new_size_before, 0 ) );
$this->set_size_after( max( $new_size_after, 0 ) );
}
/**
* @param $to_check Media_Item_Stats
*
* @return boolean
*/
public function equals( $to_check ) {
return $this->get_size_before() === $to_check->get_size_before()
&& $this->get_size_after() === $to_check->get_size_after()
&& $this->get_time() === $to_check->get_time();
}
private function calculate_percentage( $size_before, $size_after ) {
$savings = $size_before - $size_after;
if ( $savings > 0 && $size_before > 0 ) {
$percentage = ( $savings / $size_before ) * 100;
return $percentage > 0
? round( $percentage, 2 )
: $percentage;
}
return 0;
}
/**
* @param $to_copy Media_Item_Stats
*
* @return void
*/
public function copy( $to_copy ) {
$this->from_array( $to_copy->to_array() );
}
}

File diff suppressed because it is too large Load Diff