PluginProbe
WP-Stateless – Google Cloud Storage / 2.2.3
WP-Stateless – Google Cloud Storage v2.2.3
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 / class-utility.php

class-utility.php in WP-Stateless – Google Cloud Storage 2.2.3, at lib/classes/class-utility.php

382 lines 13.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Helper Functions List
4 *
5 * Can be called via Singleton. Since Singleton uses magic method __call().
6 * Example:
7 *
8 * Add Media to GS storage:
9 * ud_get_stateless_media()->add_media( false, $post_id );
10 *
11 * @class Utility
12 */
13 namespace wpCloud\StatelessMedia {
14
15 if( !class_exists( 'wpCloud\StatelessMedia\Utility' ) ) {
16
17 class Utility {
18
19 /**
20 * ChromeLogger
21 *
22 * @author potanin@UD
23 * @param $data
24 */
25 static public function log( $data ) {
26
27 if( !class_exists( 'wpCloud\StatelessMedia\Logger' )) {
28 include_once( __DIR__ . '/class-logger.php' );
29 }
30
31 if( !class_exists( 'wpCloud\StatelessMedia\Logger' )) {
32 return;
33 }
34
35 if( defined( 'WP_STATELESS_CONSOLE_LOG' ) && WP_STATELESS_CONSOLE_LOG ) {
36 Logger::log( '[wp-stateless]', $data );
37 }
38
39 }
40
41 /**
42 * Override Cache Control
43 * @param $cacheControl
44 * @return mixed
45 */
46 public static function override_cache_control( $cacheControl ) {
47 return ud_get_stateless_media()->get( 'sm.cache_control' );
48 }
49
50 /**
51 * wp_normalize_path was added in 3.9.0
52 *
53 * @param $path
54 * @return mixed|string
55 *
56 */
57 public static function normalize_path( $path ) {
58
59 if( function_exists( 'wp_normalize_path' ) ) {
60 return wp_normalize_path( $path );
61 }
62
63 $path = str_replace( '\\', '/', $path );
64 $path = preg_replace( '|/+|','/', $path );
65 return $path;
66
67 }
68
69 /**
70 * Randomize file name
71 * @param $filename
72 * @return string
73 */
74 public static function randomize_filename( $filename ) {
75 $return = apply_filters('stateless_skip_cache_busting', null, $filename);
76 if($return){
77 return $return;
78 }
79 $info = pathinfo($filename);
80 $ext = empty($info['extension']) ? '' : '' . $info['extension'];
81 $_parts = array();
82 $rand = substr(md5(time()), 0, 8);
83
84 $body_rewrite_types = ud_get_stateless_media()->get( 'sm.body_rewrite_types' );
85 if(empty($info['extension']) || strpos($body_rewrite_types, $info['extension']) === false){
86 return $filename;
87 }
88
89 if(strpos($filename, $rand) !== false){
90 return $filename;
91 }
92
93 if (strpos($info['filename'], '@')) {
94 $_cleanName = explode('@', $info['filename'])[0];
95 $_retna = explode('@', $info['filename'])[1];
96 $_parts[] = $rand;
97 $_parts[] = '-';
98 $_parts[] = strtolower($_cleanName);
99 $_parts[] = '@' . strtolower($_retna);
100 } else {
101 $_parts[] = $rand;
102 $_parts[] = '-';
103 $_parts[] = strtolower($info['filename']);
104 }
105
106 $filename = join('', $_parts);
107 if(!empty($ext)){
108 $filename .= '.' . $ext;
109 }
110
111 return $filename;
112 }
113
114 /**
115 * Get Media Item Content Disposition
116 *
117 * @param null $attachment_id
118 * @param array $metadata
119 * @param array $data
120 * @return string
121 */
122 public static function getContentDisposition( $attachment_id = null, $metadata = array(), $data = array() ) {
123 // return 'Content-Disposition: attachment; filename=some-file.sql';
124
125 return apply_filters( 'sm:item:contentDisposition', null, array( 'attachment_id' => $attachment_id, 'mime_type' => get_post_mime_type( $attachment_id ), 'metadata' => $metadata, 'data' => $data ) );
126
127 }
128
129 /**
130 * @param null $attachment_id
131 * @param array $metadata
132 * @param array $data
133 * @return string
134 */
135 public static function getCacheControl( $attachment_id = null, $metadata = array(), $data = array() ) {
136
137 if( !$attachment_id ) {
138 return apply_filters( 'sm:item:cacheControl', 'private, no-cache, no-store', $attachment_id, array( 'attachment_id' => null, 'mime_type' => null, 'metadata' => $metadata, 'data' => $data ) );
139 }
140
141 $_mime_type = get_post_mime_type( $attachment_id );
142
143 // Treat images as public.
144 if( strpos( $_mime_type, 'image/' ) !== false ) {
145 return apply_filters( 'sm:item:cacheControl', 'public, max-age=36000, must-revalidate', array( 'attachment_id' => $attachment_id, 'mime_type' => null, 'metadata' => $metadata, 'data' => $data ) );
146 }
147
148 // Treat images as public.
149 if( strpos( $_mime_type, 'sql' ) !== false ) {
150 return apply_filters( 'sm:item:cacheControl', 'private, no-cache, no-store', array( 'attachment_id' => $attachment_id, 'mime_type' => null, 'metadata' => $metadata, 'data' => $data ) );
151 }
152
153 return apply_filters( 'sm:item:cacheControl', 'public, max-age=30, no-store, must-revalidate', array( 'attachment_id' => $attachment_id, 'mime_type' => null, 'metadata' => $metadata, 'data' => $data ) );
154
155 }
156
157 /**
158 * Add/Update Media to Bucket
159 * Fired for every action with image add or update
160 *
161 * @action wp_generate_attachment_metadata
162 * @author peshkov@UD
163 * @param $metadata
164 * @param $attachment_id
165 * @param $force Whether to force the upload incase of it's already exists.
166 * @return bool|string
167 */
168 public static function add_media( $metadata, $attachment_id, $force = false, $args = array() ) {
169 global $stateless_synced_full_size;
170 $file = '';
171 $upload_dir = wp_upload_dir();
172 $args = wp_parse_args($args, array(
173 'no_thumb' => false,
174 ));
175
176 /* Get metadata in case if method is called directly. */
177 if( current_filter() !== 'wp_generate_attachment_metadata' && current_filter() !== 'wp_update_attachment_metadata' ) {
178 $metadata = wp_get_attachment_metadata( $attachment_id );
179 }
180
181 $client = ud_get_stateless_media()->get_client();
182
183 if( !is_wp_error( $client ) ) {
184
185 $fullsizepath = wp_normalize_path( get_attached_file( $attachment_id ) );
186 // Make non-images uploadable.
187 if( empty( $metadata['file'] ) && $attachment_id ) {
188 $file = str_replace( wp_normalize_path(trailingslashit( $upload_dir[ 'basedir' ] )), '', $fullsizepath );
189 if(empty($metadata)){
190 $metadata = array();
191 }
192 $mime_type = get_post_mime_type( $attachment_id );
193 if($mime_type != "application/pdf"){
194 $metadata["file"] = $file;
195 }
196 }
197
198 $file = wp_normalize_path( !empty($metadata[ 'file' ])?$metadata[ 'file' ]:$file );
199
200 $image_host = ud_get_stateless_media()->get_gs_host();
201 $bucketLink = apply_filters('wp_stateless_bucket_link', $image_host);
202
203 $_metadata = array(
204 "width" => isset( $metadata[ 'width' ] ) ? $metadata[ 'width' ] : null,
205 "height" => isset( $metadata[ 'height' ] ) ? $metadata[ 'height' ] : null,
206 'object-id' => $attachment_id,
207 'source-id' => md5( $attachment_id.ud_get_stateless_media()->get( 'sm.bucket' ) ),
208 'file-hash' => md5( $file )
209 );
210
211 if($attachment_id && !empty($metadata) && !$force){
212 $db_metadata = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
213 if($db_metadata != $metadata){
214 $force = true;
215 }
216 }
217
218 /* Add default image */
219 $media = $client->add_media( $_mediaOptions = array_filter( array(
220 'force' => $force && $stateless_synced_full_size != $attachment_id,
221 'name' => $file,
222 'absolutePath' => wp_normalize_path( get_attached_file( $attachment_id ) ),
223 'cacheControl' => $_cacheControl = self::getCacheControl( $attachment_id, $metadata, null ),
224 'contentDisposition' => $_contentDisposition = self::getContentDisposition( $attachment_id, $metadata, null ),
225 'mimeType' => get_post_mime_type( $attachment_id ),
226 'metadata' => $_metadata
227 ) ));
228
229 // Break if we have errors.
230 // @note Errors could be due to key being invalid or now having sufficient permissions in which case should notify user.
231 if( is_wp_error( $media ) ) {
232 return $metadata;
233 }
234
235 /* Add Google Storage metadata to our attachment */
236 $fileLink = $bucketLink . '/' . ( !empty($media['name']) ? $media['name'] : $file );
237
238 $cloud_meta = array(
239 'id' => $media[ 'id' ],
240 'name' => !empty($media['name']) ? $media['name'] : $file,
241 'fileLink' => $fileLink,
242 'storageClass' => $media[ 'storageClass' ],
243 'mediaLink' => $media[ 'mediaLink' ],
244 'selfLink' => $media[ 'selfLink' ],
245 'bucket' => ud_get_stateless_media()->get( 'sm.bucket' ),
246 'object' => $media,
247 'sizes' => array(),
248 );
249
250 if( isset( $_cacheControl ) && $_cacheControl ) {
251 //update_post_meta( $attachment_id, 'sm_cloud:cacheControl', $_cacheControl );
252 $cloud_meta[ 'cacheControl' ] = $_cacheControl;
253 }
254
255 if( isset( $_contentDisposition ) && $_contentDisposition ) {
256 //update_post_meta( $attachment_id, 'sm_cloud:contentDisposition', $_contentDisposition );
257 $cloud_meta[ 'contentDisposition' ] = $_contentDisposition;
258 }
259
260 if( empty( $metadata[ 'sizes' ] ) ) {
261 // @note This could happen if WordPress does not have any wp_get_image_editor(), e.g. Imagemagic not installed.
262 }
263
264 /* Now we go through all available image sizes and upload them to Google Storage */
265 if( !empty( $metadata[ 'sizes' ] ) && is_array( $metadata[ 'sizes' ] ) && $args['no_thumb'] != true ) {
266
267 $path = wp_normalize_path( dirname( get_attached_file( $attachment_id ) ) );
268 $mediaPath = wp_normalize_path( trim( dirname( $file ), '\/\\' ) );
269
270 /**
271 * @see https://github.com/wpCloud/wp-stateless/issues/343
272 **/
273 $mediaPath = $mediaPath === '.' ? '' : $mediaPath;
274
275 foreach( (array) $metadata[ 'sizes' ] as $image_size => $data ) {
276
277 $absolutePath = wp_normalize_path( $path . '/' . $data[ 'file' ] );
278
279 /* Add 'image size' image */
280 $media = $client->add_media( array(
281 'force' => $force,
282 'name' => $file_path = trim($mediaPath . '/' . $data[ 'file' ], '/'),
283 'absolutePath' => $absolutePath,
284 'cacheControl' => $_cacheControl,
285 'contentDisposition' => $_contentDisposition,
286 'mimeType' => $data[ 'mime-type' ],
287 'metadata' => array_merge( $_metadata, array(
288 'width' => $data['width'],
289 'height' => $data['height'],
290 'child-of' => $attachment_id,
291 'file-hash' => md5( $data[ 'file' ] )
292 ))
293 ));
294
295 /* Break if we have errors. */
296 if( !is_wp_error( $media ) ) {
297
298 $fileLink = $bucketLink . '/' . (!empty($media['name']) ? $media['name'] : $file_path);
299
300 // @note We don't add storageClass because it's same as parent...
301 $cloud_meta[ 'sizes' ][ $image_size ] = array(
302 'id' => $mediaPath . '/' . $media[ 'id' ],
303 'name' => !empty($media['name']) ? $media['name'] : $file_path,
304 'fileLink' => $fileLink,
305 'mediaLink' => $media[ 'mediaLink' ],
306 'selfLink' => $media[ 'selfLink' ]
307 );
308
309 // Stateless mode: we don't need the local version.
310 if(ud_get_stateless_media()->get( 'sm.mode' ) === 'stateless'){
311 unlink($absolutePath);
312 }
313 }
314
315
316 }
317
318 }
319
320 // Stateless mode: we don't need the local version.
321 if(ud_get_stateless_media()->get( 'sm.mode' ) === 'stateless' && $args['no_thumb'] != true){
322 unlink($fullsizepath);
323 }
324
325 update_post_meta( $attachment_id, 'sm_cloud', $cloud_meta );
326
327 if($args['no_thumb'] == true){
328 $stateless_synced_full_size = $attachment_id;
329 }
330 }
331
332 return $metadata;
333 }
334
335 /**
336 * Remove Media from Bucket by post ID
337 * Fired on calling function wp_delete_attachment()
338 *
339 * @todo: add error logging. peshkov@UD
340 * @see wp_delete_attachment()
341 * @action delete_attachment
342 * @author peshkov@UD
343 * @param $post_id
344 */
345 public static function remove_media( $post_id ) {
346 /* Get attachments metadata */
347 $metadata = wp_get_attachment_metadata( $post_id );
348
349 /* Be sure we have the same bucket in settings and have GS object's name before proceed. */
350 if(
351 isset( $metadata[ 'gs_name' ] ) &&
352 isset( $metadata[ 'gs_bucket' ] ) &&
353 $metadata[ 'gs_bucket' ] == ud_get_stateless_media()->get( 'sm.bucket' )
354 ) {
355
356 $client = ud_get_stateless_media()->get_client();
357 if( !is_wp_error( $client ) ) {
358
359 /* Remove default image */
360 $client->remove_media( $metadata[ 'gs_name' ] );
361
362 /* Now, go through all sizes and remove 'image sizes' images from Bucket too. */
363 if( !empty( $metadata[ 'sizes' ] ) && is_array( $metadata[ 'sizes' ] ) ) {
364 foreach( $metadata[ 'sizes' ] as $k => $v ) {
365 if( !empty( $v[ 'gs_name' ] ) ) {
366 $client->remove_media( $v[ 'gs_name' ] );
367 }
368 }
369 }
370
371 }
372
373 }
374
375 }
376
377 }
378
379 }
380
381 }
382