PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 5.0
MainWP Dashboard: Self-hosted WordPress Management for Agencies v5.0
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.0, at class/class-mainwp-utility.php

1,434 lines 33.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 {
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 === self::$instance ) {
74 self::$instance = new self();
75 }
76
77 return self::$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 ( self::starts_with( $url, 'http://' ) ) {
127 if ( ! $showHttp ) {
128 $url = substr( $url, 7 );
129 }
130 } elseif ( self::starts_with( $pUrl, 'https://' ) ) {
131 if ( ! $showHttp ) {
132 $url = substr( $url, 8 );
133 }
134 } elseif ( $showHttp ) {
135 $url = 'http://' . $url;
136 }
137
138 if ( self::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 ) {
189 $sorted = array();
190 if ( is_array( $arr ) && 0 < count( $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 ) && 0 < count( $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 trim_slashes()
251 *
252 * Trim stashes from element.
253 *
254 * @param mixed $elem Element to trim.
255 *
256 * @return string Return string with no slashes.
257 */
258 public static function trim_slashes( $elem ) {
259 return trim( $elem, '/' );
260 }
261
262 /**
263 * Method sanitize()
264 *
265 * Sanitize given string.
266 *
267 * @param mixed $str String to sanitize.
268 *
269 * @return string Sanitized string.
270 */
271 public static function sanitize( $str ) {
272 return preg_replace( '/[\\\\\/\:"\*\?\<\>\|]+/', '', $str );
273 }
274
275 /**
276 * Method sanitize_alphanumeric()
277 *
278 * Sanitize given string.
279 *
280 * @param mixed $str String to sanitize.
281 *
282 * @return string Sanitized string.
283 */
284 public static function sanitize_attr_slug( $str ) {
285 $str = strtolower( $str );
286 $str = str_replace( array( '=', '?', '/' ), '-', $str );
287 $str = preg_replace( '/[^A-Za-z0-9^\-]/', '', $str );
288 return $str;
289 }
290
291 /**
292 * Method end_session()
293 *
294 * End a session.
295 *
296 * @return void
297 */
298 public static function end_session() {
299
300 if ( defined( 'WP_CLI' ) && WP_CLI ) {
301 return;
302 }
303
304 if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
305 return;
306 }
307
308 session_write_close();
309 if ( 0 < ob_get_length() ) {
310 ob_end_flush();
311 }
312 }
313
314 /**
315 * Method get_timestamp()
316 *
317 * Get time stamp in gmt_offset.
318 *
319 * @param mixed $timestamp Time stamp to convert.
320 *
321 * @return string Time stamp in general mountain time offset.
322 */
323 public static function get_timestamp( $timestamp = false ) {
324 if ( false === $timestamp ) {
325 $timestamp = time();
326 }
327 $gmtOffset = get_option( 'gmt_offset' );
328
329 return ( $gmtOffset ? ( $gmtOffset * HOUR_IN_SECONDS ) + $timestamp : $timestamp );
330 }
331
332 /**
333 * Method date()
334 *
335 * Show date in given format.
336 *
337 * @param mixed $format Format to display date in.
338 *
339 * @return string Date.
340 */
341 public static function date( $format ) {
342 // phpcs:ignore -- use local date function.
343 return date( $format, self::get_timestamp() );
344 }
345
346 /**
347 * Method format_timestamp()
348 *
349 * Format the given timestamp.
350 *
351 * @param mixed $timestamp Timestamp to format.
352 *
353 * @return string Formatted timestamp.
354 */
355 public static function format_timestamp( $timestamp ) {
356 return date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $timestamp );
357 }
358
359 /**
360 * Method format_timestamp()
361 *
362 * Format the given timestamp.
363 *
364 * @param mixed $timestamp Timestamp to format.
365 *
366 * @return string Formatted timestamp.
367 */
368 public static function format_date( $timestamp ) {
369 return date_i18n( get_option( 'date_format' ), $timestamp );
370 }
371
372 /**
373 * Format duration time to show.
374 *
375 * @param float $time timestamp.
376 * @return mixed result.
377 */
378 public static function format_duration_time( $time ) {
379
380 $original_sec = absint( $time );
381 $dura_sec = $original_sec;
382 $days = floor( $dura_sec / 86400 );
383 $dura_sec -= $days * 86400;
384 $dura_hour_sec = $dura_sec;
385 $dura_hours = floor( $dura_sec / 3600 );
386
387 if ( $days > 0 ) {
388 $formatted_dura = ( $days * 24 + $dura_hours ) . gmdate( 'i\m s\s', $dura_hour_sec );
389 } else {
390 $formatted_dura = gmdate( 'H\h i\m s\s', $original_sec );
391 }
392 return '<bdi>' . esc_html( $formatted_dura ) . '</bdi>';
393 }
394
395
396 /**
397 * Method human_filesize()
398 *
399 * Convert to human readable file size format,
400 * (B|kB|MB|GB|TB|PB|EB|ZB|YB).
401 *
402 * @param mixed $bytes File in bytes.
403 * @param integer $decimals Number of decimals to output.
404 *
405 * @return string Human readable file size.
406 */
407 public static function human_filesize( $bytes, $decimals = 2 ) {
408 $size = array( 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' );
409 $factor = floor( ( strlen( $bytes ) - 1 ) / 3 );
410
411 return sprintf( "%.{$decimals}f", $bytes / pow( 1024, $factor ) ) . @$size[ $factor ];
412 }
413
414 /**
415 * Method map_fields()
416 *
417 * Map Site.
418 *
419 * @param mixed $data data to map.
420 * @param mixed $keys Keys to map.
421 * @param bool $object_output Output format array|object.
422 *
423 * @return mixed Mapped data.
424 */
425 public static function map_fields( &$data, $keys, $object_output = true ) {
426 return self::map_site( $data, $keys, $object_output );
427 }
428
429 /**
430 * Method map_site()
431 *
432 * Map Site.
433 *
434 * @param mixed $website Website to map.
435 * @param mixed $keys Keys to map.
436 * @param bool $object_output Output format array|object.
437 *
438 * @return mixed $outputSite Mapped site.
439 */
440 public static function map_site( &$website, $keys, $object_output = true ) {
441 $outputSite = array();
442 if ( ! empty( $website ) ) {
443 if ( is_object( $website ) ) {
444 foreach ( $keys as $key ) {
445 $outputSite[ $key ] = $website->$key;
446 }
447 } elseif ( is_array( $website ) ) {
448 foreach ( $keys as $key ) {
449 $outputSite[ $key ] = $website[ $key ];
450 }
451 }
452 }
453
454 if ( $object_output ) {
455 return (object) $outputSite;
456 } else {
457 return $outputSite;
458 }
459 }
460
461 /**
462 * Method array_merge()
463 *
464 * Merge two given arrays into one.
465 *
466 * @param mixed $arr1 First array.
467 * @param mixed $arr2 Second array.
468 *
469 * @return array Merged Array.
470 */
471 public static function array_merge( $arr1, $arr2 ) {
472 if ( ! is_array( $arr1 ) && ! is_array( $arr2 ) ) {
473 return array();
474 }
475 if ( ! is_array( $arr1 ) ) {
476 return $arr2;
477 }
478 if ( ! is_array( $arr2 ) ) {
479 return $arr1;
480 }
481
482 $output = array();
483 foreach ( $arr1 as $el ) {
484 $output[] = $el;
485 }
486 foreach ( $arr2 as $el ) {
487 $output[] = $el;
488 }
489
490 return $output;
491 }
492
493 /**
494 * Method update_option()
495 *
496 * Update option.
497 *
498 * @param mixed $option_name Option name.
499 * @param mixed $option_value Option value.
500 *
501 * @return (boolean) False if value was not updated and true if value was updated.
502 */
503 public static function update_option( $option_name, $option_value ) {
504 $success = add_option( $option_name, $option_value, '', 'no' );
505
506 if ( ! $success ) {
507 $success = update_option( $option_name, $option_value );
508 }
509
510 return $success;
511 }
512
513 /**
514 * Method update_user_option()
515 *
516 * Update option.
517 *
518 * @param mixed $option_name Option name.
519 * @param mixed $option_value Option value.
520 *
521 * @return (boolean) False if value was not updated and true if value was updated.
522 */
523 public static function update_user_option( $option_name, $option_value ) {
524 $user = wp_get_current_user();
525 if ( $user ) {
526 return update_user_option( $user->ID, $option_name, $option_value );
527 }
528 return false;
529 }
530
531 /**
532 * Method remove_preslash_spaces()
533 *
534 * Remove spaces before slashes.
535 *
536 * @param string $text String to strip.
537 *
538 * @return string $text Cleaned string.
539 */
540 public static function remove_preslash_spaces( $text ) {
541 while ( stristr( $text, ' /' ) ) {
542 $text = str_replace( ' /', '/', $text );
543 }
544
545 return $text;
546 }
547
548 /**
549 * Method remove_http_prefix()
550 *
551 * Remove http prefixes from given url.
552 *
553 * @param mixed $pUrl Given URL.
554 * @param bool $pTrimSlashes Whether or not to trim slashes. Default is false.
555 *
556 * @return string Trimmed URL.
557 */
558 public static function remove_http_prefix( $pUrl, $pTrimSlashes = false ) {
559 return str_replace( array( 'http:' . ( $pTrimSlashes ? '//' : '' ), 'https:' . ( $pTrimSlashes ? '//' : '' ) ), array( '', '' ), $pUrl );
560 }
561
562 /**
563 * Method remove_http_www_prefix()
564 *
565 * Remove 'www.' from given URL.
566 *
567 * @param mixed $pUrl Given URL.
568 *
569 * @return string Cleaned URL.
570 */
571 public static function remove_http_www_prefix( $pUrl ) {
572 $pUrl = self::remove_http_prefix( $pUrl, true );
573 return str_replace( 'www.', '', $pUrl );
574 }
575
576 /**
577 * Method sanitize_file_name()
578 *
579 * Sanitize file names.
580 *
581 * @param mixed $filename File name to sanitize.
582 *
583 * @return string Sanitized filename.
584 */
585 public static function sanitize_file_name( $filename ) {
586 $filename = str_replace( array( '|', '/', '\\', ' ', ':' ), array( '-', '-', '-', '-', '-' ), $filename );
587 return sanitize_file_name( $filename );
588 }
589
590 /**
591 * Method normalize_filename()
592 *
593 * Normalize filename.
594 *
595 * @param mixed $s Filename to normalize.
596 *
597 * @return string $s Normalised filename.
598 */
599 public static function normalize_filename( $s ) {
600 $s = preg_replace( '@\x{00c4}@u', 'A', $s );
601 $s = preg_replace( '@\x{00d6}@u', 'O', $s );
602 $s = preg_replace( '@\x{00dc}@u', 'U', $s );
603 $s = preg_replace( '@\x{00cb}@u', 'E', $s );
604 $s = preg_replace( '@\x{00e4}@u', 'a', $s );
605 $s = preg_replace( '@\x{00f6}@u', 'o', $s );
606 $s = preg_replace( '@\x{00fc}@u', 'u', $s );
607 $s = preg_replace( '@\x{00eb}@u', 'e', $s );
608 $s = preg_replace( '@\x{00f1}@u', 'n', $s );
609 $s = preg_replace( '@\x{00ff}@u', 'y', $s );
610 return $s;
611 }
612
613
614 /**
615 * Method esc_content()
616 *
617 * Escape content,
618 * allowed content (a,href,title,br,em,strong,p,hr,ul,ol,li,h1,h2 ... ).
619 *
620 * @param mixed $content Content to escape.
621 * @param string $type Type of content. Default = note.
622 * @param mixed $more_allowed input allowed tags - options.
623 *
624 * @return string Filtered content containing only the allowed HTML.
625 */
626 public static function esc_content( $content, $type = 'note', $more_allowed = array() ) {
627 if ( ! is_string( $content ) ) {
628 return $content;
629 }
630
631 if ( 'note' === $type ) {
632
633 $allowed_html = array(
634 'a' => array(
635 'href' => array(),
636 'title' => array(),
637 ),
638 'br' => array(),
639 'em' => array(),
640 'strong' => array(),
641 'p' => array(),
642 'hr' => array(),
643 'ul' => array(),
644 'ol' => array(),
645 'li' => array(),
646 'h1' => array(),
647 'h2' => array(),
648 );
649
650 if ( is_array( $more_allowed ) && ! empty( $more_allowed ) ) {
651 $allowed_html = array_merge( $allowed_html, $more_allowed );
652 }
653
654 $content = wp_kses( $content, $allowed_html );
655
656 } elseif ( 'mixed' === $type ) {
657
658 $allowed_html = array(
659 'a' => array(
660 'href' => array(),
661 'title' => array(),
662 'class' => array(),
663 'onclick' => array(),
664 ),
665 'img' => array(
666 'src' => array(),
667 'title' => array(),
668 'class' => array(),
669 'onclick' => array(),
670 'alt' => array(),
671 'width' => array(),
672 'height' => array(),
673 'sizes' => array(),
674 'srcset' => array(),
675 'usemap' => array(),
676 ),
677 'br' => array(),
678 'em' => array(),
679 'strong' => array(),
680 'p' => array(),
681 'hr' => array(),
682 'ul' => array(
683 'style' => array(),
684 ),
685 'ol' => array(),
686 'li' => array(),
687 'h1' => array(),
688 'h2' => array(),
689 'head' => array(),
690 'html' => array(
691 'lang' => array(),
692 ),
693 'meta' => array(
694 'name' => array(),
695 'http-equiv' => array(),
696 'content' => array(),
697 'charset' => array(),
698 ),
699 'title' => array(),
700 'body' => array(
701 'style' => array(),
702 ),
703 'span' => array(
704 'id' => array(),
705 'style' => array(),
706 'class' => array(),
707 ),
708 'form' => array(
709 'id' => array(),
710 'method' => array(),
711 'action' => array(),
712 'onsubmit' => array(),
713 ),
714 'table' => array(
715 'class' => array(),
716 ),
717 'thead' => array(
718 'class' => array(),
719 ),
720 'tbody' => array(
721 'class' => array(),
722 ),
723 'tr' => array(
724 'id' => array(),
725 ),
726 'td' => array(
727 'class' => array(),
728 ),
729 'div' => array(
730 'id' => array(),
731 'style' => array(),
732 'class' => array(),
733 ),
734 'input' => array(
735 'type' => array(),
736 'name' => array(),
737 'class' => array(),
738 'value' => array(),
739 'onclick' => array(),
740 ),
741 'button' => array(
742 'type' => array(),
743 'name' => array(),
744 'value' => array(),
745 'class' => array(),
746 'title' => array(),
747 'onclick' => array(),
748 ),
749 );
750
751 if ( is_array( $more_allowed ) && ! empty( $more_allowed ) ) {
752 $allowed_html = array_merge( $allowed_html, $more_allowed );
753 }
754
755 $content = wp_kses( $content, $allowed_html );
756 } else {
757 $content = wp_kses_post( $content );
758 }
759
760 return $content;
761 }
762
763 /**
764 * Method esc_mixed_content()
765 *
766 * Escape mixed content,
767 * allowed content (a,href,title,br,em,strong,p,hr,ul,ol,li,h1,h2 ... ).
768 *
769 * @param mixed $data data to escape.
770 * @param string $depth Maximum depth to walk through $data. Must be greater than 0.
771 * @param mixed $more_allowed input allowed tags - options.
772 *
773 * @throws \Exception Excetpion message.
774 *
775 * @return string Filtered content containing only the allowed HTML.
776 */
777 public static function esc_mixed_content( $data, $depth, $more_allowed = array() ) {
778 if ( $depth < 0 ) {
779 throw new \Exception( 'Reached depth limit' );
780 }
781
782 if ( is_array( $data ) ) {
783 $output = array();
784 foreach ( $data as $id => $el ) {
785 // Don't forget to sanitize the ID!
786 if ( is_string( $id ) ) {
787 $clean_id = self::esc_content( $id, 'mixed', $more_allowed );
788 } else {
789 $clean_id = $id;
790 }
791
792 // Check the element type, so that we're only recursing if we really have to.
793 if ( is_array( $el ) || is_object( $el ) ) {
794 $output[ $clean_id ] = self::esc_mixed_content( $el, $depth - 1 );
795 } elseif ( is_string( $el ) ) {
796 $output[ $clean_id ] = self::esc_content( $el, 'mixed', $more_allowed );
797 } else {
798 $output[ $clean_id ] = $el;
799 }
800 }
801 } elseif ( is_object( $data ) ) {
802 $output = new stdClass();
803 foreach ( $data as $id => $el ) {
804 if ( is_string( $id ) ) {
805 $clean_id = self::esc_content( $id, 'mixed', $more_allowed );
806 } else {
807 $clean_id = $id;
808 }
809
810 if ( is_array( $el ) || is_object( $el ) ) {
811 $output->$clean_id = self::esc_mixed_content( $el, $depth - 1, $more_allowed );
812 } elseif ( is_string( $el ) ) {
813 $output->$clean_id = self::esc_content( $el, 'mixed', $more_allowed );
814 } else {
815 $output->$clean_id = $el;
816 }
817 }
818 } elseif ( is_string( $data ) ) {
819 return self::esc_content( $data, 'mixed', $more_allowed );
820 } else {
821 return $data;
822 }
823
824 return $output;
825 }
826
827 /**
828 * Method show_mainwp_message()
829 *
830 * Check whenther or not to show the MainWP Message.
831 *
832 * @param mixed $type Type of message.
833 * @param mixed $notice_id Notice ID.
834 *
835 * @return boolean true|false.
836 */
837 public static function show_mainwp_message( $type, $notice_id ) {
838 $status = get_user_option( 'mainwp_notice_saved_status' );
839 if ( ! is_array( $status ) ) {
840 $status = array();
841 }
842 if ( isset( $status[ $notice_id ] ) ) {
843 return false;
844 }
845 return true;
846 }
847
848 /**
849 * Method get_hide_notice_status()
850 *
851 * Check whenther or not to show the MainWP Message.
852 *
853 * @param mixed $notice_id Notice ID.
854 *
855 * @return mixed true|false|time.
856 */
857 public static function get_hide_notice_status( $notice_id ) {
858 $notices = get_user_option( 'mainwp_notice_saved_status' );
859 if ( ! is_array( $notices ) ) {
860 $notices = array();
861 }
862 if ( isset( $notices[ $notice_id ] ) ) {
863 return $notices[ $notice_id ];
864 }
865 return false;
866 }
867
868 /**
869 * Method get_flash_message()
870 *
871 * Get saved flash Message.
872 *
873 * @param mixed $message_id Notice ID.
874 * @param bool $delete True to delete the message after get it.
875 *
876 * @return boolean true|false.
877 */
878 public static function get_flash_message( $message_id, $delete = true ) {
879 $flash_messages = get_user_option( 'mainwp_flash_messages' );
880 if ( ! is_array( $flash_messages ) ) {
881 $flash_messages = array();
882 }
883 if ( ! isset( $flash_messages[ $message_id ] ) ) {
884 return false;
885 }
886 $content = $flash_messages[ $message_id ];
887 if ( $delete ) {
888 unset( $flash_messages[ $message_id ] );
889 self::update_user_option( 'mainwp_flash_messages', $flash_messages );
890 }
891 return $content;
892 }
893
894 /**
895 * Method update_flash_message()
896 *
897 * Check whenther or not to show the MainWP Message.
898 *
899 * @param mixed $message_id Notice ID.
900 * @param mixed $content Content of message.
901 *
902 * @return boolean true|false.
903 */
904 public static function update_flash_message( $message_id, $content ) {
905 $flash_messages = get_user_option( 'mainwp_flash_messages' );
906 if ( ! is_array( $flash_messages ) ) {
907 $flash_messages = array();
908 }
909 $current = isset( $flash_messages[ $message_id ] ) ? $flash_messages[ $message_id ] : '';
910 if ( empty( $current ) ) {
911 $current = $content;
912 } else {
913 $current .= '|' . $content;
914 }
915 $flash_messages[ $message_id ] = $current;
916 return self::update_user_option( 'mainwp_flash_messages', $flash_messages );
917 }
918
919 /**
920 * Method array_sort()
921 *
922 * Sort given array by given flags.
923 *
924 * @param mixed $arr Array to sort.
925 * @param mixed $key Array key.
926 * @param string $sort_flag Flags to sort by. Default = SORT_STRING.
927 */
928 public static function array_sort( &$arr, $key, $sort_flag = SORT_STRING ) {
929 $sorter = array();
930 $ret = array();
931 reset( $arr );
932 foreach ( $arr as $ii => $val ) {
933 $sorter[ $ii ] = $val[ $key ];
934 }
935 asort( $sorter, $sort_flag );
936 foreach ( $sorter as $ii => $val ) {
937 $ret[ $ii ] = $arr[ $ii ];
938 }
939 $arr = $ret;
940 }
941
942 /**
943 * Method array_sort_existed_keys()
944 *
945 * Sort given array by given flags.
946 *
947 * @param mixed $arr Array to sort.
948 * @param mixed $key Array key.
949 * @param string $sort_flag Flags to sort by. Default = SORT_STRING.
950 */
951 public static function array_sort_existed_keys( &$arr, $key, $sort_flag = SORT_STRING ) {
952 $sorter = array();
953 $ret = array();
954 reset( $arr );
955
956 // get items with $key to sort.
957 foreach ( $arr as $ii => $val ) {
958 if ( isset( $val[ $key ] ) ) {
959 $sorter[ $ii ] = $val[ $key ];
960 }
961 }
962 asort( $sorter, $sort_flag );
963
964 foreach ( $sorter as $ii => $val ) {
965 $ret[ $ii ] = $arr[ $ii ];
966 }
967
968 // asign other items (without $keys).
969 foreach ( $arr as $ii => $val ) {
970 if ( ! isset( $val[ $key ] ) ) {
971 $ret[ $ii ] = $val;
972 }
973 }
974
975 $arr = $ret;
976 }
977
978 /**
979 * Method array_numeric_filter()
980 *
981 * Filter given numeric array.
982 *
983 * @param array $arr_ints Array to filter.
984 * @return array $arr_ints Array filtered.
985 */
986 public static function array_numeric_filter( $arr_ints ) {
987 $arr_ints = array_filter(
988 $arr_ints,
989 function ( $e ) {
990 return ( is_numeric( $e ) && 0 < $e ) ? true : false;
991 }
992 );
993 return $arr_ints;
994 }
995
996 /**
997 * Method enabled_wp_seo()
998 *
999 * Check if Yoast SEO is enabled.
1000 *
1001 * @return boolean true|false.
1002 */
1003 public static function enabled_wp_seo() {
1004 if ( null === self::$enabled_wp_seo ) {
1005 self::$enabled_wp_seo = is_plugin_active( 'wordpress-seo-extension/wordpress-seo-extension.php' );
1006 }
1007 return self::$enabled_wp_seo;
1008 }
1009
1010 /**
1011 * Method value_to_string()
1012 *
1013 * Value to string.
1014 *
1015 * @param mixed $var_value Value to convert to string.
1016 *
1017 * @return string Value that has been converted into a string.
1018 */
1019 public static function value_to_string( $var_value ) {
1020 if ( is_array( $var_value ) || is_object( $var_value ) ) {
1021 //phpcs:ignore -- for debug only
1022 return print_r( $var_value, true );
1023 } elseif ( is_string( $var_value ) ) {
1024 return $var_value;
1025 }
1026 return '';
1027 }
1028
1029 /**
1030 * Get Health Site value.
1031 *
1032 * @param mixed $issue_counts Health site issues.
1033 *
1034 * @return array Health status value.
1035 */
1036 public static function get_site_health( $issue_counts ) {
1037
1038 if ( empty( $issue_counts ) ) {
1039 $issue_counts = array(
1040 'good' => 0,
1041 'recommended' => 0,
1042 'critical' => 0,
1043 );
1044 }
1045
1046 $totalTests = intval( $issue_counts['good'] ) + intval( $issue_counts['recommended'] ) + intval( $issue_counts['critical'] ) * 1.5;
1047 $failedTests = intval( $issue_counts['recommended'] ) * 0.5 + $issue_counts['critical'] * 1.5;
1048
1049 if ( empty( $totalTests ) ) {
1050 $val = 100;
1051 } else {
1052 $val = 100 - ceil( ( $failedTests / $totalTests ) * 100 );
1053 }
1054
1055 if ( 0 > $val ) {
1056 $val = 0;
1057 }
1058
1059 if ( 100 < $val ) {
1060 $val = 100;
1061 }
1062
1063 return array(
1064 'val' => $val,
1065 'critical' => $issue_counts['critical'],
1066 );
1067 }
1068
1069
1070 /**
1071 * Get HTTP code.
1072 *
1073 * @param int $code HTTP code.
1074 *
1075 * @return array $http_codes HTTP code.
1076 */
1077 public static function get_http_codes( $code = false ) {
1078
1079 $http_codes = array(
1080 100 => 'Continue',
1081 101 => 'Switching Protocols',
1082 200 => 'OK',
1083 201 => 'Created',
1084 202 => 'Accepted',
1085 203 => 'Non-Authoritative Information',
1086 204 => 'No Content',
1087 205 => 'Reset Content',
1088 206 => 'Partial Content',
1089 300 => 'Multiple Choices',
1090 301 => 'Moved Permanently',
1091 302 => 'Found',
1092 303 => 'See Other',
1093 304 => 'Not Modified',
1094 305 => 'Use Proxy',
1095 306 => '(Unused)',
1096 307 => 'Temporary Redirect',
1097 400 => 'Bad Request',
1098 401 => 'Unauthorized',
1099 402 => 'Payment Required',
1100 403 => 'Forbidden',
1101 404 => 'Not Found',
1102 405 => 'Method Not Allowed',
1103 406 => 'Not Acceptable',
1104 407 => 'Proxy Authentication Required',
1105 408 => 'Request Timeout',
1106 409 => 'Conflict',
1107 410 => 'Gone',
1108 411 => 'Length Required',
1109 412 => 'Precondition Failed',
1110 413 => 'Request Entity Too Large',
1111 414 => 'Request-URI Too Long',
1112 415 => 'Unsupported Media Type',
1113 416 => 'Requested Range Not Satisfiable',
1114 417 => 'Expectation Failed',
1115 500 => 'Internal Server Error',
1116 501 => 'Not Implemented',
1117 502 => 'Bad Gateway',
1118 503 => 'Service Unavailable',
1119 504 => 'Gateway Timeout',
1120 505 => 'HTTP Version Not Supported',
1121 );
1122
1123 if ( false === $code ) {
1124 return $http_codes;
1125 }
1126
1127 return isset( $http_codes[ $code ] ) ? $http_codes[ $code ] : '';
1128 }
1129
1130 /**
1131 * Method valid_input_emails().
1132 *
1133 * @param string $emails Input emails string.
1134 *
1135 * @return string $valid_emails Valid emails string.
1136 */
1137 public static function valid_input_emails( $emails ) {
1138
1139 if ( is_string( $emails ) ) {
1140 $emails = array_filter( explode( ',', $emails ) );
1141 }
1142
1143 $valid_emails = array();
1144 if ( is_array( $emails ) ) {
1145 foreach ( $emails as $email ) {
1146 $email = esc_html( trim( $email ) );
1147 if ( ! empty( $email ) && ! in_array( $email, $valid_emails, true ) ) {
1148 $valid_emails[] = $email;
1149 }
1150 }
1151 }
1152 $valid_emails = implode( ',', $valid_emails );
1153 return $valid_emails;
1154 }
1155
1156 /**
1157 * Method check_image_file_name()
1158 *
1159 * Check if the file image.
1160 *
1161 * @param string $filename Contains image (file) name.
1162 *
1163 * @return true|false valid name or not.
1164 */
1165 public static function check_image_file_name( $filename ) {
1166 if ( validate_file( $filename ) ) {
1167 return false;
1168 }
1169
1170 $allowed_files = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico' );
1171 $file_ext = array_values( array_slice( explode( '.', $filename ), -1 ) )[0];
1172 $file_ext = strtolower( $file_ext );
1173 if ( ! in_array( $file_ext, $allowed_files ) ) {
1174 return false;
1175 }
1176
1177 return true;
1178 }
1179
1180 /**
1181 * Method check_abandoned()
1182 *
1183 * Get site's icon.
1184 *
1185 * @param mixed $siteId site's id.
1186 * @param string $which to check plugin/theme.
1187 *
1188 * @return array result error or success
1189 * @throws \Exception Error message.
1190 */
1191 public static function check_abandoned( $siteId = null, $which = '' ) {
1192 if ( self::ctype_digit( $siteId ) ) {
1193 $website = MainWP_DB::instance()->get_website_by_id( $siteId );
1194 if ( MainWP_System_Utility::can_edit_website( $website ) ) {
1195 $error = '';
1196 try {
1197 $information = MainWP_Connect::fetch_url_authed( $website, 'check_abandoned', array( 'which' => $which ) );
1198 if ( is_array( $information ) && isset( $information['sync'] ) && ! empty( $information['sync'] ) ) {
1199 MainWP_Sync::sync_information_array( $website, $information['sync'] );
1200 unset( $information['sync'] );
1201 }
1202 } catch ( MainWP_Exception $e ) {
1203 $error = $e->getMessage();
1204 }
1205
1206 if ( '' !== $error ) {
1207 return array( 'error' => $error );
1208 } elseif ( isset( $information['success'] ) && ! empty( $information['success'] ) ) {
1209 return array( 'result' => 'success' );
1210 } else {
1211 return array( 'undefined_error' => true );
1212 }
1213 }
1214 }
1215 return array( 'result' => 'NOSITE' );
1216 }
1217
1218 /**
1219 * Get directory or slug of plugin.
1220 *
1221 * @param string $slug Plugin slug.
1222 *
1223 * @return string $value directory or slug of plugin.
1224 */
1225 public static function get_dir_slug( $slug ) {
1226 $value = '';
1227 if ( false === strpos( $slug, '/' ) ) {
1228 if ( false !== strpos( $slug, '.' ) ) {
1229 $value = substr( $slug, 0, strpos( $slug, '.' ) );
1230 }
1231 } else {
1232 $value = dirname( $slug );
1233 }
1234 if ( empty( $value ) ) {
1235 return $slug;
1236 }
1237 return $value;
1238 }
1239
1240 /**
1241 * Metho get_siteview_mode().
1242 *
1243 * Get site view mode.
1244 *
1245 * @return string $viewmode Site view mode.
1246 */
1247 public static function get_siteview_mode() {
1248 $viewmode = get_user_option( 'mainwp_sitesviewmode' );
1249 if ( 'grid' !== $viewmode && 'table' !== $viewmode ) {
1250 $viewmode = 'grid';
1251 }
1252 return $viewmode;
1253 }
1254
1255
1256 /**
1257 * Metho delete_file().
1258 *
1259 * Delete file.
1260 *
1261 * @param string $file_path File path.
1262 *
1263 * @return bool true|false.
1264 */
1265 public static function delete_file( $file_path ) {
1266
1267 global $wp_filesystem;
1268
1269 if ( ! empty( $file_path ) ) {
1270 if ( $wp_filesystem ) {
1271 if ( $wp_filesystem->exists( $file_path ) ) {
1272 $wp_filesystem->delete( $file_path );
1273 }
1274 } elseif ( file_exists( $file_path ) ) {
1275 wp_delete_file( $file_path );
1276 }
1277 return true;
1278 }
1279
1280 return false;
1281 }
1282
1283 /**
1284 * Method get_disable_functions()
1285 *
1286 * Get disable functions.
1287 *
1288 * @return string
1289 */
1290 public function get_disable_functions() {
1291 if ( null === self::$disabled_functions ) {
1292 self::$disabled_functions = ini_get( 'disable_functions' );
1293 }
1294 return self::$disabled_functions;
1295 }
1296
1297 /**
1298 * Method is_disable_functions()
1299 *
1300 * Check if it is disabled functions.
1301 *
1302 * @param string $func Function name to check.
1303 *
1304 * @return string
1305 */
1306 public function is_disabled_functions( $func ) {
1307 $dis_funcs = $this->get_disable_functions();
1308
1309 if ( ! empty( $dis_funcs ) && ( false !== stristr( $dis_funcs, $func ) ) ) {
1310 return true;
1311 }
1312 return false;
1313 }
1314
1315 /**
1316 * Method hook_verify_ping_nonce()
1317 *
1318 * Verify nonce without session and user id.
1319 *
1320 * @param bool $input_value Boolean value, it should always be FALSE.
1321 * @param string $nonce Nonce to verify.
1322 * @param mixed $siteid Site ID.
1323 *
1324 * @return mixed If verified return 1 or 2, if not return false.
1325 */
1326 public static function hook_verify_ping_nonce( $input_value, $nonce = '', $siteid = false ) {
1327 $action = 'pingnonce';
1328 return self::verify_site_nonce( $nonce, $action, $siteid );
1329 }
1330
1331 /**
1332 * Method create_site_nonce()
1333 *
1334 * Create action nonce for site.
1335 *
1336 * @param mixed $action Action to perform.
1337 * @param mixed $siteid Site ID.
1338 *
1339 * @return string Custom nonce.
1340 */
1341 public static function create_site_nonce( $action = - 1, $siteid = false ) {
1342 if ( empty( $action ) || empty( $siteid || ! is_numeric( $siteid ) ) ) {
1343 return false;
1344 }
1345 return substr( wp_hash( 'site|' . $siteid . '|' . $action, 'nonce' ), - 12, 10 );
1346 }
1347
1348 /**
1349 * Method verify_site_nonce()
1350 *
1351 * Verify nonce without session and user id.
1352 *
1353 * @param string $nonce Nonce to verify.
1354 * @param mixed $action Action to perform.
1355 * @param mixed $siteid Site ID.
1356 *
1357 * @return mixed If verified return 1 or 2, if not return false.
1358 */
1359 public static function verify_site_nonce( $nonce, $action = - 1, $siteid = 0 ) {
1360 $nonce = (string) $nonce;
1361 if ( empty( $nonce ) || empty( $siteid || ! is_numeric( $siteid ) ) ) {
1362 return false;
1363 }
1364
1365 $expected = substr( wp_hash( 'site|' . $siteid . '|' . $action, 'nonce' ), - 12, 10 );
1366 if ( hash_equals( $expected, $nonce ) ) {
1367 return 1;
1368 }
1369 return false;
1370 }
1371
1372
1373 /**
1374 * Find for multi keywords.
1375 *
1376 * @param string $name_str string find on.
1377 * @param array $words Array string input.
1378 * @return bool True|False.
1379 */
1380 public static function multi_find_keywords( $name_str, $words = array() ) {
1381 if ( ! is_array( $words ) ) {
1382 return false;
1383 }
1384 foreach ( $words as $word ) {
1385 if ( stristr( $name_str, $word ) ) {
1386 return true;
1387
1388 }
1389 }
1390 return false;
1391 }
1392
1393 /**
1394 * Merge values from right array to left array.
1395 *
1396 * @param array $left_array left array.
1397 * @param array $right_array right array.
1398 *
1399 * @return array $result result array.
1400 */
1401 public static function right_array_merge( $left_array, $right_array ) {
1402 if ( ! is_array( $left_array ) || ! is_array( $right_array ) ) {
1403 return array();
1404 }
1405 $result = array_intersect_key( $right_array, $left_array );
1406 return array_merge( $left_array, $result );
1407 }
1408
1409
1410 /**
1411 * Method get_set_deactivated_licenses_alerted().
1412 *
1413 * @param string $slug Extension slug.
1414 * @param bool $time_value Time value.
1415 * @param string $act get/set value.
1416 *
1417 * @return array $result result array.
1418 */
1419 public function get_set_deactivated_licenses_alerted( $slug, $time_value = false, $act = 'get' ) {
1420 if ( null === $this->last_deactivated_alerts ) {
1421 $this->last_deactivated_alerts = get_option( 'mainwp_cron_licenses_deactivated_alerted', array() );
1422 if ( ! is_array( $this->last_deactivated_alerts ) ) {
1423 $this->last_deactivated_alerts = array();
1424 }
1425 }
1426 if ( 'get' === $act ) {
1427 return isset( $this->last_deactivated_alerts[ $slug ] ) ? $this->last_deactivated_alerts[ $slug ] : 0;
1428 } elseif ( 'set' === $act ) {
1429 $this->last_deactivated_alerts[ $slug ] = intval( $time_value );
1430 get_option( 'mainwp_cron_licenses_deactivated_alerted', $this->last_deactivated_alerts );
1431 }
1432 }
1433 }
1434