PluginProbe ʕ •ᴥ•ʔ
Admin and Site Enhancements (ASE) / 9.0.2
Admin and Site Enhancements (ASE) v9.0.2
9.1.1 9.1.0 9.0.2 9.0.1 9.0.0 8.9.2 8.9.1 8.9.0 8.8.8 8.8.7 8.8.6 8.8.5 8.8.4 8.8.3 8.8.2 8.8.1 8.8.0 8.7.3 8.7.2 8.7.1 8.2.1 8.2.2 8.2.3 8.3.0 8.3.1 8.3.2 8.4.0 8.4.1 8.4.2 8.5.0 8.5.1 8.5.2 8.6.0 8.6.1 8.6.2 8.7.0 5.0.1 5.0.2 5.0.2.1 5.0.2.2 5.0.2.3 5.0.2.4 5.1.0 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.8.0 5.8.1 6.0.0 6.0.3 6.0.4 6.0.5 6.0.5.1 6.0.6 6.0.7 6.0.8.1 6.1.0 6.1.3 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.3.0 6.3.1 6.3.2 6.4.0 6.5.0 6.5.1 6.6.0 6.7.0 6.8.0 6.8.2 6.8.3 6.9.0 6.9.1 6.9.10 6.9.11 6.9.12 6.9.13.1 6.9.13.2 6.9.2 6.9.3 6.9.4 6.9.5 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.2 7.0.2.1 7.0.2.2 7.0.2.3 7.0.3 7.1.0 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2.0 7.2.1 7.3.0 7.3.1 7.3.2 7.3.3 7.4.0 7.4.2 7.4.4 7.4.5 7.4.6 7.4.7 7.4.8 7.5.0 7.5.1 7.5.2 7.5.3 7.5.4 7.6.0 7.6.1 7.6.1.1 7.6.10 7.6.11 7.6.2 7.6.3 7.6.4 7.6.5 7.6.6 7.6.7 7.6.7.1 7.6.8 7.6.9 7.7.0 7.8.0 7.8.1 7.8.10 7.8.11 7.8.12 7.8.13 7.8.14 7.8.15 7.8.16 7.8.17 7.8.18 7.8.2 7.8.3 7.8.4 7.8.5 7.8.5.1 7.8.6 7.8.7 7.8.8 7.8.9 7.9.0 7.9.1 7.9.10 7.9.11 7.9.2 7.9.3 7.9.4 7.9.5 7.9.6 7.9.7 7.9.8 7.9.9 8.0.0 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.0.6 8.0.7 8.0.8 8.1.0 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 trunk 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 1.9.0 2.0.0 2.1.0 2.2.0 2.3.0 2.4.0 2.5.0 2.6.0 2.7.0 2.8.0 2.8.1 2.8.2 2.8.3 2.9.0 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.2.0 3.3.0 3.4.0 3.5.0 3.6.1 3.7.0 3.8.0 3.9.0 3.9.1 3.9.2 4.0.0 4.0.1 4.1.0 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.9.0 4.9.1 4.9.2 4.9.3 5.0.0
admin-site-enhancements / classes / class-image-upload-control.php
admin-site-enhancements / classes Last commit date
class-activation.php 2 weeks ago class-admin-menu-organizer.php 2 weeks ago class-admin-menu-svg-icon-mask.php 2 weeks ago class-auto-publish-posts-with-missed-schedule.php 2 weeks ago class-avif-upload.php 2 weeks ago class-captcha-protection.php 2 weeks ago class-change-login-url.php 2 weeks ago class-cleanup-admin-bar.php 2 weeks ago class-common-methods.php 2 weeks ago class-content-duplication.php 2 weeks ago class-content-order.php 2 weeks ago class-custom-admin-footer-text.php 2 weeks ago class-custom-body-class.php 2 weeks ago class-custom-css.php 2 weeks ago class-custom-nav-menu-items-in-new-tab.php 2 weeks ago class-deactivation.php 2 weeks ago class-disable-author-archives.php 2 weeks ago class-disable-comments.php 2 weeks ago class-disable-dashboard-widgets.php 2 weeks ago class-disable-embeds.php 2 weeks ago class-disable-feeds.php 2 weeks ago class-disable-gutenberg.php 2 weeks ago class-disable-rest-api.php 2 weeks ago class-disable-smaller-components.php 2 weeks ago class-disable-updates.php 2 weeks ago class-disable-user-account.php 2 weeks ago class-disable-xml-rpc.php 2 weeks ago class-display-system-summary.php 2 weeks ago class-email-address-obfuscator.php 2 weeks ago class-email-delivery.php 2 weeks ago class-enhance-list-tables.php 2 weeks ago class-external-permalinks.php 2 weeks ago class-heartbeat-control.php 2 weeks ago class-hide-admin-bar.php 2 weeks ago class-hide-admin-notices.php 2 weeks ago class-image-sizes-panel.php 2 weeks ago class-image-upload-control.php 2 weeks ago class-insert-head-body-footer-code.php 2 weeks ago class-last-login-column.php 2 weeks ago class-limit-login-attempts.php 2 weeks ago class-login-id-type.php 2 weeks ago class-login-logout-menu.php 2 weeks ago class-maintenance-mode.php 2 weeks ago class-manage-ads-appads-txt.php 2 weeks ago class-manage-robots-txt.php 2 weeks ago class-media-files-visibility-control.php 2 weeks ago class-media-replacement.php 2 weeks ago class-multiple-user-roles.php 2 weeks ago class-navigation-menu-duplicator.php 2 weeks ago class-obfuscate-author-slugs.php 2 weeks ago class-open-external-links-in-new-tab.php 2 weeks ago class-password-protection.php 2 weeks ago class-redirect-after-login.php 2 weeks ago class-redirect-after-logout.php 2 weeks ago class-redirect-fourofour.php 2 weeks ago class-registration-date-column.php 2 weeks ago class-revisions-control.php 2 weeks ago class-search-engines-visibility.php 2 weeks ago class-settings-fields-render.php 2 weeks ago class-settings-sanitization.php 2 weeks ago class-settings-sections-fields.php 2 weeks ago class-show-custom-taxonomy-filters.php 2 weeks ago class-site-identity-on-login-page.php 2 weeks ago class-svg-upload.php 2 weeks ago class-third-party-compat.php 2 weeks ago class-various-admin-ui-enhancements.php 2 weeks ago class-view-admin-as-role.php 2 weeks ago class-wider-admin-menu.php 2 weeks ago class-wp-config-transformer.php 2 weeks ago
class-image-upload-control.php
488 lines
1 <?php
2
3 namespace ASENHA\Classes;
4
5 use Imagick;
6 /**
7 * Class for Image Upload Control module
8 *
9 * @since 6.9.5
10 */
11 class Image_Upload_Control {
12 public $png_is_transparent;
13
14 /**
15 * Array storing the file names that were processed, as keys.
16 *
17 * @since 7.5.0
18 * @link https://plugins.trac.wordpress.org/browser/fix-image-rotation/tags/2.2.2/includes/class-fix-image-rotation.php#L30
19 *
20 * @access private
21 *
22 * @var array
23 */
24 private $orientation_fixed;
25
26 /**
27 * Array storing the meta data of original files in case it
28 * needs to be restored later.
29 *
30 * @since 7.5.0
31 * @link https://plugins.trac.wordpress.org/browser/fix-image-rotation/tags/2.2.2/includes/class-fix-image-rotation.php#L42
32 *
33 * @access private
34 *
35 * @var array
36 */
37 private $previous_meta;
38
39 /**
40 * Constructor
41 * @since 7.4.3
42 */
43 function __construct() {
44 $this->png_is_transparent = false;
45 $this->orientation_fixed = array();
46 $this->previous_meta = array();
47 }
48
49 /**
50 * Handler for image uploads. Convert and resize images.
51 *
52 * @since 4.3.0
53 */
54 public function image_upload_handler( $upload ) {
55 $options = get_option( ASENHA_SLUG_U, array() );
56 $applicable_mime_types = array(
57 'image/bmp',
58 'image/x-ms-bmp',
59 'image/png',
60 'image/jpeg',
61 'image/jpg',
62 'image/webp'
63 );
64 $disable_image_conversion = false;
65 if ( in_array( $upload['type'], $applicable_mime_types ) ) {
66 // Exlude from conversion and resizing images with filenames ending with '-nr', e.g. birds-nr.png
67 if ( false !== strpos( $upload['file'], '-nr.' ) ) {
68 return $upload;
69 }
70 // Image conversion is not disabled
71 if ( !$disable_image_conversion ) {
72 // Convert BMP
73 if ( 'image/bmp' === $upload['type'] || 'image/x-ms-bmp' === $upload['type'] ) {
74 $upload = $this->maybe_convert_image( 'bmp', $upload );
75 }
76 // Convert PNG without transparency
77 if ( 'image/png' === $upload['type'] ) {
78 $upload = $this->maybe_convert_image( 'png', $upload );
79 }
80 }
81 // At this point, BMPs and non-transparent PNGs are already converted to JPGs, unless excluded with '-nr' suffix.
82 // Let's perform resize operation as needed, i.e. if image dimension is larger than specified
83 $mime_types_to_resize = array(
84 'image/jpeg',
85 'image/jpg',
86 'image/png',
87 'image/webp'
88 );
89 if ( !is_wp_error( $upload ) && in_array( $upload['type'], $mime_types_to_resize ) && filesize( $upload['file'] ) > 0 ) {
90 // https://developer.wordpress.org/reference/classes/wp_image_editor/
91 $wp_image_editor = wp_get_image_editor( $upload['file'] );
92 if ( !is_wp_error( $wp_image_editor ) ) {
93 $image_size = $wp_image_editor->get_size();
94 $max_width = $options['image_max_width'];
95 $max_height = $options['image_max_height'];
96 $convert_to_jpg_quality = 82;
97 $did_resize = false;
98 // Check upload image's dimension and only resize if larger than the defined max dimension
99 if ( isset( $image_size['width'] ) && $image_size['width'] > $max_width || isset( $image_size['height'] ) && $image_size['height'] > $max_height ) {
100 $wp_image_editor->resize( $max_width, $max_height, false );
101 // false is for no cropping
102 $did_resize = true;
103 }
104 // Save only when a resize happened.
105 // Avoid re-encoding (and potentially recompressing) images that are already within max dimensions.
106 if ( $did_resize ) {
107 if ( 'image/jpg' === $upload['type'] || 'image/jpeg' === $upload['type'] ) {
108 $wp_image_editor->set_quality( $convert_to_jpg_quality );
109 }
110 $wp_image_editor->save( $upload['file'] );
111 }
112 }
113 }
114 }
115 return $upload;
116 }
117
118 /**
119 * Convert BMP or PNG without transparency into JPG
120 *
121 * @since 4.3.0
122 */
123 public function maybe_convert_image( $file_extension, $upload ) {
124 $image_object = null;
125 // Get image object from uploaded BMP/PNG
126 if ( 'bmp' === $file_extension ) {
127 if ( is_file( $upload['file'] ) ) {
128 // Generate image object from BMP for conversion to JPG later
129 if ( function_exists( 'imagecreatefrombmp' ) ) {
130 // PHP >= v7.2
131 $image_object = \imagecreatefrombmp( $upload['file'] );
132 } else {
133 // PHP < v7.2
134 require_once ASENHA_PATH . 'includes/bmp-to-image-object.php';
135 $image_object = bmp_to_image_object( $upload['file'] );
136 }
137 }
138 }
139 if ( 'png' === $file_extension ) {
140 // Detect alpha/transparency in PNG
141 $this->png_is_transparent = false;
142 if ( is_file( $upload['file'] ) ) {
143 if ( function_exists( 'imagecreatefrompng' ) ) {
144 // GD library is present, so 'imagecreatefrompng' function is available
145 // Generate image object from PNG for potential conversion to JPG later.
146 $image_object = \imagecreatefrompng( $upload['file'] );
147 // Get image dimension
148 list( $width, $height ) = getimagesize( $upload['file'] );
149 // Run through pixels until transparent pixel is found
150 if ( false !== $image_object ) {
151 for ($x = 0; $x < $width; $x++) {
152 for ($y = 0; $y < $height; $y++) {
153 $pixel_color_index = \imagecolorat( $image_object, $x, $y );
154 $pixel_rgba = \imagecolorsforindex( $image_object, $pixel_color_index );
155 // array of red, green, blue and alpha values
156 if ( $pixel_rgba['alpha'] > 0 ) {
157 // a pixel with alpha/transparency has been found
158 // alpha value range from 0 (completely opaque) to 127 (fully transparent).
159 // Ref: https://www.php.net/manual/en/function.imagecolorallocatealpha.php
160 $this->png_is_transparent = true;
161 break 2;
162 // Break both 'for' loops
163 }
164 }
165 }
166 }
167 } else {
168 if ( class_exists( 'Imagick' ) ) {
169 $imagick = new Imagick();
170 $imagick->readImage( $upload['file'] );
171 // Ref: https://stackoverflow.com/a/52295997
172 // Ref: https://www.php.net/manual/en/imagick.getimagechannelrange.php
173 // If the channel is defined, and has any transparent areas across any frame, then maxima will always be greater then minima.
174 // If the channel is NOT defined, then minima will be Inf placeholder, and maxima will be -Inf placeholder, so the above check will still work.
175 $alpha_range = $imagick->getImageChannelRange( Imagick::CHANNEL_ALPHA );
176 $this->png_is_transparent = $alpha_range['minima'] < $alpha_range['maxima'];
177 }
178 }
179 }
180 // Do not convert PNG with alpha/transparency
181 if ( $this->png_is_transparent ) {
182 return $upload;
183 }
184 }
185 // Let's convert BMP and non-transparent PNG into JPG
186 $converted_to_jpg = false;
187 $keep_original_image = false;
188 if ( is_object( $image_object ) || class_exists( 'Imagick' ) ) {
189 $wp_uploads = wp_upload_dir();
190 $old_filename = wp_basename( $upload['file'] );
191 // Assign new, unique file name for the converted image
192 // $new_filename = wp_basename( str_ireplace( '.' . $file_extension, '.jpg', $old_filename ) );
193 $new_filename = str_ireplace( '.' . $file_extension, '.jpg', $old_filename );
194 $new_filename = wp_unique_filename( dirname( $upload['file'] ), $new_filename );
195 // original image is always deleted in ASE Free
196 $keep_original_image = false;
197 $converted_to_jpg = false;
198 }
199 // Prefer GD when JPEG encode is available. Some custom PHP builds ship GD with PNG
200 // support but without imagejpeg(); guard that case and fall back to Imagick below.
201 if ( is_object( $image_object ) && function_exists( 'imagejpeg' ) ) {
202 // When conversion from BMP/PNG to JPG is successful using GD. Last parameter is JPG quality (0-100).
203 if ( \imagejpeg( $image_object, $wp_uploads['path'] . '/' . $new_filename, 90 ) ) {
204 $converted_to_jpg = true;
205 }
206 }
207 // Fall back to Imagick when GD image object creation failed, imagejpeg() is unavailable,
208 // or GD JPEG encode returned false.
209 if ( !$converted_to_jpg && class_exists( 'Imagick' ) ) {
210 $imagick = new Imagick();
211 $imagick->readImage( $upload['file'] );
212 $imagick->setImageCompressionQuality( 90 );
213 $imagick->setImageFormat( 'jpg' );
214 // $imagick->setFormat( 'jpg' );
215 if ( $imagick->writeImage( $wp_uploads['path'] . '/' . $new_filename ) ) {
216 $converted_to_jpg = true;
217 }
218 // Clear the Imagick object
219 $imagick->clear();
220 $imagick->destroy();
221 }
222 if ( $converted_to_jpg ) {
223 // Delete original BMP / PNG
224 if ( !$keep_original_image ) {
225 unlink( $upload['file'] );
226 }
227 // Add converted JPG info into $upload
228 $upload['file'] = $wp_uploads['path'] . '/' . $new_filename;
229 $upload['url'] = $wp_uploads['url'] . '/' . $new_filename;
230 $upload['type'] = 'image/jpeg';
231 }
232 return $upload;
233 }
234
235 /**
236 * Generate image object from PNG/JPG with GD library
237 *
238 * @since 6.9.11
239 */
240 public function gd_generate_webp(
241 $file,
242 $file_extension,
243 $webp_path,
244 $webp_conversion_quality
245 ) {
246 $image_object = null;
247 if ( 'png' == $file_extension && function_exists( 'imagecreatefrompng' ) ) {
248 $image_object = \imagecreatefrompng( $file );
249 if ( false !== $image_object && $this->png_is_transparent && function_exists( 'imagepalettetotruecolor' ) ) {
250 \imagepalettetotruecolor( $image_object );
251 }
252 }
253 if ( ('jpg' == $file_extension || 'jpeg' == $file_extension) && function_exists( 'imagecreatefromjpeg' ) ) {
254 $image_object = \imagecreatefromjpeg( $file );
255 }
256 // When creation of image object from PNG/JPG is successful. let's generate WebP image
257 // Second parameter is file path, last parameter is WebP quality (0-100).
258 if ( !is_null( $image_object ) && is_object( $image_object ) && function_exists( 'imagewebp' ) ) {
259 \imagewebp( $image_object, $webp_path, $webp_conversion_quality );
260 }
261 }
262
263 /**
264 * Checks the filename before it is uploaded to WordPress and
265 * runs the fix_image_orientation function in case its needed.
266 *
267 * @since 7.5.0
268 * @link https://plugins.trac.wordpress.org/browser/fix-image-rotation/tags/2.2.2/includes/class-fix-image-rotation.php#L172
269 *
270 * @access public
271 *
272 * @hook wp_handle_upload_prefilter
273 *
274 * @param array $file An array of data for a single file.
275 *
276 * @return array An array of data for a single file.
277 */
278 public function prefilter_maybe_fix_image_orientation( $file ) {
279 // Get the file extension
280 // $suffix = substr( $file['name'], strrpos( $file['name'], '.', -1 ) + 1 );
281 $suffix = pathinfo( $file['name'], PATHINFO_EXTENSION );
282 if ( in_array( strtolower( $suffix ), array('jpg', 'jpeg', 'tiff'), true ) ) {
283 $this->fix_image_orientation( $file['tmp_name'] );
284 }
285 return $file;
286 }
287
288 /**
289 * Checks the filename before it is uploaded to WordPress and
290 * runs the fix_image_orientation function in case its needed.
291 *
292 * @since 7.5.0
293 * @link https://plugins.trac.wordpress.org/browser/fix-image-rotation/tags/2.2.2/includes/class-fix-image-rotation.php#L150
294 *
295 * @access public
296 *
297 * @hook wp_handle_upload
298 *
299 * @param array $file {
300 * Array of upload data.
301 *
302 * @type string $file Filename of the newly-uploaded file.
303 * @type string $url URL of the uploaded file.
304 * @type string $type File type.
305 * }
306 *
307 * @return array Array of upload data.
308 */
309 public function maybe_fix_image_orientation( $file ) {
310 $suffix = substr( $file['file'], strrpos( $file['file'], '.', -1 ) + 1 );
311 if ( in_array( strtolower( $suffix ), array('jpg', 'jpeg', 'tiff'), true ) ) {
312 $this->fix_image_orientation( $file['file'] );
313 }
314 return $file;
315 }
316
317 /**
318 * Fixes the orientation of the image based on exif data
319 *
320 * @since 7.5.0
321 * @link https://plugins.trac.wordpress.org/browser/fix-image-rotation/tags/2.2.2/includes/class-fix-image-rotation.php#L191
322 *
323 * @access public
324 *
325 * @param string $file Path of the file.
326 *
327 * @return void
328 */
329 public function fix_image_orientation( $file ) {
330 if ( !isset( $this->orientation_fixed[$file] ) ) {
331 $exif = @exif_read_data( $file );
332 if ( isset( $exif ) && isset( $exif['Orientation'] ) && $exif['Orientation'] > 1 ) {
333 // Need it so that image editors are available to us.
334 // include_once ABSPATH . 'wp-admin/includes/image-edit.php';
335 // Calculate the operations we need to perform on the image.
336 $operations = $this->calculate_flip_and_rotate( $file, $exif );
337 if ( false !== $operations ) {
338 // Lets flip flop and rotate the image as needed.
339 $this->do_flip_and_rotate( $file, $operations );
340 }
341 }
342 }
343 }
344
345 /**
346 * Calculate the flips and rotations image will need to do to fix its orientation.
347 *
348 * @since 7.5.0
349 * @link https://plugins.trac.wordpress.org/browser/fix-image-rotation/tags/2.2.2/includes/class-fix-image-rotation.php#L225
350 *
351 * @access private
352 *
353 * @param string $file Path of the file.
354 *
355 * @param array $exif Exif data of the image.
356 *
357 * @return array|bool Array of operations to be performed on the image,
358 * false if no operations are needed.
359 */
360 private function calculate_flip_and_rotate( $file, $exif ) {
361 $rotator = false;
362 $flipper = false;
363 $orientation = 0;
364 // Lets switch to the orientation defined in the exif data.
365 switch ( $exif['Orientation'] ) {
366 case 1:
367 // We don't want to fix an already correct image :).
368 $this->orientation_fixed[$file] = true;
369 return false;
370 case 2:
371 $flipper = array(false, true);
372 break;
373 case 3:
374 $orientation = -180;
375 $rotator = true;
376 break;
377 case 4:
378 $flipper = array(true, false);
379 break;
380 case 5:
381 $orientation = -90;
382 $rotator = true;
383 $flipper = array(false, true);
384 break;
385 case 6:
386 $orientation = -90;
387 $rotator = true;
388 break;
389 case 7:
390 $orientation = -270;
391 $rotator = true;
392 $flipper = array(false, true);
393 break;
394 case 8:
395 case 9:
396 $orientation = -270;
397 $rotator = true;
398 break;
399 default:
400 $orientation = 0;
401 $rotator = true;
402 break;
403 }
404 return compact( 'orientation', 'rotator', 'flipper' );
405 }
406
407 /**
408 * Flips and rotates the image based on the parameters provided.
409 *
410 * @since 7.5.0
411 * @link https://plugins.trac.wordpress.org/browser/fix-image-rotation/tags/2.2.2/includes/class-fix-image-rotation.php#L299
412 *
413 * @access private
414 *
415 * @param string $file Path of the file.
416 *
417 * @param array $operations {
418 * Array of operations to be performed on the image.
419 *
420 * @type bool $rotator Whether to rotate the image or not.
421 * @type int $orientation Amount of rotation to be performed in degrees.
422 * @type array|bool $flipper {
423 * Whether to flip the image or not, false if no flipping needed.
424 *
425 * @type bool $0 Flip along Horizontal Axis.
426 * @type bool $1 Flip along Vertical Axis.
427 * }
428 * }
429 *
430 * @return bool Returns true if operations were successful, false otherwise.
431 */
432 private function do_flip_and_rotate( $file, $operations ) {
433 $editor = wp_get_image_editor( $file );
434 // If GD Library is being used, then we need to store metadata to restore later.
435 if ( 'WP_Image_Editor_GD' === get_class( $editor ) ) {
436 include_once ABSPATH . 'wp-admin/includes/image.php';
437 $this->previous_meta[$file] = wp_read_image_metadata( $file );
438 }
439 if ( !is_wp_error( $editor ) ) {
440 // Lets rotate and flip the image based on exif orientation.
441 if ( true === $operations['rotator'] ) {
442 $editor->rotate( $operations['orientation'] );
443 }
444 if ( false !== $operations['flipper'] ) {
445 $editor->flip( $operations['flipper'][0], $operations['flipper'][1] );
446 }
447 $editor->save( $file );
448 $this->orientation_fixed[$file] = true;
449 add_filter(
450 'wp_read_image_metadata',
451 array($this, 'restore_meta_data'),
452 10,
453 2
454 );
455 return true;
456 }
457 return false;
458 }
459
460 /**
461 * Restores the meta data of the image after being processed.
462 *
463 * WordPress' Imagick Library does not need this, but GD library
464 * removes metadata from the image upon rotation or flip so this
465 * method restores those values.
466 *
467 * @since 7.5.0
468 * @link https://plugins.trac.wordpress.org/browser/fix-image-rotation/tags/2.2.2/includes/class-fix-image-rotation.php#L341
469 *
470 * @hook wp_read_image_metadata
471 *
472 * @param array $meta Image meta data.
473 * @param string $file Path to image file.
474 *
475 * @return array Image meta data.
476 */
477 public function restore_meta_data( $meta, $file ) {
478 if ( isset( $this->previous_meta[$file] ) ) {
479 $meta = $this->previous_meta[$file];
480 // Setting the Orientation meta to the new value after fixing the rotation.
481 $meta['orientation'] = 1;
482 return $meta;
483 }
484 return $meta;
485 }
486
487 }
488