File: /var/www/html/triad-infosec/wp-content/themes/Avada/includes/lib/inc/class-fusion-dynamic-js.php
<?php
/**
* Dynamic-JS loader.
*
* @package Fusion-Library
* @since 1.0.0
*/
/**
* Handles enqueueing files dynamically.
*/
final class Fusion_Dynamic_JS {
/**
* An array of our scripts.
* Each script also lists its dependencies.
*
* @static
* @access protected
* @since 1.0.0
* @var array
*/
protected static $scripts = [];
/**
* Array of script to enqueue, in the correct order.
*
* @static
* @access protected
* @since 3.2
* @var array
*/
protected static $ordered_scripts = null;
/**
* An array of our wp_localize_script calls.
*
* @static
* @access protected
* @since 1.0.0
* @var array
*/
protected static $localize_scripts = [];
/**
* An array of external dependencies.
*
* @static
* @access protected
* @since 3.2
* @var array
*/
protected static $external_dependencies = [];
/**
* An instance of the Fusion_Dynamic_JS_File class.
* null if the class was not instantiated.
*
* @access public
* @since 1.0.0
* @var null|object Fusion_Dynamic_JS_File
*/
public $file = null;
/**
* Constructor.
*
* @access public
* @since 1.0.0
*/
public function __construct() {
add_action( 'wp_footer', [ $this, 'init' ] );
add_action( 'save_post', [ 'Fusion_Dynamic_JS_File', 'reset_cached_filenames' ] );
add_action( 'fusionredux/options/fusion_options/saved', [ 'Fusion_Dynamic_JS_File', 'delete_dynamic_js_transient' ] );
}
/**
* This is fired on 'wp'.
*
* @access public
* @since 1.0.0
* @return void
*/
public function init() {
// If JS compiler is disabled, or if WP_SCRIPT_DEBUG is set to true or if on builder frame after change load separate files.
$option = Fusion_Settings::get_option_name();
if ( ( defined( 'FUSION_DISABLE_COMPILERS' ) && FUSION_DISABLE_COMPILERS ) ||
'0' === fusion_library()->get_option( 'js_compiler' ) ||
( defined( 'AVADA_DEV_MODE' ) && AVADA_DEV_MODE && defined( 'FUSION_BUILDER_DEV_MODE' ) && FUSION_BUILDER_DEV_MODE && defined( 'FUSION_LIBRARY_DEV_MODE' ) && FUSION_LIBRARY_DEV_MODE ) ||
( defined( 'WP_SCRIPT_DEBUG' ) && WP_SCRIPT_DEBUG ) ||
post_password_required() ||
( isset( $_GET['builder_id'] ) && get_transient( 'fusion_app_emulated-' . sanitize_text_field( wp_unslash( $_GET['builder_id'] ) ) . '-' . $option ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
new Fusion_Dynamic_JS_Separate( $this );
return;
}
$this->file = new Fusion_Dynamic_JS_File( $this );
}
/**
* Registers a script.
*
* @static
* @access public
* @since 1.0.0
* @param string $handle The script's handle.
* @param string $url The URL to the script.
* @param string $path The path to the script.
* @param array $deps An array of dependencies.
* @param bool|string $ver The script version.
* @param bool $in_footer Whether the script should be in the footer or not.
*/
public static function register_script( $handle = '', $url = '', $path = '', $deps = [], $ver = false, $in_footer = false ) {
self::add_script( 'register', $handle, $url, $path, $deps, $ver, $in_footer );
}
/**
* Enqueues a script.
*
* @static
* @access public
* @since 1.0.0
* @param string $handle The script's handle.
* @param string $url The URL to the script.
* @param string $path The path to the script.
* @param array $deps An array of dependencies.
* @param bool|string $ver The script version.
* @param bool $in_footer Whether the script should be in the footer or not.
*/
public static function enqueue_script( $handle = '', $url = '', $path = '', $deps = [], $ver = false, $in_footer = false ) {
self::add_script( 'enqueue', $handle, $url, $path, $deps, $ver, $in_footer );
}
/**
* Deregisters a script.
*
* @static
* @access public
* @since 1.0.0
* @param string $handle The script's handle.
*/
public static function deregister_script( $handle ) {
foreach ( self::$scripts as $key => $script ) {
if ( $handle === $script['handle'] ) {
unset( self::$scripts[ $key ] );
}
}
}
/**
* Dequeues a script.
*
* @static
* @access public
* @since 1.0.0
* @param string $handle The script's handle.
*/
public static function dequeue_script( $handle ) {
foreach ( self::$scripts as $key => $script ) {
if ( $handle === $script['handle'] ) {
self::$scripts[ $key ]['action'] = 'register';
}
}
}
/**
* Add a script to the array.
*
* @static
* @access private
* @since 1.0.0
* @param string $action The action to take. Can be enqueue|register.
* @param string $handle The script's handle.
* @param string $url The URL to the script.
* @param string $path The path to the script.
* @param array $deps An array of dependencies.
* @param bool|string $ver The script version.
* @param bool $in_footer Whether the script should be in the footer or not.
*/
private static function add_script( $action = 'enqueue', $handle = '', $url = '', $path = '', $deps = [], $ver = false, $in_footer = false ) {
$is_builder = ( function_exists( 'fusion_is_preview_frame' ) && fusion_is_preview_frame() ) || ( function_exists( 'fusion_is_builder_frame' ) && fusion_is_builder_frame() );
// Early exit if $handle is not defined.
if ( ! $handle ) {
return;
}
// Check if our script already exists in the array.
foreach ( self::$scripts as $script ) {
if ( $handle === $script['handle'] ) {
if ( 'register' === $script['action'] ) {
// We're enqueueing the script.
if ( 'enqueue' === $action ) {
$url = ( '' === $url ) ? $script['url'] : $url;
$path = ( '' === $path ) ? $script['path'] : $path;
$deps = ( empty( $deps ) ) ? $script['deps'] : $deps;
$ver = ( false ) ? $script['ver'] : $ver;
$in_footer = ( false ) ? $script['in_footer'] : $in_footer;
} elseif ( 'register' === $action ) {
return;
}
} elseif ( 'enqueue' === $script['action'] ) {
// The script was previously enqueued.
if ( 'enqueue' === $action ) {
return;
} elseif ( 'register' === $action ) {
$action = 'enqueue';
}
}
}
}
// If animations are disabled in TO, we have to delete the dependency from the $deps array.
if ( 'off' === fusion_library()->get_option( 'status_css_animations' ) && ! $is_builder ) {
$key = array_search( 'fusion-animations', $deps, true );
if ( false !== $key ) {
unset( $deps[ $key ] );
}
}
self::$scripts[] = [
'action' => (string) $action,
'handle' => (string) $handle,
'url' => (string) $url,
'path' => (string) $path,
'deps' => (array) $deps,
'ver' => (string) $ver,
'in_footer' => true,
];
}
/**
* Localize scripts and add variables.
*
* @static
* @access public
* @since 1.0.0
* @param string $handle The script's handle.
* @param string $name The variable name.
* @param array $data An array of data.
*/
public static function localize_script( $handle = '', $name = '', $data = [] ) {
// Early exit if $handle or $name are not defined.
if ( ! $handle || ! $name ) {
return;
}
// Early exit if the script already exists in the array.
foreach ( self::$localize_scripts as $script ) {
if ( $handle === $script['handle'] && $name === $script['name'] ) {
return;
}
}
self::$localize_scripts[] = [
'handle' => (string) $handle,
'name' => (string) $name,
'data' => (array) $data,
];
}
/**
* Get the scripts.
*
* @static
* @access public
* @since 1.0.0
* @param bool $reorder Whether we want to reorder the scripts or not.
* @return array
*/
public function get_scripts( $reorder = true ) {
return self::$scripts;
}
/**
* Get the scripts.
*
* @access public
* @since 1.0.0
* @return array
*/
public function get_localizations() {
return self::$localize_scripts;
}
/**
* Check for grandparent dependency and merge.
*
* @access public
* @since 3.2
*/
public function merge_dependencies() {
if ( empty( self::$ordered_scripts ) ) {
return;
}
foreach ( self::$ordered_scripts as $key => $script ) {
// Script is dependencies.
if ( isset( $script['deps'] ) && ! empty( $script['deps'] ) ) {
foreach ( $script['deps'] as $dependency_key => $dependency ) {
$dependency_slug = $this->get_key_from_handle( $dependency );
if ( false === $dependency_slug ) {
continue;
}
$parent_script = self::$ordered_scripts[ $dependency_slug ];
if ( $parent_script && isset( $parent_script['deps'] ) && ! empty( $parent_script['deps'] ) ) {
self::$ordered_scripts[ $key ]['deps'] = array_merge( self::$ordered_scripts[ $key ]['deps'], $parent_script['deps'] );
}
}
}
}
}
/**
* Reorder scripts based on their dependencies.
*
* @access public
* @since 1.0.0
*/
public function reorder_scripts() {
// Build an ordered array of our dependent scripts.
$dependent_scripts = [];
self::$ordered_scripts = self::$scripts;
// Merge grandparent dependency in, so that full array is present on each script.
$this->merge_dependencies();
foreach ( self::$ordered_scripts as $key => $script ) {
if ( 'enqueue' !== $script['action'] ) {
continue;
}
// Check if the script has dependencies.
if ( isset( $script['deps'] ) && ! empty( $script['deps'] ) ) {
foreach ( $script['deps'] as $dependency_key => $dependency ) {
// Check if our dependencies exist and does not start with fusion.
// If not, assume they are external dependencies.
if ( false === $this->get_key_from_handle( $dependency ) && 0 !== strpos( $dependency, 'fusion' ) ) {
self::$external_dependencies[] = $dependency;
unset( self::$ordered_scripts['deps'][ $dependency_key ] );
continue;
}
// Make sure dependency is enqueued.
self::$ordered_scripts[ $this->get_key_from_handle( $dependency ) ]['action'] = 'enqueue';
// Inject item in array.
if ( in_array( $dependency, $dependent_scripts, true ) ) {
$dependent_key = array_search( $dependency, $dependent_scripts, true );
$dependent_scripts = $this->add_element( $dependent_scripts, $dependent_key, $dependency );
}
// Add the script to the end of the array if it doesn't exist.
if ( ! in_array( $script['handle'], $dependent_scripts, true ) ) {
$dependent_scripts[] = $script['handle'];
}
$dependent_scripts = array_unique( $dependent_scripts );
}
}
}
// Go through our dependent scripts and shuffle them in the self::$scripts array
// so that the final array is ordered for dependencies handling.
$dependent_scripts = array_reverse( $dependent_scripts );
foreach ( $dependent_scripts as $dependent ) {
$key = $this->get_key_from_handle( $dependent );
$script = self::$ordered_scripts[ $key ];
self::$ordered_scripts[] = $script;
unset( self::$ordered_scripts[ $key ] );
}
// Remove scripts that are not to be enqueued.
foreach ( self::$ordered_scripts as $key => $script ) {
if ( 'enqueue' !== $script['action'] ) {
unset( self::$ordered_scripts[ $key ] );
}
}
}
/**
* Get scripts to enqueue in proper order.
*
* @access public
* @since 3.2
* @return array
*/
public function get_ordered_scripts() {
// We have already worked it out, just return them.
if ( null !== self::$ordered_scripts ) {
return self::$ordered_scripts;
}
$this->reorder_scripts();
return self::$ordered_scripts;
}
/**
* Find the key of an item in the script array using the script's handle.
*
* @access private
* @since 1.0.0
* @param string $handle The script's handle.
* @return int The position of the script in self::$scripts.
*/
private function get_key_from_handle( $handle ) {
foreach ( self::$scripts as $key => $script ) {
if ( $handle === $script['handle'] ) {
return $key;
}
}
return false;
}
/**
* Add element in the middle of an array.
*
* @access public
* @access protected
* @since 1.0.0
* @param array $array The array.
* @param int $new_key The position of the new item in the array.
* @param mixed $new_value The value of the item we're adding to the array.
* @return array
*/
protected function add_element( $array, $new_key, $new_value ) {
$length = count( $array );
$new_array = [];
// If we're adding as the last element it's easy.
if ( $new_key >= $length ) {
$array[] = $new_value;
return $array;
}
// Loop the array and add the item where appropriate.
foreach ( $array as $key => $value ) {
if ( $key === $new_key ) {
$new_array[] = $new_value;
continue;
}
$new_array[] = $value;
}
return $new_array;
}
/**
* Get the array of external dependencies.
*
* @static
* @access public
* @since 1.0.0
* @return array
*/
public function get_external_dependencies() {
return self::$external_dependencies;
}
/**
* Determine if the server is HTTP/2 or not.
*
* @static
* @access public
* @since 1.0.0
* @return bool
*/
public static function is_http2() {
if ( isset( $_SERVER['SERVER_PROTOCOL'] ) ) {
$ver = 1;
$ver = ( isset( $_SERVER['SERVER_PROTOCOL'] ) ) ? str_replace( 'HTTP/', '', sanitize_text_field( wp_unslash( $_SERVER['SERVER_PROTOCOL'] ) ) ) : '1';
if ( 2 <= intval( $ver ) ) {
return true;
}
}
return false;
}
}