PluginProbe
WP-Stateless – Google Cloud Storage / 2.2.2
WP-Stateless – Google Cloud Storage v2.2.2
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 / shortpixel.php

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

320 lines 14.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: ShortPixel Image Optimizer
4 * Plugin URI: https://wordpress.org/plugins/shortpixel-image-optimiser/
5 *
6 * Compatibility Description: Ensures compatibility with ShortPixel Image Optimizer.
7 *
8 */
9
10 namespace wpCloud\StatelessMedia {
11
12 if(!class_exists('wpCloud\StatelessMedia\ShortPixel')) {
13
14 class ShortPixel extends ICompatibility {
15
16 protected $id = 'shortpixel';
17 protected $title = 'ShortPixel Image Optimizer';
18 protected $constant = 'WP_STATELESS_COMPATIBILITY_SHORTPIXEL';
19 protected $description = 'Ensures compatibility with ShortPixel Image Optimizer.';
20 protected $plugin_file = 'shortpixel-image-optimiser/wp-shortpixel.php';
21
22 public function module_init($sm){
23 add_action( 'shortpixel_image_optimised', array($this, 'shortpixel_image_optimised') );
24 add_filter( 'get_attached_file', array($this, 'fix_missing_file'), 10, 2 );
25 add_action( 'shortpixel_before_restore_image', array($this, 'sync_backup_file') );
26 add_action( 'shortpixel_after_restore_image', array($this, 'handleRestoreBackup') );
27 add_action( 'admin_enqueue_scripts', array( $this, 'shortPixelJS') );
28 // Sync from sync tab
29 add_action( 'sm:synced::image', array( $this, 'sync_backup_file'), 10, 2 );
30 }
31
32 public function shortPixelJS(){
33 $upload_dir = wp_upload_dir();
34 $jsSuffix = '.min.js';
35
36 if (defined('SHORTPIXEL_DEBUG') && SHORTPIXEL_DEBUG === true) {
37 $jsSuffix = '.js'; //use unminified versions for easier debugging
38 }
39 $dep = 'short-pixel' . $jsSuffix;
40 wp_enqueue_script('stateless-short-pixel', ud_get_stateless_media()->path( 'lib/classes/compatibility/js/shortpixel.js', 'url'), array($dep), '', true);
41
42 $image_host = ud_get_stateless_media()->get_gs_host();
43 $bucketLink = apply_filters('wp_stateless_bucket_link', $image_host);
44
45 wp_localize_script( 'stateless-short-pixel', '_stateless_short_pixel', array(
46 'baseurl' => $upload_dir[ 'baseurl' ],
47 'bucketLink' => $bucketLink,
48 ));
49
50 }
51
52
53 /**
54 * Try to restore images before compression
55 *
56 * @param $file
57 * @param $attachment_id
58 * @return mixed
59 */
60 public function fix_missing_file( $file, $attachment_id ) {
61
62 /**
63 * If hook is triggered by ShortPixel
64 */
65 if ( !$this->hook_from_shortpixel() ) return $file;
66
67 /**
68 * If mode is stateless then we change it to cdn in order images not being deleted before optimization
69 * Remember that we changed mode via global var
70 */
71 if ( ud_get_stateless_media()->get( 'sm.mode' ) == 'stateless' ) {
72 ud_get_stateless_media()->set( 'sm.mode', 'cdn' );
73 global $wp_stateless_shortpixel_mode;
74 $wp_stateless_shortpixel_mode = 'stateless';
75 }
76
77 $upload_dir = wp_upload_dir();
78 $meta_data = wp_get_attachment_metadata( $attachment_id );
79
80 /**
81 * Try to get all missing files from GCS
82 */
83 if ( !file_exists( $file ) ) {
84 ud_get_stateless_media()->get_client()->get_media( apply_filters( 'wp_stateless_file_name', str_replace( trailingslashit( $upload_dir[ 'basedir' ] ), '', $file )), true, $file );
85 }
86
87 if ( !empty( $meta_data['sizes'] ) && is_array( $meta_data['sizes'] ) ) {
88 foreach( $meta_data['sizes'] as $image ) {
89 if ( !empty( $image['gs_name'] ) && !file_exists( $_file = trailingslashit( $upload_dir[ 'basedir' ] ).$image['gs_name'] ) ) {
90 ud_get_stateless_media()->get_client()->get_media( apply_filters( 'wp_stateless_file_name', $image['gs_name']), true, $_file );
91 }
92 }
93 }
94
95 return $file;
96 }
97
98 /**
99 * Determine where we hook from
100 * We need to do this only for something specific in shortpixel plugin
101 *
102 * @return bool
103 */
104 private function hook_from_shortpixel() {
105 $call_stack = debug_backtrace();
106
107 if ( !empty( $call_stack ) && is_array( $call_stack ) ) {
108 foreach( $call_stack as $step ) {
109 if ( $step['function'] == 'getURLsAndPATHs' && strpos( $step['file'], 'wp-short-pixel' ) ) {
110 return true;
111 }
112 }
113 }
114
115 return false;
116 }
117
118 /**
119 * If image size not exist then upload it to GS.
120 *
121 * $args = array(
122 * 'thumbnail' => $thumbnail,
123 * 'p_img_large' => $p_img_large,
124 * )
125 */
126 public function shortpixel_image_optimised($id){
127
128 /**
129 * Restore stateless mode if needed
130 */
131 global $wp_stateless_shortpixel_mode;
132 if ( $wp_stateless_shortpixel_mode == 'stateless' ) {
133 ud_get_stateless_media()->set( 'sm.mode', 'stateless' );
134 }
135
136 $metadata = wp_get_attachment_metadata( $id );
137 ud_get_stateless_media()->add_media( $metadata, $id, true );
138
139 $this->sync_backup_file($id, $metadata);
140 }
141
142 /**
143 * Sync backup image
144 */
145 public function sync_backup_file($id, $metadata = null){
146
147 /* Get metadata in case if method is called directly. */
148 if( empty($metadata) ) {
149 $metadata = wp_get_attachment_metadata( $id );
150 }
151 /* Now we go through all available image sizes and upload them to Google Storage */
152 if( !empty( $metadata[ 'sizes' ] ) && is_array( $metadata[ 'sizes' ] ) ) {
153
154 // Sync backup file with GCS
155 $file_path = get_attached_file( $id );
156 $fullSubDir = $this->returnSubDir($file_path);
157 $backup_path = SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir;
158
159 /**
160 * If mode is stateless then we change it to cdn in order images not being deleted before optimization
161 * Remember that we changed mode via global var
162 */
163 $wp_stateless_shortpixel_mode;
164
165 if ( ud_get_stateless_media()->get( 'sm.mode' ) == 'stateless' ) {
166 ud_get_stateless_media()->set( 'sm.mode', 'cdn' );
167 $wp_stateless_shortpixel_mode = 'stateless';
168 }
169 foreach( (array) $metadata[ 'sizes' ] as $image_size => $data ) {
170 $absolutePath = $backup_path . $data[ 'file' ];
171 $name = apply_filters( 'wp_stateless_file_name', basename(SHORTPIXEL_BACKUP_FOLDER) . '/' . $fullSubDir . $data[ 'file' ]);
172
173 do_action( 'sm:sync::syncFile', $name, $absolutePath, true);
174 }
175
176 if ( $wp_stateless_shortpixel_mode == 'stateless' ) {
177 ud_get_stateless_media()->set( 'sm.mode', 'stateless' );
178 }
179
180
181 }
182 }
183
184 /**
185 * return subdir for that particular attached file - if it's media library then last 3 path items, otherwise substract the uploads path
186 * Has trailing directory separator (/)
187 *
188 * @copied from shortpixel-image-optimiser\class\db\shortpixel-meta-facade.php
189 * @param type $file
190 * @return string
191 */
192 public function returnSubDir($file){
193 $hp = wp_normalize_path(get_home_path());
194 $file = wp_normalize_path($file);
195 $sp__uploads = wp_upload_dir();
196 if(strstr($file, $hp)) {
197 $path = str_replace( $hp, "", $file);
198 } elseif( strstr($file, dirname( WP_CONTENT_DIR ))) { //in some situations the content dir is not inside the root, check this also (ex. single.shortpixel.com)
199 $path = str_replace( trailingslashit(dirname( WP_CONTENT_DIR )), "", $file);
200 } elseif( (strstr(realpath($file), realpath($hp)))) {
201 $path = str_replace( realpath($hp), "", realpath($file));
202 } elseif( strstr($file, trailingslashit(dirname(dirname( $sp__uploads['basedir'] )))) ) {
203 $path = str_replace( trailingslashit(dirname(dirname( $sp__uploads['basedir'] ))), "", $file);
204 } else {
205 $path = (substr($file, 1));
206 }
207 $pathArr = explode('/', $path);
208 unset($pathArr[count($pathArr) - 1]);
209 return implode('/', $pathArr) . '/';
210 }
211
212 /**
213 * Sync images after shortpixel restore them from backup.
214 */
215 public function handleRestoreBackup($attachmentID){
216 $metadata = wp_get_attachment_metadata( $attachmentID );
217 $this->add_media( $metadata, $attachmentID );
218 }
219
220 /**
221 * Customized version of wpCloud\StatelessMedia\Utility::add_media()
222 * to satisfied our need in restore backup
223 * If a image isn't restored from backup then ignore it.
224 */
225 public static function add_media( $metadata, $attachment_id ) {
226 $upload_dir = wp_upload_dir();
227
228 $client = ud_get_stateless_media()->get_client();
229
230 if( !is_wp_error( $client ) ) {
231
232 $fullsizepath = wp_normalize_path( get_attached_file( $attachment_id ) );
233 // Make non-images uploadable.
234 if( empty( $metadata['file'] ) && $attachment_id ) {
235 $metadata = array( "file" => str_replace( trailingslashit( $upload_dir[ 'basedir' ] ), '', get_attached_file( $attachment_id ) ) );
236 }
237
238 $file = wp_normalize_path( $metadata[ 'file' ] );
239 $image_host = ud_get_stateless_media()->get_gs_host();
240 $bucketLink = apply_filters('wp_stateless_bucket_link', $image_host);
241 $_cacheControl = \wpCloud\StatelessMedia\Utility::getCacheControl( $attachment_id, $metadata, null );
242 $_contentDisposition = \wpCloud\StatelessMedia\Utility::getContentDisposition( $attachment_id, $metadata, null );
243 $_metadata = array(
244 "width" => isset( $metadata[ 'width' ] ) ? $metadata[ 'width' ] : null,
245 "height" => isset( $metadata[ 'height' ] ) ? $metadata[ 'height' ] : null,
246 'object-id' => $attachment_id,
247 'source-id' => md5( $attachment_id . ud_get_stateless_media()->get( 'sm.bucket' ) ),
248 'file-hash' => md5( $metadata[ 'file' ] )
249 );
250
251 if(file_exists($fullsizepath)){
252
253 /* Add default image */
254 $media = $client->add_media( $_mediaOptions = array_filter( array(
255 'force' => true,
256 'name' => $file,
257 'absolutePath' => wp_normalize_path( get_attached_file( $attachment_id ) ),
258 'cacheControl' => $_cacheControl,
259 'contentDisposition' => $_contentDisposition,
260 'mimeType' => get_post_mime_type( $attachment_id ),
261 'metadata' => $_metadata
262 ) ));
263
264 // Stateless mode: we don't need the local version.
265 if(ud_get_stateless_media()->get( 'sm.mode' ) === 'stateless'){
266 unlink($fullsizepath);
267 }
268 }
269
270 /* Now we go through all available image sizes and upload them to Google Storage */
271 if( !empty( $metadata[ 'sizes' ] ) && is_array( $metadata[ 'sizes' ] ) ) {
272
273 $path = wp_normalize_path( dirname( get_attached_file( $attachment_id ) ) );
274 $mediaPath = wp_normalize_path( trim( dirname( $metadata[ 'file' ] ), '\/\\' ) );
275
276 foreach( (array) $metadata[ 'sizes' ] as $image_size => $data ) {
277
278 $absolutePath = wp_normalize_path( $path . '/' . $data[ 'file' ] );
279
280 if( !file_exists($absolutePath)){
281 continue;
282 }
283
284 /* Add 'image size' image */
285 $media = $client->add_media( array(
286 'force' => true,
287 'name' => $file_path = trim($mediaPath . '/' . $data[ 'file' ], '/'),
288 'absolutePath' => $absolutePath,
289 'cacheControl' => $_cacheControl,
290 'contentDisposition' => $_contentDisposition,
291 'mimeType' => $data[ 'mime-type' ],
292 'metadata' => array_merge( $_metadata, array(
293 'width' => $data['width'],
294 'height' => $data['height'],
295 'child-of' => $attachment_id,
296 'file-hash' => md5( $data[ 'file' ] )
297 ))
298 ));
299
300 /* Break if we have errors. */
301 if( !is_wp_error( $media ) ) {
302 // Stateless mode: we don't need the local version.
303 if(ud_get_stateless_media()->get( 'sm.mode' ) === 'stateless'){
304 unlink($absolutePath);
305 }
306 }
307
308 }
309
310 }
311
312 }
313 }
314 // End add_media
315 }
316
317 }
318
319 }
320