PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 5.3
MainWP Dashboard: Self-hosted WordPress Management for Agencies v5.3
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
mainwp / class / class-mainwp-utility.php

class-mainwp-utility.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 5.3, at class/class-mainwp-utility.php

1,800 lines 52.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Utility Helper.
4 *
5 * @package MainWP/Dashboard
6 */
7
8 namespace MainWP\Dashboard;
9
10 // phpcs:disable WordPress.DB.RestrictedFunctions, WordPress.WP.AlternativeFunctions, WordPress.PHP.NoSilencedErrors, Generic.Metrics.CyclomaticComplexity -- Using cURL functions.
11
12 /**
13 * Class MainWP_Utility
14 *
15 * @package MainWP\Dashboard
16 */
17 class MainWP_Utility { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
18
19 /**
20 * Yoast SEO is enabled return true else return null.
21 *
22 * @static
23 * @var boolean $enabled_wp_seo If Yoast SEO is enabled return true else return null.
24 */
25 public static $enabled_wp_seo = null;
26
27 /**
28 * Private static variable.
29 *
30 * @static
31 *
32 * @var mixed Default null
33 */
34 public static $last_deactivated_alerts = null;
35
36 /**
37 * Private static variable to hold the single instance of the class.
38 *
39 * @static
40 *
41 * @var mixed Default null
42 */
43 private static $instance = null;
44
45 /**
46 * Store the disabled php functions.
47 *
48 * @static
49 * @var string $disabled_functions disabled php functions.
50 */
51 public static $disabled_functions = null;
52
53 /**
54 * Method get_class_name()
55 *
56 * Get Class Name.
57 *
58 * @return object __CLASS__
59 */
60 public static function get_class_name() {
61 return __CLASS__;
62 }
63
64 /**
65 * Method instance()
66 *
67 * Create public static instance.
68 *
69 * @static
70 * @return MainWP_Utility
71 */
72 public static function instance() {
73 if ( null === static::$instance ) {
74 static::$instance = new self();
75 }
76
77 return static::$instance;
78 }
79
80 /**
81 * Method starts_with()
82 *
83 * Start of Stack Trace.
84 *
85 * @param mixed $haystack The full stack.
86 * @param mixed $needle The function that is throwing the error.
87 *
88 * @return mixed Needle in the Haystack.
89 */
90 public static function starts_with( $haystack, $needle ) {
91 return ! strncmp( $haystack, $needle, strlen( $needle ) );
92 }
93
94 /**
95 * Method ends_with()
96 *
97 * End of Stack Trace.
98 *
99 * @param mixed $haystack Haystack parameter.
100 * @param mixed $needle Needle parameter.
101 *
102 * @return boolean
103 */
104 public static function ends_with( $haystack, $needle ) {
105 $length = strlen( $needle );
106 if ( 0 === $length ) {
107 return true;
108 }
109
110 return substr( $haystack, - $length ) === $needle;
111 }
112
113 /**
114 * Method get_nice_url()
115 *
116 * Grab url.
117 *
118 * @param string $pUrl Website URL.
119 * @param bool $showHttp Show HTTP.
120 *
121 * @return string $url.
122 */
123 public static function get_nice_url( $pUrl, $showHttp = false ) {
124 $url = $pUrl;
125
126 if ( static::starts_with( $url, 'http://' ) ) {
127 if ( ! $showHttp ) {
128 $url = substr( $url, 7 );
129 }
130 } elseif ( static::starts_with( $pUrl, 'https://' ) ) {
131 if ( ! $showHttp ) {
132 $url = substr( $url, 8 );
133 }
134 } elseif ( $showHttp ) {
135 $url = 'http://' . $url;
136 }
137
138 if ( static::ends_with( $url, '/' ) ) {
139 if ( ! $showHttp ) {
140 $url = substr( $url, 0, strlen( $url ) - 1 );
141 }
142 } else {
143 $url = $url . '/';
144 }
145
146 return $url;
147 }
148
149 /**
150 * Method is_domain_valid()
151 *
152 * Check $url against FILTER_VALIDATE_URL.
153 *
154 * @param mixed $url Domain to check.
155 *
156 * @return boolean True|False.
157 */
158 public static function is_domain_valid( $url ) {
159 return filter_var( $url, FILTER_VALIDATE_URL );
160 }
161
162 /**
163 * Method ctype_digit()
164 *
165 * Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise.
166 *
167 * @param mixed $str String to check.
168 *
169 * @return boolean Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise.
170 */
171 public static function ctype_digit( $str ) {
172 return ( is_string( $str ) || is_int( $str ) || is_float( $str ) ) && preg_match( '/^\d+\z/', $str );
173 }
174
175 /**
176 * Method sortmulti()
177 *
178 * Sort the given array, Acending, Decending or by Natural Order.
179 *
180 * @param mixed $arr Array to sort.
181 * @param mixed $index Index of array.
182 * @param mixed $order Acending or Decending order.
183 * @param bool $natsort Sort an array using a "natural order" algorithm. Default: false.
184 * @param bool $case_sensitive If case sensitive return true else return false. Default: false.
185 *
186 * @return array $sorted Return the sorted array.
187 */
188 public static function sortmulti( $arr, $index, $order, $natsort = false, $case_sensitive = false ) { // phpcs:ignore -- NOSONAR - complex.
189 $sorted = array();
190 if ( is_array( $arr ) && ! empty( $arr ) ) {
191 foreach ( array_keys( $arr ) as $key ) {
192 $temp[ $key ] = $arr[ $key ][ $index ];
193 }
194 if ( ! $natsort ) {
195 if ( 'asc' === $order ) {
196 asort( $temp );
197 } else {
198 arsort( $temp );
199 }
200 } else {
201 if ( true === $case_sensitive ) {
202 natsort( $temp );
203 } else {
204 natcasesort( $temp );
205 }
206 if ( 'asc' !== $order ) {
207 $temp = array_reverse( $temp, true );
208 }
209 }
210 foreach ( array_keys( $temp ) as $key ) {
211 if ( is_numeric( $key ) ) {
212 $sorted[] = $arr[ $key ];
213 } else {
214 $sorted[ $key ] = $arr[ $key ];
215 }
216 }
217
218 return $sorted;
219 }
220
221 return $sorted;
222 }
223
224 /**
225 * Method get_sub_array_having()
226 *
227 * Get sub array.
228 *
229 * @param mixed $arr Array to traverse.
230 * @param mixed $index Index of array.
231 * @param mixed $value Array values.
232 *
233 * void array $output Sub array.
234 */
235 public static function get_sub_array_having( $arr, $index, $value ) {
236 $output = array();
237 if ( is_array( $arr ) && ! empty( $arr ) ) {
238 foreach ( $arr as $arrvalue ) {
239 $existed = isset( $arrvalue[ $index ] ) ? $arrvalue[ $index ] : null;
240 if ( $existed === $value ) {
241 $output[] = $arrvalue;
242 }
243 }
244 }
245
246 return $output;
247 }
248
249 /**
250 * Method get_sub_array_with_limit()
251 *
252 * Get sub array.
253 *
254 * @param mixed $arr Array to traverse.
255 * @param mixed $start start index of array.
256 * @param mixed $count count values.
257 *
258 * void array $output Sub array.
259 */
260 public static function get_sub_array_with_limit( $arr, $start, $count ) {
261 $output = array();
262 if ( is_array( $arr ) && ! empty( $arr ) ) {
263 if ( $start > count( $arr ) ) {
264 return array();
265 }
266 $i = 0;
267 foreach ( $arr as $value ) {
268 if ( $i >= $start && $i < $start + $count ) {
269 $output[] = $value;
270 }
271 ++$i;
272 if ( $i > $start + $count ) {
273 break;
274 }
275 }
276 }
277 return $output;
278 }
279
280
281 /**
282 * Method trim_slashes()
283 *
284 * Trim stashes from element.
285 *
286 * @param mixed $elem Element to trim.
287 *
288 * @return string Return string with no slashes.
289 */
290 public static function trim_slashes( $elem ) {
291 return trim( $elem, '/' );
292 }
293
294 /**
295 * Method sanitize()
296 *
297 * Sanitize given string.
298 *
299 * @param mixed $str String to sanitize.
300 *
301 * @return string Sanitized string.
302 */
303 public static function sanitize( $str ) {
304 return preg_replace( '/[\\\\\/\:"\*\?\<\>\|]+/', '', $str );
305 }
306
307 /**
308 * Method sanitize_alphanumeric()
309 *
310 * Sanitize given string.
311 *
312 * @param mixed $str String to sanitize.
313 *
314 * @return string Sanitized string.
315 */
316 public static function sanitize_attr_slug( $str ) {
317 $str = strtolower( $str );
318 $str = str_replace( array( '=', '?', '/' ), '-', $str );
319 $str = preg_replace( '/[^A-Za-z0-9^\-]/', '', $str );
320 return $str;
321 }
322
323 /**
324 * Method end_session()
325 *
326 * End a session.
327 *
328 * @return void
329 */
330 public static function end_session() {
331
332 if ( defined( 'WP_CLI' ) && WP_CLI ) {
333 return;
334 }
335
336 if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
337 return;
338 }
339
340 session_write_close();
341 if ( 0 < ob_get_length() ) {
342 ob_end_flush();
343 }
344 }
345
346 /**
347 * Method get_timestamp()
348 *
349 * Get time stamp in gmt_offset.
350 *
351 * @param mixed $timestamp Time stamp to convert.
352 *
353 * @return string Time stamp in general mountain time offset.
354 */
355 public static function get_timestamp( $timestamp = false ) {
356 if ( false === $timestamp ) {
357 $timestamp = time();
358 }
359 $gmtOffset = get_option( 'gmt_offset' );
360
361 return $gmtOffset ? ( $gmtOffset * HOUR_IN_SECONDS ) + $timestamp : $timestamp;
362 }
363
364 /**
365 * Method date()
366 *
367 * Show date in given format.
368 *
369 * @param mixed $format Format to display date in.
370 *
371 * @return string Date.
372 */
373 public static function date( $format ) {
374 // phpcs:ignore -- use local date function.
375 return date( $format, static::get_timestamp() );
376 }
377
378 /**
379 * Method format_timestamp()
380 *
381 * Format the given timestamp.
382 *
383 * @param mixed $timestamp Timestamp to format.
384 *
385 * @return string Formatted timestamp.
386 */
387 public static function format_timestamp( $timestamp ) {
388 return date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $timestamp );
389 }
390
391 /**
392 * Method format_timestamp()
393 *
394 * Format the given timestamp.
395 *
396 * @param mixed $timestamp Timestamp to format.
397 *
398 * @return string Formatted timestamp.
399 */
400 public static function format_date( $timestamp ) {
401 return date_i18n( get_option( 'date_format' ), $timestamp );
402 }
403
404 /**
405 * Method format_time()
406 *
407 * Format the given timestamp.
408 *
409 * @param mixed $timestamp Timestamp to format.
410 *
411 * @return string Formatted timestamp.
412 */
413 public static function format_time( $timestamp ) {
414 return date_i18n( get_option( 'time_format' ), $timestamp );
415 }
416
417 /**
418 * Format duration time to show.
419 *
420 * @param float $time timestamp.
421 * @return mixed result.
422 */
423 public static function format_duration_time( $time ) {
424
425 $original_sec = absint( $time );
426 $dura_sec = $original_sec;
427 $days = floor( $dura_sec / 86400 );
428 $dura_sec -= $days * 86400;
429 $dura_hour_sec = $dura_sec;
430 $dura_hours = floor( $dura_sec / 3600 );
431
432 if ( $days > 0 ) {
433 $formatted_dura = ( $days * 24 + $dura_hours ) . gmdate( 'i\m s\s', $dura_hour_sec );
434 } else {
435 $formatted_dura = gmdate( 'H\h i\m s\s', $original_sec );
436 }
437 return '<bdi>' . esc_html( $formatted_dura ) . '</bdi>';
438 }
439
440
441 /**
442 * Method human_filesize()
443 *
444 * Convert to human readable file size format,
445 * (B|kB|MB|GB|TB|PB|EB|ZB|YB).
446 *
447 * @param mixed $bytes File in bytes.
448 * @param integer $decimals Number of decimals to output.
449 *
450 * @return string Human readable file size.
451 */
452 public static function human_filesize( $bytes, $decimals = 2 ) {
453 $size = array( 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' );
454 $factor = floor( ( strlen( $bytes ) - 1 ) / 3 );
455
456 return sprintf( "%.{$decimals}f", $bytes / pow( 1024, $factor ) ) . @$size[ $factor ];
457 }
458
459 /**
460 * Method map_fields()
461 *
462 * Map Site.
463 *
464 * @param mixed $data data to map.
465 * @param mixed $keys Keys to map.
466 * @param bool $object_output Output format array|object.
467 *
468 * @return mixed Mapped data.
469 */
470 public static function map_fields( &$data, $keys, $object_output = true ) {
471 return static::map_site( $data, $keys, $object_output );
472 }
473
474 /**
475 * Method map_site()
476 *
477 * Map Site.
478 *
479 * @param mixed $website Website to map.
480 * @param mixed $keys Keys to map.
481 * @param bool $object_output Output format array|object.
482 *
483 * @return mixed $outputSite Mapped site.
484 */
485 public static function map_site( &$website, $keys, $object_output = true ) { // phpcs:ignore -- NOSONAR - complex.
486 if ( $object_output ) {
487 $outputSite = new \stdClass();
488 if ( ! empty( $website ) ) {
489 if ( is_object( $website ) ) {
490 foreach ( $keys as $key ) {
491 if ( property_exists( $website, $key ) ) {
492 $outputSite->{$key} = $website->$key;
493 } else {
494 $outputSite->{$key} = '';
495 }
496 }
497 } elseif ( is_array( $website ) ) {
498 foreach ( $keys as $key ) {
499 if ( isset( $website[ $key ] ) ) {
500 $outputSite->{$key} = $website[ $key ];
501 } else {
502 $outputSite->{$key} = '';
503 }
504 }
505 }
506 }
507 } else {
508 $outputSite = array();
509 if ( ! empty( $website ) ) {
510 if ( is_object( $website ) ) {
511 foreach ( $keys as $key ) {
512 if ( property_exists( $website, $key ) ) {
513 $outputSite[ $key ] = $website->$key;
514 } else {
515 $outputSite[ $key ] = '';
516 }
517 }
518 } elseif ( is_array( $website ) ) {
519 foreach ( $keys as $key ) {
520 if ( isset( $website[ $key ] ) ) {
521 $outputSite[ $key ] = $website[ $key ];
522 } else {
523 $outputSite[ $key ] = '';
524 }
525 }
526 }
527 }
528 }
529 return $outputSite;
530 }
531
532 /**
533 * Method array_merge()
534 *
535 * Merge two given arrays into one.
536 *
537 * @param mixed $arr1 First array.
538 * @param mixed $arr2 Second array.
539 *
540 * @return array Merged Array.
541 */
542 public static function array_merge( $arr1, $arr2 ) {
543 if ( ! is_array( $arr1 ) && ! is_array( $arr2 ) ) {
544 return array();
545 }
546 if ( ! is_array( $arr1 ) ) {
547 return $arr2;
548 }
549 if ( ! is_array( $arr2 ) ) {
550 return $arr1;
551 }
552
553 $output = array();
554 foreach ( $arr1 as $el ) {
555 $output[] = $el;
556 }
557 foreach ( $arr2 as $el ) {
558 $output[] = $el;
559 }
560
561 return $output;
562 }
563
564 /**
565 * Method update_option()
566 *
567 * Update option.
568 *
569 * @param mixed $option_name Option name.
570 * @param mixed $option_value Option value.
571 *
572 * @return (boolean) False if value was not updated and true if value was updated.
573 */
574 public static function update_option( $option_name, $option_value ) {
575 $success = add_option( $option_name, $option_value, '', 'no' );
576
577 if ( ! $success ) {
578 $success = update_option( $option_name, $option_value );
579 }
580
581 return $success;
582 }
583
584 /**
585 * Method update_user_option()
586 *
587 * Update option.
588 *
589 * @param mixed $option_name Option name.
590 * @param mixed $option_value Option value.
591 *
592 * @return (boolean) False if value was not updated and true if value was updated.
593 */
594 public static function update_user_option( $option_name, $option_value ) {
595 $user = wp_get_current_user();
596 if ( $user ) {
597 return update_user_option( $user->ID, $option_name, $option_value );
598 }
599 return false;
600 }
601
602 /**
603 * Method remove_preslash_spaces()
604 *
605 * Remove spaces before slashes.
606 *
607 * @param string $text String to strip.
608 *
609 * @return string $text Cleaned string.
610 */
611 public static function remove_preslash_spaces( $text ) {
612 while ( stristr( $text, ' /' ) ) {
613 $text = str_replace( ' /', '/', $text );
614 }
615
616 return $text;
617 }
618
619 /**
620 * Method remove_http_prefix()
621 *
622 * Remove http prefixes from given url.
623 *
624 * @param mixed $pUrl Given URL.
625 * @param bool $pTrimSlashes Whether or not to trim slashes. Default is false.
626 *
627 * @return string Trimmed URL.
628 */
629 public static function remove_http_prefix( $pUrl, $pTrimSlashes = false ) {
630 return str_replace( array( 'http:' . ( $pTrimSlashes ? '//' : '' ), 'https:' . ( $pTrimSlashes ? '//' : '' ) ), array( '', '' ), $pUrl );
631 }
632
633 /**
634 * Method remove_http_www_prefix()
635 *
636 * Remove 'www.' from given URL.
637 *
638 * @param mixed $pUrl Given URL.
639 *
640 * @return string Cleaned URL.
641 */
642 public static function remove_http_www_prefix( $pUrl ) {
643 $pUrl = static::remove_http_prefix( $pUrl, true );
644 if ( static::starts_with( strtolower( $pUrl ), 'www.' ) ) {
645 $pUrl = substr( $pUrl, 4 );
646 }
647 return $pUrl;
648 }
649
650 /**
651 * Method sanitize_file_name()
652 *
653 * Sanitize file names.
654 *
655 * @param mixed $filename File name to sanitize.
656 *
657 * @return string Sanitized filename.
658 */
659 public static function sanitize_file_name( $filename ) {
660 $filename = str_replace( array( '|', '/', '\\', ' ', ':' ), array( '-', '-', '-', '-', '-' ), $filename );
661 return sanitize_file_name( $filename );
662 }
663
664
665
666 /**
667 * Method esc_content()
668 *
669 * Escape content,
670 * allowed content (a,href,title,br,em,strong,p,hr,ul,ol,li,h1,h2 ... ).
671 *
672 * @param mixed $content Content to escape.
673 * @param string $type Type of content. Default = note.
674 * @param mixed $more_allowed input allowed tags - options.
675 *
676 * @return string Filtered content containing only the allowed HTML.
677 */
678 public static function esc_content( $content, $type = 'note', $more_allowed = array() ) {
679 if ( ! is_string( $content ) ) {
680 return $content;
681 }
682
683 if ( 'note' === $type ) {
684
685 $allowed_html = array(
686 'a' => array(
687 'href' => array(),
688 'title' => array(),
689 ),
690 'br' => array(),
691 'em' => array(),
692 'strong' => array(),
693 'p' => array(),
694 'hr' => array(),
695 'ul' => array(),
696 'ol' => array(),
697 'li' => array(),
698 'h1' => array(),
699 'h2' => array(),
700 );
701
702 if ( is_array( $more_allowed ) && ! empty( $more_allowed ) ) {
703 $allowed_html = array_merge( $allowed_html, $more_allowed );
704 }
705
706 $content = wp_kses( $content, $allowed_html );
707
708 } elseif ( 'mixed' === $type ) {
709
710 $allowed_html = array(
711 'a' => array(
712 'href' => array(),
713 'title' => array(),
714 'class' => array(),
715 'onclick' => array(),
716 ),
717 'img' => array(
718 'src' => array(),
719 'title' => array(),
720 'class' => array(),
721 'onclick' => array(),
722 'alt' => array(),
723 'width' => array(),
724 'height' => array(),
725 'sizes' => array(),
726 'srcset' => array(),
727 'usemap' => array(),
728 ),
729 'br' => array(),
730 'em' => array(),
731 'strong' => array(),
732 'p' => array(),
733 'hr' => array(),
734 'ul' => array(
735 'style' => array(),
736 ),
737 'ol' => array(),
738 'li' => array(),
739 'h1' => array(),
740 'h2' => array(),
741 'head' => array(),
742 'html' => array(
743 'lang' => array(),
744 ),
745 'meta' => array(
746 'name' => array(),
747 'http-equiv' => array(),
748 'content' => array(),
749 'charset' => array(),
750 ),
751 'title' => array(),
752 'body' => array(
753 'style' => array(),
754 ),
755 'span' => array(
756 'id' => array(),
757 'style' => array(),
758 'class' => array(),
759 ),
760 'form' => array(
761 'id' => array(),
762 'method' => array(),
763 'action' => array(),
764 'onsubmit' => array(),
765 ),
766 'table' => array(
767 'class' => array(),
768 ),
769 'thead' => array(
770 'class' => array(),
771 ),
772 'tbody' => array(
773 'class' => array(),
774 ),
775 'tr' => array(
776 'id' => array(),
777 ),
778 'td' => array(
779 'class' => array(),
780 ),
781 'div' => array(
782 'id' => array(),
783 'style' => array(),
784 'class' => array(),
785 ),
786 'input' => array(
787 'type' => array(),
788 'name' => array(),
789 'class' => array(),
790 'value' => array(),
791 'onclick' => array(),
792 ),
793 'button' => array(
794 'type' => array(),
795 'name' => array(),
796 'value' => array(),
797 'class' => array(),
798 'title' => array(),
799 'onclick' => array(),
800 ),
801 );
802
803 if ( is_array( $more_allowed ) && ! empty( $more_allowed ) ) {
804 $allowed_html = array_merge( $allowed_html, $more_allowed );
805 }
806
807 $content = wp_kses( $content, $allowed_html );
808 } else {
809 $content = wp_kses_post( $content );
810 }
811
812 return $content;
813 }
814
815 /**
816 * Method esc_mixed_content()
817 *
818 * Escape mixed content,
819 * allowed content (a,href,title,br,em,strong,p,hr,ul,ol,li,h1,h2 ... ).
820 *
821 * @param mixed $data data to escape.
822 * @param string $depth Maximum depth to walk through $data. Must be greater than 0.
823 * @param mixed $more_allowed input allowed tags - options.
824 *
825 * @throws \MainWP_Exception Excetpion message.
826 *
827 * @return string Filtered content containing only the allowed HTML.
828 */
829 public static function esc_mixed_content( $data, $depth, $more_allowed = array() ) { // phpcs:ignore -- NOSONAR - complex.
830 if ( $depth < 0 ) {
831 throw new MainWP_Exception( 'Reached depth limit' );
832 }
833
834 if ( is_array( $data ) ) {
835 $output = array();
836 foreach ( $data as $id => $el ) {
837 // Don't forget to sanitize the ID!
838 if ( is_string( $id ) ) {
839 $clean_id = static::esc_content( $id, 'mixed', $more_allowed );
840 } else {
841 $clean_id = $id;
842 }
843
844 // Check the element type, so that we're only recursing if we really have to.
845 if ( is_array( $el ) || is_object( $el ) ) {
846 $output[ $clean_id ] = static::esc_mixed_content( $el, $depth - 1 );
847 } elseif ( is_string( $el ) ) {
848 $output[ $clean_id ] = static::esc_content( $el, 'mixed', $more_allowed );
849 } else {
850 $output[ $clean_id ] = $el;
851 }
852 }
853 } elseif ( is_object( $data ) ) {
854 $output = new stdClass();
855 foreach ( $data as $id => $el ) {
856 if ( is_string( $id ) ) {
857 $clean_id = static::esc_content( $id, 'mixed', $more_allowed );
858 } else {
859 $clean_id = $id;
860 }
861
862 if ( is_array( $el ) || is_object( $el ) ) {
863 $output->$clean_id = static::esc_mixed_content( $el, $depth - 1, $more_allowed );
864 } elseif ( is_string( $el ) ) {
865 $output->$clean_id = static::esc_content( $el, 'mixed', $more_allowed );
866 } else {
867 $output->$clean_id = $el;
868 }
869 }
870 } elseif ( is_string( $data ) ) {
871 return static::esc_content( $data, 'mixed', $more_allowed );
872 } else {
873 return $data;
874 }
875
876 return $output;
877 }
878
879 /**
880 * Method parse_html_error_message()
881 *
882 * @param string $error_msg Error message.
883 *
884 * @return mixed array|string.
885 */
886 public static function parse_html_error_message( $error_msg ) {
887 // pasing error message that included link html.
888 preg_match( '/([^\<]*)(<a[^\>]*>)([^\<]*)(<[^\>]*>)(.*)/', $error_msg, $output_array );
889 if ( is_array( $output_array ) && 6 === count( $output_array ) ) {
890 preg_match( '/<a href="([^\"]*)"(.*)/', $output_array[2], $link_array );
891 $link = '';
892 if ( is_array( $link_array ) && 3 === count( $link_array ) ) {
893 $link = $link_array[1];
894 }
895 if ( ! empty( $link ) ) {
896 return array(
897 'el_before' => esc_html( $output_array[1] ),
898 'el_link' => esc_html( $link ),
899 'el_text' => esc_html( $output_array[3] ),
900 'el_after' => esc_html( $output_array[5] ),
901 );
902 }
903 }
904 return $error_msg;
905 }
906
907 /**
908 * Method show_mainwp_message()
909 *
910 * Check whenther or not to show the MainWP Message.
911 *
912 * @param mixed $type Type of message.
913 * @param mixed $notice_id Notice ID.
914 *
915 * @return boolean true|false.
916 */
917 public static function show_mainwp_message( $type, $notice_id ) {
918 unset( $type );
919 $status = get_user_option( 'mainwp_notice_saved_status' );
920 if ( ! is_array( $status ) ) {
921 $status = array();
922 }
923 if ( isset( $status[ $notice_id ] ) ) {
924 return false;
925 }
926 return true;
927 }
928
929 /**
930 * Method get_hide_notice_status()
931 *
932 * Check whenther or not to show the MainWP Message.
933 *
934 * @param mixed $notice_id Notice ID.
935 *
936 * @return mixed true|false|time.
937 */
938 public static function get_hide_notice_status( $notice_id ) {
939 $notices = get_user_option( 'mainwp_notice_saved_status' );
940 if ( ! is_array( $notices ) ) {
941 $notices = array();
942 }
943 if ( isset( $notices[ $notice_id ] ) ) {
944 return $notices[ $notice_id ];
945 }
946 return false;
947 }
948
949 /**
950 * Method get_flash_message()
951 *
952 * Get saved flash Message.
953 *
954 * @param mixed $message_id Notice ID.
955 * @param bool $delete True to delete the message after get it.
956 *
957 * @return boolean true|false.
958 */
959 public static function get_flash_message( $message_id, $delete = true ) {
960 $flash_messages = get_user_option( 'mainwp_flash_messages' );
961 if ( ! is_array( $flash_messages ) ) {
962 $flash_messages = array();
963 }
964 if ( ! isset( $flash_messages[ $message_id ] ) ) {
965 return false;
966 }
967 $content = $flash_messages[ $message_id ];
968 if ( $delete ) {
969 unset( $flash_messages[ $message_id ] );
970 static::update_user_option( 'mainwp_flash_messages', $flash_messages );
971 }
972 return $content;
973 }
974
975 /**
976 * Method update_flash_message()
977 *
978 * Check whenther or not to show the MainWP Message.
979 *
980 * @param mixed $message_id Notice ID.
981 * @param mixed $content Content of message.
982 *
983 * @return boolean true|false.
984 */
985 public static function update_flash_message( $message_id, $content ) {
986 $flash_messages = get_user_option( 'mainwp_flash_messages' );
987 if ( ! is_array( $flash_messages ) ) {
988 $flash_messages = array();
989 }
990 $current = isset( $flash_messages[ $message_id ] ) ? $flash_messages[ $message_id ] : '';
991 if ( empty( $current ) ) {
992 $current = $content;
993 } else {
994 $current .= '|' . $content;
995 }
996 $flash_messages[ $message_id ] = $current;
997 return static::update_user_option( 'mainwp_flash_messages', $flash_messages );
998 }
999
1000 /**
1001 * Method array_sort()
1002 *
1003 * Sort given array by given flags.
1004 *
1005 * @param mixed $arr Array to sort.
1006 * @param mixed $key Array key.
1007 * @param string $sort_flag Flags to sort by. Default = SORT_STRING.
1008 */
1009 public static function array_sort( &$arr, $key, $sort_flag = SORT_STRING ) {
1010 $sorter = array();
1011 $ret = array();
1012 reset( $arr );
1013 foreach ( $arr as $ii => $val ) {
1014 $sorter[ $ii ] = $val[ $key ];
1015 }
1016 asort( $sorter, $sort_flag );
1017 foreach ( $sorter as $ii => $val ) {
1018 $ret[ $ii ] = $arr[ $ii ];
1019 }
1020 $arr = $ret;
1021 }
1022
1023 /**
1024 * Method array_sort_existed_keys()
1025 *
1026 * Sort given array by given flags.
1027 *
1028 * @param mixed $arr Array to sort.
1029 * @param mixed $key Array key.
1030 * @param string $sort_flag Flags to sort by. Default = SORT_STRING.
1031 */
1032 public static function array_sort_existed_keys( &$arr, $key, $sort_flag = SORT_STRING ) {
1033 $sorter = array();
1034 $ret = array();
1035 reset( $arr );
1036
1037 // get items with $key to sort.
1038 foreach ( $arr as $ii => $val ) {
1039 if ( isset( $val[ $key ] ) ) {
1040 $sorter[ $ii ] = $val[ $key ];
1041 }
1042 }
1043 asort( $sorter, $sort_flag );
1044
1045 foreach ( $sorter as $ii => $val ) {
1046 $ret[ $ii ] = $arr[ $ii ];
1047 }
1048
1049 // asign other items (without $keys).
1050 foreach ( $arr as $ii => $val ) {
1051 if ( ! isset( $val[ $key ] ) ) {
1052 $ret[ $ii ] = $val;
1053 }
1054 }
1055
1056 $arr = $ret;
1057 }
1058
1059 /**
1060 * Method numeric_filter()
1061 *
1062 * Filter given numeric.
1063 *
1064 * @param int $int_num Int number.
1065 * @return array $arr_ints Array filtered.
1066 */
1067 public static function numeric_filter( $int_num ) {
1068 return ( (string) (int) $int_num === (string) $int_num && 0 < $int_num ) ? $int_num : false;
1069 }
1070
1071 /**
1072 * Method array_numeric_filter()
1073 *
1074 * Filter given numeric array.
1075 *
1076 * @param array $arr_ints Array to filter.
1077 * @return array $arr_ints Array filtered.
1078 */
1079 public static function array_numeric_filter( $arr_ints ) {
1080 $arr_ints = array_filter(
1081 $arr_ints,
1082 function ( $e ) {
1083 return ( (string) (int) $e === (string) $e && 0 < $e ) ? true : false;
1084 }
1085 );
1086 return $arr_ints;
1087 }
1088
1089 /**
1090 * Method enabled_wp_seo()
1091 *
1092 * Check if Yoast SEO is enabled.
1093 *
1094 * @return boolean true|false.
1095 */
1096 public static function enabled_wp_seo() {
1097 if ( null === static::$enabled_wp_seo ) {
1098 static::$enabled_wp_seo = is_plugin_active( 'wordpress-seo-extension/wordpress-seo-extension.php' );
1099 }
1100 return static::$enabled_wp_seo;
1101 }
1102
1103 /**
1104 * Method value_to_string()
1105 *
1106 * Value to string.
1107 *
1108 * @param mixed $var_value Value to convert to string.
1109 *
1110 * @return string Value that has been converted into a string.
1111 */
1112 public static function value_to_string( $var_value ) {
1113 if ( is_array( $var_value ) || is_object( $var_value ) ) {
1114 //phpcs:ignore -- for debug only
1115 return print_r( $var_value, true );
1116 } elseif ( is_string( $var_value ) ) {
1117 return $var_value;
1118 }
1119 return '';
1120 }
1121
1122 /**
1123 * Get Health Site value.
1124 *
1125 * @param mixed $issue_counts Health site issues.
1126 *
1127 * @return array Health status value.
1128 */
1129 public static function get_site_health( $issue_counts ) {
1130
1131 if ( empty( $issue_counts ) ) {
1132 $issue_counts = array(
1133 'good' => 0,
1134 'recommended' => 0,
1135 'critical' => 0,
1136 );
1137 }
1138
1139 $totalTests = intval( $issue_counts['good'] ) + intval( $issue_counts['recommended'] ) + intval( $issue_counts['critical'] ) * 1.5;
1140 $failedTests = intval( $issue_counts['recommended'] ) * 0.5 + $issue_counts['critical'] * 1.5;
1141
1142 if ( empty( $totalTests ) ) {
1143 $val = 100;
1144 } else {
1145 $val = 100 - ceil( ( $failedTests / $totalTests ) * 100 );
1146 }
1147
1148 if ( 0 > $val ) {
1149 $val = 0;
1150 }
1151
1152 if ( 100 < $val ) {
1153 $val = 100;
1154 }
1155
1156 return array(
1157 'val' => $val,
1158 'critical' => $issue_counts['critical'],
1159 );
1160 }
1161
1162
1163 /**
1164 * Get HTTP code.
1165 *
1166 * @param int $code HTTP code.
1167 *
1168 * @return array $http_codes HTTP code.
1169 */
1170 public static function get_http_codes( $code = false ) {
1171
1172 $http_codes = array(
1173 100 => 'Continue',
1174 101 => 'Switching Protocols',
1175 200 => 'OK',
1176 201 => 'Created',
1177 202 => 'Accepted',
1178 203 => 'Non-Authoritative Information',
1179 204 => 'No Content',
1180 205 => 'Reset Content',
1181 206 => 'Partial Content',
1182 300 => 'Multiple Choices',
1183 301 => 'Moved Permanently',
1184 302 => 'Found',
1185 303 => 'See Other',
1186 304 => 'Not Modified',
1187 305 => 'Use Proxy',
1188 306 => '(Unused)',
1189 307 => 'Temporary Redirect',
1190 400 => 'Bad Request',
1191 401 => 'Unauthorized',
1192 402 => 'Payment Required',
1193 403 => 'Forbidden',
1194 404 => 'Not Found',
1195 405 => 'Method Not Allowed',
1196 406 => 'Not Acceptable',
1197 407 => 'Proxy Authentication Required',
1198 408 => 'Request Timeout',
1199 409 => 'Conflict',
1200 410 => 'Gone',
1201 411 => 'Length Required',
1202 412 => 'Precondition Failed',
1203 413 => 'Request Entity Too Large',
1204 414 => 'Request-URI Too Long',
1205 415 => 'Unsupported Media Type',
1206 416 => 'Requested Range Not Satisfiable',
1207 417 => 'Expectation Failed',
1208 500 => 'Internal Server Error',
1209 501 => 'Not Implemented',
1210 502 => 'Bad Gateway',
1211 503 => 'Service Unavailable',
1212 504 => 'Gateway Timeout',
1213 505 => 'HTTP Version Not Supported',
1214 );
1215
1216 if ( false === $code ) {
1217 return $http_codes;
1218 }
1219
1220 return isset( $http_codes[ $code ] ) ? $http_codes[ $code ] : '';
1221 }
1222
1223 /**
1224 * Method valid_input_emails().
1225 *
1226 * @param string $emails Input emails string.
1227 *
1228 * @return string $valid_emails Valid emails string.
1229 */
1230 public static function valid_input_emails( $emails ) {
1231
1232 if ( is_string( $emails ) ) {
1233 $emails = array_filter( explode( ',', $emails ) );
1234 }
1235
1236 $valid_emails = array();
1237 if ( is_array( $emails ) ) {
1238 foreach ( $emails as $email ) {
1239 $email = esc_html( trim( $email ) );
1240 if ( ! empty( $email ) && ! in_array( $email, $valid_emails, true ) ) {
1241 $valid_emails[] = $email;
1242 }
1243 }
1244 }
1245 $valid_emails = implode( ',', $valid_emails );
1246 return $valid_emails;
1247 }
1248
1249 /**
1250 * Method check_image_file_name()
1251 *
1252 * Check if the file image.
1253 *
1254 * @param string $filename Contains image (file) name.
1255 *
1256 * @return true|false valid name or not.
1257 */
1258 public static function check_image_file_name( $filename ) {
1259 if ( validate_file( $filename ) ) {
1260 return false;
1261 }
1262
1263 $allowed_files = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'webp', 'heic' );
1264 $file_ext = array_values( array_slice( explode( '.', $filename ), -1 ) )[0];
1265 $file_ext = strtolower( $file_ext );
1266 if ( ! in_array( $file_ext, $allowed_files ) ) {
1267 return false;
1268 }
1269
1270 return true;
1271 }
1272
1273 /**
1274 * Method check_abandoned()
1275 *
1276 * Get site's icon.
1277 *
1278 * @param mixed $siteId site's id.
1279 * @param string $which to check plugin/theme.
1280 *
1281 * @return array result error or success
1282 * @throws \MainWP_Exception Error message.
1283 */
1284 public static function check_abandoned( $siteId = null, $which = '' ) { // phpcs:ignore -- NOSONAR - complex.
1285 if ( static::ctype_digit( $siteId ) ) {
1286 $website = MainWP_DB::instance()->get_website_by_id( $siteId );
1287 if ( MainWP_System_Utility::can_edit_website( $website ) ) {
1288 $error = '';
1289 try {
1290 $information = MainWP_Connect::fetch_url_authed( $website, 'check_abandoned', array( 'which' => $which ) );
1291 if ( is_array( $information ) && isset( $information['sync'] ) && ! empty( $information['sync'] ) ) {
1292 MainWP_Sync::sync_information_array( $website, $information['sync'] );
1293 unset( $information['sync'] );
1294 }
1295 } catch ( MainWP_Exception $e ) {
1296 $error = $e->getMessage();
1297 }
1298
1299 if ( '' !== $error ) {
1300 return array( 'error' => $error );
1301 } elseif ( isset( $information['success'] ) && ! empty( $information['success'] ) ) {
1302 return array( 'result' => 'success' );
1303 } else {
1304 return array( 'undefined_error' => true );
1305 }
1306 }
1307 }
1308 return array( 'result' => 'NOSITE' );
1309 }
1310
1311 /**
1312 * Get directory or slug of plugin.
1313 *
1314 * @param string $slug Plugin slug.
1315 *
1316 * @return string $value directory or slug of plugin.
1317 */
1318 public static function get_dir_slug( $slug ) {
1319 $value = '';
1320 if ( false === strpos( $slug, '/' ) ) {
1321 if ( false !== strpos( $slug, '.' ) ) {
1322 $value = substr( $slug, 0, strpos( $slug, '.' ) );
1323 }
1324 } else {
1325 $value = dirname( $slug );
1326 }
1327 if ( empty( $value ) ) {
1328 return $slug;
1329 }
1330 return $value;
1331 }
1332
1333 /**
1334 * Metho get_siteview_mode().
1335 *
1336 * Get site view mode.
1337 *
1338 * @return string $viewmode Site view mode.
1339 */
1340 public static function get_siteview_mode() {
1341 $viewmode = get_user_option( 'mainwp_sitesviewmode' );
1342 if ( 'grid' !== $viewmode && 'table' !== $viewmode ) {
1343 $viewmode = 'grid';
1344 }
1345 return $viewmode;
1346 }
1347
1348
1349 /**
1350 * Metho delete_file().
1351 *
1352 * Delete file.
1353 *
1354 * @param string $file_path File path.
1355 *
1356 * @return bool true|false.
1357 */
1358 public static function delete_file( $file_path ) {
1359
1360 global $wp_filesystem;
1361
1362 if ( ! empty( $file_path ) ) {
1363 if ( $wp_filesystem ) {
1364 if ( $wp_filesystem->exists( $file_path ) ) {
1365 $wp_filesystem->delete( $file_path );
1366 }
1367 } elseif ( file_exists( $file_path ) ) {
1368 wp_delete_file( $file_path );
1369 }
1370 return true;
1371 }
1372
1373 return false;
1374 }
1375
1376 /**
1377 * Method get_disable_functions()
1378 *
1379 * Get disable functions.
1380 *
1381 * @return string
1382 */
1383 public function get_disable_functions() {
1384 if ( null === static::$disabled_functions ) {
1385 static::$disabled_functions = ini_get( 'disable_functions' );
1386 }
1387 return static::$disabled_functions;
1388 }
1389
1390 /**
1391 * Method is_disable_functions()
1392 *
1393 * Check if it is disabled functions.
1394 *
1395 * @param string $func Function name to check.
1396 *
1397 * @return string
1398 */
1399 public function is_disabled_functions( $func ) {
1400 $dis_funcs = $this->get_disable_functions();
1401
1402 if ( ! empty( $dis_funcs ) && ( false !== stristr( $dis_funcs, $func ) ) ) {
1403 return true;
1404 }
1405 return false;
1406 }
1407
1408 /**
1409 * Method hook_verify_ping_nonce()
1410 *
1411 * Verify nonce without session and user id.
1412 *
1413 * @param bool $input_value Boolean value, it should always be FALSE.
1414 * @param string $nonce Nonce to verify.
1415 * @param mixed $siteid Site ID.
1416 *
1417 * @return mixed If verified return 1 or 2, if not return false.
1418 */
1419 public static function hook_verify_ping_nonce( $input_value, $nonce = '', $siteid = false ) {
1420 unset( $input_value );
1421 $action = 'pingnonce';
1422 return static::verify_site_nonce( $nonce, $action, $siteid );
1423 }
1424
1425 /**
1426 * Method create_site_nonce()
1427 *
1428 * Create action nonce for site.
1429 *
1430 * @param mixed $action Action to perform.
1431 * @param mixed $siteid Site ID.
1432 *
1433 * @return string Custom nonce.
1434 */
1435 public static function create_site_nonce( $action = - 1, $siteid = false ) {
1436 if ( empty( $action ) || empty( $siteid || ! is_numeric( $siteid ) ) ) {
1437 return false;
1438 }
1439 return substr( wp_hash( 'site|' . $siteid . '|' . $action, 'nonce' ), - 12, 10 );
1440 }
1441
1442 /**
1443 * Method verify_site_nonce()
1444 *
1445 * Verify nonce without session and user id.
1446 *
1447 * @param string $nonce Nonce to verify.
1448 * @param mixed $action Action to perform.
1449 * @param mixed $siteid Site ID.
1450 *
1451 * @return mixed If verified return 1 or 2, if not return false.
1452 */
1453 public static function verify_site_nonce( $nonce, $action = - 1, $siteid = 0 ) {
1454 $nonce = (string) $nonce;
1455 if ( empty( $nonce ) || empty( $siteid || ! is_numeric( $siteid ) ) ) {
1456 return false;
1457 }
1458
1459 $expected = substr( wp_hash( 'site|' . $siteid . '|' . $action, 'nonce' ), - 12, 10 );
1460 if ( hash_equals( $expected, $nonce ) ) {
1461 return 1;
1462 }
1463 return false;
1464 }
1465
1466
1467 /**
1468 * Find for multi keywords.
1469 *
1470 * @param string $name_str string find on.
1471 * @param array $words Array string input.
1472 * @return bool True|False.
1473 */
1474 public static function multi_find_keywords( $name_str, $words = array() ) {
1475 if ( ! is_array( $words ) ) {
1476 return false;
1477 }
1478 foreach ( $words as $word ) {
1479 if ( stristr( $name_str, $word ) ) {
1480 return true;
1481
1482 }
1483 }
1484 return false;
1485 }
1486
1487 /**
1488 * Merge values from right array to left array.
1489 *
1490 * @param array $left_array left array.
1491 * @param array $right_array right array.
1492 *
1493 * @return array $result result array.
1494 */
1495 public static function right_array_merge( $left_array, $right_array ) {
1496 if ( ! is_array( $left_array ) || ! is_array( $right_array ) ) {
1497 return array();
1498 }
1499 $result = array_intersect_key( $right_array, $left_array );
1500 return array_merge( $left_array, $result );
1501 }
1502
1503
1504 /**
1505 * Method get_set_deactivated_licenses_alerted().
1506 *
1507 * @param string $slug Extension slug.
1508 * @param bool $time_value Time value.
1509 * @param string $act get/set value.
1510 *
1511 * @return array $result result array.
1512 */
1513 public function get_set_deactivated_licenses_alerted( $slug, $time_value = false, $act = 'get' ) {
1514 if ( null === $this->last_deactivated_alerts ) {
1515 $this->last_deactivated_alerts = get_option( 'mainwp_cron_licenses_deactivated_alerted', array() );
1516 if ( ! is_array( $this->last_deactivated_alerts ) ) {
1517 $this->last_deactivated_alerts = array();
1518 }
1519 }
1520 if ( 'get' === $act ) {
1521 return isset( $this->last_deactivated_alerts[ $slug ] ) ? $this->last_deactivated_alerts[ $slug ] : 0;
1522 } elseif ( 'set' === $act ) {
1523 $this->last_deactivated_alerts[ $slug ] = intval( $time_value );
1524 get_option( 'mainwp_cron_licenses_deactivated_alerted', $this->last_deactivated_alerts );
1525 }
1526 }
1527
1528 /**
1529 * Method get_remote_favicon().
1530 *
1531 * @param string $url Url.
1532 * @param string $favi favicon file name.
1533 * @param int $item_id item id.
1534 * @param string $file_prefix favicon file prefix name.
1535 *
1536 * @return mixed result.
1537 */
1538 public static function get_remote_favicon( $url, $favi = '', $item_id = false, $file_prefix = '' ) { // phpcs:ignore -- NOSONAR - complex.
1539
1540 if ( empty( $favi ) ) {
1541 $favi = 'favicon.ico';
1542 }
1543
1544 if ( '/' !== substr( $url, - 1 ) ) {
1545 $url .= '/';
1546 }
1547
1548 $favi_url = $url . $favi;
1549
1550 $content = MainWP_Connect::get_file_content( $favi_url );
1551
1552 if ( empty( $content ) && 'favicon.ico' === $favi ) {
1553 $favi_url = $url . 'favicon.png';
1554 $content = MainWP_Connect::get_file_content( $favi_url ); // try other file.
1555 }
1556
1557 if ( ! empty( $content ) ) {
1558
1559 MainWP_System_Utility::get_wp_file_system();
1560
1561 global $wp_filesystem;
1562
1563 $dirs = MainWP_System_Utility::get_mainwp_dir( 'icons', true );
1564 $iconsDir = $dirs[0];
1565 if ( $favi ) {
1566
1567 $tmp = explode( '.', $favi );
1568 if ( 2 !== count( $tmp ) ) {
1569 return false;
1570 }
1571
1572 $favi_ext = $tmp[1];
1573
1574 if ( empty( $item_id ) ) {
1575 $item_id = time() . '-' . wp_rand( 100, 999 );
1576 }
1577 if ( ! empty( $file_prefix ) ) {
1578 $filename = $file_prefix . $item_id . '.' . $favi_ext;
1579 } else {
1580 $filename = 'favi-' . $item_id . '.' . $favi_ext;
1581 }
1582
1583 $size = $wp_filesystem->put_contents( $iconsDir . $filename, $content ); // phpcs:ignore --
1584 if ( $size ) {
1585 MainWP_Logger::instance()->debug( 'Icon Cost Product size :: ' . $size );
1586 return array(
1587 'result' => 'success',
1588 'file' => $filename,
1589 'dir' => $iconsDir,
1590 );
1591 } else {
1592 return array( 'error' => 'Save icon file failed.' );
1593 }
1594 }
1595 return false;
1596 } else {
1597 return array( 'error' => esc_html__( 'Download icon file failed', 'mainwp' ) );
1598 }
1599 }
1600
1601 /**
1602 * Method get_saved_favicon_url()
1603 *
1604 * @param string $favi Favicon file name.
1605 *
1606 * @return mixed $faviurl Favicon URL.
1607 */
1608 public static function get_saved_favicon_url( $favi ) {
1609 $faviurl = '';
1610 if ( ! empty( $favi ) ) {
1611 $dirs = MainWP_System_Utility::get_icons_dir();
1612 if ( file_exists( $dirs[0] . $favi ) ) {
1613 $faviurl = $dirs[1] . $favi;
1614 } else {
1615 $faviurl = '';
1616 }
1617 }
1618 return $faviurl;
1619 }
1620
1621 /**
1622 * Method delete_saved_favicon()
1623 *
1624 * @param string $favi Favicon file name.
1625 *
1626 * @return bool Success result.
1627 */
1628 public static function delete_saved_favicon( $favi ) {
1629 if ( ! empty( $favi ) ) {
1630 $hasWPFileSystem = MainWP_System_Utility::get_wp_file_system();
1631 global $wp_filesystem;
1632 $dirs = MainWP_System_Utility::get_icons_dir();
1633 if ( $hasWPFileSystem && $wp_filesystem->exists( $dirs[0] . $favi ) ) {
1634 $wp_filesystem->delete( $dirs[0] . $favi );
1635 return true;
1636 }
1637 }
1638 return false;
1639 }
1640
1641 /**
1642 * Delete icon file.
1643 *
1644 * @param string $sub_dir Sub dir file icon.
1645 * @param string $cost_icon file icon.
1646 */
1647 public function delete_uploaded_icon_file( $sub_dir, $cost_icon ) {
1648 $valid_file = 0 === validate_file( $cost_icon ) ? true : false;
1649 if ( $valid_file ) {
1650 $dirs = MainWP_System_Utility::get_mainwp_dir( $sub_dir, true );
1651 $f = $dirs[0] . $cost_icon;
1652 if ( file_exists( $f ) ) {
1653 wp_delete_file( $f );
1654 }
1655 }
1656 }
1657
1658 /**
1659 * Method get_table_orders().
1660 *
1661 * @param array $data table data.
1662 */
1663 public function get_table_orders( $data ) {
1664
1665 $values = array(
1666 'orderby' => null,
1667 'order' => null,
1668 );
1669
1670 if ( isset( $data['order'] ) ) {
1671 $columns = isset( $data['columns'] ) ? wp_unslash( $data['columns'] ) : array();
1672 $ord_col = isset( $data['order'][0]['column'] ) ? sanitize_text_field( wp_unslash( $data['order'][0]['column'] ) ) : '';
1673 if ( isset( $columns[ $ord_col ] ) ) {
1674 $values = array(
1675 'orderby' => isset( $columns[ $ord_col ]['data'] ) ? sanitize_text_field( wp_unslash( $columns[ $ord_col ]['data'] ) ) : '',
1676 'order' => isset( $data['order'][0]['dir'] ) ? sanitize_text_field( wp_unslash( $data['order'][0]['dir'] ) ) : '',
1677 );
1678 }
1679 }
1680
1681 return $values;
1682 }
1683
1684 /**
1685 * Method valid_file_check().
1686 *
1687 * @param string $path file path.
1688 * @param bool $readable readable.
1689 *
1690 * @return bool is valid.
1691 */
1692 public static function valid_file_check( $path, $readable = true ) {
1693 $valid = is_string( $path ) && ! stristr( $path, '..' );
1694 if ( $valid && $readable ) {
1695 $valid = is_readable( $path );
1696 }
1697 return $valid;
1698 }
1699
1700
1701 /**
1702 * Handle sanitize POST data.
1703 *
1704 * @param array $data input data.
1705 *
1706 * @return array
1707 */
1708 public function sanitize_data( $data ) {
1709 if ( ! is_array( $data ) ) {
1710 return array();
1711 }
1712
1713 // Sanitize all record values.
1714 return array_map(
1715 function ( $value ) {
1716 if ( ! is_array( $value ) ) {
1717 return wp_strip_all_tags( $value );
1718 }
1719
1720 return $value;
1721 },
1722 $data
1723 );
1724 }
1725
1726 /**
1727 * String ends by.
1728 *
1729 * @param mixed $str str.
1730 * @param mixed $ends ends.
1731 * @return bool value value.
1732 */
1733 public static function string_ends_by( $str, $ends ) {
1734 if ( function_exists( '\str_ends_with' ) ) {
1735 return \str_ends_with( $str, $ends );
1736 } else {
1737 $ends_len = strlen( $ends );
1738 if ( $ends_len > strlen( $str ) ) {
1739 return false;
1740 }
1741 return substr( $str, -$ends_len ) === $ends;
1742 }
1743 }
1744 /**
1745 * Returns number in shorter format.
1746 *
1747 * @param int $number str.
1748 * @return string $number Shorer number.
1749 */
1750 public static function short_number_format( $number ) {
1751 if ( $number > 999 && $number < 1000000 ) {
1752 // Anything between 1000 and 1000000.
1753 $number = number_format( $number / 1000, 1 ) . 'K';
1754 } elseif ( $number >= 1000000000 ) {
1755 // 1000000 or higher.
1756 $number = number_format( $number / 1000000, 2 ) . 'M';
1757 }
1758 return $number;
1759 }
1760
1761 /**
1762 * Returns date in time ago format
1763 *
1764 * @param mixed $ptime Date stamp.
1765 * @return string $string Time elapsed string.
1766 */
1767 public static function time_elapsed_string( $ptime ) {
1768 $etime = time() - $ptime;
1769
1770 if ( $etime < 1 ) {
1771 return '0 seconds';
1772 }
1773
1774 $a = array(
1775 365 * 24 * 60 * 60 => 'year',
1776 30 * 24 * 60 * 60 => 'month',
1777 24 * 60 * 60 => 'day',
1778 60 * 60 => 'hour',
1779 60 => 'minute',
1780 1 => 'second',
1781 );
1782 $a_plural = array(
1783 'year' => 'years',
1784 'month' => 'months',
1785 'day' => 'days',
1786 'hour' => 'hours',
1787 'minute' => 'minutes',
1788 'second' => 'seconds',
1789 );
1790
1791 foreach ( $a as $secs => $str ) {
1792 $d = $etime / $secs;
1793 if ( $d >= 1 ) {
1794 $r = round( $d );
1795 return $r . ' ' . ( $r > 1 ? $a_plural[ $str ] : $str ) . ' ago';
1796 }
1797 }
1798 }
1799 }
1800