| @@ -8,11 +8,11 @@ | ||
| 8 | 8 | |
| 9 | 9 | class WPO_Webp_Task_Manager extends Updraft_Task_Manager_1_4 { |
| 10 | 10 | |
| 11 | 11 | /** |
| 12 | - * @var WPO_Webp_Task_Manager | |
| 12 | + * Maximum number of images to collect per batch. | |
| 13 | 13 | */ |
| 14 | - static protected $_instance = null; | |
| 14 | + const BATCH_SIZE = 50; | |
| 15 | 15 | |
| 16 | 16 | /** |
| 17 | 17 | * Logs a message using the WebP optimization instance. |
| 18 | 18 | * |
| @@ -17,31 +17,41 @@ | ||
| 17 | 17 | * Logs a message using the WebP optimization instance. |
| 18 | 18 | * |
| 19 | 19 | * @param string $message The message to log. |
| 20 | 20 | * @param string $error_type Optional. The type of error. Default 'info'. |
| 21 | + * @return void | |
| 21 | 22 | */ |
| 22 | - public function log($message, $error_type = 'info') { | |
| 23 | + public function log($message, $error_type = 'info'): void { | |
| 23 | 24 | $webp_instance = WP_Optimize()->get_webp_instance(); |
| 24 | 25 | $webp_instance->log($message, $error_type); |
| 25 | 26 | } |
| 26 | 27 | |
| 27 | 28 | /** |
| 29 | + * Ensures singleton instance | |
| 30 | + */ | |
| 31 | + private function __construct() { | |
| 32 | + parent::__construct(); | |
| 33 | + } | |
| 34 | + | |
| 35 | + /** | |
| 28 | 36 | * Instance of WP_Optimize_Webp_Task_Manager. |
| 29 | 37 | * |
| 30 | 38 | * @return self |
| 31 | 39 | */ |
| 32 | 40 | public static function get_instance(): self { |
| 33 | - if (empty(self::$_instance)) { | |
| 34 | - self::$_instance = new self(); | |
| 41 | + static $_instance = null; | |
| 42 | + if (null === $_instance) { | |
| 43 | + $_instance = new self(); | |
| 35 | 44 | } |
| 36 | - | |
| 37 | - return self::$_instance; | |
| 45 | + return $_instance; | |
| 38 | 46 | } |
| 39 | 47 | |
| 40 | 48 | /** |
| 41 | 49 | * Convert already compressed images to webp format |
| 50 | + * | |
| 51 | + * @return void | |
| 42 | 52 | */ |
| 43 | - public function webp_convert_compressed_images() { | |
| 53 | + public function webp_convert_compressed_images(): void { | |
| 44 | 54 | $task_type = 'webp-convert-compressed-images-task'; |
| 45 | 55 | |
| 46 | 56 | $creating_tasks_semaphore = new Updraft_Semaphore_3_0('wpo_' . $task_type); |
| 47 | 57 | $lock = $creating_tasks_semaphore->lock(); |
| @@ -74,16 +84,20 @@ | ||
| 74 | 84 | */ |
| 75 | 85 | private function create_webp_convert_compressed_image_task(string $task_type, int $blog_id) { |
| 76 | 86 | $this->clean_up_old_tasks($task_type); |
| 77 | 87 | $images = $this->get_compressed_images_to_convert(); |
| 88 | + $images = $this->exclude_gifs($images); | |
| 78 | 89 | foreach ($images as $image) { |
| 79 | - $blog_info = ', Blog ID : '. $blog_id; | |
| 80 | - $description = 'Webp Conversion of Compressed Image with ID - ' . $image['post_id'] . $blog_info; | |
| 90 | + $description = sprintf( | |
| 91 | + 'Webp Conversion of Compressed Image with ID - %d, Blog ID : %d', | |
| 92 | + $image['post_id'], | |
| 93 | + $blog_id | |
| 94 | + ); | |
| 81 | 95 | $options = array( |
| 82 | 96 | 'attachment_id' => $image['post_id'], |
| 83 | 97 | 'blog_id' => $blog_id, |
| 84 | 98 | 'attachment_source' => $image['source'], |
| 85 | - 'anonymous_user_allowed' => (defined('DOING_CRON') && DOING_CRON) || (defined('WP_CLI') && WP_CLI) | |
| 99 | + 'anonymous_user_allowed' => wp_doing_cron() || (defined('WP_CLI') && WP_CLI) | |
| 86 | 100 | ); |
| 87 | 101 | WPO_Webp_Convert_Image_Task::create_task($task_type, $description, $options); |
| 88 | 102 | } |
| 89 | 103 | } |
| @@ -90,36 +104,45 @@ | ||
| 90 | 104 | |
| 91 | 105 | /** |
| 92 | 106 | * Get compressed images to convert |
| 93 | 107 | * |
| 94 | - * @return array[] Array of arrays containing: | |
| 95 | - * 'post_id' (int) The ID of the attachment post | |
| 96 | - * 'source' (string) The file path of the attachment | |
| 108 | + * @return array<array<string, int|string>> Array of arrays containing | |
| 109 | + * 'post_id' (int) The ID of the attachment post, and | |
| 110 | + * 'source' (string) The file path of the attachment | |
| 97 | 111 | */ |
| 98 | 112 | private function get_compressed_images_to_convert(): array { |
| 99 | - $args = array( | |
| 113 | + $args = array( | |
| 100 | 114 | 'meta_query' => $this->get_compressed_images_meta_query(), |
| 101 | 115 | 'post_type' => 'attachment', |
| 102 | - 'numberposts' => 50, | |
| 116 | + 'numberposts' => self::BATCH_SIZE, | |
| 103 | 117 | ); |
| 104 | 118 | |
| 105 | 119 | $page = 1; |
| 106 | - $webp_converter = new WPO_WebP_Convert(); | |
| 107 | - $posts = 0; | |
| 108 | - $query_is_not_empty = true; | |
| 120 | + $collected_count = 0; | |
| 109 | 121 | $filtered_post_ids = array(); |
| 110 | - while ($posts < 50 && $query_is_not_empty) { | |
| 122 | + | |
| 123 | + while ($collected_count < self::BATCH_SIZE) { | |
| 111 | 124 | $args['paged'] = $page; |
| 112 | 125 | $query = get_posts($args); |
| 113 | - if (empty($query)) $query_is_not_empty = false; | |
| 114 | 126 | |
| 127 | + if (empty($query)) { | |
| 128 | + break; | |
| 129 | + } | |
| 130 | + | |
| 115 | 131 | foreach ($query as $post) { |
| 132 | + if ($collected_count >= self::BATCH_SIZE) { | |
| 133 | + break 2; | |
| 134 | + } | |
| 135 | + | |
| 116 | 136 | $source = get_attached_file($post->ID); |
| 117 | - if (false === $source) continue; | |
| 118 | - $destination = $webp_converter->get_destination_path($source); | |
| 137 | + if (false === $source) { | |
| 138 | + continue; | |
| 139 | + } | |
| 140 | + | |
| 141 | + $destination = WPO_WebP_Utils::get_destination_path($source); | |
| 119 | 142 | if (file_exists($destination)) { |
| 120 | 143 | // A way of backfilling already webp converted images |
| 121 | - update_post_meta($post->ID, 'wpo-webp-conversion-complete', true); | |
| 144 | + update_post_meta($post->ID, WPO_Webp_Convert_Image_Task::WEBP_CONVERSION_META_KEY, true); | |
| 122 | 145 | continue; |
| 123 | 146 | } |
| 124 | 147 | |
| 125 | 148 | $filtered_post_ids[] = array( |
| @@ -125,43 +148,61 @@ | ||
| 125 | 148 | $filtered_post_ids[] = array( |
| 126 | 149 | 'post_id' => $post->ID, |
| 127 | 150 | 'source' => $source |
| 128 | 151 | ); |
| 129 | - $posts++; | |
| 152 | + $collected_count++; | |
| 130 | 153 | } |
| 131 | 154 | $page++; |
| 132 | - }; | |
| 155 | + } | |
| 133 | 156 | |
| 134 | 157 | return $filtered_post_ids; |
| 135 | 158 | } |
| 136 | 159 | |
| 137 | 160 | /** |
| 138 | - * Meta query array for getting compressed images | |
| 161 | + * Meta query array for getting compressed images not yet converted to WebP | |
| 139 | 162 | * |
| 140 | - * @return array | |
| 163 | + * @return array<int|string, array<int|string, array<string, string>|string>|string> | |
| 141 | 164 | */ |
| 142 | 165 | private function get_compressed_images_meta_query(): array { |
| 143 | 166 | return array( |
| 144 | 167 | 'relation' => 'AND', |
| 145 | 168 | array( |
| 146 | - 'key' => 'smush-complete', | |
| 169 | + 'key' => '_wpo-smush-complete', | |
| 147 | 170 | 'compare' => '=', |
| 148 | 171 | 'value' => '1', |
| 149 | 172 | ), |
| 150 | - // Check if the image is not already converted to webp | |
| 151 | 173 | array( |
| 152 | 174 | 'relation' => 'OR', |
| 153 | 175 | array( |
| 154 | - 'key' => 'wpo-webp-conversion-complete', | |
| 176 | + 'key' => WPO_Webp_Convert_Image_Task::WEBP_CONVERSION_META_KEY, | |
| 155 | 177 | 'compare' => 'NOT EXISTS', |
| 156 | 178 | 'value' => '', |
| 157 | 179 | ), |
| 158 | 180 | array( |
| 159 | - 'key' => 'wpo-webp-conversion-complete', | |
| 181 | + 'key' => WPO_Webp_Convert_Image_Task::WEBP_CONVERSION_META_KEY, | |
| 160 | 182 | 'compare' => '!=', |
| 161 | 183 | 'value' => '1', |
| 162 | 184 | ) |
| 163 | - ), | |
| 185 | + ) | |
| 164 | 186 | ); |
| 187 | + } | |
| 188 | + | |
| 189 | + /** | |
| 190 | + * Exclude GIF files from the array | |
| 191 | + * | |
| 192 | + * @param array<array<string, int|string>> $images An array of arrays containing: | |
| 193 | + * 'post_id' (int) The ID of the attachment post | |
| 194 | + * 'source' (string) The file path of the attachment | |
| 195 | + * | |
| 196 | + * @return array<array<string, int|string>> | |
| 197 | + */ | |
| 198 | + private function exclude_gifs(array $images): array { | |
| 199 | + $allowed_extensions = array_diff(WPO_Image_Utils::get_allowed_extensions(), array('gif')); | |
| 200 | + return array_values(array_filter($images, function($image) use ($allowed_extensions) { | |
| 201 | + /** @var string $source */ | |
| 202 | + $source = $image['source']; | |
| 203 | + $ext = WPO_Image_Utils::get_extension($source); | |
| 204 | + return in_array($ext, $allowed_extensions, true); | |
| 205 | + })); | |
| 165 | 206 | } |
| 166 | 207 | } |
| 167 | 208 | endif; |