PluginProbe
WP-Stateless – Google Cloud Storage / 2.1.7
WP-Stateless – Google Cloud Storage v2.1.7
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.1.7, at lib/classes/class-utility.php

347 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 * 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 $info = pathinfo($filename);
76 $ext = empty($info['extension']) ? '' : '' . $info['extension'];
77 $_parts = array();
78 if (strpos($info['filename'], '@')) {
79 $_cleanName = explode('@', $info['filename'])[0];
80 $_retna = explode('@', $info['filename'])[1];
81 $_parts[] = substr(md5(time()), 0, 8);
82 $_parts[] = '-';
83 $_parts[] = strtolower($_cleanName);
84 $_parts[] = '@' . strtolower($_retna);
85 } else {
86 $_parts[] = substr(md5(time()), 0, 8);
87 $_parts[] = '-';
88 $_parts[] = strtolower($info['filename']);
89 }
90
91 $filename = join('', $_parts);
92 if(!empty($ext)){
93 $filename .= '.' . $ext;
94 }
95
96 return $filename;
97 }
98
99 /**
100 * Get Media Item Content Disposition
101 *
102 * @param null $attachment_id
103 * @param array $metadata
104 * @param array $data
105 * @return string
106 */
107 public static function getContentDisposition( $attachment_id = null, $metadata = array(), $data = array() ) {
108 // return 'Content-Disposition: attachment; filename=some-file.sql';
109
110 return apply_filters( 'sm:item:contentDisposition', null, array( 'attachment_id' => $attachment_id, 'mime_type' => get_post_mime_type( $attachment_id ), 'metadata' => $metadata, 'data' => $data ) );
111
112 }
113
114 /**
115 * @param null $attachment_id
116 * @param array $metadata
117 * @param array $data
118 * @return string
119 */
120 public static function getCacheControl( $attachment_id = null, $metadata = array(), $data = array() ) {
121
122 if( !$attachment_id ) {
123 return apply_filters( 'sm:item:cacheControl', 'private, no-cache, no-store', $attachment_id, array( 'attachment_id' => null, 'mime_type' => null, 'metadata' => $metadata, 'data' => $data ) );
124 }
125
126 $_mime_type = get_post_mime_type( $attachment_id );
127
128 // Treat images as public.
129 if( strpos( $_mime_type, 'image/' ) !== false ) {
130 return apply_filters( 'sm:item:cacheControl', 'public, max-age=36000, must-revalidate', array( 'attachment_id' => $attachment_id, 'mime_type' => null, 'metadata' => $metadata, 'data' => $data ) );
131 }
132
133 // Treat images as public.
134 if( strpos( $_mime_type, 'sql' ) !== false ) {
135 return apply_filters( 'sm:item:cacheControl', 'private, no-cache, no-store', array( 'attachment_id' => $attachment_id, 'mime_type' => null, 'metadata' => $metadata, 'data' => $data ) );
136 }
137
138 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 ) );
139
140 }
141
142 /**
143 * Add/Update Media to Bucket
144 * Fired for every action with image add or update
145 *
146 * @action wp_generate_attachment_metadata
147 * @author peshkov@UD
148 * @param $metadata
149 * @param $attachment_id
150 * @param $force Whether to force the upload incase of it's already exists.
151 * @return bool|string
152 */
153 public static function add_media( $metadata, $attachment_id, $force = false ) {
154 $upload_dir = wp_upload_dir();
155
156 /* Get metadata in case if method is called directly. */
157 if( current_filter() !== 'wp_generate_attachment_metadata' && current_filter() !== 'wp_update_attachment_metadata' ) {
158 $metadata = wp_get_attachment_metadata( $attachment_id );
159 }
160
161 $client = ud_get_stateless_media()->get_client();
162
163 if( !is_wp_error( $client ) ) {
164
165 $fullsizepath = wp_normalize_path( get_attached_file( $attachment_id ) );
166 // Make non-images uploadable.
167 if( empty( $metadata['file'] ) && $attachment_id ) {
168 $metadata = array( "file" => str_replace( trailingslashit( $upload_dir[ 'basedir' ] ), '', get_attached_file( $attachment_id ) ) );
169 }
170
171 $file = wp_normalize_path( $metadata[ 'file' ] );
172
173 $image_host = ud_get_stateless_media()->get_gs_host();
174 $bucketLink = apply_filters('wp_stateless_bucket_link', $image_host);
175
176 $_metadata = array(
177 "width" => isset( $metadata[ 'width' ] ) ? $metadata[ 'width' ] : null,
178 "height" => isset( $metadata[ 'height' ] ) ? $metadata[ 'height' ] : null,
179 'object-id' => $attachment_id,
180 'source-id' => md5( $attachment_id.ud_get_stateless_media()->get( 'sm.bucket' ) ),
181 'file-hash' => md5( $metadata[ 'file' ] )
182 );
183
184 if($attachment_id && !empty($metadata) && !$force){
185 $db_metadata = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
186 if($db_metadata != $metadata){
187 $force = true;
188 }
189 }
190
191 /* Add default image */
192 $media = $client->add_media( $_mediaOptions = array_filter( array(
193 'force' => $force,
194 'name' => $file,
195 'absolutePath' => wp_normalize_path( get_attached_file( $attachment_id ) ),
196 'cacheControl' => $_cacheControl = self::getCacheControl( $attachment_id, $metadata, null ),
197 'contentDisposition' => $_contentDisposition = self::getContentDisposition( $attachment_id, $metadata, null ),
198 'mimeType' => get_post_mime_type( $attachment_id ),
199 'metadata' => $_metadata
200 ) ));
201
202 // Break if we have errors.
203 // @note Errors could be due to key being invalid or now having sufficient permissions in which case should notify user.
204 if( is_wp_error( $media ) ) {
205 return $metadata;
206 }
207
208 /* Add Google Storage metadata to our attachment */
209 $fileLink = $bucketLink . '/' . ( !empty($media['name']) ? $media['name'] : $file );
210
211 $cloud_meta = array(
212 'id' => $media[ 'id' ],
213 'name' => !empty($media['name']) ? $media['name'] : $file,
214 'fileLink' => $fileLink,
215 'storageClass' => $media[ 'storageClass' ],
216 'mediaLink' => $media[ 'mediaLink' ],
217 'selfLink' => $media[ 'selfLink' ],
218 'bucket' => ud_get_stateless_media()->get( 'sm.bucket' ),
219 'object' => $media,
220 'sizes' => array(),
221 );
222
223 if( isset( $_cacheControl ) && $_cacheControl ) {
224 //update_post_meta( $attachment_id, 'sm_cloud:cacheControl', $_cacheControl );
225 $cloud_meta[ 'cacheControl' ] = $_cacheControl;
226 }
227
228 if( isset( $_contentDisposition ) && $_contentDisposition ) {
229 //update_post_meta( $attachment_id, 'sm_cloud:contentDisposition', $_contentDisposition );
230 $cloud_meta[ 'contentDisposition' ] = $_contentDisposition;
231 }
232
233 if( empty( $metadata[ 'sizes' ] ) ) {
234 // @note This could happen if WordPress does not have any wp_get_image_editor(), e.g. Imagemagic not installed.
235 }
236
237 /* Now we go through all available image sizes and upload them to Google Storage */
238 if( !empty( $metadata[ 'sizes' ] ) && is_array( $metadata[ 'sizes' ] ) ) {
239
240 $path = wp_normalize_path( dirname( get_attached_file( $attachment_id ) ) );
241 $mediaPath = wp_normalize_path( trim( dirname( $metadata[ 'file' ] ), '\/\\' ) );
242
243 foreach( (array) $metadata[ 'sizes' ] as $image_size => $data ) {
244
245 $absolutePath = wp_normalize_path( $path . '/' . $data[ 'file' ] );
246
247 /* Add 'image size' image */
248 $media = $client->add_media( array(
249 'force' => $force,
250 'name' => $file_path = trim($mediaPath . '/' . $data[ 'file' ], '/'),
251 'absolutePath' => $absolutePath,
252 'cacheControl' => $_cacheControl,
253 'contentDisposition' => $_contentDisposition,
254 'mimeType' => $data[ 'mime-type' ],
255 'metadata' => array_merge( $_metadata, array(
256 'width' => $data['width'],
257 'height' => $data['height'],
258 'child-of' => $attachment_id,
259 'file-hash' => md5( $data[ 'file' ] )
260 ))
261 ));
262
263 /* Break if we have errors. */
264 if( !is_wp_error( $media ) ) {
265
266 $fileLink = $bucketLink . '/' . (!empty($media['name']) ? $media['name'] : $file_path);
267
268 // @note We don't add storageClass because it's same as parent...
269 $cloud_meta[ 'sizes' ][ $image_size ] = array(
270 'id' => $mediaPath . '/' . $media[ 'id' ],
271 'name' => !empty($media['name']) ? $media['name'] : $file_path,
272 'fileLink' => $fileLink,
273 'mediaLink' => $media[ 'mediaLink' ],
274 'selfLink' => $media[ 'selfLink' ]
275 );
276
277 // Stateless mode: we don't need the local version.
278 if(ud_get_stateless_media()->get( 'sm.mode' ) === 'stateless'){
279 unlink($absolutePath);
280 }
281 }
282
283
284 }
285
286 }
287
288 // Stateless mode: we don't need the local version.
289 if(ud_get_stateless_media()->get( 'sm.mode' ) === 'stateless'){
290 unlink($fullsizepath);
291 }
292
293 update_post_meta( $attachment_id, 'sm_cloud', $cloud_meta );
294
295 }
296
297 return $metadata;
298 }
299
300 /**
301 * Remove Media from Bucket by post ID
302 * Fired on calling function wp_delete_attachment()
303 *
304 * @todo: add error logging. peshkov@UD
305 * @see wp_delete_attachment()
306 * @action delete_attachment
307 * @author peshkov@UD
308 * @param $post_id
309 */
310 public static function remove_media( $post_id ) {
311 /* Get attahcment's metadata */
312 $metadata = wp_get_attachment_metadata( $post_id );
313
314 /* Be sure we have the same bucket in settings and have GS object's name before proceed. */
315 if(
316 isset( $metadata[ 'gs_name' ] ) &&
317 isset( $metadata[ 'gs_bucket' ] ) &&
318 $metadata[ 'gs_bucket' ] == ud_get_stateless_media()->get( 'sm.bucket' )
319 ) {
320
321 $client = ud_get_stateless_media()->get_client();
322 if( !is_wp_error( $client ) ) {
323
324 /* Remove default image */
325 $client->remove_media( $metadata[ 'gs_name' ] );
326
327 /* Now, go through all sizes and remove 'image sizes' images from Bucket too. */
328 if( !empty( $metadata[ 'sizes' ] ) && is_array( $metadata[ 'sizes' ] ) ) {
329 foreach( $metadata[ 'sizes' ] as $k => $v ) {
330 if( !empty( $v[ 'gs_name' ] ) ) {
331 $client->remove_media( $v[ 'gs_name' ] );
332 }
333 }
334 }
335
336 }
337
338 }
339
340 }
341
342 }
343
344 }
345
346 }
347