PluginProbe
Media Cloud Sync / 1.2.13
Media Cloud Sync v1.2.13
1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 All 34 releases
media-cloud-sync / includes / config / utils.php

utils.php in Media Cloud Sync 1.2.13, at includes/config/utils.php

745 lines 23.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Dudlewebs\WPMCS;
4
5 defined('ABSPATH') || exit;
6
7 class Utils {
8 /**
9 * Check a variable is empty
10 * @since 1.0.0
11 * @param string|integer|array|float
12 * @return boolean
13 */
14 public static function is_empty($var){
15 if (is_array($var)) {
16 return empty($var);
17 } else {
18 return ($var === null || $var === false || $var === '');
19 }
20 }
21
22 /**
23 * Function To get Plugin Specific Wordpress Option
24 * @since 1.0.0
25 * @return array|boolean|string|integer|float|double
26 */
27 public static function get_option($key, $default = false, $meta_name = false, $expire = false){
28 $data = Cache::get_object_cache( $key, false, $meta_name, $expire );
29 return $data == false ? $default : $data;
30 }
31
32 /**
33 * Function To update Plugin Specific Wordpress Option
34 * @since 1.0.0
35 * @return boolean
36 */
37 public static function update_option($key, $options, $meta_name = false, $expire = false){
38 return Cache::set_object_cache( $key, $options, false, $meta_name, $expire );
39 }
40
41 /**
42 * Function To delete Plugin Specific Wordpress Option
43 * @since 1.0.0
44 * @return boolean
45 */
46 public static function delete_option($key, $meta_name = false){
47 return Cache::delete_object_cache( $key, false, $meta_name );
48 }
49
50 /**
51 * Function To get Plugin Specific Wordpress post meta
52 * @since 1.0.0
53 * @return array|boolean|string|integer|float|double
54 */
55 public static function get_meta($post_id, $key, $default = false, $meta_name = false, $expire = false){
56 $data = Cache::get_object_cache( $key, $post_id, $meta_name, $expire );
57 return $data == false ? $default : $data;
58 }
59
60 /**
61 * Function To update Plugin Specific Wordpress post meta
62 * @since 1.0.0
63 * @return boolean
64 */
65 public static function update_meta($post_id, $key, $options, $meta_name = false, $expire = false){
66 return Cache::set_object_cache( $key, $options, $post_id, $meta_name, $expire );
67 }
68
69 /**
70 * Function To delete Plugin Specific Wordpress post meta
71 * @since 1.0.0
72 * @return boolean
73 */
74 public static function delete_meta($post_id, $key, $meta_name = false){
75 return Cache::delete_object_cache( $key, $post_id, $meta_name );
76 }
77
78 /**
79 * Function To get Plugin Specific Wordpress user meta
80 * @since 1.0.0
81 * @return array|boolean|string|integer|float|double
82 */
83 public static function get_user_meta($post_id, $key, $default = false, $meta_name = false, $expire = false){
84 $data = Cache::get_object_cache( $key, $post_id, $meta_name, $expire, true );
85 return $data == false ? $default : $data;
86 }
87
88 /**
89 * Function To update Plugin Specific Wordpress user meta
90 * @since 1.0.0
91 * @return boolean
92 */
93 public static function update_user_meta($post_id, $key, $options, $meta_name = false, $expire = false){
94 return Cache::set_object_cache( $key, $options, $post_id, $meta_name, $expire, true );
95 }
96
97 /**
98 * Function To delete Plugin Specific Wordpress user meta
99 * @since 1.0.0
100 * @return boolean
101 */
102 public static function delete_user_meta($post_id, $key, $meta_name = false){
103 return Cache::delete_object_cache( $key, $post_id, $meta_name, true );
104 }
105
106 /**
107 * Function To get Current credentials
108 * @since 1.0.0
109 * @return array|boolean|string|integer|float|double
110 */
111 public static function get_credentials($option='', $default=false){
112 $current_setttings = self::get_option('credentials',[], Schema::getConstant('GLOBAL_SETTINGS_KEY'));
113 if(isset($current_setttings) && !empty($current_setttings)){
114 if(isset($option) && !empty($option)){
115 if(isset($current_setttings[$option])) {
116 return $current_setttings[$option];
117 } else {
118 return $default;
119 }
120 } else {
121 return $current_setttings;
122 }
123 } else {
124 return $default;
125 }
126 }
127
128 /**
129 * Function To get Current settings
130 * @since 1.0.0
131 * @return array|boolean|string|integer|float|double
132 */
133 public static function get_settings($option='', $default=false){
134 $current_setttings = self::get_option('settings',[], Schema::getConstant('GLOBAL_SETTINGS_KEY'));
135 if(isset($current_setttings) && !empty($current_setttings)){
136 if(isset($option) && !empty($option)){
137 if(isset($current_setttings[$option])) {
138 return $current_setttings[$option];
139 } else {
140 return $default;
141 }
142 } else {
143 return $current_setttings;
144 }
145 } else {
146 return $default;
147 }
148 }
149
150 /**
151 * Function To get Current statuses
152 * @since 1.0.0
153 * @return array|boolean|string|integer|float|double
154 */
155 public static function get_status($option='', $default=false){
156 $current_setttings = self::get_option('status',[], Schema::getConstant('STATUS_KEY'));
157 if(isset($current_setttings) && !empty($current_setttings)){
158 if(isset($option) && !empty($option)){
159 if(isset($current_setttings[$option])) {
160 return $current_setttings[$option];
161 } else {
162 return $default;
163 }
164 } else {
165 return $current_setttings;
166 }
167 } else {
168 return $default;
169 }
170 }
171
172 /**
173 * Function To set statuses
174 * @since 1.0.0
175 *
176 */
177 public static function set_status($option='', $data=[]){
178 $current_setttings = self::get_option('status',[], Schema::getConstant('STATUS_KEY'));
179 if(isset($option) && !empty($option)){
180 $current_setttings[$option] = $data;
181 return self::update_option('status', $current_setttings, Schema::getConstant('STATUS_KEY'));
182 } else {
183 return false;
184 }
185 }
186
187 /**
188 * Function To get Current Service
189 * @since 1.0.0
190 * @return array|boolean|string|integer|float|double
191 */
192 public static function get_service(){
193 $current_service = self::get_credentials('service', '');
194 if(isset($current_service) && !empty($current_service)){
195 return $current_service;
196 } else {
197 return false;
198 }
199 }
200
201 /**
202 * Function To get Current config
203 * @since 1.0.0
204 * @return array|boolean|string|integer|float|double
205 */
206 public static function get_config($option='', $default=false){
207 $current_setttings = self::get_credentials('config',[]);
208 if(isset($current_setttings) && !empty($current_setttings)){
209 if(isset($option) && !empty($option)){
210 if(isset($current_setttings[$option])) {
211 return $current_setttings[$option];
212 } else {
213 return $default;
214 }
215 } else {
216 return $current_setttings;
217 }
218 } else {
219 return $default;
220 }
221 }
222
223 /**
224 * Function to check serving media environment is ok
225 * @since 1.0.0
226 * @return boolean
227 */
228 public static function is_ok_to_serve($attachment_id = false, $check_id = true){
229 return (
230 self::get_service() &&
231 self::get_settings('rewrite_url') &&
232 ( $check_id ? isset($attachment_id) && !empty($attachment_id) : true )
233 );
234 }
235
236 /**
237 * Function to check uploading media environment is ok
238 * @since 1.0.0
239 * @return boolean
240 */
241 public static function is_ok_to_upload($attachment_id = false){
242 return (
243 self::get_service() &&
244 self::get_settings('copy_to_bucket') &&
245 isset($attachment_id) && !empty($attachment_id)
246 );
247 }
248
249 /**
250 * Function To check service is enabled
251 * @since 1.0.0
252 * @return array|boolean|string|integer|float|double
253 */
254 public static function is_service_enabled(){
255 return !!self::get_service();
256 }
257
258 /**
259 * Check whether a file exist in a list of files
260 * @since 1.0.1
261 * @return boolean
262 */
263 public static function check_existing_file_names( $filename, $files ) {
264 $fname = pathinfo( $filename, PATHINFO_FILENAME );
265 $ext = pathinfo( $filename, PATHINFO_EXTENSION );
266
267 // Edge case, file names like `.ext`.
268 if ( empty( $fname ) ) {
269 return false;
270 }
271
272 if ( $ext ) {
273 $ext = ".$ext";
274 }
275
276 $regex = '/^' . preg_quote( $fname ) . '-(?:\d+x\d+|scaled|rotated)' . preg_quote( $ext ) . '$/i';
277
278 foreach ( $files as $file ) {
279 if (
280 preg_match( $regex, wp_basename($file) ) ||
281 $filename == $file
282 ) {
283 return true;
284 }
285 }
286
287 return false;
288 }
289
290 /**
291 * Get Post Meta Data By Query
292 * @since 1.0.0
293 * @return boolean
294 */
295 public static function get_post_meta($post_id, $key, $single=false, $db_query=false){
296 global $wpdb;
297 if(!(!empty($key) || $post_id)) return false;
298
299 if($db_query) {
300 $meta_data = $wpdb->get_row( "SELECT meta_value FROM $wpdb->postmeta WHERE post_id=$post_id AND meta_key='$key'" );
301 if ($wpdb->last_error || null === $meta_data || !isset($meta_data)) {
302 return false;
303 }
304 return $meta_data->meta_value;
305 } else {
306 return get_post_meta( $post_id, $key, $single );
307 }
308 }
309
310 /**
311 * Get Image URL and path from URL
312 * Return Relative URL and Path of an attachment.
313 * @since 1.0.0
314 *
315 */
316 public static function get_attachment_source_path($file) {
317 if ( isset($file) && !empty($file) ) {
318 $uploads = wp_get_upload_dir();
319 $file_path = '';
320 $site_url = site_url('/');
321 $enable_base_path = self::get_settings('enable_base_path', true);
322 $server_base_path = self::get_settings('base_path', 'wp-content/uploads');
323 if ( $uploads && false === $uploads['error'] ) {
324
325 $uploadDir = substr( $uploads['baseurl'], strpos( $uploads['baseurl'], $site_url ) + strlen($site_url));
326
327 // Get URL and PATH
328 if ( 0 === strpos( $file, $uploads['basedir'] ) || 0 === strpos( $file, $uploads['baseurl'] ) ) { // If URL is full link
329 $file_path = str_replace( $uploads['basedir'], '', $file );
330 $file_path = str_replace( $uploads['baseurl'], '', $file_path ); // Replace if has URl
331 } else if (
332 0 === strpos( $file, str_replace('/','\\', $uploads['basedir'] )) ||
333 0 === strpos( $file, str_replace('\\','/', $uploads['baseurl'] ))
334 ) { // If URL is full link and the url is slash unified (Like: str_replace('/','\\', $dir))
335 $file_path = str_replace( str_replace('/','\\', $uploads['basedir'] ), '', $file );
336 $file_path = str_replace( str_replace('\\','/', $uploads['baseurl'] ), '', $file_path ); // Replace if has URl
337 $file_path = str_replace('\\','/', $file_path );
338 } else if ( false !== strpos( $file, $uploadDir ) ) { //If URL has sub Directory That matches end of base URL(eg: wp-content/uploads)
339 $fileDir = dirname( $file );
340 $start_pos = strpos( $fileDir, $uploadDir ) + strlen($uploadDir);
341 $subDir = substr( $fileDir, $start_pos, strlen($fileDir)); // Find Sub Directory
342 $file_name = wp_basename( $file );
343
344 $file_path = trailingslashit($subDir) . $file_name;
345 } else if($enable_base_path && $server_base_path && false !== strpos( $file, trailingslashit($server_base_path))) {
346 $fileDir = dirname( $file );
347 $start_pos = strpos( $fileDir, $server_base_path) + strlen($server_base_path);
348 $subDir = substr( $fileDir, $start_pos, strlen($fileDir)); // Find Sub Directory
349 $file_name = wp_basename( $file );
350
351 $file_path = trailingslashit($subDir) . $file_name;
352 } else if(filter_var($file, FILTER_VALIDATE_URL)) {
353 $parsed = parse_url($file);
354 $path = isset($parsed["path"]) ? $parsed["path"] : '';
355 $query = isset($parsed["query"]) ? '?'.$parsed["query"] : '';
356 $file_path = $path. $query;
357 } else {
358 $file_path = $file;
359 }
360
361 return apply_filters( 'wpmcs_get_relative_file_path_from_upload_directory', untrailingslashit(ltrim( $file_path, '/\\' )), $file );
362 }
363 }
364 return false;
365 }
366
367 /**
368 * Check extension is compatible
369 * @since 1.0.0
370 * @return boolean
371 */
372 public static function is_extension_available($path){
373 $settings = self::get_settings();
374 $path_parts = pathinfo($path);
375
376 if(!isset($path_parts['basename']) || !isset($path_parts['extension'])) return false;
377
378 $alowed = isset($settings['extensions_include']) ? $settings['extensions_include'] : [];
379 $not_allowed = isset($settings['extensions_exclude']) ? $settings['extensions_exclude'] : [];
380
381 if(
382 (in_array($path_parts['extension'], $not_allowed)) ||
383 (!empty($alowed) && !in_array($path_parts['extension'], $alowed))
384 ) {
385 return false;
386 }
387
388 $type_and_ext = wp_check_filetype_and_ext($path, $path_parts['basename']);
389 $ext = empty( $type_and_ext['ext'] ) ? '' : $type_and_ext['ext'];
390 $type = empty( $type_and_ext['type'] ) ? '' : $type_and_ext['type'];
391
392 if ( ( ! $type || ! $ext ) && ! current_user_can( 'unfiltered_upload' ) ) {
393 return false;
394 }
395
396 return true;
397 }
398
399 /**
400 * Generate prefix for object versioning
401 * @since 1.0.0
402 * @return string
403 */
404 public static function generate_object_versioning_prefix(){
405 $year_month = self::get_settings('year_month');
406 $date_format = $year_month ? 'dHis' : 'YmdHis';
407
408 // Use current time so that object version is unique
409 $time = current_time('timestamp');
410
411 $object_version = date($date_format, $time) . '/';
412 $object_version = apply_filters('wpmcs_object_version_prefix', $object_version);
413
414 return $object_version;
415 }
416
417 /**
418 * Generate Key for Objects
419 * @since 1.0.0
420 */
421 /**
422 * Generate Key for Objects
423 * @since 1.0.0
424 */
425 public static function generate_object_key($media_path, $prefix) {
426 $upload_path = '';
427 $enable_base_path = self::get_settings('enable_base_path', true);
428 $base_path = self::get_settings('base_path', 'wp-content/uploads');
429 $year_month = self::get_settings('year_month', true);
430 $media_path = ltrim( $media_path, '/' );
431 $file_name = wp_basename( $media_path );
432
433 if(!$enable_base_path) { // If base path is not enabled
434 $base_path = '';
435 }
436
437 $keep_original_folder_structure = apply_filters( 'wpmcs_keep_original_folder_structure', false );
438
439 if(isset($base_path) && !empty($base_path)) {
440 $upload_path.= preg_replace('~/+~', '/',
441 str_replace('\\', '/',
442 trim($base_path," \n\r\t\v\x00\/ ")
443 )
444 );
445 }
446
447 if($keep_original_folder_structure) {
448 $object_key = ltrim($upload_path . '/' . dirname( $media_path ) . '/' . $prefix . $file_name, '/');
449 } else {
450 if(isset($year_month) && $year_month) {
451 $year_month_prefix = self::get_year_month_from_file_path($media_path);
452 if($year_month_prefix) {
453 $upload_path.= '/'.$year_month_prefix;
454 } else {
455 $upload_path.= '/'.date("Y/m");
456 }
457 }
458
459 $object_key = ltrim($upload_path.'/'.$prefix.$file_name, '/');
460 }
461
462 return apply_filters( 'wpmcs_object_key', $object_key, $media_path, $prefix );
463 }
464
465
466 /**
467 * Check if a file path or URL follows the year/month structure and return the year/month as a string.
468 *
469 * @param string $path_or_url The relative path, absolute path, or URL to check.
470 * @return string|false The year/month string if valid, false otherwise.
471 */
472 public static function get_year_month_from_file_path( $path_or_url ) {
473 // Regex pattern to match paths and URLs containing 'YYYY/MM/' at any depth, allowing subdirectories afterward
474 $pattern = '#(?:^|/)(\d{4})/(0[1-9]|1[0-2])/[^/]+(?:/[^/]+)*$#';
475
476 // Check if the input matches the pattern
477 if ( preg_match( $pattern, $path_or_url, $matches ) ) {
478 // Return the year/month as a string in the format 'YYYY/MM'
479 return $matches[1] . '/' . $matches[2];
480 }
481
482 return false; // Invalid format
483 }
484
485
486 /**
487 * Maybe convert size to string
488 *
489 * @param int $attachment_id
490 * @param mixed $size
491 *
492 * @return null|string
493 */
494 public static function maybe_convert_size_to_string( $attachment_id, $size ) {
495 if ( is_array( $size ) ) {
496 $width = ( isset( $size[0] ) && $size[0] > 0 ) ? $size[0] : 1;
497 $height = ( isset( $size[1] ) && $size[1] > 0 ) ? $size[1] : 1;
498 $original_aspect_ratio = $width / $height;
499 $meta = wp_get_attachment_metadata( $attachment_id );
500
501 if ( ! isset( $meta['sizes'] ) || empty( $meta['sizes'] ) ) {
502 return false;
503 }
504
505 $sizes = $meta['sizes'];
506 uasort( $sizes, function ( $a, $b ) {
507 // Order by image area
508 return ( $a['width'] * $a['height'] ) - ( $b['width'] * $b['height'] );
509 } );
510
511 $near_matches = array();
512
513 foreach ( $sizes as $size => $value ) {
514 if ( $width > $value['width'] || $height > $value['height'] ) {
515 continue;
516 }
517 $aspect_ratio = $value['width'] / $value['height'];
518 if ( $aspect_ratio === $original_aspect_ratio ) {
519 return $size;
520 }
521 $near_matches[] = $size;
522 }
523 // Return nearest match
524 if ( ! empty( $near_matches ) ) {
525 return $near_matches[0];
526 }
527 }
528
529 return $size;
530 }
531
532 /**
533 * Reduce the given URL down to the simplest version of itself.
534 *
535 * Useful for matching against the full version of the URL in a full-text search
536 * or saving as a key for dictionary type lookup.
537 *
538 * @param string $url
539 *
540 * @return string
541 */
542 public static function reduce_url( $url ) {
543 $parts = static::parse_url( $url );
544 $host = isset( $parts['host'] ) ? $parts['host'] : '';
545 $port = isset( $parts['port'] ) ? ":{$parts['port']}" : '';
546 $path = isset( $parts['path'] ) ? $parts['path'] : '';
547
548 return '//' . $host . $port . $path;
549 }
550
551 /**
552 * Remove scheme from URL.
553 *
554 * @param string $url
555 * @return string
556 */
557 public static function remove_scheme( $url ) {
558 return preg_replace( '/^(?:http|https):/', '', $url );
559 }
560
561 /**
562 * Remove size from filename (image[-100x100].jpeg).
563 *
564 * @param string $url
565 * @param bool $remove_extension
566 *
567 * @return string
568 */
569 public static function remove_size_from_filename( $url, $remove_extension = false ) {
570 $url = preg_replace( '/^(\S+)-[0-9]{1,4}x[0-9]{1,4}(\.[a-zA-Z0-9\.]{2,})?/', '$1$2', $url );
571
572 $url = apply_filters( 'wpmcs_remove_size_from_filename', $url );
573
574 if ( $remove_extension ) {
575 $ext = pathinfo( $url, PATHINFO_EXTENSION );
576 $url = str_replace( ".$ext", '', $url );
577 }
578
579 return $url;
580 }
581
582 /**
583 * Is the string a URL?
584 *
585 * @param mixed $string
586 *
587 * @return bool
588 */
589 public static function is_url( $string ): bool {
590 if ( empty( $string ) || ! is_string( $string ) ) {
591 return false;
592 }
593
594 if ( preg_match( '@^(?:https?:)?//[a-zA-Z0-9\-]+@', $string ) ) {
595 return true;
596 }
597
598 return false;
599 }
600
601 /**
602 * Parses a URL into its components. Compatible with PHP < 5.4.7.
603 *
604 * @param string $url The URL to parse.
605 *
606 * @param int $component PHP_URL_ constant for URL component to return.
607 *
608 * @return mixed An array of the parsed components, mixed for a requested component, or false on error.
609 */
610 public static function parse_url( $url, $component = -1 ) {
611 $url = trim( $url );
612 $no_scheme = 0 === strpos( $url, '//' );
613
614 if ( $no_scheme ) {
615 $url = 'http:' . $url;
616 }
617
618 $parts = parse_url( $url, $component );
619
620 if ( 0 < $component ) {
621 return $parts;
622 }
623
624 if ( $no_scheme && is_array( $parts ) ) {
625 unset( $parts['scheme'] );
626 }
627
628 return $parts;
629 }
630
631 /**
632 * Is the given string a usable URL?
633 *
634 * We need URLs that include at least a domain and filename with extension
635 * for URL rewriting in either direction.
636 *
637 * @param mixed $url
638 *
639 * @return bool
640 */
641 public static function is_file_url( $url ): bool {
642 if ( ! static::is_url( $url ) ) {
643 return false;
644 }
645
646 $parts = static::parse_url( $url );
647
648 if (
649 empty( $parts['host'] ) ||
650 empty( $parts['path'] ) ||
651 ! pathinfo( $parts['path'], PATHINFO_EXTENSION )
652 ) {
653 return false;
654 }
655
656 return true;
657 }
658
659
660 /**
661 * Remove query strings of services.
662 *
663 * @param string $content
664 * @param string $base_url Optional base URL that must exist within URL for Amazon query strings to be removed.
665 *
666 * @return string
667 */
668 public static function remove_query_strings( $content, $base_url = '' ) {
669 $pattern = '\?[^\s"<\?]*(?:X-Amz-Algorithm|AWSAccessKeyId|Key-Pair-Id|GoogleAccessId)=[^\s"<\?]+';
670 $group = 0;
671
672 if ( ! is_string( $content ) ) {
673 return $content;
674 }
675
676 if ( ! empty( $base_url ) ) {
677 $pattern = preg_quote( $base_url, '/' ) . '[^\s"<\?]+(' . $pattern . ')';
678 $group = 1;
679 }
680 if ( ! preg_match_all( '/' . $pattern . '/', $content, $matches ) || ! isset( $matches[ $group ] ) ) {
681 // No query strings found, return
682 return $content;
683 }
684
685 $matches = array_unique( $matches[ $group ] );
686
687 foreach ( $matches as $match ) {
688 $content = str_replace( $match, '', $content );
689 }
690 return $content;
691 }
692
693 /**
694 * Maybe unserialize data, but not if an object.
695 *
696 * @param mixed $data
697 *
698 * @return mixed
699 */
700 public static function maybe_unserialize( $data ) {
701 if ( is_serialized( $data ) ) {
702 return @unserialize( $data, array( 'allowed_classes' => false ) ); // @phpcs:ignore
703 }
704
705 return $data;
706 }
707
708
709 /**
710 * Validate JSON
711 */
712 public static function is_json( $string ) {
713 json_decode( $string );
714 return ( json_last_error() == JSON_ERROR_NONE );
715 }
716
717 /**
718 * Is this an AJAX process?
719 *
720 * @return bool
721 */
722 public static function is_ajax() {
723 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
724 return true;
725 }
726
727 return false;
728 }
729
730 /**
731 * Helper function for filtering super globals. Easily testable.
732 *
733 * @param string $variable
734 * @param int $type
735 * @param int $filter
736 * @param mixed $options
737 *
738 * @return mixed
739 */
740 public static function filter_input( $variable, $type = INPUT_GET, $filter = FILTER_DEFAULT, $options = array() ) {
741 return filter_input( $type, $variable, $filter, $options );
742 }
743
744 }
745