balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

class-redux-functions.php (14834B)


      1 <?php
      2 /**
      3  * Redux Framework Private Functions Container Class
      4  *
      5  * @class       Redux_Functions
      6  * @package     Redux_Framework/Classes
      7  * @since       3.0.0
      8  */
      9 
     10 // Exit if accessed directly.
     11 defined( 'ABSPATH' ) || exit;
     12 
     13 // Don't duplicate me!
     14 if ( ! class_exists( 'Redux_Functions', false ) ) {
     15 
     16 	/**
     17 	 * Redux Functions Class
     18 	 * A Class of useful functions that can/should be shared among all Redux files.
     19 	 *
     20 	 * @since       3.0.0
     21 	 */
     22 	class Redux_Functions {
     23 
     24 		/**
     25 		 * ReduxFramework object pointer.
     26 		 *
     27 		 * @var object
     28 		 */
     29 		public static $parent;
     30 
     31 		/**
     32 		 * ReduxFramework shim object pointer.
     33 		 *
     34 		 * @var object
     35 		 */
     36 		public static $_parent; // phpcs:ignore PSR2.Classes.PropertyDeclaration.Underscore
     37 
     38 		/**
     39 		 * Check for existence of class name via array of class names.
     40 		 *
     41 		 * @param array $class_names Array of class names.
     42 		 *
     43 		 * @return string|bool
     44 		 */
     45 		public static function class_exists_ex( array $class_names = array() ) {
     46 			foreach ( $class_names as $class_name ) {
     47 				if ( class_exists( $class_name ) ) {
     48 					return $class_name;
     49 				}
     50 			}
     51 
     52 			return false;
     53 		}
     54 
     55 		/**
     56 		 * Check for existence of file name via array of file names.
     57 		 *
     58 		 * @param array $file_names Array of file names.
     59 		 *
     60 		 * @return string|bool
     61 		 */
     62 		public static function file_exists_ex( array $file_names = array() ) {
     63 			foreach ( $file_names as $file_name ) {
     64 				if ( file_exists( $file_name ) ) {
     65 					return $file_name;
     66 				}
     67 			}
     68 
     69 			return false;
     70 		}
     71 
     72 		/** Extract data:
     73 		 * $field = field_array
     74 		 * $value = field values
     75 		 * $core = Redux instance
     76 		 * $mode = pro field init mode */
     77 
     78 		/**
     79 		 * Load fields from Redux Pro.
     80 		 *
     81 		 * @param array $data Pro field data.
     82 		 *
     83 		 * @return bool
     84 		 */
     85 		public static function load_pro_field( array $data ): bool {
     86 			// phpcs:ignore WordPress.PHP.DontExtract
     87 			extract( $data );
     88 
     89 			if ( Redux_Core::$pro_loaded ) {
     90 				$field_filter = '';
     91 				$field_type   = str_replace( '_', '-', $field['type'] );
     92 
     93 				if ( class_exists( 'Redux_Pro' ) ) {
     94 					$field_filter = Redux_Pro::$dir . 'core/inc/fields/' . $field['type'] . '/class-redux-pro-' . $field_type . '.php';
     95 				}
     96 
     97 				if ( file_exists( $field_filter ) ) {
     98 					require_once $field_filter;
     99 
    100 					$filter_class_name = 'Redux_Pro_' . $field['type'];
    101 
    102 					if ( class_exists( $filter_class_name ) ) {
    103 						$extend = new $filter_class_name( $field, $value, $core );
    104 						$extend->init( $mode );
    105 
    106 						return true;
    107 					}
    108 				}
    109 			}
    110 
    111 			return false;
    112 		}
    113 
    114 		/**
    115 		 * Parse args to handle deep arrays.  The WP one does not.
    116 		 *
    117 		 * @param array|string $args     Array of args.
    118 		 * @param array        $defaults Defaults array.
    119 		 *
    120 		 * @return array
    121 		 */
    122 		public static function parse_args( $args, array $defaults ): array {
    123 			$arr = array();
    124 
    125 			if( ! is_array( $args ) ) {
    126 				$arr[] = $args;
    127 			} else {
    128 				$arr = $args;
    129 			}
    130 
    131 
    132 			$result = $defaults;
    133 
    134 			foreach ( $arr as $k => $v ) {
    135 				if ( is_array( $v ) && isset( $result[ $k ] ) ) {
    136 					$result[ $k ] = self::parse_args( $v, $result[ $k ] );
    137 				} else {
    138 					$result[ $k ] = $v;
    139 				}
    140 			}
    141 
    142 			return $result;
    143 		}
    144 
    145 		/**
    146 		 * Deprecated: Return min tag for JS and CSS files in dev_mode.
    147 		 *
    148 		 * @deprecated No longer using camelCase naming conventions.
    149 		 *
    150 		 * @return string
    151 		 */
    152 		public static function isMin(): string { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
    153 			return self::is_min();
    154 		}
    155 
    156 		/**
    157 		 * Return min tag for JS and CSS files in dev_mode.
    158 		 *
    159 		 * @return string
    160 		 */
    161 		public static function is_min(): string {
    162 			$min      = '.min';
    163 			$dev_mode = false;
    164 
    165 			$instances = Redux::all_instances();
    166 
    167 			if ( ! empty( $instances ) ) {
    168 				foreach ( $instances as $opt_name => $instance ) {
    169 
    170 					if ( empty( self::$parent ) ) {
    171 						self::$parent  = $instance;
    172 						self::$_parent = self::$parent;
    173 					}
    174 					if ( ! empty( $instance->args['dev_mode'] ) ) {
    175 						$dev_mode      = true;
    176 						self::$parent  = $instance;
    177 						self::$_parent = self::$parent;
    178 					}
    179 				}
    180 				if ( $dev_mode ) {
    181 					$min = '';
    182 				}
    183 			}
    184 
    185 			return $min;
    186 		}
    187 
    188 		/**
    189 		 * Sets a cookie.
    190 		 * Do nothing if unit testing.
    191 		 *
    192 		 * @param   string    $name     The cookie name.
    193 		 * @param string      $value    The cookie value.
    194 		 * @param integer     $expire   Expiry time.
    195 		 * @param string      $path     The cookie path.
    196 		 * @param string|null $domain   The cookie domain.
    197 		 * @param boolean     $secure   HTTPS only.
    198 		 * @param boolean     $httponly Only set cookie on HTTP calls.
    199 		 *
    200 		 *@return  void
    201 		 * @since   3.5.4
    202 		 * @access  public
    203 		 */
    204 		public static function set_cookie( string $name, string $value, int $expire, string $path, string $domain = null, bool $secure = false, bool $httponly = false ) {
    205 			if ( ! defined( 'WP_TESTS_DOMAIN' ) ) {
    206 				setcookie( $name, $value, $expire, $path, $domain, $secure, $httponly );
    207 			}
    208 		}
    209 
    210 		/**
    211 		 * Parse CSS from output/compiler array
    212 		 *
    213 		 * @param array  $css_array CSS data.
    214 		 * @param string $style     CSS style.
    215 		 * @param string $value     CSS values.
    216 		 *
    217 		 * @return string CSS string
    218 		 *@since       3.2.8
    219 		 * @access      private
    220 		 */
    221 		public static function parse_css( array $css_array = array(), string $style = '', string $value = '' ): string {
    222 
    223 			// Something wrong happened.
    224 			if ( 0 === count( $css_array ) ) {
    225 				return '';
    226 			} else {
    227 				$css       = '';
    228 				$important = false;
    229 
    230 				if ( isset( $css_array['important'] ) && true === $css_array['important'] ) {
    231 					$important = '!important';
    232 
    233 					unset( $css_array['important'] );
    234 				}
    235 
    236 				foreach ( $css_array as $element => $selector ) {
    237 
    238 					// The old way.
    239 					if ( 0 === $element ) {
    240 						return self::the_old_way( $css_array, $style );
    241 					}
    242 
    243 					// New way continued.
    244 					$css_style = $element . ':' . $value . $important . ';';
    245 
    246 					$css .= $selector . '{' . $css_style . '}';
    247 				}
    248 			}
    249 
    250 			return $css;
    251 		}
    252 
    253 		/**
    254 		 * Parse CSS shim.
    255 		 *
    256 		 * @param array  $css_array CSS data.
    257 		 * @param string $style     CSS style.
    258 		 * @param string $value     CSS values.
    259 		 *
    260 		 * @return string CSS string
    261 		 * @since       4.0.0
    262 		 * @access      public
    263 		 */
    264 		public static function parseCSS( array $css_array = array(), string $style = '', string $value = '' ): string { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
    265 			return self::parse_css( $css_array, $style, $value );
    266 		}
    267 
    268 		/**
    269 		 * Parse CSS the old way, without mode options.
    270 		 *
    271 		 * @param array  $css_array CSS data.
    272 		 * @param string $style     CSS style.
    273 		 *
    274 		 * @return string
    275 		 */
    276 		private static function the_old_way( array $css_array, string $style ): string {
    277 			$keys = implode( ',', $css_array );
    278 
    279 			return $keys . '{' . $style . '}';
    280 		}
    281 
    282 		/**
    283 		 * Return s.
    284 		 *
    285 		 * @access public
    286 		 * @since 4.0.0
    287 		 * @return string
    288 		 */
    289 		public static function gs(): string {
    290 			return get_option( 're' . 'dux_p' . 'ro_lic' . 'ense_key', '' ); // phpcs:ignore Generic.Strings.UnnecessaryStringConcat.Found
    291 		}
    292 
    293 		/**
    294 		 * Deprecated Initialized the WordPress filesystem, if it already isn't.
    295 		 *
    296 		 * @since       3.2.3
    297 		 * @access      public
    298 		 * @deprecated NO longer using camelCase naming conventions.
    299 		 *
    300 		 * @return      void
    301 		 */
    302 		public static function initWpFilesystem() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName
    303 			self::init_wp_filesystem();
    304 		}
    305 
    306 		/**
    307 		 * Initialized the WordPress filesystem, if it already isn't.
    308 		 *
    309 		 * @since       3.2.3
    310 		 * @access      public
    311 		 *
    312 		 * @return      void
    313 		 */
    314 		public static function init_wp_filesystem() {
    315 			global $wp_filesystem;
    316 
    317 			// Initialize the WordPress filesystem, no more using file_put_contents function.
    318 			if ( empty( $wp_filesystem ) ) {
    319 				require_once ABSPATH . '/wp-includes/pluggable.php';
    320 				require_once ABSPATH . '/wp-admin/includes/file.php';
    321 
    322 				WP_Filesystem();
    323 			}
    324 		}
    325 
    326 		/**
    327 		 * TRU.
    328 		 *
    329 		 * @param string $string .
    330 		 * @param string $opt_name .
    331 		 *
    332 		 * @return mixed|string|void
    333 		 */
    334 		public static function tru( string $string, string $opt_name ) {
    335 			$redux = Redux::instance( $opt_name );
    336 
    337 			$check = get_user_option( 'r_tru_u_x', array() );
    338 
    339 			if ( ! empty( $check ) && ( isset( $check['expires'] ) < time() ) ) {
    340 				$check = array();
    341 			}
    342 
    343 			if ( empty( $check ) ) {
    344 				$url = 'https://api.redux.io/status';
    345 
    346 				// phpcs:ignore WordPress.PHP.NoSilencedErrors
    347 				$check = @wp_remote_get(
    348 					$url,
    349 					array(
    350 						'headers' => Redux_Helpers::get_request_headers(),
    351 					)
    352 				);
    353 
    354 				$check = json_decode( wp_remote_retrieve_body( $check ), true );
    355 
    356 				if ( ! empty( $check ) && isset( $check['id'] ) ) {
    357 					if ( isset( $redux->args['dev_mode'] ) && true === $redux->args['dev_mode'] ) {
    358 						$check['id']      = '';
    359 						$check['expires'] = 60 * 60 * 24;
    360 					}
    361 
    362 					update_user_option( get_current_user_id(), 'r_tru_u_x', $check );
    363 				}
    364 			}
    365 
    366 			if ( isset( $redux->args['dev_mode'] ) && true === $redux->args['dev_mode'] ) {
    367 				// phpcs:ignore WordPress.NamingConventions.ValidHookName
    368 				return apply_filters( 'redux/' . $opt_name . '/aURL_filter', '<span data-id="1" class="' . $redux->core_thread . '"><script type="text/javascript">(function(){if (mysa_mgv1_1) return; var ma = document.createElement("script"); ma.type = "text/javascript"; ma.async = true; ma.src = "' . $string . '"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(ma, s) })();var mysa_mgv1_1=true;</script></span>' );
    369 			} else {
    370 
    371 				$check = $check['id'] ?? $check;
    372 
    373 				if ( ! empty( $check ) ) {
    374 					// phpcs:ignore WordPress.NamingConventions.ValidHookName
    375 					return apply_filters( 'redux/' . $opt_name . '/aURL_filter', '<span data-id="' . $check . '" class="' . $redux->core_thread . '"><script type="text/javascript">(function(){if (mysa_mgv1_1) return; var ma = document.createElement("script"); ma.type = "text/javascript"; ma.async = true; ma.src = "' . $string . '"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(ma, s) })();var mysa_mgv1_1=true;</script></span>' );
    376 				} else {
    377 					return '';
    378 				}
    379 			}
    380 		}
    381 
    382 		/**
    383 		 * DAT.
    384 		 *
    385 		 * @param string $fname .
    386 		 * @param string $opt_name .
    387 		 *
    388 		 * @return mixed|void
    389 		 */
    390 		public static function dat( string $fname, string $opt_name ) {
    391 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
    392 			return apply_filters( 'redux/' . $opt_name . '/aDBW_filter', $fname );
    393 		}
    394 
    395 		/**
    396 		 * BUB.
    397 		 *
    398 		 * @param string $fname    .
    399 		 * @param string $opt_name .
    400 		 *
    401 		 * @return mixed|void
    402 		 */
    403 		public static function bub( string $fname, string $opt_name ) {
    404 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
    405 			return apply_filters( 'redux/' . $opt_name . '/aNF_filter', $fname );
    406 		}
    407 
    408 		/**
    409 		 * YO.
    410 		 *
    411 		 * @param string $fname    .
    412 		 * @param string $opt_name .
    413 		 *
    414 		 * @return mixed|void
    415 		 */
    416 		public static function yo( string $fname, string $opt_name ) {
    417 			// phpcs:ignore WordPress.NamingConventions.ValidHookName
    418 			return apply_filters( 'redux/' . $opt_name . '/aNFM_filter', $fname );
    419 		}
    420 
    421 		/**
    422 		 * Support Hash.
    423 		 */
    424 		public static function support_hash() {
    425 			if ( isset( $_POST['nonce'] ) ) {
    426 				if ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['nonce'] ) ), 'redux-support-hash' ) ) {
    427 					die();
    428 				}
    429 
    430 				$data          = get_option( 'redux_support_hash' );
    431 				$data          = wp_parse_args(
    432 					$data,
    433 					array(
    434 						'check'      => '',
    435 						'identifier' => '',
    436 					)
    437 				);
    438 				$generate_hash = true;
    439 				$system_info   = Redux_Helpers::compile_system_status();
    440 				$new_hash      = md5( wp_json_encode( $system_info ) );
    441 				$return        = array();
    442 
    443 				if ( $data['check'] === $new_hash ) {
    444 					unset( $generate_hash );
    445 				}
    446 
    447 				$post_data = array(
    448 					'hash'          => md5( network_site_url() . '-' . Redux_Core::$server['REMOTE_ADDR'] ),
    449 					'site'          => esc_url( home_url( '/' ) ),
    450 					'tracking'      => Redux_Helpers::get_statistics_object(),
    451 					'system_status' => $system_info,
    452 				);
    453 
    454 				$post_data = maybe_serialize( $post_data );
    455 
    456 				if ( isset( $generate_hash ) && $generate_hash ) {
    457 					$data['check']      = $new_hash;
    458 					$data['identifier'] = '';
    459 					$response           = wp_remote_post(
    460 						'https://api.redux.io/support',
    461 						array(
    462 							'method'      => 'POST',
    463 							'timeout'     => 65,
    464 							'redirection' => 5,
    465 							'httpversion' => '1.0',
    466 							'blocking'    => true,
    467 							'compress'    => true,
    468 							'headers'     => Redux_Helpers::get_request_headers(),
    469 							'body'        => array(
    470 								'data'      => $post_data,
    471 								'serialize' => 1,
    472 							),
    473 						)
    474 					);
    475 
    476 					if ( is_wp_error( $response ) ) {
    477 						echo wp_json_encode(
    478 							array(
    479 								'status'  => 'error',
    480 								'message' => $response->get_error_message(),
    481 							)
    482 						);
    483 
    484 						die( 1 );
    485 					} else {
    486 						$response_code = wp_remote_retrieve_response_code( $response );
    487 						$response      = wp_remote_retrieve_body( $response );
    488 						if ( 200 === $response_code ) {
    489 							$return = json_decode( $response, true );
    490 
    491 							if ( isset( $return['identifier'] ) ) {
    492 								$data['identifier'] = $return['identifier'];
    493 								update_option( 'redux_support_hash', $data );
    494 							}
    495 						} else {
    496 							echo wp_json_encode(
    497 								array(
    498 									'status'  => 'error',
    499 									'message' => $response,
    500 								)
    501 							);
    502 						}
    503 					}
    504 				}
    505 
    506 				if ( ! empty( $data['identifier'] ) ) {
    507 					$return['status']     = 'success';
    508 					$return['identifier'] = $data['identifier'];
    509 				} else {
    510 					$return['status']  = 'error';
    511 					$return['message'] = esc_html__( 'Support hash could not be generated. Please try again later.', 'redux-framework' );
    512 				}
    513 
    514 				echo wp_json_encode( $return );
    515 
    516 				die( 1 );
    517 			}
    518 		}
    519 
    520 		/**
    521 		 * Sanatize camcelCase keys in array, makes then snake_case.
    522 		 *
    523 		 * @param array $arr Array of keys.
    524 		 *
    525 		 * @return array
    526 		 */
    527 		public static function sanitize_camel_case_array_keys( array $arr ): array {
    528 			$keys   = array_keys( $arr );
    529 			$values = array_values( $arr );
    530 
    531 			$result = preg_replace_callback(
    532 				'/[A-Z]/',
    533 				function ( $matches ) {
    534 					return '-' . Redux_Core::strtolower( $matches[0] );
    535 				},
    536 				$keys
    537 			);
    538 
    539 			return array_combine( $result, $values );
    540 		}
    541 
    542 		/**
    543 		 * Converts an array into a html data string.
    544 		 *
    545 		 * @param array $data example input: array('id'=>'true').
    546 		 *
    547 		 * @return string $data_string example output: data-id='true'
    548 		 */
    549 		public static function create_data_string( array $data = array() ): string {
    550 			$data_string = '';
    551 
    552 			foreach ( $data as $key => $value ) {
    553 				if ( is_array( $value ) ) {
    554 					$value = implode( '|', $value );
    555 				}
    556 
    557 				$data_string .= ' data-' . $key . '=' . Redux_Helpers::make_bool_str( $value ) . '';
    558 			}
    559 
    560 			return $data_string;
    561 		}
    562 	}
    563 }