PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 2.3.1
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v2.3.1
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
imagify / inc / 3rd-party / nextgen-gallery / classes / Bulk / NGG.php

NGG.php in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF 2.3.1, at inc/3rd-party/nextgen-gallery/classes/Bulk/NGG.php

283 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Imagify\ThirdParty\NGG\Bulk;
3
4 use C_Gallery_Storage;
5 use Imagify\Bulk\AbstractBulk;
6 use Imagify\ThirdParty\NGG\DB;
7
8 /**
9 * Class to use for bulk for NextGen Gallery.
10 *
11 * @since 1.9
12 */
13 class NGG extends AbstractBulk {
14 /**
15 * Context "short name".
16 *
17 * @var string
18 * @since 1.9
19 */
20 protected $context = 'ngg';
21
22 /**
23 * Get all unoptimized media ids.
24 *
25 * @since 1.9
26 *
27 * @param int $optimization_level The optimization level.
28 * @return array A list of unoptimized media IDs.
29 */
30 public function get_unoptimized_media_ids( $optimization_level ) {
31 // @codeCoverageIgnoreStart — requires live NGG POPE classes and DB; not available in unit tests.
32 if ( ! imagify_ngg_has_pope_storage() || ! DB::get_instance()->can_operate() ) {
33 return [];
34 }
35 // @codeCoverageIgnoreEnd
36
37 global $wpdb;
38
39 $this->set_no_time_limit();
40
41 $storage = C_Gallery_Storage::get_instance();
42 $ngg_table = $wpdb->prefix . 'ngg_pictures';
43 $data = [];
44 $images = $wpdb->get_results(
45 $wpdb->prepare( // WPCS: unprepared SQL ok.
46 "
47 SELECT DISTINCT picture.pid as id, picture.filename, idata.optimization_level, idata.status, idata.data
48 FROM $ngg_table as picture
49 LEFT JOIN $wpdb->ngg_imagify_data as idata
50 ON picture.pid = idata.pid
51 WHERE idata.pid IS NULL
52 OR idata.optimization_level != %d
53 OR idata.status = 'error'
54 LIMIT %d",
55 $optimization_level,
56 imagify_get_unoptimized_attachment_limit()
57 ),
58 ARRAY_A
59 );
60
61 if ( ! $images ) {
62 return [];
63 }
64
65 foreach ( $images as $image ) {
66 $id = absint( $image['id'] );
67 $file_path = $storage->get_image_abspath( $id );
68
69 if ( ! $file_path || ! $this->filesystem->exists( $file_path ) ) {
70 continue;
71 }
72
73 $attachment_data = maybe_unserialize( $image['data'] );
74 $attachment_error = '';
75
76 if ( isset( $attachment_data['sizes']['full']['error'] ) ) {
77 $attachment_error = $attachment_data['sizes']['full']['error'];
78 }
79
80 $attachment_error = trim( $attachment_error );
81 $attachment_status = $image['status'];
82 $attachment_optimization_level = $image['optimization_level'];
83 $attachment_backup_path = get_imagify_ngg_attachment_backup_path( $file_path );
84
85 // Don't try to re-optimize if the optimization level is still the same.
86 if ( $optimization_level === $attachment_optimization_level && is_string( $attachment_error ) ) {
87 continue;
88 }
89
90 // Don't try to re-optimize if there is no backup file.
91 if ( 'success' === $attachment_status && $optimization_level !== $attachment_optimization_level && ! $this->filesystem->exists( $attachment_backup_path ) ) {
92 continue;
93 }
94
95 // Don't try to re-optimize images already compressed.
96 if ( 'already_optimized' === $attachment_status && $attachment_optimization_level >= $optimization_level ) {
97 continue;
98 }
99
100 // Don't try to re-optimize images with an empty error message.
101 if ( 'error' === $attachment_status && empty( $attachment_error ) ) {
102 continue;
103 }
104
105 $data[] = $id;
106 }
107
108 return $data;
109 }
110
111 /**
112 * Get all optimized media ids that can be restored.
113 *
114 * @since 2.3
115 *
116 * @return array A list of optimized media IDs with backup files available.
117 */
118 public function get_optimized_media_ids(): array {
119 return [];
120 }
121
122 /**
123 * Get ids of all optimized media without next-gen versions.
124 *
125 * @since 2.2
126 *
127 * @param string $format Format we are looking for. (webp|avif).
128 *
129 * @return array {
130 * @type array $ids A list of media IDs.
131 * @type array $errors {
132 * @type array $no_file_path A list of media IDs.
133 * @type array $no_backup A list of media IDs.
134 * }
135 * }
136 */
137 public function get_optimized_media_ids_without_format( $format ) {
138 // @codeCoverageIgnoreStart — requires live NGG POPE classes and DB; not available in unit tests.
139 if ( ! imagify_ngg_has_pope_storage() || ! DB::get_instance()->can_operate() ) {
140 return [
141 'ids' => [],
142 'errors' => [
143 'no_file_path' => [],
144 'no_backup' => [],
145 ],
146 ];
147 }
148 // @codeCoverageIgnoreEnd
149
150 global $wpdb;
151
152 $this->set_no_time_limit();
153
154 $storage = C_Gallery_Storage::get_instance();
155 $ngg_table = $wpdb->prefix . 'ngg_pictures';
156 $data_table = DB::get_instance()->get_table_name();
157 $suffix = constant( imagify_get_optimization_process_class_name( 'ngg' ) . '::WEBP_SUFFIX' );
158
159 if ( 'avif' === get_imagify_option( 'optimization_format' ) ) {
160 $suffix = constant( imagify_get_optimization_process_class_name( 'ngg' ) . '::AVIF_SUFFIX' );
161 }
162
163 $files = $wpdb->get_col(
164 $wpdb->prepare( // WPCS: unprepared SQL ok.
165 "
166 SELECT ngg.pid
167 FROM $ngg_table as ngg
168 INNER JOIN $data_table AS data
169 ON ( ngg.pid = data.pid )
170 WHERE
171 ( data.status = 'success' OR data.status = 'already_optimized' )
172 AND data.data NOT LIKE %s
173 ORDER BY ngg.pid DESC",
174 '%' . $wpdb->esc_like( $suffix . '";a:4:{s:7:"success";b:1;' ) . '%'
175 )
176 );
177
178 $wpdb->flush();
179 unset( $ngg_table, $data_table, $suffix );
180
181 $data = [
182 'ids' => [],
183 'errors' => [
184 'no_file_path' => [],
185 'no_backup' => [],
186 ],
187 ];
188
189 if ( ! $files ) {
190 return $data;
191 }
192
193 foreach ( $files as $file_id ) {
194 $file_id = absint( $file_id );
195 $file_path = $storage->get_image_abspath( $file_id );
196
197 if ( ! $file_path ) {
198 // Problem.
199 $data['errors']['no_file_path'][] = $file_id;
200 continue;
201 }
202
203 $backup_path = get_imagify_ngg_attachment_backup_path( $file_path );
204
205 if ( ! $this->filesystem->exists( $backup_path ) ) {
206 // No backup, no next-gen.
207 $data['errors']['no_backup'][] = $file_id;
208 continue;
209 }
210
211 $data['ids'][] = $file_id;
212 }
213
214 return $data;
215 }
216
217 /**
218 * Tell if there are optimized media without next-gen versions.
219 *
220 * @since 2.2
221 *
222 * @return int The number of media.
223 */
224 public function has_optimized_media_without_nextgen() {
225 // @codeCoverageIgnoreStart — requires live NGG DB table; not available in unit tests.
226 if ( ! DB::get_instance()->can_operate() ) {
227 return 0;
228 }
229 // @codeCoverageIgnoreEnd
230
231 global $wpdb;
232
233 $ngg_table = $wpdb->prefix . 'ngg_pictures';
234 $data_table = DB::get_instance()->get_table_name();
235 $suffix = constant( imagify_get_optimization_process_class_name( 'ngg' ) . '::WEBP_SUFFIX' );
236
237 if ( 'avif' === get_imagify_option( 'optimization_format' ) ) {
238 $suffix = constant( imagify_get_optimization_process_class_name( 'ngg' ) . '::AVIF_SUFFIX' );
239 }
240
241 return (int) $wpdb->get_var(
242 $wpdb->prepare( // WPCS: unprepared SQL ok.
243 "
244 SELECT COUNT(ngg.pid)
245 FROM $ngg_table as ngg
246 INNER JOIN $data_table AS data
247 ON ( ngg.pid = data.pid )
248 WHERE
249 ( data.status = 'success' OR data.status = 'already_optimized' )
250 AND data.data NOT LIKE %s",
251 '%' . $wpdb->esc_like( $suffix . '";a:4:{s:7:"success";b:1;' ) . '%'
252 )
253 );
254 }
255
256 /**
257 * Get the context data.
258 *
259 * @since 1.9
260 *
261 * @return array {
262 * The formated data.
263 *
264 * @type string $count-optimized Number of media optimized.
265 * @type string $count-errors Number of media having an optimization error, with a link to the page listing the optimization errors.
266 * @type string $optimized-size Optimized filesize.
267 * @type string $original-size Original filesize.
268 * }
269 */
270 public function get_context_data() {
271 $total_saving_data = imagify_count_saving_data();
272 $data = [
273 'count-optimized' => imagify_ngg_count_optimized_attachments(),
274 'count-errors' => imagify_ngg_count_error_attachments(),
275 'optimized-size' => $total_saving_data['optimized_size'],
276 'original-size' => $total_saving_data['original_size'],
277 'errors_url' => get_imagify_admin_url( 'folder-errors', $this->context ),
278 ];
279
280 return $this->format_context_data( $data );
281 }
282 }
283