rebase from live enviornment
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Class for deprecated methods from Imagify_Abstract_DB.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
class Imagify_Abstract_DB_Deprecated {
|
||||
|
||||
/**
|
||||
* Check if the given table exists.
|
||||
*
|
||||
* @since 1.5 In Imagify_Abstract_DB.
|
||||
* @since 1.7 Deprecated.
|
||||
* @access public
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $table The table name.
|
||||
* @return bool True if the table name exists.
|
||||
*/
|
||||
public function table_exists( $table ) {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.7.0', 'Imagify_DB::table_exists( $table )' );
|
||||
|
||||
return Imagify_DB::table_exists( $table );
|
||||
}
|
||||
|
||||
/**
|
||||
* Main Instance.
|
||||
* Ensures only one instance of class is loaded or can be loaded.
|
||||
* Well, actually it ensures nothing since it's not a full singleton pattern.
|
||||
*
|
||||
* @since 1.5 In Imagify_NGG_DB.
|
||||
* @since 1.7 Deprecated.
|
||||
* @access public
|
||||
* @author Jonathan Buttigieg
|
||||
* @deprecated
|
||||
*
|
||||
* @return object Main instance.
|
||||
*/
|
||||
public static function instance() {
|
||||
_deprecated_function( 'Imagify_Abstract_DB::instance()', '1.6.5', 'Imagify_Abstract_DB::get_instance()' );
|
||||
|
||||
return self::get_instance();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,509 @@
|
||||
<?php
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Class for deprecated methods from Imagify_Admin_Ajax_Post.
|
||||
*
|
||||
* @since 1.8.4
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
class Imagify_Admin_Ajax_Post_Deprecated {
|
||||
|
||||
/**
|
||||
* Optimize image on picture uploading with async request.
|
||||
*
|
||||
* @since 1.6.11
|
||||
* @since 1.8.4 Deprecated
|
||||
* @access public
|
||||
* @author Julio Potier
|
||||
* @see _imagify_optimize_attachment()
|
||||
* @deprecated
|
||||
*/
|
||||
public function imagify_async_optimize_upload_new_media_callback() {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.8.4', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_auto_optimize_callback()' );
|
||||
|
||||
if ( empty( $_POST['_ajax_nonce'] ) || empty( $_POST['attachment_id'] ) || empty( $_POST['metadata'] ) || empty( $_POST['context'] ) ) { // WPCS: CSRF ok.
|
||||
return;
|
||||
}
|
||||
|
||||
$context = imagify_sanitize_context( $_POST['context'] );
|
||||
$attachment_id = absint( $_POST['attachment_id'] );
|
||||
|
||||
imagify_check_nonce( 'new_media-' . $attachment_id );
|
||||
imagify_check_user_capacity( 'auto-optimize' );
|
||||
|
||||
$attachment = get_imagify_attachment( $context, $attachment_id, 'imagify_async_optimize_upload_new_media' );
|
||||
|
||||
// Optimize it!!!!!
|
||||
$attachment->optimize( null, $_POST['metadata'] );
|
||||
die( 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimize image on picture editing (resize, crop...) with async request.
|
||||
*
|
||||
* @since 1.6.11
|
||||
* @since 1.8.4 Deprecated
|
||||
* @access public
|
||||
* @author Julio Potier
|
||||
* @deprecated
|
||||
*/
|
||||
public function imagify_async_optimize_save_image_editor_file_callback() {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.8.4', 'Imagify_Admin_Ajax_Post::get_instance()->imagify_auto_optimize_callback()' );
|
||||
|
||||
$attachment_id = ! empty( $_POST['postid'] ) ? absint( $_POST['postid'] ) : 0;
|
||||
|
||||
if ( ! $attachment_id || empty( $_POST['do'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
imagify_check_nonce( 'image_editor-' . $attachment_id );
|
||||
imagify_check_user_capacity( 'edit_post', $attachment_id );
|
||||
|
||||
$attachment = get_imagify_attachment( 'wp', $attachment_id, 'wp_ajax_imagify_async_optimize_save_image_editor_file' );
|
||||
|
||||
if ( ! $attachment->get_data() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$optimization_level = $attachment->get_optimization_level();
|
||||
$metadata = wp_get_attachment_metadata( $attachment_id );
|
||||
|
||||
// Remove old optimization data.
|
||||
$attachment->delete_imagify_data();
|
||||
|
||||
if ( 'restore' === $_POST['do'] ) {
|
||||
// Restore the backup file.
|
||||
$attachment->restore();
|
||||
|
||||
// Get old metadata to regenerate all thumbnails.
|
||||
$metadata = array( 'sizes' => array() );
|
||||
$backup_sizes = (array) get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true );
|
||||
|
||||
foreach ( $backup_sizes as $size_key => $size_data ) {
|
||||
$size_key = str_replace( '-origin', '' , $size_key );
|
||||
$metadata['sizes'][ $size_key ] = $size_data;
|
||||
}
|
||||
}
|
||||
|
||||
// Optimize it!!!!!
|
||||
$attachment->optimize( $optimization_level, $metadata );
|
||||
die( 1 );
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** CUSTOM FOLDERS CALLBACKS ================================================================ */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Optimize a file.
|
||||
*
|
||||
* @since 1.7
|
||||
* @since 1.9 Deprecated
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
public function imagify_bulk_optimize_file_callback() {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9', '$this->imagify_bulk_optimize_callback()' );
|
||||
|
||||
imagify_check_nonce( 'imagify-bulk-upload' );
|
||||
imagify_check_user_capacity( 'optimize-file' );
|
||||
|
||||
$file_id = filter_input( INPUT_POST, 'image', FILTER_VALIDATE_INT );
|
||||
$context = imagify_sanitize_context( filter_input( INPUT_POST, 'context', FILTER_SANITIZE_STRING ) );
|
||||
$context = ! $context || 'wp' === strtolower( $context ) ? 'File' : $context;
|
||||
|
||||
if ( ! $file_id ) {
|
||||
imagify_die( __( 'Invalid request', 'imagify' ) );
|
||||
}
|
||||
|
||||
$file = get_imagify_attachment( $context, $file_id, 'imagify_bulk_optimize_file' );
|
||||
|
||||
if ( ! $file->is_valid() ) {
|
||||
imagify_die( __( 'Invalid file ID', 'imagify' ) );
|
||||
}
|
||||
|
||||
// Restore before re-optimizing.
|
||||
if ( false !== $file->get_optimization_level() ) {
|
||||
$file->restore();
|
||||
}
|
||||
|
||||
// Optimize it.
|
||||
$result = $file->optimize( $this->get_optimization_level() );
|
||||
|
||||
// Return the optimization statistics.
|
||||
if ( ! $file->is_optimized() ) {
|
||||
$data = array(
|
||||
'success' => false,
|
||||
'error_code' => '',
|
||||
'error' => (string) $file->get_optimized_error(),
|
||||
);
|
||||
|
||||
if ( ! $file->has_error() ) {
|
||||
$data['error_code'] = 'already-optimized';
|
||||
} else {
|
||||
$message = 'You\'ve consumed all your data. You have to upgrade your account to continue';
|
||||
|
||||
if ( $data['error'] === $message ) {
|
||||
$data['error_code'] = 'over-quota';
|
||||
}
|
||||
}
|
||||
|
||||
$data['error'] = imagify_translate_api_message( $data['error'] );
|
||||
|
||||
imagify_die( $data );
|
||||
}
|
||||
|
||||
$data = $file->get_size_data();
|
||||
|
||||
wp_send_json_success( array(
|
||||
'success' => true,
|
||||
'original_size_human' => imagify_size_format( $data['original_size'], 2 ),
|
||||
'new_size_human' => imagify_size_format( $data['optimized_size'], 2 ),
|
||||
'overall_saving' => $data['original_size'] - $data['optimized_size'],
|
||||
'overall_saving_human' => imagify_size_format( $data['original_size'] - $data['optimized_size'], 2 ),
|
||||
'original_overall_size' => $data['original_size'],
|
||||
'original_overall_size_human' => imagify_size_format( $data['original_size'], 2 ),
|
||||
'new_overall_size' => $data['optimized_size'],
|
||||
'percent_human' => $data['percent'] . '%',
|
||||
'thumbnails' => $file->get_optimized_sizes_count(),
|
||||
) );
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** AUTOMATIC OPTIMIZATION ================================================================== */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Auto-optimize files.
|
||||
*
|
||||
* @since 1.8.4
|
||||
* @since 1.9 Deprecated
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
* @see Imagify_Auto_Optimization->do_auto_optimization()
|
||||
* @deprecated
|
||||
*/
|
||||
public function imagify_auto_optimize_callback() {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9' );
|
||||
|
||||
if ( empty( $_POST['_ajax_nonce'] ) || empty( $_POST['attachment_id'] ) || empty( $_POST['context'] ) ) { // WPCS: CSRF ok.
|
||||
imagify_die( __( 'Invalid request', 'imagify' ) );
|
||||
}
|
||||
|
||||
$media_id = $this->get_media_id( 'POST' );
|
||||
|
||||
imagify_check_nonce( 'imagify_auto_optimize-' . $media_id );
|
||||
|
||||
if ( ! get_transient( 'imagify-auto-optimize-' . $media_id ) ) {
|
||||
imagify_die();
|
||||
}
|
||||
|
||||
delete_transient( 'imagify-auto-optimize-' . $media_id );
|
||||
|
||||
$context = $this->get_context( 'POST' );
|
||||
$process = imagify_get_optimization_process( $media_id, $context );
|
||||
|
||||
if ( ! $process->is_valid() ) {
|
||||
imagify_die( __( 'This media is not valid.', 'imagify' ) );
|
||||
}
|
||||
|
||||
if ( ! $process->get_media()->is_supported() ) {
|
||||
imagify_die( __( 'This type of file is not supported.', 'imagify' ) );
|
||||
}
|
||||
|
||||
$this->check_can_optimize();
|
||||
|
||||
/**
|
||||
* Let's start.
|
||||
*/
|
||||
$is_new_upload = ! empty( $_POST['is_new_upload'] );
|
||||
|
||||
/**
|
||||
* Triggered before a media is auto-optimized.
|
||||
*
|
||||
* @since 1.8.4
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $media_id The media ID.
|
||||
* @param bool $is_new_upload True if it's a new upload. False otherwize.
|
||||
*/
|
||||
do_action( 'imagify_before_auto_optimization', $media_id, $is_new_upload );
|
||||
|
||||
if ( $is_new_upload ) {
|
||||
/**
|
||||
* It's a new upload.
|
||||
*/
|
||||
// Optimize.
|
||||
$process->optimize();
|
||||
} else {
|
||||
/**
|
||||
* The media has already been optimized (or at least it has been tried).
|
||||
*/
|
||||
$data = $process->get_data();
|
||||
|
||||
// Get the optimization level before deleting the optimization data.
|
||||
$optimization_level = $data->get_optimization_level();
|
||||
|
||||
// Remove old optimization data.
|
||||
$data->delete_imagify_data();
|
||||
|
||||
// Some specifics for the image editor.
|
||||
if ( ! empty( $_POST['data']['do'] ) && 'restore' === $_POST['data']['do'] ) {
|
||||
// Restore the backup file.
|
||||
$process->restore();
|
||||
}
|
||||
|
||||
// Optimize.
|
||||
$process->optimize( $optimization_level );
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered after a media is auto-optimized.
|
||||
*
|
||||
* @since 1.8.4
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $media_id The media ID.
|
||||
* @param bool $is_new_upload True if it's a new upload. False otherwize.
|
||||
*/
|
||||
do_action( 'imagify_after_auto_optimization', $media_id, $is_new_upload );
|
||||
die( 1 );
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** VARIOUS FOR OPTIMIZATION ================================================================ */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Get all unoptimized attachment ids.
|
||||
*
|
||||
* @since 1.6.11
|
||||
* @since 1.9 Deprecated
|
||||
* @access public
|
||||
* @author Jonathan Buttigieg
|
||||
* @deprecated
|
||||
*/
|
||||
public function imagify_get_unoptimized_attachment_ids_callback() {
|
||||
global $wpdb;
|
||||
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9', '$this->imagify_get_media_ids_callback()' );
|
||||
|
||||
imagify_check_nonce( 'imagify-bulk-upload' );
|
||||
imagify_check_user_capacity( 'bulk-optimize' );
|
||||
$this->check_can_optimize();
|
||||
|
||||
@set_time_limit( 0 );
|
||||
|
||||
// Get (ordered) IDs.
|
||||
$optimization_level = $this->get_optimization_level();
|
||||
|
||||
$mime_types = Imagify_DB::get_mime_types();
|
||||
$statuses = Imagify_DB::get_post_statuses();
|
||||
$nodata_join = Imagify_DB::get_required_wp_metadata_join_clause();
|
||||
$nodata_where = Imagify_DB::get_required_wp_metadata_where_clause( array(
|
||||
'prepared' => true,
|
||||
) );
|
||||
$ids = $wpdb->get_col( $wpdb->prepare( // WPCS: unprepared SQL ok.
|
||||
"
|
||||
SELECT p.ID
|
||||
FROM $wpdb->posts AS p
|
||||
$nodata_join
|
||||
LEFT JOIN $wpdb->postmeta AS mt1
|
||||
ON ( p.ID = mt1.post_id AND mt1.meta_key = '_imagify_status' )
|
||||
LEFT JOIN $wpdb->postmeta AS mt2
|
||||
ON ( p.ID = mt2.post_id AND mt2.meta_key = '_imagify_optimization_level' )
|
||||
WHERE
|
||||
p.post_mime_type IN ( $mime_types )
|
||||
AND (
|
||||
mt1.meta_value = 'error'
|
||||
OR
|
||||
mt2.meta_value != %d
|
||||
OR
|
||||
mt2.post_id IS NULL
|
||||
)
|
||||
AND p.post_type = 'attachment'
|
||||
AND p.post_status IN ( $statuses )
|
||||
$nodata_where
|
||||
GROUP BY p.ID
|
||||
ORDER BY
|
||||
CASE mt1.meta_value
|
||||
WHEN 'already_optimized' THEN 2
|
||||
ELSE 1
|
||||
END ASC,
|
||||
p.ID DESC
|
||||
LIMIT 0, %d",
|
||||
$optimization_level,
|
||||
imagify_get_unoptimized_attachment_limit()
|
||||
) );
|
||||
|
||||
$wpdb->flush();
|
||||
unset( $mime_types );
|
||||
$ids = array_filter( array_map( 'absint', $ids ) );
|
||||
|
||||
if ( ! $ids ) {
|
||||
wp_send_json_success( array() );
|
||||
}
|
||||
|
||||
$results = Imagify_DB::get_metas( array(
|
||||
// Get attachments filename.
|
||||
'filenames' => '_wp_attached_file',
|
||||
// Get attachments data.
|
||||
'data' => '_imagify_data',
|
||||
// Get attachments optimization level.
|
||||
'optimization_levels' => '_imagify_optimization_level',
|
||||
// Get attachments status.
|
||||
'statuses' => '_imagify_status',
|
||||
), $ids );
|
||||
|
||||
// First run.
|
||||
foreach ( $ids as $i => $id ) {
|
||||
$attachment_status = isset( $results['statuses'][ $id ] ) ? $results['statuses'][ $id ] : false;
|
||||
$attachment_optimization_level = isset( $results['optimization_levels'][ $id ] ) ? $results['optimization_levels'][ $id ] : false;
|
||||
$attachment_error = '';
|
||||
|
||||
if ( isset( $results['data'][ $id ]['sizes']['full']['error'] ) ) {
|
||||
$attachment_error = $results['data'][ $id ]['sizes']['full']['error'];
|
||||
}
|
||||
|
||||
// Don't try to re-optimize if the optimization level is still the same.
|
||||
if ( $optimization_level === $attachment_optimization_level && is_string( $attachment_error ) ) {
|
||||
unset( $ids[ $i ] );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't try to re-optimize images already compressed.
|
||||
if ( 'already_optimized' === $attachment_status && $attachment_optimization_level >= $optimization_level ) {
|
||||
unset( $ids[ $i ] );
|
||||
continue;
|
||||
}
|
||||
|
||||
$attachment_error = trim( $attachment_error );
|
||||
|
||||
// Don't try to re-optimize images with an empty error message.
|
||||
if ( 'error' === $attachment_status && empty( $attachment_error ) ) {
|
||||
unset( $ids[ $i ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $ids ) {
|
||||
wp_send_json_success( array() );
|
||||
}
|
||||
|
||||
$ids = array_values( $ids );
|
||||
|
||||
/**
|
||||
* Triggered before testing for file existence.
|
||||
*
|
||||
* @since 1.6.7
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $ids An array of attachment IDs.
|
||||
* @param array $results An array of the data fetched from the database.
|
||||
* @param int $optimization_level The optimization level that will be used for the optimization.
|
||||
*/
|
||||
do_action( 'imagify_bulk_optimize_before_file_existence_tests', $ids, $results, $optimization_level );
|
||||
|
||||
$data = array();
|
||||
|
||||
foreach ( $ids as $i => $id ) {
|
||||
if ( empty( $results['filenames'][ $id ] ) ) {
|
||||
// Problem.
|
||||
continue;
|
||||
}
|
||||
|
||||
$file_path = get_imagify_attached_file( $results['filenames'][ $id ] );
|
||||
|
||||
/** This filter is documented in inc/deprecated/deprecated.php. */
|
||||
$file_path = apply_filters( 'imagify_file_path', $file_path );
|
||||
|
||||
if ( ! $file_path || ! $this->filesystem->exists( $file_path ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attachment_backup_path = get_imagify_attachment_backup_path( $file_path );
|
||||
$attachment_status = isset( $results['statuses'][ $id ] ) ? $results['statuses'][ $id ] : false;
|
||||
$attachment_optimization_level = isset( $results['optimization_levels'][ $id ] ) ? $results['optimization_levels'][ $id ] : false;
|
||||
|
||||
// Don't try to re-optimize if there is no backup file.
|
||||
if ( 'success' === $attachment_status && $optimization_level !== $attachment_optimization_level && ! $this->filesystem->exists( $attachment_backup_path ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data[ '_' . $id ] = get_imagify_attachment_url( $results['filenames'][ $id ] );
|
||||
} // End foreach().
|
||||
|
||||
if ( ! $data ) {
|
||||
wp_send_json_success( array() );
|
||||
}
|
||||
|
||||
wp_send_json_success( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all unoptimized file ids.
|
||||
*
|
||||
* @since 1.7
|
||||
* @since 1.9 Deprecated
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
public function imagify_get_unoptimized_file_ids_callback() {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9', '$this->imagify_get_media_ids_callback()' );
|
||||
|
||||
imagify_check_nonce( 'imagify-bulk-upload' );
|
||||
imagify_check_user_capacity( 'optimize-file' );
|
||||
|
||||
$this->check_can_optimize();
|
||||
|
||||
@set_time_limit( 0 );
|
||||
|
||||
$optimization_level = $this->get_optimization_level();
|
||||
|
||||
/**
|
||||
* Get the folders from DB.
|
||||
*/
|
||||
$folders = Imagify_Custom_Folders::get_folders( array(
|
||||
'active' => true,
|
||||
) );
|
||||
|
||||
if ( ! $folders ) {
|
||||
wp_send_json_success( array() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered before getting file IDs.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $folders An array of folders data.
|
||||
* @param int $optimization_level The optimization level that will be used for the optimization.
|
||||
*/
|
||||
do_action( 'imagify_bulk_optimize_files_before_get_files', $folders, $optimization_level );
|
||||
|
||||
/**
|
||||
* Get the files from DB, and from the folders.
|
||||
*/
|
||||
$files = Imagify_Custom_Folders::get_files_from_folders( $folders, array(
|
||||
'optimization_level' => $optimization_level,
|
||||
) );
|
||||
|
||||
if ( ! $files ) {
|
||||
wp_send_json_success( array() );
|
||||
}
|
||||
|
||||
// We need to output file URLs.
|
||||
foreach ( $files as $k => $file ) {
|
||||
$files[ $k ] = Imagify_Files_Scan::remove_placeholder( $file['path'], 'url' );
|
||||
}
|
||||
|
||||
wp_send_json_success( $files );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,990 @@
|
||||
<?php
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Imagify WP Offload S3 attachment class.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @since 1.9 Deprecated
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
class Imagify_AS3CF_Attachment extends Imagify_Attachment {
|
||||
|
||||
/**
|
||||
* Class version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '1.1.2';
|
||||
|
||||
/**
|
||||
* Tell if AS3CF settings will be used for this attachment.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $use_s3_settings;
|
||||
|
||||
/**
|
||||
* Tell if the files should be deleted once sent to S3.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $delete_files;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Jonathan Buttigieg
|
||||
*
|
||||
* @param int|object $id An image attachment ID or a NGG object.
|
||||
*/
|
||||
public function __construct( $id ) {
|
||||
imagify_deprecated_class( get_class( $this ), '1.9' );
|
||||
|
||||
parent::__construct( $id );
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** ATTACHMENT PATHS AND URLS =============================================================== */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Get the original attachment path.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string|bool Path to the file if it exists or has been successfully retrieved from S3. False on failure.
|
||||
*/
|
||||
public function get_original_path() {
|
||||
return $this->get_thumbnail_path();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a thumbnail path.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param string $size_file The basename of the file. If not provided, the path to the main file is returned.
|
||||
* @return string|bool Path to the file if it exists or has been successfully retrieved from S3. False on failure.
|
||||
*/
|
||||
public function get_thumbnail_path( $size_file = false ) {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$file_path = get_attached_file( $this->id, true );
|
||||
|
||||
if ( $size_file ) {
|
||||
// It's not the full size.
|
||||
$file_path = $this->filesystem->dir_path( $file_path ) . $size_file;
|
||||
}
|
||||
|
||||
return $file_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the original attachment URL.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string|bool The main file URL. False on failure.
|
||||
*/
|
||||
public function get_original_url() {
|
||||
return $this->get_thumbnail_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a thumbnail URL.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param string $size_file The basename of the file. If not provided, the main file's URL is returned.
|
||||
* @return string|bool The file URL. False on failure.
|
||||
*/
|
||||
public function get_thumbnail_url( $size_file = false ) {
|
||||
if ( ! $this->is_extension_supported() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$file_url = wp_get_attachment_url( $this->id );
|
||||
|
||||
if ( $size_file ) {
|
||||
// It's not the full size.
|
||||
$file_url = $this->filesystem->dir_path( $file_url ) . $size_file;
|
||||
}
|
||||
|
||||
return $file_url;
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** THE PUBLIC STUFF ======================================================================== */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Optimize all sizes with Imagify.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $optimization_level The optimization level (2 = ultra, 1 = aggressive, 0 = normal).
|
||||
* @param array $metadata The attachment meta data, containing the sizes. Provide only for a new attachment.
|
||||
* @return array|bool The optimization data. False on failure.
|
||||
*/
|
||||
public function optimize( $optimization_level = null, $metadata = array() ) {
|
||||
$metadata_changed = false;
|
||||
|
||||
/**
|
||||
* Make some sanity tests first.
|
||||
*/
|
||||
|
||||
// Check if the attachment extension is allowed.
|
||||
if ( ! $this->is_extension_supported() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// To avoid issue with "original_size" at 0 in "_imagify_data".
|
||||
if ( 0 === (int) $this->get_stats_data( 'original_size' ) ) {
|
||||
$this->delete_imagify_data();
|
||||
}
|
||||
|
||||
$optimization_level = isset( $optimization_level ) ? (int) $optimization_level : get_imagify_option( 'optimization_level' );
|
||||
|
||||
// Check if the full size is already optimized with this level.
|
||||
if ( $this->is_optimized() && $this->get_optimization_level() === $optimization_level ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get file path of the full size.
|
||||
$attachment_path = $this->get_original_path();
|
||||
$attachment_url = $this->get_original_url();
|
||||
|
||||
if ( ! $attachment_path ) {
|
||||
// We're in deep sh**.
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->filesystem->exists( $attachment_path ) && ! $this->get_file_from_s3( $attachment_path ) ) {
|
||||
// The file doesn't exist and couldn't be retrieved from S3.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the process.
|
||||
*/
|
||||
$this->set_running_status();
|
||||
|
||||
/** This hook is documented in /inc/classes/class-imagify-attachment.php. */
|
||||
do_action( 'before_imagify_optimize_attachment', $this->id );
|
||||
|
||||
$metadata = $this->set_deletion_status( $metadata );
|
||||
|
||||
// Store the paths of the files that may be deleted once optimized and sent to S3.
|
||||
$to_delete = array();
|
||||
$filesize_total = 0;
|
||||
|
||||
// Maybe resize (and backup) the image.
|
||||
$resized = $this->is_image() && $this->maybe_resize( $attachment_path );
|
||||
|
||||
if ( $resized ) {
|
||||
$size = $this->filesystem->get_image_size( $attachment_path );
|
||||
|
||||
if ( $size ) {
|
||||
$metadata['width'] = $size['width'];
|
||||
$metadata['height'] = $size['height'];
|
||||
$metadata_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Optimize the full size.
|
||||
$response = do_imagify( $attachment_path, array(
|
||||
'optimization_level' => $optimization_level,
|
||||
'context' => 'wp',
|
||||
'resized' => $resized,
|
||||
'original_size' => $this->get_original_size( false ),
|
||||
) );
|
||||
|
||||
$data = $this->fill_data( null, $response );
|
||||
|
||||
if ( $this->delete_files ) {
|
||||
$to_delete[] = $attachment_path;
|
||||
// This is used by AS3CF.
|
||||
$bytes = $this->filesystem->size( $attachment_path );
|
||||
|
||||
if ( false !== $bytes ) {
|
||||
$metadata_changed = true;
|
||||
$filesize_total += $bytes;
|
||||
$metadata['filesize'] = $bytes;
|
||||
} else {
|
||||
$metadata['filesize'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** This filter is documented in /inc/classes/class-imagify-attachment.php. */
|
||||
$data = apply_filters( 'imagify_fill_full_size_data', $data, $response, $this->id, $attachment_path, $attachment_url, 'full', $optimization_level, $metadata );
|
||||
|
||||
// Save the optimization level.
|
||||
update_post_meta( $this->id, '_imagify_optimization_level', $optimization_level );
|
||||
|
||||
if ( ! $data ) {
|
||||
// The optimization failed.
|
||||
$metadata = $metadata_changed ? $metadata : false;
|
||||
$this->cleanup( $metadata, $to_delete );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Optimize all thumbnails.
|
||||
if ( ! empty( $metadata['sizes'] ) ) {
|
||||
$disallowed_sizes = get_imagify_option( 'disallowed-sizes' );
|
||||
$is_active_for_network = imagify_is_active_for_network();
|
||||
|
||||
foreach ( $metadata['sizes'] as $size_key => $size_data ) {
|
||||
$thumbnail_path = $this->get_thumbnail_path( $size_data['file'] );
|
||||
$thumbnail_url = $this->get_thumbnail_url( $size_data['file'] );
|
||||
|
||||
if ( $this->delete_files ) {
|
||||
$to_delete[] = $thumbnail_path;
|
||||
|
||||
// Even if this size must not be optimized ($disallowed_sizes), we must fetch the file from S3 to get its size, and not to trigger a `WP_Error` in `upload_attachment_to_s3()`.
|
||||
if ( ! $this->filesystem->exists( $thumbnail_path ) && ! $this->get_file_from_s3( $thumbnail_path ) ) {
|
||||
// Doesn't exist and couldn't be retrieved from S3.
|
||||
$data['sizes'][ $size_key ] = array(
|
||||
'success' => false,
|
||||
'error' => __( 'This size could not be retrieved from Amazon S3.', 'imagify' ),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// This is used by AS3CF.
|
||||
$bytes = $this->filesystem->size( $thumbnail_path );
|
||||
|
||||
if ( false !== $bytes ) {
|
||||
$filesize_total += $bytes;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this size has to be optimized.
|
||||
if ( ! $is_active_for_network && isset( $disallowed_sizes[ $size_key ] ) && $this->is_image() ) {
|
||||
$data['sizes'][ $size_key ] = array(
|
||||
'success' => false,
|
||||
'error' => __( 'This size is not authorized to be optimized. Update your Imagify settings if you want to optimize it.', 'imagify' ),
|
||||
);
|
||||
|
||||
/** This filter is documented in /inc/classes/class-imagify-attachment.php. */
|
||||
$data = apply_filters( 'imagify_fill_unauthorized_thumbnail_data', $data, $this->id, $thumbnail_path, $thumbnail_url, $size_key, $optimization_level, $metadata );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! $this->delete_files && ! $this->filesystem->exists( $thumbnail_path ) && ! $this->get_file_from_s3( $thumbnail_path ) ) {
|
||||
// Doesn't exist and couldn't be retrieved from S3.
|
||||
$data['sizes'][ $size_key ] = array(
|
||||
'success' => false,
|
||||
'error' => __( 'This size could not be retrieved from Amazon S3.', 'imagify' ),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! $this->is_image() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Optimize the thumbnail size.
|
||||
$response = do_imagify( $thumbnail_path, array(
|
||||
'backup' => false,
|
||||
'optimization_level' => $optimization_level,
|
||||
'context' => 'wp',
|
||||
) );
|
||||
|
||||
$data = $this->fill_data( $data, $response, $size_key );
|
||||
|
||||
/** This filter is documented in /inc/classes/class-imagify-attachment.php. */
|
||||
$data = apply_filters( 'imagify_fill_thumbnail_data', $data, $response, $this->id, $thumbnail_path, $thumbnail_url, $size_key, $optimization_level, $metadata );
|
||||
} // End foreach().
|
||||
} // End if().
|
||||
|
||||
$data['stats']['percent'] = round( ( ( $data['stats']['original_size'] - $data['stats']['optimized_size'] ) / $data['stats']['original_size'] ) * 100, 2 );
|
||||
|
||||
update_post_meta( $this->id, '_imagify_data', $data );
|
||||
update_post_meta( $this->id, '_imagify_status', 'success' );
|
||||
|
||||
if ( $this->delete_files && $filesize_total ) {
|
||||
// Add the total file size for all image sizes. This is a meta used by AS3CF.
|
||||
update_post_meta( $this->id, 'wpos3_filesize_total', $filesize_total );
|
||||
}
|
||||
|
||||
$optimized_data = $this->get_data();
|
||||
|
||||
/** This hook is documented in /inc/classes/class-imagify-attachment.php. */
|
||||
do_action( 'after_imagify_optimize_attachment', $this->id, $optimized_data );
|
||||
|
||||
$sent = $this->maybe_send_attachment_to_s3( $metadata, $attachment_path );
|
||||
// Update metadata only if they changed.
|
||||
$metadata = $metadata_changed ? $metadata : false;
|
||||
// Delete files only if they have been uploaded to S3.
|
||||
$to_delete = $sent ? $to_delete : array();
|
||||
|
||||
$this->cleanup( $metadata, $to_delete );
|
||||
|
||||
return $optimized_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimize missing thumbnail sizes with Imagify.
|
||||
*
|
||||
* @since 1.6.10
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $optimization_level The optimization level (2=ultra, 1=aggressive, 0=normal).
|
||||
* @return array|object An array of thumbnail data, size by size. A WP_Error object on failure.
|
||||
*/
|
||||
public function optimize_missing_thumbnails( $optimization_level = null ) {
|
||||
// Check if the attachment extension is allowed.
|
||||
if ( ! $this->is_extension_supported() || ! $this->is_image() ) {
|
||||
return new WP_Error( 'mime_type_not_supported', __( 'This type of file is not supported.', 'imagify' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create missing thumbnails and optimize them.
|
||||
*/
|
||||
$result = parent::optimize_missing_thumbnails( $optimization_level );
|
||||
$result_sizes = array();
|
||||
|
||||
$this->set_running_status();
|
||||
|
||||
if ( is_array( $result ) ) {
|
||||
// All good.
|
||||
$result_sizes = $result;
|
||||
} elseif ( is_wp_error( $result ) ) {
|
||||
// Some thumbnails could not be created. Lets see if some were.
|
||||
$result_sizes = $result->get_error_data( 'image_resize_error' );
|
||||
$result_sizes = ! empty( $result_sizes['sizes_succeeded'] ) ? $result_sizes['sizes_succeeded'] : array();
|
||||
}
|
||||
|
||||
if ( ! $result_sizes ) {
|
||||
// No thumbnails created.
|
||||
$this->delete_running_status();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all images from S3 if they're not on the server.
|
||||
* S3 Offload needs ALL images (so it can update its metas), we can't just send some of them without entering Hell -_-'.
|
||||
*/
|
||||
$metadata = $this->set_deletion_status();
|
||||
|
||||
if ( ! $this->can_send_to_s3() ) {
|
||||
// The other thumbnails are not on S3, so we don't need to send the new ones.
|
||||
$this->delete_running_status();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main file.
|
||||
*/
|
||||
$attachment_path = $this->get_original_path();
|
||||
$to_delete = array();
|
||||
$to_skip = array();
|
||||
$filesize_total = 0;
|
||||
$metadata_changed = false;
|
||||
|
||||
if ( ! $attachment_path ) {
|
||||
// WAT?!
|
||||
if ( ! is_wp_error( $result ) ) {
|
||||
$result = new WP_Error( 'no_attachment_path', __( 'Files could not be sent to Amazon S3.', 'imagify' ), array(
|
||||
'sizes_succeeded' => $result_sizes,
|
||||
) );
|
||||
} else {
|
||||
$result->add( 'no_attachment_path', __( 'Files could not be sent to Amazon S3.', 'imagify' ) );
|
||||
}
|
||||
|
||||
$this->delete_running_status();
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ( ! $this->filesystem->exists( $attachment_path ) && ! $this->get_file_from_s3( $attachment_path ) ) {
|
||||
// The file doesn't exist and couldn't be retrieved from S3.
|
||||
if ( ! is_wp_error( $result ) ) {
|
||||
$result = new WP_Error( 'main_file_not_on_s3', __( 'The main image could not be retrieved from Amazon S3.', 'imagify' ), array(
|
||||
'sizes_succeeded' => $result_sizes,
|
||||
) );
|
||||
} else {
|
||||
$result->add( 'main_file_not_on_s3', __( 'The main image could not be retrieved from Amazon S3.', 'imagify' ) );
|
||||
}
|
||||
|
||||
$this->delete_running_status();
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Files that must not be retrieved from S3.
|
||||
foreach ( $result_sizes as $size_key => $size_data ) {
|
||||
$to_skip[] = $this->get_thumbnail_path( $size_data['file'] );
|
||||
}
|
||||
|
||||
// Store the paths of the files that may be deleted once sent to S3.
|
||||
if ( $this->delete_files ) {
|
||||
$to_delete[] = $attachment_path;
|
||||
$to_delete = array_merge( $to_delete, $to_skip );
|
||||
|
||||
// This is used by AS3CF.
|
||||
$bytes = $this->filesystem->size( $attachment_path );
|
||||
|
||||
if ( false !== $bytes ) {
|
||||
$metadata_changed = true;
|
||||
$filesize_total += $bytes;
|
||||
$metadata['filesize'] = $bytes;
|
||||
} elseif ( ! isset( $metadata['filesize'] ) ) {
|
||||
$metadata_changed = true;
|
||||
$metadata['filesize'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The thumbnails.
|
||||
*/
|
||||
if ( ! empty( $metadata['sizes'] ) ) {
|
||||
$to_skip = array_flip( $to_skip );
|
||||
|
||||
foreach ( $metadata['sizes'] as $size_key => $size_data ) {
|
||||
$thumbnail_path = $this->get_thumbnail_path( $size_data['file'] );
|
||||
|
||||
if ( isset( $to_skip[ $thumbnail_path ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! $this->filesystem->exists( $thumbnail_path ) && ! $this->get_file_from_s3( $thumbnail_path ) ) {
|
||||
// The file doesn't exist and couldn't be retrieved from S3.
|
||||
if ( ! is_wp_error( $result ) ) {
|
||||
$result = new WP_Error( 'thumbnail_not_on_s3', __( 'This size could not be retrieved from Amazon S3.', 'imagify' ), array(
|
||||
'sizes_succeeded' => $result_sizes,
|
||||
'size' => $size_key,
|
||||
) );
|
||||
} else {
|
||||
$result->add( 'thumbnail_not_on_s3', __( 'This size could not be retrieved from Amazon S3.', 'imagify' ), array(
|
||||
'size' => $size_key,
|
||||
) );
|
||||
}
|
||||
|
||||
$this->delete_running_status();
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ( $this->delete_files ) {
|
||||
$to_delete[] = $thumbnail_path;
|
||||
|
||||
// This is used by AS3CF.
|
||||
$bytes = $this->filesystem->size( $thumbnail_path );
|
||||
|
||||
if ( false !== $bytes ) {
|
||||
$filesize_total += $bytes;
|
||||
}
|
||||
}
|
||||
} // End foreach().
|
||||
} // End if().
|
||||
|
||||
if ( $this->delete_files && $filesize_total ) {
|
||||
// Add the total file size for all image sizes. This is a meta used by AS3CF.
|
||||
update_post_meta( $this->id, 'wpos3_filesize_total', $filesize_total );
|
||||
}
|
||||
|
||||
$sent = $this->maybe_send_attachment_to_s3( $metadata, $attachment_path );
|
||||
// Update metadata only if they changed.
|
||||
$metadata = $metadata_changed ? $metadata : false;
|
||||
// Delete files only if they have been uploaded to S3.
|
||||
$to_delete = $sent ? $to_delete : array();
|
||||
|
||||
$this->cleanup( $metadata, $to_delete );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-optimize the given thumbnail sizes to the same level.
|
||||
* Not supported yet in this context.
|
||||
*
|
||||
* @since 1.7.1
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $sizes The sizes to optimize.
|
||||
* @return array|void A WP_Error object on failure.
|
||||
*/
|
||||
public function reoptimize_thumbnails( $sizes ) {}
|
||||
|
||||
/**
|
||||
* Process an attachment restoration from the backup file.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return array A list of files sent to S3.
|
||||
*/
|
||||
public function restore() {
|
||||
// Check if the attachment extension is allowed.
|
||||
if ( ! $this->is_extension_supported() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Stop the process if there is no backup file to restore.
|
||||
if ( ! $this->has_backup() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** This hook is documented in /inc/classes/class-imagify-attachment.php. */
|
||||
do_action( 'before_imagify_restore_attachment', $this->id );
|
||||
|
||||
$backup_path = $this->get_backup_path();
|
||||
$attachment_path = $this->get_original_path();
|
||||
|
||||
if ( ! $attachment_path ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the original image from the backup.
|
||||
$this->filesystem->copy( $backup_path, $attachment_path, true );
|
||||
$this->filesystem->chmod_file( $attachment_path );
|
||||
|
||||
if ( ! $this->filesystem->exists( $attachment_path ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->set_deletion_status();
|
||||
|
||||
// Remove old optimization data.
|
||||
$this->delete_imagify_data();
|
||||
|
||||
if ( ! $this->is_image() ) {
|
||||
// We need to delete the thumbnails for pdf, or new ones will be generated with new unique file names.
|
||||
$metadata = wp_get_attachment_metadata( $this->id );
|
||||
|
||||
if ( ! empty( $metadata['sizes'] ) && is_array( $metadata['sizes'] ) ) {
|
||||
foreach ( $metadata['sizes'] as $size_key => $size_data ) {
|
||||
$thumbnail_path = $this->get_thumbnail_path( $size_data['file'] );
|
||||
|
||||
if ( $this->filesystem->exists( $thumbnail_path ) ) {
|
||||
$this->filesystem->delete( $thumbnail_path );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
}
|
||||
|
||||
// Generate new thumbnails and new metadata.
|
||||
$metadata = wp_generate_attachment_metadata( $this->id, $attachment_path );
|
||||
|
||||
// Send to S3.
|
||||
$sent = $this->maybe_send_attachment_to_s3( $metadata, $attachment_path );
|
||||
// Files restored (and maybe to delete).
|
||||
$files = array();
|
||||
// If the files must be deleted, we need to store the file sizes.
|
||||
$filesize_total = 0;
|
||||
|
||||
if ( $sent ) {
|
||||
$files[] = $attachment_path;
|
||||
}
|
||||
|
||||
if ( $this->delete_files ) {
|
||||
// This is used by AS3CF.
|
||||
$bytes = $this->filesystem->size( $attachment_path );
|
||||
|
||||
if ( false !== $bytes ) {
|
||||
$filesize_total += $bytes;
|
||||
$metadata['filesize'] = $bytes;
|
||||
} else {
|
||||
$metadata['filesize'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $metadata['sizes'] ) && ( $sent || $this->delete_files ) ) {
|
||||
foreach ( $metadata['sizes'] as $size_key => $size_data ) {
|
||||
$thumbnail_path = $this->get_thumbnail_path( $size_data['file'] );
|
||||
|
||||
if ( $sent ) {
|
||||
$files[] = $thumbnail_path;
|
||||
}
|
||||
|
||||
if ( $this->delete_files ) {
|
||||
// This is used by AS3CF.
|
||||
$bytes = $this->filesystem->size( $thumbnail_path );
|
||||
|
||||
if ( false !== $bytes ) {
|
||||
$filesize_total += $bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->delete_files && $filesize_total ) {
|
||||
// Add the total file size for all image sizes. This is a meta used by AS3CF.
|
||||
update_post_meta( $this->id, 'wpos3_filesize_total', $filesize_total );
|
||||
}
|
||||
|
||||
/** This hook is documented in /inc/classes/class-imagify-attachment.php. */
|
||||
do_action( 'after_imagify_restore_attachment', $this->id );
|
||||
|
||||
$to_delete = $this->delete_files ? $files : array();
|
||||
|
||||
$this->cleanup( $metadata, $to_delete );
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** INTERNAL UTILITIES ====================================================================== */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Cleanup after optimization or a restore:
|
||||
* - Maybe update metadata.
|
||||
* - Maybe delete local files.
|
||||
* - Delete the "optimization status" transient.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $new_metadata New attachment metadata to be stored.
|
||||
* @param array $files_to_remove Files to delete.
|
||||
*/
|
||||
protected function cleanup( $new_metadata, $files_to_remove ) {
|
||||
if ( $new_metadata ) {
|
||||
/**
|
||||
* Filter the metadata stored after optimization or a restore.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $new_metadata New attachment metadata to be stored.
|
||||
* @param int $id The attachment ID.
|
||||
*/
|
||||
$new_metadata = apply_filters( 'imagify_as3cf_attachment_cleanup_metadata', $new_metadata, $this->id );
|
||||
/**
|
||||
* Update the attachment meta that contains the file sizes.
|
||||
* Here we don't use wp_update_attachment_metadata() to prevent triggering unwanted hooks.
|
||||
*/
|
||||
update_post_meta( $this->id, '_wp_attachment_metadata', $new_metadata );
|
||||
}
|
||||
|
||||
if ( $files_to_remove ) {
|
||||
$attachment_path = $this->get_original_path();
|
||||
/** This filter is documented in /amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php. */
|
||||
$files_to_remove = (array) apply_filters( 'as3cf_upload_attachment_local_files_to_remove', $files_to_remove, $this->id, $attachment_path );
|
||||
$files_to_remove = array_filter( $files_to_remove );
|
||||
|
||||
if ( $files_to_remove ) {
|
||||
$files_to_remove = array_unique( $files_to_remove );
|
||||
/**
|
||||
* Delete the local files.
|
||||
*/
|
||||
array_map( array( $this, 'maybe_delete_file' ), $files_to_remove );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the "optimization status" transient.
|
||||
*/
|
||||
$this->delete_running_status();
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe resize (and backup) an image.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param string $attachment_path The file path.
|
||||
* @return bool True on success. False on failure.
|
||||
*/
|
||||
protected function maybe_resize( $attachment_path ) {
|
||||
if ( ! $this->is_image() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$do_resize = get_imagify_option( 'resize_larger' );
|
||||
$resize_width = get_imagify_option( 'resize_larger_w' );
|
||||
$attachment_size = $this->filesystem->get_image_size( $attachment_path );
|
||||
|
||||
if ( ! $do_resize || ! $attachment_size || $resize_width >= $attachment_size['width'] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$resized_attachment_path = $this->resize( $attachment_path, $attachment_size, $resize_width );
|
||||
|
||||
if ( is_wp_error( $resized_attachment_path ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$backuped = imagify_backup_file( $attachment_path );
|
||||
|
||||
if ( is_wp_error( $backuped ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->filesystem->move( $resized_attachment_path, $attachment_path, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell if the files must be deleted after being optimized or restored.
|
||||
* It sets the 2 properties $this->use_s3_settings and $this->delete_files.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $metadata Attachment metadata. Provide, only if it comes from a 'wp_generate_attachment_metadata' or 'wp_update_attachment_metadata' hook.
|
||||
* @return array Attachment metadata. If not provided as argument, new values are fetched.
|
||||
*/
|
||||
protected function set_deletion_status( $metadata = false ) {
|
||||
global $as3cf;
|
||||
|
||||
if ( $metadata ) {
|
||||
/**
|
||||
* Metadata is provided: we were in a 'wp_generate_attachment_metadata' or 'wp_update_attachment_metadata' hook.
|
||||
* This means we'll follow AS3CF settings to know if the local files must be sent to S3 and/or deleted.
|
||||
*/
|
||||
$this->use_s3_settings = true;
|
||||
$this->delete_files = $as3cf && $as3cf->get_setting( 'remove-local-file' ) && $this->can_send_to_s3();
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata is not provided: we were not in a 'wp_generate_attachment_metadata' or 'wp_update_attachment_metadata' hook.
|
||||
* So, we fetch the current meta value.
|
||||
* This also means we won't follow AS3CF settings to know if the local files must be sent to S3 and/or deleted.
|
||||
* In that case we'll send the files to S3 if they already are there, and delete them if they is a 'filesize' entry in the metadata.
|
||||
*/
|
||||
$metadata = wp_get_attachment_metadata( $this->id, true );
|
||||
$this->use_s3_settings = false;
|
||||
$this->delete_files = isset( $metadata['filesize'] ) && $this->can_send_to_s3();
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** S3 UTILITIES ============================================================================ */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Tell if AS3CF is set up.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_s3_setup() {
|
||||
global $as3cf;
|
||||
static $is;
|
||||
|
||||
if ( ! isset( $is ) ) {
|
||||
$is = $as3cf && $as3cf->is_plugin_setup();
|
||||
}
|
||||
|
||||
return $is;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell if an attachment is stored on S3.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return array|bool The S3 info on success. False if the attachment is not on S3.
|
||||
*/
|
||||
public function get_s3_info() {
|
||||
global $as3cf;
|
||||
|
||||
if ( ! $as3cf ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( method_exists( $as3cf, 'get_attachment_s3_info' ) ) {
|
||||
return $as3cf->get_attachment_s3_info( $this->id );
|
||||
}
|
||||
|
||||
return $as3cf->get_attachment_provider_info( $this->id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file from S3.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param string $file_path The file path.
|
||||
* @return string|bool The file path on success, false on failure.
|
||||
*/
|
||||
protected function get_file_from_s3( $file_path ) {
|
||||
global $as3cf;
|
||||
|
||||
if ( ! $this->is_extension_supported() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->is_s3_setup() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$s3_object = $this->get_s3_info();
|
||||
|
||||
if ( ! $s3_object ) {
|
||||
// The attachment is not on S3.
|
||||
return false;
|
||||
}
|
||||
|
||||
$directory = $this->filesystem->dir_path( $s3_object['key'] );
|
||||
$directory = $this->filesystem->is_root( $directory ) ? '' : $directory;
|
||||
$s3_object['key'] = $directory . $this->filesystem->file_name( $file_path );
|
||||
|
||||
// Retrieve file from S3.
|
||||
if ( method_exists( $as3cf->plugin_compat, 'copy_s3_file_to_server' ) ) {
|
||||
$as3cf->plugin_compat->copy_s3_file_to_server( $s3_object, $file_path );
|
||||
} else {
|
||||
$as3cf->plugin_compat->copy_provider_file_to_server( $s3_object, $file_path );
|
||||
}
|
||||
|
||||
return $this->filesystem->exists( $file_path ) ? $file_path : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe send the attachment to S3.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $metadata The attachment metadata.
|
||||
* @param string $attachment_path The attachment path.
|
||||
* @param bool $remove_local_files True to let AS3CF delete the local files (if set in the settings). We usually don't want that, we do it by ourselves.
|
||||
* @return bool True on success. False otherwize.
|
||||
*/
|
||||
protected function maybe_send_attachment_to_s3( $metadata = null, $attachment_path = null, $remove_local_files = false ) {
|
||||
global $as3cf;
|
||||
|
||||
if ( ! $this->can_send_to_s3() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$s3_object = $this->get_s3_info();
|
||||
|
||||
if ( ! $s3_object ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$full_file_path = $this->get_original_path();
|
||||
|
||||
if ( ! $full_file_path ) {
|
||||
// This is bad.
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( method_exists( $as3cf, 'upload_attachment_to_s3' ) ) {
|
||||
$s3_data = $as3cf->upload_attachment_to_s3( $this->id, $metadata, $attachment_path, false, $remove_local_files );
|
||||
} else {
|
||||
$s3_data = $as3cf->upload_attachment( $this->id, $metadata, $attachment_path, false, $remove_local_files );
|
||||
}
|
||||
|
||||
return ! is_wp_error( $s3_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell if an attachment can be sent to S3.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function can_send_to_s3() {
|
||||
global $as3cf;
|
||||
static $can = array();
|
||||
static $copy_to_s3;
|
||||
|
||||
if ( isset( $can[ $this->id ] ) ) {
|
||||
return $can[ $this->id ];
|
||||
}
|
||||
|
||||
if ( ! isset( $copy_to_s3 ) ) {
|
||||
$copy_to_s3 = $as3cf && $as3cf->get_setting( 'copy-to-s3' );
|
||||
}
|
||||
|
||||
$is_s3_setup = $this->is_s3_setup();
|
||||
$s3_object = $this->get_s3_info();
|
||||
// S3 is set up and the attachment is on S3.
|
||||
$can[ $this->id ] = $is_s3_setup && $s3_object;
|
||||
|
||||
if ( $can[ $this->id ] && ! empty( $this->use_s3_settings ) ) {
|
||||
// Use AS3CF setting to tell if we're allowed to send the files.
|
||||
$can[ $this->id ] = $copy_to_s3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the result of Imagify_AS3CF_Attachment::can_send_to_s3().
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param bool $can True if the attachment can be sent. False otherwize.
|
||||
* @param int $id The attachment ID.
|
||||
* @param array $s3_object The S3 infos.
|
||||
* @param bool $is_s3_setup AS3CF is set up or not.
|
||||
* @param bool $copy_to_s3 AS3CF setting that tells if a "new" attachment can be sent.
|
||||
* @param bool $use_s3_settings Tell if we must use AS3CF setting in this case.
|
||||
*/
|
||||
$can[ $this->id ] = (bool) apply_filters( 'imagify_can_send_to_s3', $can[ $this->id ], $this->id, $s3_object, $is_s3_setup, $copy_to_s3, $this->use_s3_settings );
|
||||
|
||||
return $can[ $this->id ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe delete the local file.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param string $file_path The file path.
|
||||
* @return bool True if deleted or doesn't exist. False on failure or if the file is not supposed to be deleted.
|
||||
*/
|
||||
protected function maybe_delete_file( $file_path ) {
|
||||
if ( ! $this->file_should_be_deleted( $file_path ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->filesystem->exists( $file_path ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->filesystem->delete( $file_path, false, 'f' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell if a file should be deleted.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param string $file_path The file path.
|
||||
* @return bool True to delete, false to keep.
|
||||
*/
|
||||
protected function file_should_be_deleted( $file_path ) {
|
||||
if ( ! $file_path || ! $this->delete_files ) {
|
||||
// We keep the file.
|
||||
return false;
|
||||
}
|
||||
|
||||
/** This hook is documented in /amazon-s3-and-cloudfront/classes/amazon-s3-and-cloudfront.php. */
|
||||
$preserve = apply_filters( 'as3cf_preserve_file_from_local_removal', false, $file_path );
|
||||
|
||||
return false === $preserve;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Class for deprecated methods from Imagify_AS3CF.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
class Imagify_AS3CF_Deprecated {
|
||||
|
||||
/**
|
||||
* Class version.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.0
|
||||
* @since 1.9 Deprecated
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
const VERSION = '1.2';
|
||||
|
||||
/**
|
||||
* Context used with get_imagify_attachment().
|
||||
* It matches the class name Imagify_AS3CF_Attachment.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.6.6
|
||||
* @since 1.9 Deprecated
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
const CONTEXT = 'AS3CF';
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** VARIOUS HOOKS =========================================================================== */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Filter the context used for the optimization (and other stuff).
|
||||
* That way, we'll use the class Imagify_AS3CF_Attachment everywhere (instead of Imagify_Attachment), and make all the manual optimizations fine.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @since 1.9 Deprecated
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $context The context to determine the class name.
|
||||
* @param int $attachment_id The attachment ID.
|
||||
* @return string The new context.
|
||||
*/
|
||||
public function optimize_attachment_context( $context, $attachment_id ) {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9' );
|
||||
|
||||
if ( self::CONTEXT === $context || ( 'wp' === $context && imagify_is_attachment_mime_type_supported( $attachment_id ) ) ) {
|
||||
return self::CONTEXT;
|
||||
}
|
||||
return $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* When getting all unoptimized attachment ids before performing a bulk optimization, download the missing files from S3.
|
||||
*
|
||||
* @since 1.6.7
|
||||
* @since 1.9 Deprecated
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*
|
||||
* @param array $ids An array of attachment IDs.
|
||||
* @param array $results An array of the data fetched from the database.
|
||||
* @param int $optimization_level The optimization level that will be used for the optimization.
|
||||
*/
|
||||
public function maybe_copy_files_from_s3( $ids, $results, $optimization_level ) {
|
||||
global $wpdb, $as3cf;
|
||||
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9' );
|
||||
|
||||
if ( ! $as3cf || ! $as3cf->is_plugin_setup() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove from the list files that exist.
|
||||
$ids = array_flip( $ids );
|
||||
|
||||
foreach ( $ids as $id => $i ) {
|
||||
if ( empty( $results['filenames'][ $id ] ) ) {
|
||||
// Problem.
|
||||
unset( $ids[ $id ] );
|
||||
continue;
|
||||
}
|
||||
|
||||
$file_path = get_imagify_attached_file( $results['filenames'][ $id ] );
|
||||
|
||||
/** This filter is documented in inc/deprecated/deprecated.php. */
|
||||
$file_path = apply_filters( 'imagify_file_path', $file_path, $id, 'as3cf_maybe_copy_files_from_s3' );
|
||||
|
||||
if ( ! $file_path || $this->filesystem->exists( $file_path ) ) {
|
||||
// The file exists, no need to retrieve it from S3.
|
||||
unset( $ids[ $id ] );
|
||||
} else {
|
||||
$ids[ $id ] = $file_path;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $ids ) {
|
||||
// All files are already on the server.
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine which files are on S3.
|
||||
$ids = array_flip( $ids );
|
||||
$sql_ids = implode( ',', $ids );
|
||||
|
||||
$s3_data = $wpdb->get_results( // WPCS: unprepared SQL ok.
|
||||
"SELECT pm.post_id as id, pm.meta_value as value
|
||||
FROM $wpdb->postmeta as pm
|
||||
WHERE pm.meta_key = 'amazonS3_info'
|
||||
AND pm.post_id IN ( $sql_ids )
|
||||
ORDER BY pm.post_id DESC",
|
||||
ARRAY_A
|
||||
);
|
||||
|
||||
$wpdb->flush();
|
||||
|
||||
if ( ! $s3_data ) {
|
||||
return;
|
||||
}
|
||||
|
||||
unset( $sql_ids );
|
||||
$s3_data = Imagify_DB::combine_query_results( $ids, $s3_data, true );
|
||||
|
||||
// Retrieve the missing files from S3.
|
||||
$ids = array_flip( $ids );
|
||||
|
||||
foreach ( $s3_data as $id => $s3_object ) {
|
||||
$s3_object = maybe_unserialize( $s3_object );
|
||||
$file_path = $ids[ $id ];
|
||||
|
||||
$attachment_backup_path = get_imagify_attachment_backup_path( $file_path );
|
||||
$attachment_status = isset( $results['statuses'][ $id ] ) ? $results['statuses'][ $id ] : false;
|
||||
$attachment_optimization_level = isset( $results['optimization_levels'][ $id ] ) ? $results['optimization_levels'][ $id ] : false;
|
||||
|
||||
// Don't try to re-optimize if there is no backup file.
|
||||
if ( 'success' === $attachment_status && $optimization_level !== $attachment_optimization_level && ! $this->filesystem->exists( $attachment_backup_path ) ) {
|
||||
unset( $s3_data[ $id ], $ids[ $id ] );
|
||||
continue;
|
||||
}
|
||||
|
||||
$directory = $this->filesystem->dir_path( $s3_object['key'] );
|
||||
$directory = $this->filesystem->is_root( $directory ) ? '' : $directory;
|
||||
$s3_object['key'] = $directory . $this->filesystem->file_name( $file_path );
|
||||
|
||||
// Retrieve file from S3.
|
||||
if ( method_exists( $as3cf->plugin_compat, 'copy_s3_file_to_server' ) ) {
|
||||
$as3cf->plugin_compat->copy_s3_file_to_server( $s3_object, $file_path );
|
||||
} else {
|
||||
$as3cf->plugin_compat->copy_provider_file_to_server( $s3_object, $file_path );
|
||||
}
|
||||
|
||||
unset( $s3_data[ $id ], $ids[ $id ] );
|
||||
}
|
||||
}
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** AUTOMATIC OPTIMIZATION: OPTIMIZE AFTER S3 HAS DONE ITS WORK ============================= */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Filter the generated attachment meta data.
|
||||
* This is used when a new attachment has just been uploaded (or not, when wp_generate_attachment_metadata() is used).
|
||||
* We use it to tell the difference later in wp_update_attachment_metadata().
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @since 1.8.4 Deprecated
|
||||
* @author Grégory Viguier
|
||||
* @see $this->do_async_job()
|
||||
* @deprecated
|
||||
*
|
||||
* @param array $metadata An array of attachment meta data.
|
||||
* @param int $attachment_id Current attachment ID.
|
||||
* @return array
|
||||
*/
|
||||
public function store_upload_ids( $metadata, $attachment_id ) {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.8.4' );
|
||||
|
||||
if ( imagify_is_attachment_mime_type_supported( $attachment_id ) ) {
|
||||
$this->uploads[ $attachment_id ] = 1;
|
||||
}
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* After an image (maybe) being sent to S3, launch an async optimization.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @since 1.8.4 Deprecated
|
||||
* @author Grégory Viguier
|
||||
* @see $this->store_upload_ids()
|
||||
* @deprecated
|
||||
*
|
||||
* @param array $metadata An array of attachment meta data.
|
||||
* @param int $attachment_id Current attachment ID.
|
||||
* @return array
|
||||
*/
|
||||
public function do_async_job( $metadata, $attachment_id ) {
|
||||
static $auto_optimize;
|
||||
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.8.4' );
|
||||
|
||||
$is_new_upload = ! empty( $this->uploads[ $attachment_id ] );
|
||||
unset( $this->uploads[ $attachment_id ] );
|
||||
|
||||
if ( ! $metadata || ! imagify_is_attachment_mime_type_supported( $attachment_id ) ) {
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
if ( ! isset( $auto_optimize ) ) {
|
||||
$auto_optimize = Imagify_Requirements::is_api_key_valid() && get_imagify_option( 'auto_optimize' );
|
||||
}
|
||||
|
||||
if ( $is_new_upload ) {
|
||||
// It's a new upload.
|
||||
if ( ! $auto_optimize ) {
|
||||
// Auto-optimization is disabled.
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/** This filter is documented in inc/common/attachments.php. */
|
||||
$optimize = apply_filters( 'imagify_auto_optimize_attachment', true, $attachment_id, $metadata );
|
||||
|
||||
if ( ! $optimize ) {
|
||||
return $metadata;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $is_new_upload ) {
|
||||
$attachment = get_imagify_attachment( self::CONTEXT, $attachment_id, 'as3cf_async_job' );
|
||||
|
||||
if ( ! $attachment->get_data() ) {
|
||||
// It's not a new upload and the attachment is not optimized yet.
|
||||
return $metadata;
|
||||
}
|
||||
}
|
||||
|
||||
$data = array();
|
||||
|
||||
// Some specifics for the image editor.
|
||||
if ( isset( $_POST['action'], $_POST['do'], $_POST['postid'] ) && 'image-editor' === $_POST['action'] && (int) $_POST['postid'] === $attachment_id ) { // WPCS: CSRF ok.
|
||||
check_ajax_referer( 'image_editor-' . $_POST['postid'] );
|
||||
$data = $_POST;
|
||||
}
|
||||
|
||||
imagify_do_async_job( array(
|
||||
'action' => 'imagify_async_optimize_as3cf',
|
||||
'_ajax_nonce' => wp_create_nonce( 'imagify_async_optimize_as3cf' ),
|
||||
'post_id' => $attachment_id,
|
||||
'metadata' => $metadata,
|
||||
'data' => $data,
|
||||
) );
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Once an image has been sent to S3, optimize it and send it again.
|
||||
*
|
||||
* @since 1.6.6
|
||||
* @since 1.8.4 Deprecated
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
public function optimize() {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.8.4' );
|
||||
|
||||
check_ajax_referer( 'imagify_async_optimize_as3cf' );
|
||||
|
||||
if ( empty( $_POST['post_id'] ) || ! imagify_current_user_can( 'auto-optimize' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
$attachment_id = absint( $_POST['post_id'] );
|
||||
|
||||
if ( ! $attachment_id || empty( $_POST['metadata'] ) || ! is_array( $_POST['metadata'] ) || empty( $_POST['metadata']['sizes'] ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
if ( ! imagify_is_attachment_mime_type_supported( $attachment_id ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
$optimization_level = null;
|
||||
$attachment = get_imagify_attachment( self::CONTEXT, $attachment_id, 'as3cf_optimize' );
|
||||
|
||||
// Some specifics for the image editor.
|
||||
if ( ! empty( $_POST['data']['do'] ) ) {
|
||||
$optimization_level = $attachment->get_optimization_level();
|
||||
|
||||
// Remove old optimization data.
|
||||
$attachment->delete_imagify_data();
|
||||
|
||||
if ( 'restore' === $_POST['data']['do'] ) {
|
||||
// Restore the backup file.
|
||||
$attachment->restore();
|
||||
}
|
||||
}
|
||||
|
||||
// Optimize it.
|
||||
$attachment->optimize( $optimization_level, $_POST['metadata'] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Class containing deprecated methods of Imagify_Assets.
|
||||
*
|
||||
* @since 1.9.2
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
class Imagify_Assets_Deprecated {
|
||||
|
||||
/**
|
||||
* Add Intercom on Options page an Bulk Optimization.
|
||||
* Previously was _imagify_admin_print_intercom()
|
||||
*
|
||||
* @since 1.6.10
|
||||
* @since 1.9.2 Deprecated.
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
public function print_support_script() {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9.2' );
|
||||
|
||||
if ( ! Imagify_Requirements::is_api_key_valid() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = get_imagify_user();
|
||||
|
||||
if ( empty( $user->is_intercom ) || empty( $user->display_support ) ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<script>
|
||||
window.intercomSettings = {
|
||||
app_id: 'cd6nxj3z',
|
||||
user_id: <?php echo (int) $user->id; ?>
|
||||
};
|
||||
(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/cd6nxj3z';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);}if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})()
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure Heartbeat is registered if the given script requires it.
|
||||
* Lots of people love deregister Heartbeat.
|
||||
*
|
||||
* @since 1.6.11
|
||||
* @since 1.9.3 Deprecated.
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $handle Name of the script. Should be unique.
|
||||
*/
|
||||
protected function maybe_register_heartbeat( $handle ) {
|
||||
global $wp_version;
|
||||
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9.3' );
|
||||
|
||||
if ( wp_script_is( 'heartbeat', 'registered' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->scripts[ $handle ] ) ) {
|
||||
// If we registered it, it's one of our scripts.
|
||||
$handle = self::JS_PREFIX . $handle;
|
||||
}
|
||||
|
||||
$wp_scripts = wp_scripts();
|
||||
$dependencies = $wp_scripts->query( $handle );
|
||||
|
||||
if ( ! $dependencies || ! $dependencies->deps ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$dependencies = array_flip( $dependencies->deps );
|
||||
|
||||
if ( ! isset( $dependencies['heartbeat'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$suffix = SCRIPT_DEBUG ? '' : '.min';
|
||||
$depts = [ 'jquery' ];
|
||||
|
||||
if ( version_compare( $wp_version, '5.0.0' ) >= 0 ) {
|
||||
$depts[] = 'wp-hooks';
|
||||
}
|
||||
|
||||
wp_register_script( 'heartbeat', "/wp-includes/js/heartbeat$suffix.js", $depts, false, true ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NoExplicitVersion
|
||||
|
||||
if ( $wp_scripts->get_data( 'heartbeat', 'data' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** This filter is documented in /wp-includes/script-loader.php */
|
||||
$data = apply_filters( 'heartbeat_settings', [] );
|
||||
|
||||
if ( empty( $data['nonce'] ) ) {
|
||||
$data = wp_heartbeat_settings( $data );
|
||||
}
|
||||
|
||||
wp_localize_script( 'heartbeat', 'heartbeatSettings', $data );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,850 @@
|
||||
<?php
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Imagify Attachment class.
|
||||
*
|
||||
* @since 1.0
|
||||
* @since 1.9 Deprecated
|
||||
* @deprecated
|
||||
*/
|
||||
class Imagify_Attachment extends Imagify_Abstract_Attachment {
|
||||
|
||||
/**
|
||||
* Class version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '1.2';
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @since 1.2
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int|object $id The attachment ID or the attachment itself.
|
||||
* If an integer, make sure the attachment exists.
|
||||
*/
|
||||
public function __construct( $id = 0 ) {
|
||||
imagify_deprecated_class( get_class( $this ), '1.9', '\\Imagify\\Optimization\\Process\\WP( $id )' );
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachment backup file path, even if the file doesn't exist.
|
||||
*
|
||||
* @since 1.6.13
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
*
|
||||
* @return string|bool The file path. False on failure.
|
||||
*/
|
||||
public function get_raw_backup_path() {
|
||||
return get_imagify_attachment_backup_path( $this->get_original_path() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachment optimization data.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_data() {
|
||||
$data = get_post_meta( $this->id, '_imagify_data', true );
|
||||
return is_array( $data ) ? $data : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachment optimization level.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_optimization_level() {
|
||||
$level = get_post_meta( $this->id, '_imagify_optimization_level', true );
|
||||
return false !== $level ? (int) $level : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachment optimization status (success or error).
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_status() {
|
||||
$status = get_post_meta( $this->id, '_imagify_status', true );
|
||||
return is_string( $status ) ? $status : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the original attachment path.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_original_path() {
|
||||
return get_attached_file( $this->id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the original attachment URL.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_original_url() {
|
||||
return wp_get_attachment_url( $this->id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get width and height of the original image.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_dimensions() {
|
||||
if ( ! $this->is_image() ) {
|
||||
return parent::get_dimensions();
|
||||
}
|
||||
|
||||
$values = wp_get_attachment_image_src( $this->id, 'full' );
|
||||
|
||||
return array(
|
||||
'width' => $values[1],
|
||||
'height' => $values[2],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the metadata size of the attachment.
|
||||
*
|
||||
* @since 1.2
|
||||
* @access public
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function update_metadata_size() {
|
||||
// Check if the attachment extension is allowed.
|
||||
if ( ! $this->is_extension_supported() || ! $this->is_image() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$size = $this->filesystem->get_image_size( $this->get_original_path() );
|
||||
|
||||
if ( ! $size ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered before updating an image width and height into its metadata.
|
||||
*
|
||||
* @since 1.8.4
|
||||
* @see Imagify_Filesystem->get_image_size()
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $attachment_id The attachment ID.
|
||||
* @param array $size {
|
||||
* An array with, among other data:
|
||||
*
|
||||
* @type int $width The image width.
|
||||
* @type int $height The image height.
|
||||
* }
|
||||
*/
|
||||
do_action( 'before_imagify_update_metadata_size', $this->id, $size );
|
||||
|
||||
$metadata = wp_get_attachment_metadata( $this->id );
|
||||
$metadata['width'] = $size['width'];
|
||||
$metadata['height'] = $size['height'];
|
||||
|
||||
wp_update_attachment_metadata( $this->id, $metadata );
|
||||
|
||||
/**
|
||||
* Triggered after updating an image width and height into its metadata.
|
||||
*
|
||||
* @since 1.8.4
|
||||
* @see Imagify_Filesystem->get_image_size()
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $attachment_id The attachment ID.
|
||||
* @param array $size {
|
||||
* An array with, among other data:
|
||||
*
|
||||
* @type int $width The image width.
|
||||
* @type int $height The image height.
|
||||
* }
|
||||
*/
|
||||
do_action( 'after_imagify_update_metadata_size', $this->id, $size );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills statistics data with values from $data array.
|
||||
*
|
||||
* @since 1.0
|
||||
* @since 1.6.5 Not static anymore.
|
||||
* @since 1.6.6 Removed the attachment ID parameter.
|
||||
* @since 1.7 Removed the image URL parameter.
|
||||
* @access public
|
||||
*
|
||||
* @param array $data The statistics data.
|
||||
* @param object $response The API response.
|
||||
* @param string $size The attachment size key.
|
||||
* @return bool|array False if the original size has an error or an array contains the data for other result.
|
||||
*/
|
||||
public function fill_data( $data, $response, $size = 'full' ) {
|
||||
$data = is_array( $data ) ? $data : array();
|
||||
$data['sizes'] = ! empty( $data['sizes'] ) && is_array( $data['sizes'] ) ? $data['sizes'] : array();
|
||||
|
||||
if ( empty( $data['stats'] ) ) {
|
||||
$data['stats'] = array(
|
||||
'original_size' => 0,
|
||||
'optimized_size' => 0,
|
||||
'percent' => 0,
|
||||
);
|
||||
}
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
$error = $response->get_error_message();
|
||||
$error_status = 'error';
|
||||
|
||||
$data['sizes'][ $size ] = array(
|
||||
'success' => false,
|
||||
'error' => $error,
|
||||
);
|
||||
|
||||
// Update the error status for the original size.
|
||||
if ( 'full' === $size ) {
|
||||
update_post_meta( $this->id, '_imagify_data', $data );
|
||||
|
||||
if ( false !== strpos( $error, 'This image is already compressed' ) ) {
|
||||
$error_status = 'already_optimized';
|
||||
}
|
||||
|
||||
update_post_meta( $this->id, '_imagify_status', $error_status );
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$response = (object) array_merge( array(
|
||||
'original_size' => 0,
|
||||
'new_size' => 0,
|
||||
'percent' => 0,
|
||||
), (array) $response );
|
||||
|
||||
$data['sizes'][ $size ] = array(
|
||||
'success' => true,
|
||||
'original_size' => $response->original_size,
|
||||
'optimized_size' => $response->new_size,
|
||||
'percent' => $response->percent,
|
||||
);
|
||||
|
||||
$data['stats']['original_size'] += $response->original_size;
|
||||
$data['stats']['optimized_size'] += $response->new_size;
|
||||
} // End if().
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a thumbnail if it doesn't exist.
|
||||
*
|
||||
* @since 1.6.10
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $thumbnail_data The thumbnail data (width, height, crop, name, file).
|
||||
* @return bool|array|object True if the file exists. An array of thumbnail data if the file has just been created (width, height, crop, file). A WP_Error object on error.
|
||||
*/
|
||||
protected function create_thumbnail( $thumbnail_data ) {
|
||||
$thumbnail_size = $thumbnail_data['name'];
|
||||
$metadata = wp_get_attachment_metadata( $this->id );
|
||||
$metadata_sizes = ! empty( $metadata['sizes'] ) && is_array( $metadata['sizes'] ) ? $metadata['sizes'] : array();
|
||||
|
||||
$original_dirname = $this->filesystem->dir_path( $this->get_original_path() );
|
||||
$thumbnail_path = $original_dirname . $thumbnail_data['file'];
|
||||
|
||||
if ( ! empty( $metadata_sizes[ $thumbnail_size ] ) && $this->filesystem->exists( $thumbnail_path ) ) {
|
||||
$this->filesystem->chmod_file( $thumbnail_path );
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the editor.
|
||||
$editor = $this->get_editor( $this->get_backup_path() );
|
||||
|
||||
if ( is_wp_error( $editor ) ) {
|
||||
return $editor;
|
||||
}
|
||||
|
||||
// Create the file.
|
||||
$result = $editor->multi_resize( array( $thumbnail_size => $thumbnail_data ) );
|
||||
|
||||
if ( ! $result ) {
|
||||
return new WP_Error( 'image_resize_error' );
|
||||
}
|
||||
|
||||
// The file name can change from what we expected (1px wider, etc).
|
||||
$backup_dirname = $this->filesystem->dir_path( $this->get_backup_path() );
|
||||
$backup_thumb_path = $backup_dirname . $result[ $thumbnail_size ]['file'];
|
||||
$thumbnail_path = $original_dirname . $result[ $thumbnail_size ]['file'];
|
||||
|
||||
// Since we used the backup image as source, the new image is still in the backup folder, we need to move it.
|
||||
$moved = $this->filesystem->move( $backup_thumb_path, $thumbnail_path, true );
|
||||
|
||||
if ( ! $moved ) {
|
||||
return new WP_Error( 'image_resize_error' );
|
||||
}
|
||||
|
||||
return reset( $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create all missing thumbnails if they don't exist and update the attachment metadata.
|
||||
*
|
||||
* @since 1.6.10
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $missing_sizes An array of thumbnail data (width, height, crop, name, file) for each thumbnail size.
|
||||
* @return array An array of thumbnail data (width, height, crop, file).
|
||||
*/
|
||||
protected function create_missing_thumbnails( $missing_sizes ) {
|
||||
if ( ! $missing_sizes || ! $this->is_image() ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$metadata = wp_get_attachment_metadata( $this->id );
|
||||
$metadata['sizes'] = ! empty( $metadata['sizes'] ) && is_array( $metadata['sizes'] ) ? $metadata['sizes'] : array();
|
||||
$thumbnail_new_datas = array();
|
||||
$thumbnail_metadatas = array();
|
||||
|
||||
// Create the missing thumbnails.
|
||||
foreach ( $missing_sizes as $size_name => $thumbnail_data ) {
|
||||
$result = $this->create_thumbnail( $thumbnail_data );
|
||||
|
||||
if ( is_array( $result ) ) {
|
||||
// New file.
|
||||
$thumbnail_new_datas[ $size_name ] = $result;
|
||||
unset( $thumbnail_new_datas[ $size_name ]['name'] );
|
||||
} elseif ( true === $result ) {
|
||||
// The file already exists.
|
||||
$thumbnail_metadatas[ $size_name ] = $metadata['sizes'][ $size_name ];
|
||||
}
|
||||
}
|
||||
|
||||
// Save the new data into the attachment metadata.
|
||||
if ( $thumbnail_new_datas ) {
|
||||
$metadata['sizes'] = array_merge( $metadata['sizes'], $thumbnail_new_datas );
|
||||
|
||||
/**
|
||||
* Here we don't use wp_update_attachment_metadata() to prevent triggering unwanted hooks.
|
||||
*/
|
||||
update_post_meta( $this->id, '_wp_attachment_metadata', $metadata );
|
||||
}
|
||||
|
||||
return array_merge( $thumbnail_metadatas, $thumbnail_new_datas );
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimize all sizes with Imagify.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $optimization_level The optimization level (2=ultra, 1=aggressive, 0=normal).
|
||||
* @param array $metadata The attachment meta data.
|
||||
* @return array $optimized_data The optimization data.
|
||||
*/
|
||||
public function optimize( $optimization_level = null, $metadata = array() ) {
|
||||
// Check if the attachment extension is allowed.
|
||||
if ( ! $this->is_extension_supported() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$optimization_level = isset( $optimization_level ) ? (int) $optimization_level : get_imagify_option( 'optimization_level' );
|
||||
$metadata = $metadata ? $metadata : wp_get_attachment_metadata( $this->id );
|
||||
$sizes = ! empty( $metadata['sizes'] ) && is_array( $metadata['sizes'] ) && $this->is_image() ? $metadata['sizes'] : array();
|
||||
|
||||
// To avoid issue with "original_size" at 0 in "_imagify_data".
|
||||
if ( 0 === (int) $this->get_stats_data( 'original_size' ) ) {
|
||||
$this->delete_imagify_data();
|
||||
}
|
||||
|
||||
// Check if the full size is already optimized.
|
||||
if ( $this->is_optimized() && $this->get_optimization_level() === $optimization_level ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get file path & URL for original image.
|
||||
$attachment_path = $this->get_original_path();
|
||||
$attachment_url = $this->get_original_url();
|
||||
$attachment_original_size = $this->get_original_size( false );
|
||||
|
||||
/**
|
||||
* Fires before optimizing an attachment.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param int $id The attachment ID.
|
||||
*/
|
||||
do_action( 'before_imagify_optimize_attachment', $this->id );
|
||||
|
||||
$this->set_running_status();
|
||||
|
||||
// Get the resize values for the original size.
|
||||
$resized = false;
|
||||
$do_resize = $this->is_image() && get_imagify_option( 'resize_larger' );
|
||||
|
||||
if ( $do_resize ) {
|
||||
$resize_width = get_imagify_option( 'resize_larger_w' );
|
||||
$attachment_size = $this->filesystem->get_image_size( $attachment_path );
|
||||
|
||||
if ( $attachment_size && $resize_width < $attachment_size['width'] ) {
|
||||
$resized_attachment_path = $this->resize( $attachment_path, $attachment_size, $resize_width );
|
||||
|
||||
if ( ! is_wp_error( $resized_attachment_path ) ) {
|
||||
// TODO (@Greg): Send an error message if the backup fails.
|
||||
imagify_backup_file( $attachment_path );
|
||||
|
||||
$this->filesystem->move( $resized_attachment_path, $attachment_path, true );
|
||||
|
||||
$resized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Optimize the original size.
|
||||
$response = do_imagify( $attachment_path, array(
|
||||
'optimization_level' => $optimization_level,
|
||||
'context' => $this->get_context(),
|
||||
'resized' => $resized,
|
||||
'original_size' => $attachment_original_size,
|
||||
) );
|
||||
|
||||
$data = $this->fill_data( null, $response );
|
||||
|
||||
/**
|
||||
* Filter the optimization data of the full size.
|
||||
*
|
||||
* @since 1.8
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $data The statistics data.
|
||||
* @param object $response The API response.
|
||||
* @param int $id The attachment ID.
|
||||
* @param string $attachment_path The attachment path.
|
||||
* @param string $attachment_url The attachment URL.
|
||||
* @param string $size_key The attachment size key. The value is obviously 'full' but it's kept for concistancy with other filters.
|
||||
* @param int $optimization_level The optimization level.
|
||||
* @param array $metadata WP metadata.
|
||||
*/
|
||||
$data = apply_filters( 'imagify_fill_full_size_data', $data, $response, $this->id, $attachment_path, $attachment_url, 'full', $optimization_level, $metadata );
|
||||
|
||||
// Save the optimization level.
|
||||
update_post_meta( $this->id, '_imagify_optimization_level', $optimization_level );
|
||||
|
||||
// If we resized the original with success, we have to update the attachment metadata.
|
||||
// If not, WordPress keeps the old attachment size.
|
||||
if ( $resized ) {
|
||||
$this->update_metadata_size();
|
||||
}
|
||||
|
||||
if ( ! $data ) {
|
||||
$this->delete_running_status();
|
||||
return;
|
||||
}
|
||||
|
||||
// Optimize all thumbnails.
|
||||
if ( $sizes ) {
|
||||
$disallowed_sizes = get_imagify_option( 'disallowed-sizes' );
|
||||
$is_active_for_network = imagify_is_active_for_network();
|
||||
$attachment_path_dirname = $this->filesystem->dir_path( $attachment_path );
|
||||
$attachment_url_dirname = $this->filesystem->dir_path( $attachment_url );
|
||||
|
||||
foreach ( $sizes as $size_key => $size_data ) {
|
||||
$thumbnail_path = $attachment_path_dirname . $size_data['file'];
|
||||
$thumbnail_url = $attachment_url_dirname . $size_data['file'];
|
||||
|
||||
// Check if this size has to be optimized.
|
||||
if ( ! $is_active_for_network && isset( $disallowed_sizes[ $size_key ] ) ) {
|
||||
$data['sizes'][ $size_key ] = array(
|
||||
'success' => false,
|
||||
'error' => __( 'This size is not authorized to be optimized. Update your Imagify settings if you want to optimize it.', 'imagify' ),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filter the optimization data of an unauthorized thumbnail.
|
||||
*
|
||||
* @since 1.8
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $data The statistics data.
|
||||
* @param int $id The attachment ID.
|
||||
* @param string $thumbnail_path The thumbnail path.
|
||||
* @param string $thumbnail_url The thumbnail URL.
|
||||
* @param string $size_key The thumbnail size key.
|
||||
* @param int $optimization_level The optimization level.
|
||||
* @param array $metadata WP metadata.
|
||||
*/
|
||||
$data = apply_filters( 'imagify_fill_unauthorized_thumbnail_data', $data, $this->id, $thumbnail_path, $thumbnail_url, $size_key, $optimization_level, $metadata );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Optimize the thumbnail size.
|
||||
$response = do_imagify( $thumbnail_path, array(
|
||||
'backup' => false,
|
||||
'optimization_level' => $optimization_level,
|
||||
'context' => $this->get_context(),
|
||||
) );
|
||||
|
||||
$data = $this->fill_data( $data, $response, $size_key );
|
||||
|
||||
/**
|
||||
* Filter the optimization data of a specific thumbnail.
|
||||
*
|
||||
* @since 1.0
|
||||
* @since 1.8 Added $metadata.
|
||||
*
|
||||
* @param array $data The statistics data.
|
||||
* @param object $response The API response.
|
||||
* @param int $id The attachment ID.
|
||||
* @param string $thumbnail_path The thumbnail path.
|
||||
* @param string $thumbnail_url The thumbnail URL.
|
||||
* @param string $size_key The thumbnail size key.
|
||||
* @param int $optimization_level The optimization level.
|
||||
* @param array $metadata WP metadata.
|
||||
*/
|
||||
$data = apply_filters( 'imagify_fill_thumbnail_data', $data, $response, $this->id, $thumbnail_path, $thumbnail_url, $size_key, $optimization_level, $metadata );
|
||||
} // End foreach().
|
||||
} // End if().
|
||||
|
||||
$data['stats']['percent'] = round( ( ( $data['stats']['original_size'] - $data['stats']['optimized_size'] ) / $data['stats']['original_size'] ) * 100, 2 );
|
||||
|
||||
update_post_meta( $this->id, '_imagify_data', $data );
|
||||
update_post_meta( $this->id, '_imagify_status', 'success' );
|
||||
|
||||
$optimized_data = $this->get_data();
|
||||
|
||||
/**
|
||||
* Fires after optimizing an attachment.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param int $id The attachment ID.
|
||||
* @param array $optimized_data The optimization data.
|
||||
*/
|
||||
do_action( 'after_imagify_optimize_attachment', $this->id, $optimized_data );
|
||||
|
||||
$this->delete_running_status();
|
||||
|
||||
return $optimized_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimize missing thumbnail sizes with Imagify.
|
||||
*
|
||||
* @since 1.6.10
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $optimization_level The optimization level (2=ultra, 1=aggressive, 0=normal).
|
||||
* @return array|object An array of thumbnail data, size by size. A WP_Error object on failure.
|
||||
*/
|
||||
public function optimize_missing_thumbnails( $optimization_level = null ) {
|
||||
// Check if the attachment extension is allowed.
|
||||
if ( ! $this->is_extension_supported() || ! $this->is_image() ) {
|
||||
return new WP_Error( 'mime_type_not_supported', __( 'This type of file is not supported.', 'imagify' ) );
|
||||
}
|
||||
|
||||
$optimization_level = isset( $optimization_level ) ? (int) $optimization_level : get_imagify_option( 'optimization_level' );
|
||||
$missing_sizes = $this->get_unoptimized_sizes();
|
||||
|
||||
if ( ! $missing_sizes ) {
|
||||
// We have everything we need.
|
||||
return array();
|
||||
}
|
||||
|
||||
// Stop the process if there is no backup file to use.
|
||||
if ( ! $this->has_backup() ) {
|
||||
return new WP_Error( 'no_backup', __( 'This file has no backup file.', 'imagify' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires before optimizing the missing thumbnails.
|
||||
*
|
||||
* @since 1.6.10
|
||||
* @author Grégory Viguier
|
||||
* @see $this->get_unoptimized_sizes()
|
||||
*
|
||||
* @param int $id The attachment ID.
|
||||
* @param array $missing_sizes An array of the missing sizes.
|
||||
*/
|
||||
do_action( 'before_imagify_optimize_missing_thumbnails', $this->id, $missing_sizes );
|
||||
|
||||
$this->set_running_status();
|
||||
|
||||
$errors = new WP_Error();
|
||||
|
||||
// Create the missing thumbnails.
|
||||
$result_sizes = $this->create_missing_thumbnails( $missing_sizes );
|
||||
$failed_sizes = array_diff_key( $missing_sizes, $result_sizes );
|
||||
|
||||
if ( $failed_sizes ) {
|
||||
$failed_count = count( $failed_sizes );
|
||||
/* translators: %d is a number of thumbnails. */
|
||||
$error_message = _n( '%d thumbnail failed to be created', '%d thumbnails failed to be created', $failed_count, 'imagify' );
|
||||
$error_message = sprintf( $error_message, $failed_count );
|
||||
|
||||
$errors->add( 'image_resize_error', $error_message, array(
|
||||
'nbr_failed' => $failed_count,
|
||||
'sizes_failed' => $failed_sizes,
|
||||
'sizes_succeeded' => $result_sizes,
|
||||
) );
|
||||
}
|
||||
|
||||
if ( ! $result_sizes ) {
|
||||
$this->delete_running_status();
|
||||
return $errors;
|
||||
}
|
||||
|
||||
// Optimize.
|
||||
$imagify_data = $this->get_data();
|
||||
$original_dirname = $this->filesystem->dir_path( $this->get_original_path() );
|
||||
$orig_url_dirname = $this->filesystem->dir_path( $this->get_original_url() );
|
||||
|
||||
foreach ( $result_sizes as $size_name => $thumbnail_data ) {
|
||||
$thumbnail_path = $original_dirname . $thumbnail_data['file'];
|
||||
$thumbnail_url = $orig_url_dirname . $thumbnail_data['file'];
|
||||
|
||||
// Optimize the thumbnail size.
|
||||
$response = do_imagify( $thumbnail_path, array(
|
||||
'backup' => false,
|
||||
'optimization_level' => $optimization_level,
|
||||
'context' => $this->get_context(),
|
||||
) );
|
||||
|
||||
$imagify_data = $this->fill_data( $imagify_data, $response, $size_name );
|
||||
$metadata = wp_get_attachment_metadata( $this->id );
|
||||
|
||||
/** This filter is documented in inc/classes/class-imagify-attachment.php. */
|
||||
$imagify_data = apply_filters( 'imagify_fill_thumbnail_data', $imagify_data, $response, $this->id, $thumbnail_path, $thumbnail_url, $size_name, $optimization_level, $metadata );
|
||||
}
|
||||
|
||||
// Save Imagify data.
|
||||
$imagify_data['stats']['percent'] = round( ( ( $imagify_data['stats']['original_size'] - $imagify_data['stats']['optimized_size'] ) / $imagify_data['stats']['original_size'] ) * 100, 2 );
|
||||
|
||||
update_post_meta( $this->id, '_imagify_data', $imagify_data );
|
||||
|
||||
/**
|
||||
* Fires after optimizing the missing thumbnails.
|
||||
*
|
||||
* @since 1.6.10
|
||||
* @author Grégory Viguier
|
||||
* @see $this->create_missing_thumbnails()
|
||||
*
|
||||
* @param int $id The attachment ID.
|
||||
* @param array $result_sizes An array of created thumbnails.
|
||||
* @param object $errors A WP_Error object that stores thumbnail creation failures.
|
||||
*/
|
||||
do_action( 'after_imagify_optimize_missing_thumbnails', $this->id, $result_sizes, $errors );
|
||||
|
||||
$this->delete_running_status();
|
||||
|
||||
// Return the result.
|
||||
if ( $errors->get_error_codes() ) {
|
||||
return $errors;
|
||||
}
|
||||
|
||||
return $result_sizes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-optimize the given thumbnail sizes to the same level.
|
||||
* Before doing this, the given sizes must be restored.
|
||||
*
|
||||
* @since 1.7.1
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $sizes The sizes to optimize.
|
||||
* @return array|void A WP_Error object on failure.
|
||||
*/
|
||||
public function reoptimize_thumbnails( $sizes ) {
|
||||
// Check if the attachment extension is allowed.
|
||||
if ( ! $this->is_extension_supported() || ! $this->is_image() ) {
|
||||
return new WP_Error( 'mime_type_not_supported', __( 'This type of file is not supported.', 'imagify' ) );
|
||||
}
|
||||
|
||||
if ( ! $sizes || ! is_array( $sizes ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires before re-optimizing some thumbnails of an attachment.
|
||||
*
|
||||
* @since 1.7.1
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $id The attachment ID.
|
||||
* @param array $sizes The sizes to optimize.
|
||||
*/
|
||||
do_action( 'before_imagify_reoptimize_attachment_thumbnails', $this->id, $sizes );
|
||||
|
||||
$this->set_running_status();
|
||||
|
||||
$data = $this->get_data();
|
||||
|
||||
$data['sizes'] = ! empty( $data['sizes'] ) && is_array( $data['sizes'] ) ? $data['sizes'] : array();
|
||||
|
||||
foreach ( $sizes as $size_key => $size_data ) {
|
||||
// In case it's a disallowed size, fill in the new data. If it's not, it will be overwritten by $this->fill_data() later.
|
||||
$data['sizes'][ $size_key ] = array(
|
||||
'success' => false,
|
||||
'error' => __( 'This size is not authorized to be optimized. Update your Imagify settings if you want to optimize it.', 'imagify' ),
|
||||
);
|
||||
}
|
||||
|
||||
// Update global attachment stats.
|
||||
$data['stats'] = array(
|
||||
'original_size' => 0,
|
||||
'optimized_size' => 0,
|
||||
'percent' => 0,
|
||||
);
|
||||
|
||||
foreach ( $data['sizes'] as $size_data ) {
|
||||
if ( ! empty( $size_data['original_size'] ) ) {
|
||||
$data['stats']['original_size'] += $size_data['original_size'];
|
||||
}
|
||||
if ( ! empty( $size_data['optimized_size'] ) ) {
|
||||
$data['stats']['optimized_size'] += $size_data['optimized_size'];
|
||||
}
|
||||
}
|
||||
|
||||
// Remove disallowed sizes.
|
||||
if ( ! imagify_is_active_for_network() ) {
|
||||
$sizes = array_diff_key( $sizes, get_imagify_option( 'disallowed-sizes' ) );
|
||||
}
|
||||
|
||||
if ( ! $sizes ) {
|
||||
$data['stats']['percent'] = $data['stats']['original_size'] ? round( ( ( $data['stats']['original_size'] - $data['stats']['optimized_size'] ) / $data['stats']['original_size'] ) * 100, 2 ) : 0;
|
||||
update_post_meta( $this->id, '_imagify_data', $data );
|
||||
$this->delete_running_status();
|
||||
return;
|
||||
}
|
||||
|
||||
$optimization_level = $this->get_optimization_level();
|
||||
$thumbnail_path = $this->get_original_path();
|
||||
$thumbnail_url = $this->get_original_url();
|
||||
$attachment_path_dirname = $this->filesystem->dir_path( $thumbnail_path );
|
||||
$attachment_url_dirname = $this->filesystem->dir_path( $thumbnail_url );
|
||||
|
||||
foreach ( $sizes as $size_key => $size_data ) {
|
||||
$thumbnail_path = $attachment_path_dirname . $size_data['file'];
|
||||
$thumbnail_url = $attachment_url_dirname . $size_data['file'];
|
||||
|
||||
// Optimize the thumbnail size.
|
||||
$response = do_imagify( $thumbnail_path, array(
|
||||
'backup' => false,
|
||||
'optimization_level' => $optimization_level,
|
||||
'context' => $this->get_context(),
|
||||
) );
|
||||
|
||||
$data = $this->fill_data( $data, $response, $size_key );
|
||||
|
||||
/** This filter is documented in /inc/classes/class-imagify-attachment.php. */
|
||||
$data = apply_filters( 'imagify_fill_thumbnail_data', $data, $response, $this->id, $thumbnail_path, $thumbnail_url, $size_key, $optimization_level );
|
||||
} // End foreach().
|
||||
|
||||
$data['stats']['percent'] = round( ( ( $data['stats']['original_size'] - $data['stats']['optimized_size'] ) / $data['stats']['original_size'] ) * 100, 2 );
|
||||
|
||||
update_post_meta( $this->id, '_imagify_data', $data );
|
||||
|
||||
/**
|
||||
* Fires after re-optimizing some thumbnails of an attachment.
|
||||
*
|
||||
* @since 1.7.1
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $id The attachment ID.
|
||||
* @param array $sizes The sizes to optimize.
|
||||
*/
|
||||
do_action( 'after_imagify_reoptimize_attachment_thumbnails', $this->id, $sizes );
|
||||
|
||||
$this->delete_running_status();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an attachment restoration from the backup file.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function restore() {
|
||||
// Check if the attachment extension is allowed.
|
||||
if ( ! $this->is_extension_supported() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop the process if there is no backup file to restore.
|
||||
if ( ! $this->has_backup() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$backup_path = $this->get_backup_path();
|
||||
$attachment_path = $this->get_original_path();
|
||||
|
||||
/**
|
||||
* Fires before restoring an attachment.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param int $id The attachment ID
|
||||
*/
|
||||
do_action( 'before_imagify_restore_attachment', $this->id );
|
||||
|
||||
// Create the original image from the backup.
|
||||
$this->filesystem->copy( $backup_path, $attachment_path, true );
|
||||
$this->filesystem->chmod_file( $attachment_path );
|
||||
|
||||
if ( $this->is_image() ) {
|
||||
if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
}
|
||||
|
||||
wp_generate_attachment_metadata( $this->id, $attachment_path );
|
||||
|
||||
// Restore the original size in the metadata.
|
||||
$this->update_metadata_size();
|
||||
}
|
||||
|
||||
// Remove old optimization data.
|
||||
$this->delete_imagify_data();
|
||||
|
||||
/**
|
||||
* Fires after restoring an attachment.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @param int $id The attachment ID
|
||||
*/
|
||||
do_action( 'after_imagify_restore_attachment', $this->id );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Class that contains the deprecated methods of Imagify_Auto_Optimization.
|
||||
*
|
||||
* @since 1.9.10
|
||||
*/
|
||||
abstract class Imagify_Auto_Optimization_Deprecated {
|
||||
|
||||
/**
|
||||
* With WP 5.3+, prevent auto-optimization inside wp_generate_attachment_metadata() because it triggers a wp_update_attachment_metadata() for each thumbnail size.
|
||||
*
|
||||
* @since 1.9.8
|
||||
* @since 1.9.10 Deprecated.
|
||||
* @see wp_generate_attachment_metadata()
|
||||
* @see wp_create_image_subsizes()
|
||||
*
|
||||
* @param int $threshold The threshold value in pixels. Default 2560.
|
||||
* @param array $imagesize Indexed array of the image width and height (in that order).
|
||||
* @param string $file Full path to the uploaded image file.
|
||||
* @param int $attachment_id Attachment post ID.
|
||||
* @return int The threshold value in pixels.
|
||||
*/
|
||||
public function prevent_auto_optimization_when_generating_thumbnails( $threshold, $imagesize, $file, $attachment_id ) {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9.10' );
|
||||
|
||||
static::prevent_optimization_internally( $attachment_id );
|
||||
return $threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* With WP 5.3+, allow auto-optimization back after wp_generate_attachment_metadata().
|
||||
*
|
||||
* @since 1.9.8
|
||||
* @since 1.9.10 Deprecated.
|
||||
* @see $this->prevent_auto_optimization_when_generating_thumbnails()
|
||||
*
|
||||
* @param array $metadata An array of attachment meta data.
|
||||
* @param int $attachment_id Current attachment ID.
|
||||
* @param string $context Additional context. Can be 'create' when metadata was initially created for new attachment or 'update' when the metadata was updated.
|
||||
* @return array An array of attachment meta data.
|
||||
*/
|
||||
public function allow_auto_optimization_when_generating_thumbnails( $metadata, $attachment_id, $context = null ) {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9.10' );
|
||||
|
||||
if ( ! empty( $context ) && 'create' !== $context ) {
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
// Fired from wp_generate_attachment_metadata(): $context is empty (WP < 5.3) or equal to 'create' (>P >= 5.3).
|
||||
static::allow_optimization_internally( $attachment_id );
|
||||
return $metadata;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Compat class for Enable Media Replace plugin.
|
||||
*
|
||||
* @since 1.8.4
|
||||
* @deprecated
|
||||
*/
|
||||
class Imagify_Enable_Media_Replace_Deprecated {
|
||||
|
||||
/**
|
||||
* The attachment ID.
|
||||
*
|
||||
* @var int
|
||||
* @since 1.6.9
|
||||
* @since 1.9 Deprecated
|
||||
* @deprecated
|
||||
*/
|
||||
protected $attachment_id;
|
||||
|
||||
/**
|
||||
* The attachment.
|
||||
*
|
||||
* @var Imagify_Attachment
|
||||
* @since 1.6.9
|
||||
* @since 1.9 Deprecated
|
||||
* @deprecated
|
||||
*/
|
||||
protected $attachment;
|
||||
|
||||
/**
|
||||
* Tell if the attachment has data.
|
||||
* No data means not processed by Imagify, or restored.
|
||||
*
|
||||
* @var bool
|
||||
* @since 1.8.4
|
||||
* @since 1.9 Deprecated
|
||||
* @deprecated
|
||||
*/
|
||||
protected $attachment_has_data;
|
||||
|
||||
/**
|
||||
* Filesystem object.
|
||||
*
|
||||
* @var object Imagify_Filesystem
|
||||
* @since 1.7.1
|
||||
* @since 1.8.4 Deprecated
|
||||
* @deprecated
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* Optimize the attachment files if the old ones were also optimized.
|
||||
* Delete the old backup file.
|
||||
*
|
||||
* @since 1.6.9
|
||||
* @since 1.8.4 Deprecated.
|
||||
* @see $this->store_old_backup_path()
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $return_url The URL the user will be redirected to.
|
||||
* @return string The same URL.
|
||||
*/
|
||||
public function optimize( $return_url ) {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.8.4' );
|
||||
|
||||
$attachment = $this->get_attachment();
|
||||
|
||||
if ( $attachment->get_data() ) {
|
||||
/**
|
||||
* The old images have been optimized in the past.
|
||||
*/
|
||||
// Use the same otimization level for the new ones.
|
||||
$optimization_level = $attachment->get_optimization_level();
|
||||
|
||||
// Remove old optimization data.
|
||||
$attachment->delete_imagify_data();
|
||||
|
||||
// Optimize and overwrite the previous backup file if exists and needed.
|
||||
add_filter( 'imagify_backup_overwrite_backup', '__return_true', 42 );
|
||||
$attachment->optimize( $optimization_level );
|
||||
remove_filter( 'imagify_backup_overwrite_backup', '__return_true', 42 );
|
||||
}
|
||||
|
||||
$filesystem = Imagify_Filesystem::get_instance();
|
||||
|
||||
/**
|
||||
* Delete the old backup file.
|
||||
*/
|
||||
if ( ! $this->old_backup_path || ! $filesystem->exists( $this->old_backup_path ) ) {
|
||||
// The user didn't choose to rename the files, or there is no old backup.
|
||||
$this->old_backup_path = null;
|
||||
return $return_url;
|
||||
}
|
||||
|
||||
$new_backup_path = $attachment->get_raw_backup_path();
|
||||
|
||||
if ( $new_backup_path === $this->old_backup_path ) {
|
||||
// We don't want to delete the new backup.
|
||||
$this->old_backup_path = null;
|
||||
return $return_url;
|
||||
}
|
||||
|
||||
// Finally, delete the old backup file.
|
||||
$filesystem->delete( $this->old_backup_path );
|
||||
|
||||
$this->old_backup_path = null;
|
||||
return $return_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the user chooses to change the file name, store the old backup file path. This path will be used later to delete the file.
|
||||
*
|
||||
* @since 1.6.9
|
||||
* @since 1.9.10 Deprecated.
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $new_filename The new file name.
|
||||
* @param string $current_path The current file path.
|
||||
* @param int $post_id The attachment ID.
|
||||
* @return string The same file name.
|
||||
*/
|
||||
public function store_old_backup_path( $new_filename, $current_path, $post_id ) {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9.10' );
|
||||
|
||||
if ( ! $this->media_id || $post_id !== $this->media_id ) {
|
||||
return $new_filename;
|
||||
}
|
||||
|
||||
$this->get_process();
|
||||
|
||||
if ( ! $this->process ) {
|
||||
$this->media_id = 0;
|
||||
return $new_filename;
|
||||
}
|
||||
|
||||
$media = $this->process->get_media();
|
||||
$backup_path = $media->get_backup_path();
|
||||
|
||||
if ( $backup_path ) {
|
||||
$this->old_backup_path = $backup_path;
|
||||
|
||||
// Keep track of existing WebP files.
|
||||
$media_files = $media->get_media_files();
|
||||
|
||||
if ( $media_files ) {
|
||||
foreach ( $media_files as $media_file ) {
|
||||
$this->old_webp_paths[] = imagify_path_to_webp( $media_file['path'] );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->media_id = 0;
|
||||
$this->old_backup_path = false;
|
||||
$this->old_webp_paths = [];
|
||||
}
|
||||
|
||||
return $new_filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachment.
|
||||
*
|
||||
* @since 1.6.9
|
||||
* @since 1.9 Deprecated.
|
||||
* @deprecated
|
||||
*
|
||||
* @return object A Imagify_Attachment object (or any class extending it).
|
||||
*/
|
||||
protected function get_attachment() {
|
||||
if ( $this->attachment ) {
|
||||
return $this->attachment;
|
||||
}
|
||||
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9', '\\Imagify\\ThirdParty\\EnableMediaReplace\\Main::get_instance()->get_process()' );
|
||||
|
||||
$this->attachment = get_imagify_attachment( 'wp', $this->attachment_id, 'enable_media_replace' );
|
||||
|
||||
return $this->attachment;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,760 @@
|
||||
<?php
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Imagify Attachment class for custom folders.
|
||||
*
|
||||
* @since 1.7
|
||||
* @since 1.9 Deprecated
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
class Imagify_File_Attachment extends Imagify_Attachment {
|
||||
|
||||
/**
|
||||
* Class version.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
const VERSION = '1.1';
|
||||
|
||||
/**
|
||||
* The attachment SQL DB class.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.7
|
||||
* @access protected
|
||||
*/
|
||||
protected $db_class_name = 'Imagify_Files_DB';
|
||||
|
||||
/**
|
||||
* Tell if the optimization status is network-wide.
|
||||
*
|
||||
* @var bool
|
||||
* @since 1.7.1
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
protected $optimization_state_network_wide = true;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int|array|object $id Thefile ID.
|
||||
*/
|
||||
public function __construct( $id = 0 ) {
|
||||
imagify_deprecated_class( get_class( $this ), '1.9', '\\Imagify\\Optimization\\Process\\CustomFolders( $id )' );
|
||||
|
||||
if ( is_numeric( $id ) ) {
|
||||
$this->id = (int) $id;
|
||||
$this->get_row();
|
||||
} elseif ( is_array( $id ) || is_object( $id ) ) {
|
||||
$prim_key = $this->get_row_db_instance()->get_primary_key();
|
||||
$this->row = (array) $id;
|
||||
$this->id = $this->row[ $prim_key ];
|
||||
} else {
|
||||
$this->invalidate_row();
|
||||
}
|
||||
|
||||
$this->filesystem = Imagify_Filesystem::get_instance();
|
||||
$this->optimization_state_transient = 'imagify-file-async-in-progress-' . $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the original file path.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_original_path() {
|
||||
$row = $this->get_row();
|
||||
|
||||
if ( ! $row || empty( $row['path'] ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return Imagify_Files_Scan::remove_placeholder( $row['path'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the original file URL.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_original_url() {
|
||||
$row = $this->get_row();
|
||||
|
||||
if ( ! $row || empty( $row['path'] ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return Imagify_Files_Scan::remove_placeholder( $row['path'], 'url' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the backup file path, even if the file doesn't exist.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string|bool The file path. False on failure.
|
||||
*/
|
||||
public function get_raw_backup_path() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Imagify_Custom_Folders::get_file_backup_path( $this->get_original_path() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the backup URL.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string|bool The file URL. False on failure.
|
||||
*/
|
||||
public function get_backup_url() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return site_url( '/' ) . $this->filesystem->make_path_relative( $this->get_raw_backup_path() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optimization data.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_data() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$data = array_merge( $this->get_row_db_instance()->get_column_defaults(), $this->get_row() );
|
||||
|
||||
unset( $data['file_id'] );
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optimization level.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return int|bool
|
||||
*/
|
||||
public function get_optimization_level() {
|
||||
$row = $this->get_row();
|
||||
return isset( $row['optimization_level'] ) && is_int( $row['optimization_level'] ) ? $row['optimization_level'] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file optimization status (success, already_optimized, or error).
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_status() {
|
||||
$row = $this->get_row();
|
||||
return ! empty( $row['status'] ) ? $row['status'] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get width and height of the original image.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_dimensions() {
|
||||
$row = $this->get_row();
|
||||
|
||||
return array(
|
||||
'width' => ! empty( $row['width'] ) ? $row['width'] : 0,
|
||||
'height' => ! empty( $row['height'] ) ? $row['height'] : 0,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachment error if there is one.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string The message error
|
||||
*/
|
||||
public function get_optimized_error() {
|
||||
$row = $this->get_row();
|
||||
return ! empty( $row['error'] ) && is_string( $row['error'] ) ? trim( $row['error'] ) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Count number of optimized sizes.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_optimized_sizes_count() {
|
||||
return $this->get_status() === 'success' ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the data related to optimization.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
public function delete_imagify_data() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->update_row( $this->get_reset_imagify_data() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell if the current file extension is supported.
|
||||
* If it's in the DB, it's supported.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_extension_supported() {
|
||||
return $this->is_valid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell if the current file mime type is supported.
|
||||
* If it's in the DB, it's supported.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_mime_type_supported() {
|
||||
return $this->is_valid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell if the current attachment has the required WP metadata.
|
||||
* Well, these are not attachments, so...
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_required_metadata() {
|
||||
return $this->is_valid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the original file size.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param bool $human_format True to display the image human format size (1Mb).
|
||||
* @param int $decimals Precision of number of decimal places.
|
||||
* @return string|int
|
||||
*/
|
||||
public function get_original_size( $human_format = true, $decimals = 2 ) {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return $human_format ? imagify_size_format( 0, $decimals ) : 0;
|
||||
}
|
||||
|
||||
$row = $this->get_row();
|
||||
|
||||
if ( ! empty( $row['original_size'] ) ) {
|
||||
$size = $row['original_size'];
|
||||
} else {
|
||||
// Check for the backup file first.
|
||||
$file_path = $this->get_backup_path();
|
||||
|
||||
if ( ! $file_path ) {
|
||||
$file_path = $this->get_original_path();
|
||||
$file_path = $file_path && $this->filesystem->exists( $file_path ) ? $file_path : false;
|
||||
}
|
||||
|
||||
$size = $file_path ? $this->filesystem->size( $file_path ) : 0;
|
||||
}
|
||||
|
||||
if ( $human_format ) {
|
||||
return imagify_size_format( (int) $size, $decimals );
|
||||
}
|
||||
|
||||
return (int) $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optimized file size.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param bool $human_format True to display the image human format size (1Mb).
|
||||
* @param int $decimals Precision of number of decimal places.
|
||||
* @return string|int
|
||||
*/
|
||||
public function get_optimized_size( $human_format = true, $decimals = 2 ) {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return $human_format ? imagify_size_format( 0, $decimals ) : 0;
|
||||
}
|
||||
|
||||
$row = $this->get_row();
|
||||
|
||||
if ( ! empty( $row['optimized_size'] ) ) {
|
||||
$size = $row['optimized_size'];
|
||||
} else {
|
||||
$file_path = $this->get_original_path();
|
||||
$file_path = $file_path && $this->filesystem->exists( $file_path ) ? $file_path : false;
|
||||
$size = $file_path ? $this->filesystem->size( $file_path ) : 0;
|
||||
}
|
||||
|
||||
if ( $human_format ) {
|
||||
return imagify_size_format( (int) $size, $decimals );
|
||||
}
|
||||
|
||||
return (int) $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optimized attachment size.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return float A 2-decimals float.
|
||||
*/
|
||||
public function get_saving_percent() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return round( (float) 0, 2 );
|
||||
}
|
||||
|
||||
$row = $this->get_row();
|
||||
|
||||
if ( ! empty( $row['percent'] ) ) {
|
||||
return $row['percent'] / 100;
|
||||
}
|
||||
|
||||
$original_size = $this->get_original_size( false );
|
||||
|
||||
if ( ! $original_size ) {
|
||||
return round( (float) 0, 2 );
|
||||
}
|
||||
|
||||
$optimized_size = $this->get_optimized_size( false );
|
||||
|
||||
if ( ! $optimized_size ) {
|
||||
return round( (float) 0, 2 );
|
||||
}
|
||||
|
||||
return round( ( $original_size - $optimized_size ) / $original_size * 100, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the overall optimized size (all thumbnails).
|
||||
* And since we don't have thumbnails...
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return float A 2-decimals float.
|
||||
*/
|
||||
public function get_overall_saving_percent() {
|
||||
return $this->get_saving_percent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the statistics of the file.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param string $size The thumbnail slug. Not used here.
|
||||
* @param string $key The specific data slug.
|
||||
* @return array|string
|
||||
*/
|
||||
public function get_size_data( $size = null, $key = null ) {
|
||||
if ( ! isset( $key ) ) {
|
||||
$key = $size;
|
||||
}
|
||||
|
||||
if ( ! $this->is_valid() ) {
|
||||
return isset( $key ) ? '' : array();
|
||||
}
|
||||
|
||||
$data = imagify_merge_intersect( $this->get_row(), array(
|
||||
'original_size' => 0,
|
||||
'optimized_size' => false,
|
||||
'percent' => 0,
|
||||
'status' => false,
|
||||
'error' => false,
|
||||
) );
|
||||
|
||||
$data['success'] = 'success' === $data['status'];
|
||||
|
||||
if ( $data['status'] ) {
|
||||
unset( $data['status'], $data['error'] );
|
||||
|
||||
if ( empty( $data['percent'] ) && $data['original_size'] && $data['optimized_size'] ) {
|
||||
$data['percent'] = round( ( $data['original_size'] - $data['optimized_size'] ) / $data['original_size'] * 100, 2 );
|
||||
} elseif ( ! empty( $data['percent'] ) ) {
|
||||
$data['percent'] = $data['percent'] / 100;
|
||||
}
|
||||
} else {
|
||||
unset( $data['status'], $data['original_size'], $data['optimized_size'], $data['percent'] );
|
||||
}
|
||||
|
||||
if ( isset( $key ) ) {
|
||||
return isset( $data[ $key ] ) ? $data[ $key ] : '';
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the global statistics data or a specific one.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param string $key The specific data slug.
|
||||
* @return array|string
|
||||
*/
|
||||
public function get_stats_data( $key = null ) {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return isset( $key ) ? '' : array();
|
||||
}
|
||||
|
||||
$stats = $this->get_size_data( $key );
|
||||
$default = array(
|
||||
'original_size' => 0,
|
||||
'optimized_size' => 0,
|
||||
'percent' => 0,
|
||||
);
|
||||
|
||||
return imagify_merge_intersect( $stats, $default );
|
||||
}
|
||||
|
||||
/**
|
||||
* Since these files are not resized, this method is not needed.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function update_metadata_size() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unoptimized sizes for a specific attachment.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_unoptimized_sizes() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default values used to reset Imagify data.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
public function get_reset_imagify_data() {
|
||||
static $column_defaults;
|
||||
|
||||
if ( ! isset( $column_defaults ) ) {
|
||||
$column_defaults = $this->get_row_db_instance()->get_column_defaults();
|
||||
|
||||
// All DB columns that have `null` as default value, are Imagify data.
|
||||
foreach ( $column_defaults as $column_name => $value ) {
|
||||
if ( 'hash' === $column_name || 'modified' === $column_name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $value ) ) {
|
||||
unset( $column_defaults[ $column_name ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$imagify_columns = $column_defaults;
|
||||
|
||||
// Also set the new file hash.
|
||||
$file_path = $this->get_original_path();
|
||||
|
||||
if ( $file_path && $this->filesystem->exists( $file_path ) ) {
|
||||
$imagify_columns['hash'] = md5_file( $file_path );
|
||||
}
|
||||
|
||||
return $imagify_columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills statistics data with values from $data array.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $data The statistics data.
|
||||
* @param object $response The API response.
|
||||
* @param string $size The attachment size key. Not used here.
|
||||
* @return bool|array False if the original size has an error or an array contains the data for other result.
|
||||
*/
|
||||
public function fill_data( $data, $response, $size = null ) {
|
||||
$data = is_array( $data ) ? $data : array();
|
||||
$data = imagify_merge_intersect( $data, $this->get_reset_imagify_data() );
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
// Error or already optimized.
|
||||
$data['error'] = $response->get_error_message();
|
||||
|
||||
if ( false !== strpos( $data['error'], 'This image is already compressed' ) ) {
|
||||
$data['status'] = 'already_optimized';
|
||||
} else {
|
||||
$data['status'] = 'error';
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
// Success.
|
||||
$old_data = $this->get_data();
|
||||
$original_size = $old_data['original_size'];
|
||||
$data['percent'] = 0;
|
||||
$data['status'] = 'success';
|
||||
|
||||
if ( ! empty( $response->original_size ) && ! $original_size ) {
|
||||
$data['original_size'] = (int) $response->original_size;
|
||||
$original_size = $data['original_size'];
|
||||
}
|
||||
|
||||
if ( ! empty( $response->new_size ) ) {
|
||||
$data['optimized_size'] = (int) $response->new_size;
|
||||
} else {
|
||||
$file_path = $this->get_original_path();
|
||||
$file_path = $file_path && $this->filesystem->exists( $file_path ) ? $file_path : false;
|
||||
|
||||
$data['optimized_size'] = $file_path ? $this->filesystem->size( $file_path ) : 0;
|
||||
}
|
||||
|
||||
if ( $original_size && $data['optimized_size'] ) {
|
||||
$data['percent'] = round( ( $original_size - $data['optimized_size'] ) / $original_size * 10000 );
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimize the file with Imagify.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $optimization_level The optimization level (2=ultra, 1=aggressive, 0=normal).
|
||||
* @param array $metadata The attachment meta data. Not used here.
|
||||
* @return bool|object True on success (status success or already_optimized). A WP_Error object on failure.
|
||||
*/
|
||||
public function optimize( $optimization_level = null, $metadata = null ) {
|
||||
// Check if the file extension is allowed.
|
||||
if ( ! $this->is_extension_supported() ) {
|
||||
return new WP_Error( 'mime_type_not_supported', __( 'This type of file is not supported.', 'imagify' ) );
|
||||
}
|
||||
|
||||
$optimization_level = is_numeric( $optimization_level ) ? (int) $optimization_level : get_imagify_option( 'optimization_level' );
|
||||
|
||||
// Check if the image is already optimized.
|
||||
if ( $this->is_optimized() && ( $this->get_optimization_level() === $optimization_level ) ) {
|
||||
return new WP_Error( 'same_optimization_level', __( 'This file is already optimized with this level.', 'imagify' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires before optimizing a file.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $id The file ID.
|
||||
*/
|
||||
do_action( 'before_imagify_optimize_file', $this->id );
|
||||
|
||||
$this->set_running_status();
|
||||
|
||||
// Optimize the image.
|
||||
$response = do_imagify( $this->get_original_path(), array(
|
||||
'optimization_level' => $optimization_level,
|
||||
'context' => 'File',
|
||||
'original_size' => $this->get_original_size( false ),
|
||||
'backup_path' => $this->get_raw_backup_path(),
|
||||
) );
|
||||
|
||||
// Fill the data.
|
||||
$data = $this->fill_data( array(
|
||||
'optimization_level' => $optimization_level,
|
||||
), $response );
|
||||
|
||||
// Save the data.
|
||||
$this->update_row( $data );
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
$this->delete_running_status();
|
||||
|
||||
if ( 'error' === $data['status'] ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
// Already optimized.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires after optimizing an attachment.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $id The attachment ID.
|
||||
* @param array $optimized_data The optimization data.
|
||||
*/
|
||||
do_action( 'after_imagify_optimize_file', $this->id, $this->get_data() );
|
||||
|
||||
$this->delete_running_status();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an attachment restoration from the backup file.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return bool|object True on success (status success or already_optimized). A WP_Error object on failure.
|
||||
*/
|
||||
public function restore() {
|
||||
// Check if the file extension is allowed.
|
||||
if ( ! $this->is_extension_supported() ) {
|
||||
return new WP_Error( 'mime_type_not_supported', __( 'This type of file is not supported.', 'imagify' ) );
|
||||
}
|
||||
|
||||
$backup_path = $this->get_backup_path();
|
||||
|
||||
// Stop the process if there is no backup file to restore.
|
||||
if ( ! $backup_path ) {
|
||||
return new WP_Error( 'source_doesnt_exist', __( 'The backup file does not exist.', 'imagify' ) );
|
||||
}
|
||||
|
||||
$file_path = $this->get_original_path();
|
||||
|
||||
if ( ! $file_path ) {
|
||||
return new WP_Error( 'empty_path', __( 'The file path is empty.', 'imagify' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires before restoring a file.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $id The file ID.
|
||||
*/
|
||||
do_action( 'before_imagify_restore_file', $this->id );
|
||||
|
||||
// Create the original image from the backup.
|
||||
$this->filesystem->copy( $backup_path, $file_path, true );
|
||||
$this->filesystem->chmod_file( $file_path );
|
||||
|
||||
// Remove old optimization data.
|
||||
$this->delete_imagify_data();
|
||||
|
||||
/**
|
||||
* Fires after restoring a file.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $id The file ID.
|
||||
*/
|
||||
do_action( 'after_imagify_restore_file', $this->id );
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** DB ROW ================================================================================== */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Invalidate the row.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @access public
|
||||
*
|
||||
* @return array The row
|
||||
*/
|
||||
public function invalidate_row() {
|
||||
// Since the ID doesn't exist in any other table (not a Post ID, not a NGG gallery ID), it must be reset.
|
||||
$this->id = 0;
|
||||
$this->row = array();
|
||||
return $this->row;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Class that handles background processing of thumbnails dynamically generated.
|
||||
*
|
||||
* @since 1.8
|
||||
* @since 1.9 Deprecated
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
class Imagify_NGG_Dynamic_Thumbnails_Background_Process extends Imagify_Abstract_Background_Process {
|
||||
|
||||
/**
|
||||
* Class version.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.8
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
const VERSION = '1.1';
|
||||
|
||||
/**
|
||||
* Action.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.8
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
protected $action = 'ngg_dynamic_thumbnails';
|
||||
|
||||
/**
|
||||
* The single instance of the class.
|
||||
*
|
||||
* @var object
|
||||
* @since 1.8
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
protected static $_instance;
|
||||
|
||||
|
||||
/**
|
||||
* Get the main Instance.
|
||||
*
|
||||
* @since 1.8
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return object Main instance.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! isset( self::$_instance ) ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate new background process.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
public function __construct() {
|
||||
imagify_deprecated_class( get_class( $this ), '1.9', '\\Imagify\\ThirdParty\\NGG\\DynamicThumbnails()' );
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** BACKGROUND PROCESS ====================================================================== */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Push to queue.
|
||||
*
|
||||
* @since 1.8
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $data {
|
||||
* The data to push in queue.
|
||||
*
|
||||
* @type int $id The image ID. Required.
|
||||
* @type string $size The thumbnail size. Required.
|
||||
* }
|
||||
* @return object Class instance.
|
||||
*/
|
||||
public function push_to_queue( $data ) {
|
||||
$key = $data['id'] . '|' . $data['size'];
|
||||
|
||||
$this->data[ $key ] = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch.
|
||||
*
|
||||
* @since 1.8
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function dispatch() {
|
||||
if ( ! empty( $this->data ) ) {
|
||||
return parent::dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell if a task is already in the queue.
|
||||
*
|
||||
* @since 1.8
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $data {
|
||||
* The data to test against the queue.
|
||||
*
|
||||
* @type int $id The image ID. Required.
|
||||
* @type string $size The thumbnail size. Required.
|
||||
* }
|
||||
* @return bool
|
||||
*/
|
||||
public function is_in_queue( $data ) {
|
||||
$key = $data['id'] . '|' . $data['size'];
|
||||
|
||||
return isset( $this->data[ $key ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Task: optimize the thumbnail.
|
||||
*
|
||||
* @since 1.8
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $item {
|
||||
* The data to test against the queue.
|
||||
*
|
||||
* @type int $id The image ID. Required.
|
||||
* @type string $size The thumbnail size. Required.
|
||||
* }
|
||||
* @return bool False to remove the item from the queue.
|
||||
*/
|
||||
protected function task( $item ) {
|
||||
$attachment_id = absint( $item['id'] );
|
||||
$size = sanitize_text_field( $item['size'] );
|
||||
|
||||
if ( ! $attachment_id || ! $size ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$attachment = get_imagify_attachment( 'NGG', $attachment_id, 'ngg_optimize_dynamic_thumbnail' );
|
||||
|
||||
$attachment->optimize_new_thumbnail( $size );
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Class for deprecated methods from Imagify_Notices.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
class Imagify_Notices_Deprecated {
|
||||
|
||||
/**
|
||||
* Include the view file.
|
||||
*
|
||||
* @since 1.6.10 In Imagify_Notices
|
||||
* @since 1.7 Deprecated
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $view The view ID.
|
||||
* @param mixed $data Some data to pass to the view.
|
||||
*/
|
||||
public function render_view( $view, $data = array() ) {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.7', 'Imagify_Views::get_instance()->print_template( \'notice-\' . $view, $data )' );
|
||||
|
||||
Imagify_Views::get_instance()->print_template( 'notice-' . $view, $data );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Deprecated class that handles compatibility with Regenerate Thumbnails plugin.
|
||||
*
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
class Imagify_Regenerate_Thumbnails_Deprecated {
|
||||
|
||||
/**
|
||||
* Action used for the ajax callback.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.7.1
|
||||
* @since 1.9 Deprecated.
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
const ACTION = 'imagify_regenerate_thumbnails';
|
||||
|
||||
/**
|
||||
* List of the attachments to regenerate.
|
||||
*
|
||||
* @var array An array of Imagify attachments. The array keys are the attachment IDs.
|
||||
* @since 1.7.1
|
||||
* @since 1.9 Deprecated.
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
protected $attachments = [];
|
||||
|
||||
/**
|
||||
* Optimize the newly regenerated thumbnails.
|
||||
*
|
||||
* @since 1.7.1
|
||||
* @since 1.9 Deprecated.
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*/
|
||||
public function regenerate_thumbnails_callback() {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9' );
|
||||
|
||||
if ( empty( $_POST['_ajax_nonce'] ) || empty( $_POST['attachment_id'] ) || empty( $_POST['context'] ) ) { // WPCS: CSRF ok.
|
||||
imagify_die( __( 'Invalid request', 'imagify' ) );
|
||||
}
|
||||
|
||||
if ( empty( $_POST['sizes'] ) || ! is_array( $_POST['sizes'] ) ) { // WPCS: CSRF ok.
|
||||
imagify_die( __( 'No thumbnail sizes selected', 'imagify' ) );
|
||||
}
|
||||
|
||||
$attachment_id = absint( $_POST['attachment_id'] );
|
||||
$context = imagify_sanitize_context( $_POST['context'] ); // WPCS: CSRF ok.
|
||||
|
||||
imagify_check_nonce( static::get_nonce_name( $attachment_id, $context ) );
|
||||
imagify_check_user_capacity( 'manual-optimize', $attachment_id );
|
||||
|
||||
$attachment = get_imagify_attachment( $context, $attachment_id, static::ACTION );
|
||||
|
||||
if ( ! $attachment->is_valid() || ! $attachment->is_image() ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
// Optimize.
|
||||
$attachment->reoptimize_thumbnails( wp_unslash( $_POST['sizes'] ) );
|
||||
|
||||
// Put the optimized original file back.
|
||||
$this->put_optimized_file_back( $attachment_id );
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Imagify attachment.
|
||||
*
|
||||
* @since 1.7.1
|
||||
* @since 1.9 Deprecated.
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*
|
||||
* @param int $attachment_id Attachment ID.
|
||||
* @return object|false An Imagify attachment object. False on failure.
|
||||
*/
|
||||
protected function set_attachment( $attachment_id ) {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9', '\\Imagify\\ThirdParty\\RegenerateThumbnails\\Main::get_instance()->set_process()' );
|
||||
|
||||
if ( ! $attachment_id || ! Imagify_Requirements::is_api_key_valid() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$attachment = get_imagify_attachment( 'wp', $attachment_id, 'regenerate_thumbnails' );
|
||||
|
||||
if ( ! $attachment->is_valid() || ! $attachment->is_image() || ! $attachment->is_optimized() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This attachment can be optimized.
|
||||
$this->attachments[ $attachment_id ] = $attachment;
|
||||
return $this->attachments[ $attachment_id ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the Imagify attachment.
|
||||
*
|
||||
* @since 1.7.1
|
||||
* @since 1.9 Deprecated.
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*
|
||||
* @param int $attachment_id Attachment ID.
|
||||
*/
|
||||
protected function unset_attachment( $attachment_id ) {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9', '\\Imagify\\ThirdParty\\RegenerateThumbnails\\Main::get_instance()->unset_process()' );
|
||||
|
||||
unset( $this->attachments[ $attachment_id ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Imagify attachment.
|
||||
*
|
||||
* @since 1.7.1
|
||||
* @since 1.9 Deprecated.
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*
|
||||
* @param int $attachment_id Attachment ID.
|
||||
* @return object|false An Imagify attachment object. False on failure.
|
||||
*/
|
||||
protected function get_attachment( $attachment_id ) {
|
||||
_deprecated_function( get_class( $this ) . '::' . __FUNCTION__ . '()', '1.9', '\\Imagify\\ThirdParty\\RegenerateThumbnails\\Main::get_instance()->get_process()' );
|
||||
|
||||
return ! empty( $this->attachments[ $attachment_id ] ) ? $this->attachments[ $attachment_id ] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the nonce used for the ajax callback.
|
||||
*
|
||||
* @since 1.7.1
|
||||
* @since 1.9 Deprecated.
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
* @deprecated
|
||||
*
|
||||
* @param int $media_id The media ID.
|
||||
* @param string $context The context.
|
||||
* @return string
|
||||
*/
|
||||
public static function get_nonce_name( $media_id, $context ) {
|
||||
_deprecated_function( get_called_class() . '::' . __FUNCTION__ . '()', '1.9' );
|
||||
|
||||
return static::ACTION . '-' . $media_id . '-' . $context;
|
||||
}
|
||||
}
|
||||
265
wp/plugins/imagify/inc/deprecated/classes/class-imagify-user.php
Normal file
265
wp/plugins/imagify/inc/deprecated/classes/class-imagify-user.php
Normal file
@@ -0,0 +1,265 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Deprecated class that handles Imagify User class.
|
||||
*
|
||||
* @since 1.0
|
||||
* @deprecated
|
||||
*/
|
||||
class Imagify_User {
|
||||
/**
|
||||
* The Imagify user ID.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* The user email.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $email;
|
||||
|
||||
/**
|
||||
* The plan ID.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $plan_id;
|
||||
|
||||
/**
|
||||
* The plan label.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $plan_label;
|
||||
|
||||
/**
|
||||
* The total quota.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $quota;
|
||||
|
||||
/**
|
||||
* The total extra quota (Imagify Pack).
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $extra_quota;
|
||||
|
||||
/**
|
||||
* The extra quota consumed.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $extra_quota_consumed;
|
||||
|
||||
/**
|
||||
* The current month consumed quota.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $consumed_current_month_quota;
|
||||
|
||||
/**
|
||||
* The next month date to credit the account.
|
||||
*
|
||||
* @since 1.1.1
|
||||
*
|
||||
* @var Date
|
||||
*/
|
||||
public $next_date_update;
|
||||
|
||||
/**
|
||||
* If the account is activate or not.
|
||||
*
|
||||
* @since 1.0.1
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $is_active;
|
||||
|
||||
/**
|
||||
* Store a \WP_Error object if the request to fetch the user data failed.
|
||||
* False overwise.
|
||||
*
|
||||
* @var bool|\WP_Error
|
||||
* @since 1.9.9
|
||||
*/
|
||||
private $error;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct() {
|
||||
$user = get_imagify_user();
|
||||
|
||||
if ( is_wp_error( $user ) ) {
|
||||
$this->error = $user;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->id = $user->id;
|
||||
$this->email = $user->email;
|
||||
$this->plan_id = (int) $user->plan_id;
|
||||
$this->plan_label = ucfirst( $user->plan_label );
|
||||
$this->quota = $user->quota;
|
||||
$this->extra_quota = $user->extra_quota;
|
||||
$this->extra_quota_consumed = $user->extra_quota_consumed;
|
||||
$this->consumed_current_month_quota = $user->consumed_current_month_quota;
|
||||
$this->next_date_update = $user->next_date_update;
|
||||
$this->is_active = $user->is_active;
|
||||
$this->error = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the possible error returned when fetching user data.
|
||||
*
|
||||
* @since 1.9.9
|
||||
*
|
||||
* @return bool|\WP_Error A \WP_Error object if the request to fetch the user data failed. False overwise.
|
||||
*/
|
||||
public function get_error() {
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Percentage of consumed quota, including extra quota.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
public function get_percent_consumed_quota() {
|
||||
static $done = false;
|
||||
if ( $this->get_error() ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$quota = $this->quota;
|
||||
$consumed_quota = $this->consumed_current_month_quota;
|
||||
|
||||
if ( imagify_round_half_five( $this->extra_quota_consumed ) < $this->extra_quota ) {
|
||||
$quota += $this->extra_quota;
|
||||
$consumed_quota += $this->extra_quota_consumed;
|
||||
}
|
||||
|
||||
if ( ! $quota || ! $consumed_quota ) {
|
||||
$percent = 0;
|
||||
} else {
|
||||
$percent = 100 * $consumed_quota / $quota;
|
||||
$percent = round( $percent, 1 );
|
||||
$percent = min( max( 0, $percent ), 100 );
|
||||
}
|
||||
|
||||
$percent = (float) $percent;
|
||||
|
||||
$percent = 100;
|
||||
|
||||
if ( $done ) {
|
||||
return $percent;
|
||||
}
|
||||
|
||||
$previous_percent = Imagify_Data::get_instance()->get( 'previous_quota_percent' );
|
||||
|
||||
|
||||
// Percent is not 100% anymore.
|
||||
if ( 100.0 === (float) $previous_percent && $percent < 100 ) {
|
||||
/**
|
||||
* Triggered when the consumed quota percent decreases below 100%.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param float|int $percent The current percentage of consumed quota.
|
||||
*/
|
||||
do_action( 'imagify_not_over_quota_anymore', $percent );
|
||||
}
|
||||
|
||||
// Percent is not >= 80% anymore.
|
||||
if ( (float) $previous_percent >= 80.0 && $percent < 80 ) {
|
||||
/**
|
||||
* Triggered when the consumed quota percent decreases below 80%.
|
||||
*
|
||||
* @since 1.7
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param float|int $percent The current percentage of consumed quota.
|
||||
* @param float|int $previous_percent The previous percentage of consumed quota.
|
||||
*/
|
||||
do_action( 'imagify_not_almost_over_quota_anymore', $percent, $previous_percent );
|
||||
}
|
||||
|
||||
if ( (float) $previous_percent !== (float) $percent ) {
|
||||
Imagify_Data::get_instance()->set( 'previous_quota_percent', $percent );
|
||||
}
|
||||
|
||||
$done = true;
|
||||
|
||||
return $percent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count percent of unconsumed quota.
|
||||
*
|
||||
* @since 1.0
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
public function get_percent_unconsumed_quota() {
|
||||
return 100 - $this->get_percent_consumed_quota();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has a free account.
|
||||
*
|
||||
* @since 1.1.1
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_free() {
|
||||
return 1 === $this->plan_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has consumed all his/her quota.
|
||||
*
|
||||
* @since 1.1.1
|
||||
* @since 1.9.9 Return false if the request to fetch the user data failed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_over_quota() {
|
||||
if ( $this->get_error() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
$this->is_free()
|
||||
&&
|
||||
floatval( 100 ) === round( $this->get_percent_consumed_quota() )
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user