PluginProbe
WP-Stateless – Google Cloud Storage / 3.2.0
WP-Stateless – Google Cloud Storage v3.2.0
4.4.3 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.3.0 2.3.1 2.3.2 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 All 62 releases
wp-stateless / lib / classes / compatibility / imagify.php

imagify.php in WP-Stateless – Google Cloud Storage 3.2.0, at lib/classes/compatibility/imagify.php

309 lines 12.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: Imagify
4 * Plugin URI: https://wordpress.org/plugins/imagify/
5 *
6 * Compatibility Description: Enables support for these Imagify Image Optimizer features:
7 * auto-optimize images on upload, bulk optimizer, resize larger images, optimization levels (normal, aggressive, ultra).
8 *
9 * https://github.com/wpCloud/wp-stateless/issues/206
10 */
11
12 namespace wpCloud\StatelessMedia {
13
14 if( !class_exists( 'wpCloud\StatelessMedia\Imagify' ) ) {
15
16 class Imagify extends ICompatibility {
17 protected $id = 'imagify';
18 protected $title = 'Imagify Image Optimizer';
19 protected $constant = 'WP_STATELESS_COMPATIBILITY_IMAGIFY';
20 protected $description = 'Enables support for these Imagify Image Optimizer features: auto-optimize images on upload, bulk optimizer, resize larger images, optimization levels (normal, aggressive, ultra).';
21 protected $plugin_file = [ 'imagify/imagify.php', 'imagify-plugin/imagify.php' ];
22 protected $sm_mode_not_supported = [ 'stateless' ];
23
24 public function module_init( $sm ) {
25 // Skip sync on upload when attachment is image, sync will be handled after image is optimized.
26 // Disabling for now because it's cause problem.
27 //add_filter( 'wp_stateless_skip_add_media', array( $this, 'skip_add_media' ), 10, 5 );
28 add_filter( 'before_imagify_optimize_attachment', array( $this, 'fix_missing_file' ), 10 );
29 add_action( 'after_imagify_optimize_attachment', array( $this, 'after_imagify_optimize_attachment' ), 10 );
30
31 //hook for Imagify since version 1.9
32 add_filter( 'wp_stateless_skip_remove_media', array( $this, 'skip_remove_media' ), 10, 5 );
33 add_action( 'imagify_after_optimize_file', array( $this, 'imagify_after_optimize_file' ), 10, 2 );
34 add_action( 'imagify_before_optimize_size', array( $this, 'imagify_before_optimize_size' ), 10, 7 );
35
36 // if imagify implement this filter then enable it.
37 add_filter( 'imagify_has_backup', array( $this, 'imagify_has_backup' ), 10, 2 );
38
39 add_filter( 'before_imagify_restore_attachment', array( $this, 'get_image_from_gcs' ), 10 );
40 add_action( 'after_imagify_restore_attachment', array( $this, 'after_imagify_optimize_attachment' ), 10 );
41 // Sync from sync tab
42 add_action( 'sm:synced::image', array( $this, 'get_image_from_gcs' ) );
43 }
44
45 /**
46 * Whether to skip the sync on image upload before the image is optimized.
47 * The sync is skipped if the image is compatible with Smush.
48 *
49 * The image will be synced after it's get optimized using the 'wp_smush_image_optimised' action.
50 *
51 *
52 * @param bool $return This should return true if want to skip the sync.
53 * @param int $metadata Metadata for the attachment.
54 * @param string $attachment_id Attachment ID.
55 * @param bool $force Whether to force the sync even the file already exist in GCS.
56 * @param array $args Whether to only sync the full size image.
57 *
58 * @return bool $return True to skip the sync and false to do the sync.
59 *
60 */
61 public function skip_add_media( $return, $metadata, $attachment_id, $force = false, $args = array() ) {
62 global $doing_manual_sync;
63
64 if( $force || $doing_manual_sync || !get_imagify_option( 'auto_optimize' ) ) return false;
65
66 $imagify = new \Imagify_Attachment( $attachment_id );
67 if( is_callable( array( $imagify, 'is_extension_supported' ) ) ) {
68 if( !$imagify->is_extension_supported() ) {
69 return false;
70 }
71 } elseif( function_exists( 'imagify_is_attachment_mime_type_supported' ) ) {
72 // Use `imagify_is_attachment_mime_type_supported( $attachment_id )`.
73 if( !imagify_is_attachment_mime_type_supported( $attachment_id ) ) {
74 return false;
75 }
76 } elseif( !wp_attachment_is_image( $attachment_id ) ) {
77 return false;
78 }
79
80 return true;
81 }
82
83 /**
84 * Added fix for Imagify version 1.9
85 * In Ephemeral mode remove files from server after optimization process `imagify_after_optimize_file`
86 * @param $return
87 * @param $metadata
88 * @param $attachment_id
89 * @param bool $force
90 * @param array $args
91 * @return bool
92 * @author palant@ud
93 */
94 public function skip_remove_media( $return, $metadata, $attachment_id, $force = false, $args = array() ) {
95 global $doing_manual_sync;
96
97 if( $force || $doing_manual_sync || !get_imagify_option( 'auto_optimize' ) ) return false;
98
99 $imagify = new \Imagify\Optimization\File( get_attached_file( $attachment_id ) );
100
101 if( is_callable( array( $imagify, 'is_supported' ) ) ) {
102 if( !$imagify->is_supported( imagify_get_mime_types() ) ) {
103 return false;
104 }
105 } elseif( function_exists( 'imagify_is_attachment_mime_type_supported' ) ) {
106 // Use `imagify_is_attachment_mime_type_supported( $attachment_id )`.
107 if( !imagify_is_attachment_mime_type_supported( $attachment_id ) ) {
108 return false;
109 }
110 } elseif( !wp_attachment_is_image( $attachment_id ) ) {
111 return false;
112 }
113
114 return true;
115 }
116
117 /**
118 * Try to restore images before compression
119 *
120 * @param $attachment_id
121 * @return mixed
122 */
123 public function fix_missing_file( $attachment_id ) {
124 /**
125 * If mode is ephemeral then we change it to cdn in order images not being deleted before optimization
126 * Remember that we changed mode via global var
127 */
128 if( ud_get_stateless_media()->get( 'sm.mode' ) == 'ephemeral' ) {
129 ud_get_stateless_media()->set( 'sm.mode', 'cdn' );
130 global $wp_stateless_imagify_mode;
131 $wp_stateless_imagify_mode = 'ephemeral';
132 }
133
134 $upload_basedir = wp_upload_dir();
135 $upload_basedir = trailingslashit( $upload_basedir[ 'basedir' ] );
136 $meta_data = wp_get_attachment_metadata( $attachment_id );
137 $file = $upload_basedir . $meta_data[ 'file' ];
138
139 /**
140 * Try to get all missing files from GCS
141 */
142 if( !file_exists( $file ) ) {
143 ud_get_stateless_media()->get_client()->get_media( apply_filters( 'wp_stateless_file_name', $meta_data[ 'file' ] ), true, $file );
144 }
145
146 if( !empty( $meta_data[ 'sizes' ] ) && is_array( $meta_data[ 'sizes' ] ) ) {
147 $upload_basedir = trailingslashit( dirname( $file ) );
148 foreach( $meta_data[ 'sizes' ] as $image ) {
149 if( !empty( $image[ 'gs_name' ] ) && !file_exists( $file = $upload_basedir . $image[ 'file' ] ) ) {
150 ud_get_stateless_media()->get_client()->get_media( apply_filters( 'wp_stateless_file_name', $image[ 'gs_name' ] ), true, $file );
151 }
152 }
153 }
154
155 }
156
157 /**
158 * If image size not exist then upload it to GS.
159 *
160 * $args = array(
161 * 'thumbnail' => $thumbnail,
162 * 'p_img_large' => $p_img_large,
163 * )
164 * @param $id
165 */
166 public function after_imagify_optimize_attachment( $id ) {
167 /**
168 * Restore ephemeral mode if needed
169 */
170 global $wp_stateless_imagify_mode;
171 if( $wp_stateless_imagify_mode == 'ephemeral' ) {
172 ud_get_stateless_media()->set( 'sm.mode', 'ephemeral' );
173 }
174
175 $metadata = wp_get_attachment_metadata( $id );
176 ud_get_stateless_media()->add_media( $metadata, $id, true );
177
178 // Sync backup file with GCS
179 if( current_filter() == 'after_imagify_optimize_attachment' ) {
180 /**
181 * If mode is ephemeral then we change it to cdn in order images not being deleted before optimization
182 * Remember that we changed mode via global var
183 * @todo remove if Imagify implement "imagify_has_backup" filter.
184 */
185 if( ud_get_stateless_media()->get( 'sm.mode' ) == 'ephemeral' ) {
186 ud_get_stateless_media()->set( 'sm.mode', 'cdn' );
187 global $wp_stateless_imagify_mode;
188 $wp_stateless_imagify_mode = 'ephemeral';
189 }
190
191 $file_path = get_attached_file( $id );
192 $backup_path = get_imagify_attachment_backup_path( $file_path );
193 if( file_exists( $backup_path ) ) {
194 $overwrite = apply_filters( 'imagify_backup_overwrite_backup', false, $file_path, $backup_path );
195 // wp_stateless_file_name filter will remove the basedir from the path and prepend with root dir.
196 $name = apply_filters( 'wp_stateless_file_name', $backup_path );
197 do_action( 'sm:sync::syncFile', $name, $backup_path, $overwrite );
198 }
199 }
200 }
201
202 /**
203 * Restore backup file from GCS if not exist.
204 * @param $id
205 */
206 public function get_image_from_gcs( $id ) {
207 $file_path = get_attached_file( $id );
208 $backup_path = get_imagify_attachment_backup_path( $file_path );
209 if( !file_exists( $backup_path ) ) {
210 $upload_dir = wp_upload_dir();
211 $name = str_replace( trailingslashit( $upload_dir[ 'basedir' ] ), '', $backup_path );
212 $name = apply_filters( 'wp_stateless_file_name', $name );
213 do_action( 'sm:sync::syncFile', $name, $backup_path, true );
214 }
215 }
216
217 /**
218 * Check if backup exists in GCS.
219 * @param $return
220 * @param $has_backup
221 * @return bool
222 */
223 public function imagify_has_backup( $return, $has_backup ) {
224 if( !$return && $has_backup ) {
225 $name = apply_filters( 'wp_stateless_file_name', $has_backup );
226 $return = (bool) apply_filters( 'sm:sync::queue_is_exists', $name );
227 }
228 return $return;
229 }
230
231 /**
232 * Synchronization after optmize process
233 * @param $file
234 * @param array $args
235 */
236 public function imagify_after_optimize_file( $file, $args = array() ) {
237
238 global $wp_stateless_imagify_mode;
239 if( $wp_stateless_imagify_mode == 'ephemeral' ) {
240 ud_get_stateless_media()->set( 'sm.mode', 'ephemeral' );
241 }
242
243 $name = apply_filters( 'wp_stateless_file_name', basename( $file ) );
244
245 if( file_exists( $file ) ) {
246 add_filter( 'upload_mimes', array( $this, 'add_webp_mime' ), 10, 2 );
247 /**
248 * Media already on GCS, so only replacing data on it. For webp format adding path and status to wp_sm_sync table
249 */
250 do_action( 'sm:sync::syncFile', $name, $file, true, array( 'use_root' => true, 'skip_db' => ( substr( $name, -4 ) == "webp" ? false : true ) ) );
251 remove_filter( 'upload_mimes', array( $this, 'add_webp_mime' ), 10 );
252 }
253 }
254
255 /**
256 * @param $return
257 * @param $process
258 * @param $file
259 * @param $thumb_size
260 * @param $optimization_level
261 * @param $webp
262 * @param $is_disabled
263 * @return mixed
264 */
265 public function imagify_before_optimize_size( $return, $process, $file, $thumb_size, $optimization_level, $webp, $is_disabled ) {
266
267 try {
268 $attachment_id = $this->getProperties( $this->getProperties( $this->getProperties( $process )[ 'data' ] )[ 'media' ] )[ 'id' ];
269
270 $full_size_path = $file->get_path();
271 $name = apply_filters( 'wp_stateless_file_name', basename( $full_size_path ), true, $attachment_id );
272 do_action( 'sm:sync::syncFile', $name, $full_size_path, true, [ 'download' => true ] );
273 // error_log("\n\ndo_action( 'sm:sync::syncFile', $name, $full_size_path, true, ['download' => true] );");
274 } catch( \Throwable $th ) {
275 //throw $th;
276 }
277 return $return;
278 }
279
280 /**
281 * Get properties from protected value
282 * @param $process
283 * @return array
284 */
285 public function getProperties( $process ) {
286 $properties = array();
287 try {
288 $rc = new \ReflectionClass( $process );
289 do {
290 $rp = array();
291 /* @var $p \ReflectionProperty */
292 foreach( $rc->getProperties() as $p ) {
293 $p->setAccessible( true );
294 $rp[ $p->getName() ] = $p->getValue( $process );
295 }
296 $properties = array_merge( $rp, $properties );
297 } while( $rc = $rc->getParentClass() );
298 } catch( \ReflectionException $e ) {
299
300 }
301 return $properties;
302 }
303
304 }
305
306 }
307
308 }
309