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

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

377 lines 13.4 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 foreach( (array) $metadata[ 'sizes' ] as $image_size => $data ) {
271
272 $absolutePath = wp_normalize_path( $path . '/' . $data[ 'file' ] );
273
274 /* Add 'image size' image */
275 $media = $client->add_media( array(
276 'force' => $force,
277 'name' => $file_path = trim($mediaPath . '/' . $data[ 'file' ], '/'),
278 'absolutePath' => $absolutePath,
279 'cacheControl' => $_cacheControl,
280 'contentDisposition' => $_contentDisposition,
281 'mimeType' => $data[ 'mime-type' ],
282 'metadata' => array_merge( $_metadata, array(
283 'width' => $data['width'],
284 'height' => $data['height'],
285 'child-of' => $attachment_id,
286 'file-hash' => md5( $data[ 'file' ] )
287 ))
288 ));
289
290 /* Break if we have errors. */
291 if( !is_wp_error( $media ) ) {
292
293 $fileLink = $bucketLink . '/' . (!empty($media['name']) ? $media['name'] : $file_path);
294
295 // @note We don't add storageClass because it's same as parent...
296 $cloud_meta[ 'sizes' ][ $image_size ] = array(
297 'id' => $mediaPath . '/' . $media[ 'id' ],
298 'name' => !empty($media['name']) ? $media['name'] : $file_path,
299 'fileLink' => $fileLink,
300 'mediaLink' => $media[ 'mediaLink' ],
301 'selfLink' => $media[ 'selfLink' ]
302 );
303
304 // Stateless mode: we don't need the local version.
305 if(ud_get_stateless_media()->get( 'sm.mode' ) === 'stateless'){
306 unlink($absolutePath);
307 }
308 }
309
310
311 }
312
313 }
314
315 // Stateless mode: we don't need the local version.
316 if(ud_get_stateless_media()->get( 'sm.mode' ) === 'stateless' && $args['no_thumb'] != true){
317 unlink($fullsizepath);
318 }
319
320 update_post_meta( $attachment_id, 'sm_cloud', $cloud_meta );
321
322 if($args['no_thumb'] == true){
323 $stateless_synced_full_size = $attachment_id;
324 }
325 }
326
327 return $metadata;
328 }
329
330 /**
331 * Remove Media from Bucket by post ID
332 * Fired on calling function wp_delete_attachment()
333 *
334 * @todo: add error logging. peshkov@UD
335 * @see wp_delete_attachment()
336 * @action delete_attachment
337 * @author peshkov@UD
338 * @param $post_id
339 */
340 public static function remove_media( $post_id ) {
341 /* Get attachments metadata */
342 $metadata = wp_get_attachment_metadata( $post_id );
343
344 /* Be sure we have the same bucket in settings and have GS object's name before proceed. */
345 if(
346 isset( $metadata[ 'gs_name' ] ) &&
347 isset( $metadata[ 'gs_bucket' ] ) &&
348 $metadata[ 'gs_bucket' ] == ud_get_stateless_media()->get( 'sm.bucket' )
349 ) {
350
351 $client = ud_get_stateless_media()->get_client();
352 if( !is_wp_error( $client ) ) {
353
354 /* Remove default image */
355 $client->remove_media( $metadata[ 'gs_name' ] );
356
357 /* Now, go through all sizes and remove 'image sizes' images from Bucket too. */
358 if( !empty( $metadata[ 'sizes' ] ) && is_array( $metadata[ 'sizes' ] ) ) {
359 foreach( $metadata[ 'sizes' ] as $k => $v ) {
360 if( !empty( $v[ 'gs_name' ] ) ) {
361 $client->remove_media( $v[ 'gs_name' ] );
362 }
363 }
364 }
365
366 }
367
368 }
369
370 }
371
372 }
373
374 }
375
376 }
377