PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 4.6.1
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v4.6.1
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
wp-optimize / webp / class-wpo-webp-task-manager.php

class-wpo-webp-task-manager.php in WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance 4.6.1, at webp/class-wpo-webp-task-manager.php

219 lines 5.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) die('Access denied.');
4
5 if (!class_exists('Updraft_Task_Manager_1_4')) require_once(WPO_PLUGIN_MAIN_PATH . 'vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-manager.php');
6
7 if (!class_exists('WPO_Webp_Task_Manager')) :
8
9 class WPO_Webp_Task_Manager extends Updraft_Task_Manager_1_4 {
10
11 /**
12 * Maximum number of images to collect per batch.
13 */
14 const BATCH_SIZE = 50;
15
16 /**
17 * Logs a message using the WebP optimization instance.
18 *
19 * @param string $message The message to log.
20 * @param string $error_type Optional. The type of error. Default 'info'.
21 * @return void
22 */
23 public function log($message, $error_type = 'info'): void {
24 $webp_instance = WP_Optimize()->get_webp_instance();
25 $webp_instance->log($message, $error_type);
26 }
27
28 /**
29 * Ensures singleton instance
30 */
31 private function __construct() {
32 parent::__construct();
33 }
34
35 /**
36 * Instance of WP_Optimize_Webp_Task_Manager.
37 *
38 * @return self
39 */
40 public static function get_instance(): self {
41 static $_instance = null;
42 if (null === $_instance) {
43 $_instance = new self();
44 }
45 return $_instance;
46 }
47
48 /**
49 * Convert already compressed images to webp format
50 *
51 * @return void
52 */
53 public function webp_convert_compressed_images(): void {
54 $task_type = 'webp-convert-compressed-images-task';
55
56 $creating_tasks_semaphore = new Updraft_Semaphore_3_0('wpo_' . $task_type);
57 $lock = $creating_tasks_semaphore->lock();
58 if (!$lock) return;
59
60 if (is_multisite()) {
61 $sites = WP_Optimize()->get_sites();
62 foreach ($sites as $site) {
63 $blog_id = $site->blog_id;
64 switch_to_blog($blog_id);
65 $this->create_webp_convert_compressed_image_task($task_type, $blog_id);
66 restore_current_blog();
67 }
68 } else {
69 $this->create_webp_convert_compressed_image_task($task_type, 1);
70 }
71
72 $creating_tasks_semaphore->release();
73
74 $this->process_queue($task_type);
75 }
76
77 /**
78 * Creates tasks for converting compressed images to WebP format
79 *
80 * @param string $task_type The type identifier for the conversion task
81 * @param int $blog_id The ID of the blog/site where the images should be converted
82 *
83 * @return void
84 */
85 private function create_webp_convert_compressed_image_task(string $task_type, int $blog_id) {
86 $this->clean_up_old_tasks($task_type);
87 $images = $this->get_compressed_images_to_convert();
88 $images = $this->exclude_gifs($images);
89 foreach ($images as $image) {
90 $description = sprintf(
91 'Webp Conversion of Compressed Image with ID - %d, Blog ID : %d',
92 $image['post_id'],
93 $blog_id
94 );
95 $options = array(
96 'attachment_id' => $image['post_id'],
97 'blog_id' => $blog_id,
98 'attachment_source' => $image['source'],
99 'anonymous_user_allowed' => wp_doing_cron() || (defined('WP_CLI') && WP_CLI)
100 );
101 WPO_Webp_Convert_Image_Task::create_task($task_type, $description, $options);
102 }
103 }
104
105 /**
106 * Get compressed images to convert
107 *
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
111 */
112 private function get_compressed_images_to_convert(): array {
113 $args = array(
114 'meta_query' => $this->get_compressed_images_meta_query(),
115 'post_type' => 'attachment',
116 'numberposts' => self::BATCH_SIZE,
117 );
118
119 $page = 1;
120 $collected_count = 0;
121 $filtered_post_ids = array();
122
123 while ($collected_count < self::BATCH_SIZE) {
124 $args['paged'] = $page;
125 $query = get_posts($args);
126
127 if (empty($query)) {
128 break;
129 }
130
131 foreach ($query as $post) {
132 if ($collected_count >= self::BATCH_SIZE) {
133 break 2;
134 }
135
136 $source = get_attached_file($post->ID);
137 if (false === $source) {
138 continue;
139 }
140
141 $destination = WPO_WebP_Utils::get_destination_path($source);
142 if (file_exists($destination)) {
143 $this->backfill_webp_conversion_meta($post->ID);
144 continue;
145 }
146
147 $filtered_post_ids[] = array(
148 'post_id' => $post->ID,
149 'source' => $source
150 );
151 $collected_count++;
152 }
153 $page++;
154 }
155
156 return $filtered_post_ids;
157 }
158
159 /**
160 * Backfill the webp conversion meta for attachments that already have
161 * a WebP file present at the destination path.
162 *
163 * @param int $post_id The attachment post ID.
164 * @return void
165 */
166 private function backfill_webp_conversion_meta($post_id): void {
167 update_post_meta($post_id, '_wpo-webp-conversion-complete', true);
168 }
169
170 /**
171 * Meta query array for getting compressed images not yet converted to WebP
172 *
173 * @return array<int|string, array<int|string, array<string, string>|string>|string>
174 */
175 private function get_compressed_images_meta_query(): array {
176 return array(
177 'relation' => 'AND',
178 array(
179 'key' => '_wpo-smush-complete',
180 'compare' => '=',
181 'value' => '1',
182 ),
183 array(
184 'relation' => 'OR',
185 array(
186 'key' => '_wpo-webp-conversion-complete',
187 'compare' => 'NOT EXISTS',
188 'value' => '',
189 ),
190 array(
191 'key' => '_wpo-webp-conversion-complete',
192 'compare' => '!=',
193 'value' => '1',
194 )
195 )
196 );
197 }
198
199 /**
200 * Exclude GIF files from the array
201 *
202 * @param array<array<string, int|string>> $images An array of arrays containing:
203 * 'post_id' (int) The ID of the attachment post
204 * 'source' (string) The file path of the attachment
205 *
206 * @return array<array<string, int|string>>
207 */
208 private function exclude_gifs(array $images): array {
209 $allowed_extensions = array_diff(WPO_Image_Utils::get_allowed_extensions(), array('gif'));
210 return array_values(array_filter($images, function($image) use ($allowed_extensions) {
211 /** @var string $source */
212 $source = $image['source'];
213 $ext = WPO_Image_Utils::get_extension($source);
214 return in_array($ext, $allowed_extensions, true);
215 }));
216 }
217 }
218 endif;
219