Files
2024-09-25 09:25:31 -04:00

851 lines
26 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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 );
}
}