Skip to content

Commit

Permalink
Avif bulk
Browse files Browse the repository at this point in the history
  • Loading branch information
Miraeld committed Jan 12, 2024
1 parent cbd688b commit ffcbe66
Show file tree
Hide file tree
Showing 18 changed files with 501 additions and 228 deletions.
62 changes: 60 additions & 2 deletions classes/Avif/Avif.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?php
namespace Imagify\Avif;

use Imagify\Notices\Notices;
use Imagify\Traits\InstanceGetterTrait;

/**
Expand All @@ -19,7 +18,66 @@ public function init() {
add_action( 'update_option_imagify_settings', [ $this, 'maybe_bulk_optimize_callback' ] );
}

/**
* Update Options callback to start bulk optimization.
*
* @return void
*/
public function maybe_bulk_optimize_callback() {
// start bulk optimization if option wasn't enabled.
$level = \Imagify_Options::get_instance()->get( 'optimization_level' );
$contexts = $this->get_contexts();
foreach ( $contexts as $context ) {
do_action( 'imagify_bulk_optimize', $context, $level );
}
}

/**
* Get the context for the bulk optimization page.
*
* @return array The array of unique contexts ('wp' or 'custom-folders').
*/
public function get_contexts() {
$contexts = [];
$types = [];

// Library: in each site.
if ( ! is_network_admin() ) {
$types['library|wp'] = 1;
}

// Custom folders: in network admin only if network activated, in each site otherwise.
if ( imagify_can_optimize_custom_folders() && ( imagify_is_active_for_network() && is_network_admin() || ! imagify_is_active_for_network() ) ) {
$types['custom-folders|custom-folders'] = 1;
}

/**
* Filter the types to display in the bulk optimization page.
*
* @since 1.7.1
* @author Grégory Viguier
*
* @param array $types The folder types displayed on the page. If a folder type is "library", the context should be suffixed after a pipe character. They are passed as array keys.
*/
$types = apply_filters( 'imagify_bulk_page_types', $types );
$types = array_filter( (array) $types );

if ( isset( $types['library|wp'] ) && ! in_array( 'wp', $contexts, true ) ) {
$contexts[] = 'wp';
}

if ( isset( $types['custom-folders|custom-folders'] ) ) {
$folders_instance = \Imagify_Folders_DB::get_instance();

if ( ! $folders_instance->has_items() ) {
// New Feature!
if ( ! in_array( 'wp', $contexts, true ) ) {
$contexts[] = 'wp';
}
} elseif ( $folders_instance->has_active_folders() && ! in_array( 'custom-folders', $contexts, true ) ) {
$contexts[] = 'custom-folders';
}
}

return $contexts;
}
}
33 changes: 22 additions & 11 deletions classes/Bulk/Bulk.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ class Bulk {
*/
public function init() {
add_action( 'imagify_optimize_media', [ $this, 'optimize_media' ], 10, 3 );
add_action( 'imagify_convert_webp', [ $this, 'generate_webp_versions' ], 10, 2 );
add_action( 'imagify_convert_avif', [ $this, 'generate_avif_versions' ], 10, 2 );
add_action( 'imagify_convert_webp', [ $this, 'generate_next_gen_versions' ], 10, 2 );
add_action( 'imagify_convert_avif', [ $this, 'generate_next_gen_versions' ], 10, 2 );
add_action( 'imagify_convert_webp_finished', [ $this, 'clear_webp_transients' ], 10, 2 );
add_action( 'wp_ajax_imagify_bulk_optimize', [ $this, 'bulk_optimize_callback' ] );
add_action( 'imagify_bulk_optimize', [ $this, 'bulk_optimize' ], 10, 2 );
add_action( 'wp_ajax_imagify_missing_webp_generation', [ $this, 'missing_webp_callback' ] );
add_action( 'wp_ajax_imagify_get_folder_type_data', [ $this, 'get_folder_type_data_callback' ] );
add_action( 'wp_ajax_imagify_bulk_info_seen', [ $this, 'bulk_info_seen_callback' ] );
Expand Down Expand Up @@ -311,13 +312,13 @@ private function get_bulk_class_name( string $context ): string {
}

/**
* Filter the name of the class to use for bulk process.
*
* @since 1.9
*
* @param int $class_name The class name.
* @param string $context The context name.
*/
* Filter the name of the class to use for bulk process.
*
* @since 1.9
*
* @param int $class_name The class name.
* @param string $context The context name.
*/
$class_name = apply_filters( 'imagify_bulk_class_name', $class_name, $context );

return '\\' . ltrim( $class_name, '\\' );
Expand Down Expand Up @@ -384,12 +385,12 @@ private function force_optimize( int $media_id, string $context, int $level ) {
*
* @return bool|WP_Error True if successfully launched. A \WP_Error instance on failure.
*/
public function generate_webp_versions( int $media_id, string $context ) {
public function generate_next_gen_versions( int $media_id, string $context ) {
if ( ! $this->can_optimize() ) {
return false;
}

return imagify_get_optimization_process( $media_id, $context )->generate_webp_versions();
return imagify_get_optimization_process( $media_id, $context )->generate_next_gen_versions();
}
/**
* Generate AVIF images if they are missing.
Expand Down Expand Up @@ -473,6 +474,16 @@ public function get_optimization_level( $method = 'GET', $parameter = 'optimizat
/** BULK OPTIMIZATION CALLBACKS ============================================================= */
/** ----------------------------------------------------------------------------------------- */

/**
* Launch the bulk optimization without going through AJAX.
*
* @param string $context Current context (WP/Custom folders).
* @param int $level Optimization level.
* @return void
*/
public function bulk_optimize( $context, $level ) {
$this->run_optimize( $context, $level );
}
/**
* Launch the bulk optimization action
*
Expand Down
2 changes: 1 addition & 1 deletion classes/Job/MediaOptimization.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ private function task_optimize( $item ) {

} elseif ( 'already_optimized' === $data['status'] ) {
// Status is "already_optimized", try to create WebP versions only.
$item['sizes'] = array_filter( $item['sizes'], [ $this->optimization_process, 'is_size_webp' ] );
$item['sizes'] = array_filter( $item['sizes'], [ $this->optimization_process, 'is_size_next_gen' ] );

} elseif ( 'success' !== $data['status'] ) {
// Don't go further if the full size has not the "success" status.
Expand Down
59 changes: 46 additions & 13 deletions classes/Optimization/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public function can_be_processed() {
return new \WP_Error(
'not_exists',
sprintf(
/* translators: %s is a file path. */
/* translators: %s is a file path. */
__( 'The file %s does not seem to exist.', 'imagify' ),
'<code>' . esc_html( $this->filesystem->make_path_relative( $this->path ) ) . '</code>'
)
Expand All @@ -124,7 +124,7 @@ public function can_be_processed() {
return new \WP_Error(
'not_a_file',
sprintf(
/* translators: %s is a file path. */
/* translators: %s is a file path. */
__( 'This does not seem to be a file: %s.', 'imagify' ),
'<code>' . esc_html( $this->filesystem->make_path_relative( $this->path ) ) . '</code>'
)
Expand All @@ -135,7 +135,7 @@ public function can_be_processed() {
return new \WP_Error(
'not_writable',
sprintf(
/* translators: %s is a file path. */
/* translators: %s is a file path. */
__( 'The file %s does not seem to be writable.', 'imagify' ),
'<code>' . esc_html( $this->filesystem->make_path_relative( $this->path ) ) . '</code>'
)
Expand All @@ -148,7 +148,7 @@ public function can_be_processed() {
return new \WP_Error(
'folder_not_writable',
sprintf(
/* translators: %s is a file path. */
/* translators: %s is a file path. */
__( 'The folder %s does not seem to be writable.', 'imagify' ),
'<code>' . esc_html( $this->filesystem->make_path_relative( $parent_folder ) ) . '</code>'
)
Expand Down Expand Up @@ -197,7 +197,7 @@ public function resize( $dimensions = [], $max_width = 0 ) {
return new \WP_Error(
'not_an_image',
sprintf(
/* translators: %s is a file path. */
/* translators: %s is a file path. */
__( 'The file %s does not seem to be an image, and cannot be resized.', 'imagify' ),
'<code>' . esc_html( $this->filesystem->make_path_relative( $this->path ) ) . '</code>'
)
Expand Down Expand Up @@ -321,7 +321,7 @@ public function create_thumbnail( $destination ) {
return new \WP_Error(
'not_an_image',
sprintf(
/* translators: %s is a file path. */
/* translators: %s is a file path. */
__( 'The file %s does not seem to be an image, and cannot be resized.', 'imagify' ),
'<code>' . esc_html( $this->filesystem->make_path_relative( $this->path ) ) . '</code>'
)
Expand Down Expand Up @@ -474,7 +474,7 @@ public function optimize( $args = [] ) {
*
* @param string $path Absolute path to the media file.
* @param array $args Arguments passed to the method.
*/
*/
do_action( 'imagify_before_optimize_file', $this->path, $args );

/**
Expand All @@ -485,7 +485,7 @@ public function optimize( $args = [] ) {
*
* @param string $path Absolute path to the image file.
* @param bool $backup True if a backup will be make.
*/
*/
do_action_deprecated( 'before_do_imagify', [ $this->path, $args['backup'] ], '1.9', 'imagify_before_optimize_file' );

if ( $args['backup'] ) {
Expand All @@ -509,6 +509,7 @@ public function optimize( $args = [] ) {

if ( $args['convert'] ) {
$data['convert'] = $args['convert'];
$format = $args['convert'];
}

$response = upload_imagify_image( [
Expand All @@ -534,8 +535,8 @@ public function optimize( $args = [] ) {
$args['convert'] = '';
}

if ( 'webp' === $args['convert'] ) {
$destination_path = $this->get_path_to_webp();
if ( 'webp' === $args['convert'] || 'avif' === $args['convert'] ) {
$destination_path = $this->get_path_to_next_gen( $args['convert'] );
$this->path = $destination_path;
$this->file_type = null;
$this->editor = null;
Expand All @@ -557,7 +558,7 @@ public function optimize( $args = [] ) {
*
* @param string $path Absolute path to the image file.
* @param bool $backup True if a backup has been made.
*/
*/
do_action_deprecated( 'after_do_imagify', [ $this->path, $args['backup'] ], '1.9', 'imagify_before_optimize_file' );

/**
Expand All @@ -568,7 +569,7 @@ public function optimize( $args = [] ) {
*
* @param string $path Absolute path to the media file.
* @param array $args Arguments passed to the method.
*/
*/
do_action( 'imagify_after_optimize_file', $this->path, $args );

return $response;
Expand Down Expand Up @@ -603,7 +604,7 @@ protected function get_editor() {
$this->editor = new \WP_Error(
'image_editor',
sprintf(
/* translators: %1$s is an error message, %2$s is a "More info?" link. */
/* translators: %1$s is an error message, %2$s is a "More info?" link. */
__( 'No php extensions are available to edit images on the server. ImageMagick or GD is required. The internal error is: %1$s. %2$s', 'imagify' ),
$this->editor->get_error_message(),
'<a href="' . esc_url( imagify_get_external_url( 'documentation-imagick-gd' ) ) . '" target="_blank">' . __( 'More info?', 'imagify' ) . '</a>'
Expand Down Expand Up @@ -765,6 +766,26 @@ public function get_path_to_webp() {
return imagify_path_to_webp( $this->path );
}

/**
* Replace the file extension by its next-gen format extension.
*
* @since 2.2
*
* @param string $format the format we are targeting.
* @return string|bool The file path on success. False if not an image or on failure.
*/
public function get_path_to_next_gen( string $format ) {
if ( ! $this->is_image() ) {
return false;
}

if ( $this->is_webp() || $this->is_avif() ) {
return false;
}

return imagify_path_to_next_gen( $this->path, $format );
}

/**
* Tell if the file is a WebP image.
* Rejects "path/to/.webp" files.
Expand All @@ -778,6 +799,18 @@ public function is_webp() {
return preg_match( '@(?!^|/|\\\)\.webp$@i', $this->path );
}

/**
* Tell if the file is an AVIF image.
* Rejects "path/to/.avif" files.
*
* @since 2.2
*
* @return bool
*/
public function is_avif() {
return preg_match( '@(?!^|/|\\\)\.avif$@i', $this->path );
}

/**
* Get the file mime type + file extension.
*
Expand Down
Loading

0 comments on commit ffcbe66

Please sign in to comment.