| 1 |
<?php |
| 2 |
if (!defined('ABSPATH')) |
| 3 |
exit; // Exit if accessed directly |
| 4 |
/** |
| 5 |
* The file that defines css/js loading class and concate css files |
| 6 |
* @package Themify |
| 7 |
*/ |
| 8 |
|
| 9 |
class Themify_Enqueue_Assets { |
| 10 |
|
| 11 |
public const THEMIFY_CSS_MODULES_URI=THEMIFY_URI . '/css/modules/'; |
| 12 |
|
| 13 |
private static $wc_shortcode_type = array(); |
| 14 |
private static $wc_data = array(); |
| 15 |
private static $css = array('mobile_concate' => array()); |
| 16 |
private static $done = array(); |
| 17 |
private static $localiztion = array(); |
| 18 |
private static $theme_css_support = array('mobile-menu'=>true,'rtl'=>true); |
| 19 |
private static $concateFile = null; |
| 20 |
private static $bufferLevel = 0; |
| 21 |
private static $googleFonts = array(); |
| 22 |
private static $guttenbergCss = array(); |
| 23 |
public static $preLoadMedia = array(); |
| 24 |
public static $disableGoogleFontsLoad = null; |
| 25 |
public static $isHeader = false; |
| 26 |
public static $isFooter = false; |
| 27 |
public static $mediaMaxWidth = 1200; |
| 28 |
public static $mobileMenuActive = 1100; |
| 29 |
|
| 30 |
public static $THEME_CSS_MODULES_URI = null; |
| 31 |
public static $THEME_CSS_MODULES_DIR = null; |
| 32 |
public static $THEME_WC_CSS_MODULES_DIR = null; |
| 33 |
public static $THEME_WC_CSS_MODULES_URI = null; |
| 34 |
public static $themeVersion = null; |
| 35 |
|
| 36 |
public static function init() { |
| 37 |
if (themify_is_themify_theme()) { |
| 38 |
self::$THEME_CSS_MODULES_DIR = THEME_DIR . '/styles/modules/'; |
| 39 |
self::$THEME_CSS_MODULES_URI = THEME_URI . '/styles/modules/'; |
| 40 |
|
| 41 |
self::$THEME_WC_CSS_MODULES_DIR = THEME_DIR . '/styles/wc/modules/'; |
| 42 |
self::$THEME_WC_CSS_MODULES_URI = THEME_URI . '/styles/wc/modules/'; |
| 43 |
|
| 44 |
self::$themeVersion = wp_get_theme(get_template())->display('Version'); |
| 45 |
self::$mobileMenuActive = (int) themify_get('setting-mobile_menu_trigger_point', self::$mobileMenuActive, true); |
| 46 |
} |
| 47 |
if (!is_admin()) { |
| 48 |
add_action('wp_body_open', array(__CLASS__, 'body_open'), 1); |
| 49 |
add_filter('wp_default_scripts', array(__CLASS__, 'remove_default_js')); |
| 50 |
add_action('wp', array(__CLASS__, 'lazy_init'), 1); |
| 51 |
} else { |
| 52 |
add_action('wp_loaded', array(__CLASS__, 'lazy_init'), 1); |
| 53 |
add_action('admin_init', array(__CLASS__, 'loadMainScript')); |
| 54 |
add_action('admin_footer', array(__CLASS__, 'js_localize'), 18); |
| 55 |
} |
| 56 |
add_filter('themify_loops_wrapper_class', array(__CLASS__, 'load_loop_css'), 100, 6); |
| 57 |
add_filter('kses_allowed_protocols', array(__CLASS__, 'allow_lazy_protocols'), 100, 1); |
| 58 |
add_filter('sgo_js_minify_exclude', array(__CLASS__,'exclude_main_js' ),1); |
| 59 |
add_filter('sgo_javascript_combine_exclude', array( __CLASS__, 'exclude_main_js' ),1 ); |
| 60 |
add_filter('autoptimize_filter_js_exclude', array(__CLASS__,'exclude_main_js' ),1); |
| 61 |
add_filter('autoptimize_filter_js_consider_minified',array(__CLASS__,'exclude_main_js' ),1); |
| 62 |
add_filter('rocket_delay_js_exclusions', array( __CLASS__, 'exclude_main_js' ),1 ); |
| 63 |
add_filter('rocket_exclude_js',array( __CLASS__, 'exclude_main_js' ),1 ); |
| 64 |
add_filter( 'js_do_concat', [ __CLASS__, 'Automattic_page_optimize_js_exclude' ], 10, 2 ); |
| 65 |
add_action('pre_get_search_form', array(__CLASS__, 'load_search_form_css'), 9); |
| 66 |
if (!is_admin() || themify_is_ajax()) { |
| 67 |
add_filter('post_playlist', array(__CLASS__, 'wp_media_playlist'), 100, 3); |
| 68 |
} |
| 69 |
add_filter('cron_schedules', array(__CLASS__, 'cron_schedules')); |
| 70 |
add_action('themify_cron_clear_css', array(__CLASS__, 'cron')); |
| 71 |
if (!wp_next_scheduled('themify_cron_clear_css')) { |
| 72 |
wp_schedule_event(time() + WEEK_IN_SECONDS * 4, 'four_week', 'themify_cron_clear_css'); |
| 73 |
} |
| 74 |
} |
| 75 |
|
| 76 |
public static function lazy_init() { |
| 77 |
if (!is_admin() && !themify_is_login_page()) { |
| 78 |
remove_action('wp_head', 'wp_resource_hints', 2); |
| 79 |
if (self::$themeVersion !== null) { |
| 80 |
add_action('wp_head', array(__CLASS__, 'header_meta'),-1111); |
| 81 |
add_action('wp_head', array(__CLASS__, 'header_html')); |
| 82 |
add_filter('wp_title', array(__CLASS__, 'wp_title'), 10, 2); |
| 83 |
remove_action('wp_head', 'locale_stylesheet'); //remove rtl loading |
| 84 |
} |
| 85 |
add_action( 'template_redirect', array( __CLASS__, 'start_buffer' ), 1 ); |
| 86 |
add_action('wp_enqueue_scripts', array(__CLASS__, 'before_enqueue'), 7); |
| 87 |
add_action('wp_enqueue_scripts', array(__CLASS__, 'after_enqueue'), 11); |
| 88 |
add_filter('style_loader_tag', array(__CLASS__, 'style_header_tag'), 10, 4); |
| 89 |
add_filter('render_block_data', array(__CLASS__, 'loadGuttenbergCss'), PHP_INT_MAX, 2); |
| 90 |
add_action('wp_head', array(__CLASS__, 'css_position'),100); |
| 91 |
add_action('wp_head', array(__CLASS__, 'wp_head'),-100); |
| 92 |
add_action('wp_footer', array(__CLASS__, 'before_footer'), -1111); |
| 93 |
add_action('wp_footer', array(__CLASS__, 'js_localize'), 18); |
| 94 |
add_action('wp_footer', array(__CLASS__, 'wp_footer'), 100); |
| 95 |
} |
| 96 |
elseif(is_admin()){ |
| 97 |
add_action('admin_head', array(__CLASS__, 'dev_mode_styles')); |
| 98 |
} |
| 99 |
if(!is_admin() || themify_is_ajax()){ |
| 100 |
add_filter('widget_display_callback', array(__CLASS__, 'widget_css'), 100, 3); |
| 101 |
add_action('wp_playlist_scripts',array(__CLASS__,'disable_playlist_template'),0,1); |
| 102 |
} |
| 103 |
add_filter('wp_audio_shortcode_library', array(__CLASS__, 'media_shortcode_library'), 100, 1); |
| 104 |
add_filter('wp_video_shortcode_library', array(__CLASS__, 'media_shortcode_library'), 10, 1); |
| 105 |
add_filter('wp_audio_shortcode', array(__CLASS__, 'audio_shortcode'), 100, 5); |
| 106 |
add_filter('wp_video_shortcode_override', array(__CLASS__, 'video_shortcode'), 100, 4); |
| 107 |
add_filter('embed_oembed_html',array(__CLASS__,'embed'),100,4); |
| 108 |
if (themify_is_lazyloading()) { |
| 109 |
themify_disable_other_lazy(); |
| 110 |
} |
| 111 |
|
| 112 |
$cdn=' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com *.lottiefiles.com'; |
| 113 |
themify_set_headers(array( |
| 114 |
'CONTENT-SECURITY-POLICY'=>array( |
| 115 |
'img-src'=>'data:', |
| 116 |
'style-src'=>"'unsafe-inline'".$cdn, |
| 117 |
'style-src-elem'=>"'unsafe-inline'".$cdn, |
| 118 |
'script-src'=>"'unsafe-inline' data:".$cdn, |
| 119 |
'script-src-elem'=>"'unsafe-inline' data:".$cdn, |
| 120 |
'connect-src'=>'https://themify.org *.lottiefiles.com', |
| 121 |
'default-src'=>'https://themify.org data:'.$cdn |
| 122 |
) |
| 123 |
)); |
| 124 |
} |
| 125 |
|
| 126 |
public static function start_buffer(){ |
| 127 |
self::createDir(); |
| 128 |
ob_start(array(__CLASS__, 'getBuffer')); |
| 129 |
self::$bufferLevel = ob_get_level(); |
| 130 |
} |
| 131 |
|
| 132 |
public static function createDir():bool { |
| 133 |
if (self::$concateFile === null) { |
| 134 |
self::$concateFile = self::getCurrentVersionFolder(); |
| 135 |
if (!is_dir(self::$concateFile)) { |
| 136 |
Themify_Filesystem::mkdir(self::$concateFile,true); |
| 137 |
if (!Themify_Filesystem::is_dir(self::$concateFile)) { |
| 138 |
clearstatcache(); |
| 139 |
Themify_Filesystem::mkdir(self::$concateFile,true); |
| 140 |
if (!Themify_Filesystem::is_dir(self::$concateFile)) { |
| 141 |
self::$concateFile = null; |
| 142 |
return false; |
| 143 |
} |
| 144 |
} |
| 145 |
} |
| 146 |
} |
| 147 |
return true; |
| 148 |
} |
| 149 |
|
| 150 |
public static function remove_default_js($scripts) { |
| 151 |
if (!themify_builder_check('setting-jquery-migrate', 'performance-jquery_migrate') && !themify_is_login_page()) { |
| 152 |
$script = $scripts->registered['jquery']; |
| 153 |
if (!empty($script->deps)) { // Check whether the script has any dependencies |
| 154 |
$key = 'jquery-migrate'; |
| 155 |
$index = isset($script->deps[1]) && $script->deps[1] === $key ? 1 : array_search($key, $script->deps, true); |
| 156 |
if ($index !== false) { |
| 157 |
unset($script->deps[$index]); |
| 158 |
} |
| 159 |
} |
| 160 |
} |
| 161 |
return $scripts; |
| 162 |
} |
| 163 |
|
| 164 |
public static function before_enqueue() { |
| 165 |
self::add_css('tf_base', THEMIFY_URI . '/css/base.min.css', null, THEMIFY_VERSION); |
| 166 |
if (self::$themeVersion !== null) { |
| 167 |
self::add_css('themify_common', THEMIFY_URI . '/css/themify-common.css', null, THEMIFY_VERSION); |
| 168 |
if(is_admin_bar_showing()){ |
| 169 |
self::add_css('themify_common_logged', THEMIFY_URI . '/css/themify-common-logged.css', null, THEMIFY_VERSION,'',true); |
| 170 |
} |
| 171 |
} |
| 172 |
self::loadMainScript(); |
| 173 |
} |
| 174 |
|
| 175 |
public static function after_enqueue() { |
| 176 |
global $wp_styles, $wp_version; |
| 177 |
$css = array('wp-block-library'); |
| 178 |
$is_theme = self::$themeVersion !== null; |
| 179 |
if ($is_theme === true && themify_is_woocommerce_active()) { |
| 180 |
add_filter('woocommerce_shortcode_products_query', array(__CLASS__, 'wc_shortcode_product'), 10, 3); |
| 181 |
add_action('woocommerce_before_single_product_summary', array(__CLASS__, 'wc_shortcode_product_page')); |
| 182 |
add_action('woocommerce_before_checkout_form_cart_notices', array(__CLASS__, 'wc_shortcode_checkout')); |
| 183 |
add_action('woocommerce_account_content', array(__CLASS__, 'wc_shortcode_account')); |
| 184 |
$wc_ver = WC()->version; |
| 185 |
self::$localiztion['wc_version'] = $wc_ver; |
| 186 |
wp_enqueue_script('wc-cart-fragments');//default load has been removed from wc 7.8.0 |
| 187 |
if (themify_is_shop() || is_product() || (!is_checkout() && !is_account_page() && !is_checkout_pay_page() && !is_edit_account_page() && !is_order_received_page() && !is_add_payment_method_page())) { |
| 188 |
wp_enqueue_script('wc-add-to-cart-variation'); //load tmpl files |
| 189 |
wp_enqueue_script('wc-single-product'); |
| 190 |
wp_enqueue_script(themify_wc_get_script_handle('wc-jquery-blockui')); |
| 191 |
WC_Frontend_Scripts::localize_printed_scripts(); |
| 192 |
global $wp_scripts; |
| 193 |
|
| 194 |
$js = array(themify_wc_get_script_handle('js-cookie'), 'wc-add-to-cart', 'wc-add-to-cart-variation', 'wc-cart-fragments', 'woocommerce', 'wc_additional_variation_images_script', 'wc-single-product'); |
| 195 |
$arr = array(); |
| 196 |
$disableOptimize = themify_check('setting-optimize-wc', true); |
| 197 |
$isDefered=themify_check('setting-jquery', true)?true:($disableOptimize?false:!themify_check('setting-defer-wc', true)); |
| 198 |
foreach ($js as $v) { |
| 199 |
if (isset($wp_scripts->registered[$v]) && wp_script_is($v)) { |
| 200 |
if ($isDefered === true && !empty($wp_scripts->registered[$v]->extra['data'])) { |
| 201 |
self::$wc_data[] = $wp_scripts->registered[$v]->extra['data']; |
| 202 |
$wp_scripts->registered[$v]->extra['data']=''; |
| 203 |
} |
| 204 |
if ($v === 'wc-single-product' && is_product()) { |
| 205 |
continue; |
| 206 |
} |
| 207 |
if ($disableOptimize === false) { |
| 208 |
$wp_scripts->done[] = $v; |
| 209 |
} |
| 210 |
$arr[$v] = $wp_scripts->registered[$v]->src; |
| 211 |
if ($wc_ver !== $wp_scripts->registered[$v]->ver) { |
| 212 |
$arr[$v] .= '?ver=' . $wp_scripts->registered[$v]->ver; |
| 213 |
} |
| 214 |
} |
| 215 |
} |
| 216 |
self::$localiztion['wc_js'] = $arr; |
| 217 |
if ($disableOptimize === true) { |
| 218 |
self::$localiztion['wc_js_normal'] = true; |
| 219 |
} |
| 220 |
|
| 221 |
// Localize photoswipe css |
| 222 |
if (!empty($wp_styles->registered['photoswipe']->src)) { |
| 223 |
wp_dequeue_style('photoswipe'); |
| 224 |
wp_dequeue_style('photoswipe-default-skin'); |
| 225 |
self::$localiztion['photoswipe'] = array('main' => $wp_styles->registered['photoswipe']->src, 'skin' => $wp_styles->registered['photoswipe-default-skin']->src); |
| 226 |
} |
| 227 |
$js = $arr = null; |
| 228 |
} |
| 229 |
$wc_block_prefix = 'wc-block'; |
| 230 |
if (intval($wc_ver[0]) >= 6) { |
| 231 |
$wc_block_prefix .= 's'; |
| 232 |
} |
| 233 |
$css[] = $wc_block_prefix . '-vendors-style'; |
| 234 |
$css[] = $wc_block_prefix . '-style'; |
| 235 |
$css[] = 'wp-block-library-theme'; |
| 236 |
$css[] = 'woocommerce-layout'; |
| 237 |
$css[] = 'woocommerce-smallscreen'; |
| 238 |
$css[] = 'woocommerce-general'; |
| 239 |
$css[] = 'select2'; |
| 240 |
$css[]='woocommerce-blocktheme'; |
| 241 |
$css[] = 'woocommerce_prettyPhoto_css'; |
| 242 |
} |
| 243 |
$css = apply_filters('themify_deq_css', $css); |
| 244 |
foreach ($css as $v) { |
| 245 |
if (isset($wp_styles->registered[$v]) && wp_style_is($v)) { |
| 246 |
$src = $wp_styles->registered[$v]->src; |
| 247 |
if ($v === 'wp-block-library' || $v === 'wp-block-library-theme' || $v === $wc_block_prefix . '-style' || $v === $wc_block_prefix . '-vendors-style') { |
| 248 |
if (empty($wp_styles->registered[$v]->deps) || ($v === $wc_block_prefix . '-style' && count($wp_styles->registered[$v]->deps) === 1 && $wp_styles->registered[$v]->deps[0] === $wc_block_prefix . '-vendors-style')) { |
| 249 |
$wp_styles->done[] = $v; |
| 250 |
self::$guttenbergCss[$v] = $src; |
| 251 |
} |
| 252 |
continue; |
| 253 |
} |
| 254 |
$wp_styles->done[] = $v; |
| 255 |
$ver = $wp_styles->registered[$v]->ver; |
| 256 |
if ($src[0] === '/' && $src[1] === '/') { |
| 257 |
$src = (is_ssl() ? 'https:' : 'http:') . $src; |
| 258 |
} |
| 259 |
if (strpos($src, 'http') === false) { |
| 260 |
$src = home_url($src); |
| 261 |
} |
| 262 |
if (empty($ver)) { |
| 263 |
$ver = $wp_version; |
| 264 |
} |
| 265 |
wp_dequeue_style($v); |
| 266 |
self::add_css($v, $src, $wp_styles->registered[$v]->deps, $ver, $wp_styles->registered[$v]->args); |
| 267 |
} |
| 268 |
} |
| 269 |
$css = null; |
| 270 |
if ($is_theme === true) { |
| 271 |
if (isset(self::$theme_css_support['mobile-menu'])) { |
| 272 |
self::addMobileMenuCss('mobile-menu', THEME_URI . '/mobile-menu.css'); |
| 273 |
} |
| 274 |
if (function_exists('themify_theme_enqueue_header')) { |
| 275 |
themify_theme_enqueue_header(); |
| 276 |
} |
| 277 |
/* Disabel Guttenberg Global Style WP 5.9 */ |
| 278 |
// remove_action( 'wp_body_open', 'wp_global_styles_render_svg_filters' ); |
| 279 |
// wp_dequeue_style('global-styles'); |
| 280 |
} |
| 281 |
} |
| 282 |
|
| 283 |
public static function add_css(string $handle, string $src,?array $deps,?string $ver,?string $media = '',bool $in_footer = false) { |
| 284 |
if (!isset(self::$css[$handle], self::$done[$src])) { |
| 285 |
self::$done[$src] = true; |
| 286 |
if (!$media) { |
| 287 |
$media = 'all'; |
| 288 |
} |
| 289 |
if (self::$concateFile === null || is_admin()) { |
| 290 |
if (strpos($handle, 'http') !== false) { |
| 291 |
$handle = crc32($handle); |
| 292 |
} |
| 293 |
self::$css[$handle] = array('s' => $src, 'v' => $ver); |
| 294 |
if ($media !== 'all') {//need to get css files in ajax call(e.g builder live preview) |
| 295 |
self::$css[$handle]['m'] = $media; |
| 296 |
} |
| 297 |
wp_enqueue_style($handle, $src, $deps, $ver, $media); |
| 298 |
return; |
| 299 |
} |
| 300 |
if ($in_footer === true || self::$isFooter === true) { |
| 301 |
if (!isset(self::$css['in_footer'])) { |
| 302 |
self::$css['in_footer'] = array(); |
| 303 |
} |
| 304 |
self::$css['in_footer'][$handle] = array('s' => $src, 'v' => $ver); |
| 305 |
if ($media !== 'all') { |
| 306 |
self::$css['in_footer'][$handle]['m'] = $media; |
| 307 |
} |
| 308 |
} else { |
| 309 |
self::$css[$handle] = array('s' => $src, 'v' => $ver); |
| 310 |
if ($media !== 'all') { |
| 311 |
self::$css[$handle]['m'] = $media; |
| 312 |
} |
| 313 |
} |
| 314 |
} |
| 315 |
} |
| 316 |
|
| 317 |
/** |
| 318 |
* Deregister an stylesheet |
| 319 |
* |
| 320 |
* @param string $handle |
| 321 |
* @param string $both |
| 322 |
*/ |
| 323 |
public static function remove_css(string $handle, string $type = 'both') { |
| 324 |
if ($handle !== 'in_footer' && self::$css !== null) { |
| 325 |
if ($type === 'both' || $type === 'main') { |
| 326 |
unset(self::$css[$handle], self::$css['in_footer'][$handle]); |
| 327 |
} |
| 328 |
if ($type === 'both' || $type === 'mobile') { |
| 329 |
unset(self::$css['mobile_concate'][$handle]); |
| 330 |
} |
| 331 |
} |
| 332 |
} |
| 333 |
|
| 334 |
public static function header_meta() { |
| 335 |
?> |
| 336 |
<meta charset="<?php echo get_bloginfo('charset') ?>"> |
| 337 |
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1"> |
| 338 |
<?php |
| 339 |
} |
| 340 |
|
| 341 |
public static function dev_mode_styles(){ |
| 342 |
if ( ( themify_is_dev_mode() || Themify_Maintenance_Mode::is_enabled() ) && is_admin_bar_showing() ){ |
| 343 |
if(is_admin()): |
| 344 |
?> |
| 345 |
<style> |
| 346 |
<?php endif;?> |
| 347 |
/* admin bar dev mode */ |
| 348 |
#wpadminbar #wp-toolbar .tf_admin_bar_alert .ab-item{ |
| 349 |
padding-left:24px |
| 350 |
} |
| 351 |
.tf_admin_bar_alert>.ab-item:after{ |
| 352 |
content:''; |
| 353 |
width:12px; |
| 354 |
height:12px; |
| 355 |
border-radius:100%; |
| 356 |
background:#ff1212; |
| 357 |
position:absolute; |
| 358 |
top:50%; |
| 359 |
left:6px; |
| 360 |
transform:translateY(-50%); |
| 361 |
animation:tf_bg 2s infinite alternate |
| 362 |
} |
| 363 |
#wpadminbar .tf_admin_bar_tooltip{ |
| 364 |
width:300px; |
| 365 |
color:#ccc; |
| 366 |
background-color:rgba(51,51,51,.9); |
| 367 |
padding:10px 14px; |
| 368 |
font-size:12px; |
| 369 |
line-height:1.2em; |
| 370 |
border-radius:8px; |
| 371 |
margin-top:50px; |
| 372 |
position:absolute; |
| 373 |
display:none; |
| 374 |
top:100%; |
| 375 |
left:0; |
| 376 |
box-sizing:border-box; |
| 377 |
z-index:999999 |
| 378 |
} |
| 379 |
#wpadminbar .tf_admin_bar_alert>.ab-item:hover .tf_admin_bar_tooltip{display:block} |
| 380 |
@keyframes tf_bg{0%{background:#ffb800}100%{background:#ff1212}} |
| 381 |
<?php if(is_admin()):?> |
| 382 |
</style> |
| 383 |
<?php |
| 384 |
endif; |
| 385 |
} |
| 386 |
} |
| 387 |
|
| 388 |
public static function wp_head() { |
| 389 |
if (themify_is_lazyloading() === true) { |
| 390 |
$blur = (int) themify_get('setting-lazy-blur', 25, true); |
| 391 |
?> |
| 392 |
<style id="tf_lazy_style" data-no-optimize="1"> |
| 393 |
.tf_svg_lazy{ |
| 394 |
content-visibility:auto; |
| 395 |
background-size:100% 25%!important; |
| 396 |
background-repeat:no-repeat!important; |
| 397 |
background-position:0 0, 0 33.4%,0 66.6%,0 100%!important; |
| 398 |
transition:filter .3s linear!important; |
| 399 |
<?php if ($blur > 0): ?>filter:blur(<?php echo $blur ?>px)!important;<?php endif; ?> |
| 400 |
transform:translateZ(0) |
| 401 |
} |
| 402 |
.tf_svg_lazy_loaded{ |
| 403 |
filter:blur(0)!important |
| 404 |
} |
| 405 |
[data-lazy]:is(.module,.module_row:not(.tb_first)),.module[data-lazy] .ui,.module_row[data-lazy]:not(.tb_first):is(>.row_inner,.module_column[data-lazy],.module_subrow[data-lazy]){ |
| 406 |
background-image:none!important |
| 407 |
} |
| 408 |
</style> |
| 409 |
<noscript> |
| 410 |
<style> |
| 411 |
.tf_svg_lazy{ |
| 412 |
display:none!important |
| 413 |
} |
| 414 |
</style> |
| 415 |
</noscript> |
| 416 |
<?php |
| 417 |
} |
| 418 |
?> |
| 419 |
<style id="tf_lazy_common" data-no-optimize="1"> |
| 420 |
<?php if (self::$themeVersion !== null): ?> |
| 421 |
img{ |
| 422 |
max-width:100%; |
| 423 |
height:auto |
| 424 |
} |
| 425 |
<?php endif; ?> |
| 426 |
<?php self::dev_mode_styles()?> |
| 427 |
:where(.tf_in_flx,.tf_flx){display:inline-flex;flex-wrap:wrap;place-items:center} |
| 428 |
.tf_fa,:is(em,i) tf-lottie{display:inline-block;vertical-align:middle}:is(em,i) tf-lottie{width:1.5em;height:1.5em}.tf_fa{width:1em;height:1em;stroke-width:0;stroke:currentColor;overflow:visible;fill:currentColor;pointer-events:none;text-rendering:optimizeSpeed;buffered-rendering:static}#tf_svg symbol{overflow:visible}:where(.tf_lazy){position:relative;visibility:visible;display:block;opacity:.3}.wow .tf_lazy:not(.tf_swiper-slide){visibility:hidden;opacity:1}div.tf_audio_lazy audio{visibility:hidden;height:0;display:inline}.mejs-container{visibility:visible}.tf_iframe_lazy{transition:opacity .3s ease-in-out;min-height:10px}:where(.tf_flx),.tf_swiper-wrapper{display:flex}.tf_swiper-slide{flex-shrink:0;opacity:0;width:100%;height:100%}.tf_swiper-wrapper>br,.tf_lazy.tf_swiper-wrapper .tf_lazy:after,.tf_lazy.tf_swiper-wrapper .tf_lazy:before{display:none}.tf_lazy:after,.tf_lazy:before{content:'';display:inline-block;position:absolute;width:10px!important;height:10px!important;margin:0 3px;top:50%!important;inset-inline:auto 50%!important;border-radius:100%;background-color:currentColor;visibility:visible;animation:tf-hrz-loader infinite .75s cubic-bezier(.2,.68,.18,1.08)}.tf_lazy:after{width:6px!important;height:6px!important;inset-inline:50% auto!important;margin-top:3px;animation-delay:-.4s}@keyframes tf-hrz-loader{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(.1);opacity:.6}}.tf_lazy_lightbox{position:fixed;background:rgba(11,11,11,.8);color:#ccc;top:0;left:0;display:flex;align-items:center;justify-content:center;z-index:999}.tf_lazy_lightbox .tf_lazy:after,.tf_lazy_lightbox .tf_lazy:before{background:#fff}.tf_vd_lazy,tf-lottie{display:flex;flex-wrap:wrap}tf-lottie{aspect-ratio:1.777}.tf_w.tf_vd_lazy video{width:100%;height:auto;position:static;object-fit:cover} |
| 429 |
</style> |
| 430 |
<?php if (self::$themeVersion !== null){ |
| 431 |
themify_favicon_action(); |
| 432 |
} |
| 433 |
self::$isHeader = true; |
| 434 |
} |
| 435 |
|
| 436 |
/** |
| 437 |
* Outputs Header Code |
| 438 |
* |
| 439 |
* Hooked to "wp_head"[10], load after other scripts in the header |
| 440 |
*/ |
| 441 |
public static function header_html(){ |
| 442 |
echo themify_get('setting-header_html', '', true); |
| 443 |
} |
| 444 |
|
| 445 |
public static function css_position(){ |
| 446 |
echo '<!--tf_css_position-->';//bug in chrome https://bugs.chromium.org/p/chromium/issues/detail?id=332189x |
| 447 |
} |
| 448 |
|
| 449 |
public static function style_header_tag(string $tag, string $handle,string $href,string $media):string { |
| 450 |
$src = strtok($href, '?'); |
| 451 |
unset(self::$preLoadMedia[$src]); |
| 452 |
$preload = '<link rel="preload" href="' . $href . '" as="style"'; |
| 453 |
if ($media !== 'all' && $media) { |
| 454 |
$preload .= ' media="' . $media . '"'; |
| 455 |
} |
| 456 |
$preload .= '>' . $tag; |
| 457 |
return $preload; |
| 458 |
} |
| 459 |
|
| 460 |
/** |
| 461 |
* Set a default title for the front page |
| 462 |
* |
| 463 |
* @return string |
| 464 |
* @since 1.7.6 |
| 465 |
*/ |
| 466 |
public static function wp_title(string $title,string $sep):string { |
| 467 |
if (empty($title) && ( is_home() || is_front_page() )) { |
| 468 |
global $aioseop_options; |
| 469 |
return !empty($aioseop_options) && class_exists('All_in_One_SEO_Pack',false) ? $aioseop_options['aiosp_home_title'] : get_bloginfo('name'); |
| 470 |
} |
| 471 |
return str_replace($sep, '', $title); |
| 472 |
} |
| 473 |
|
| 474 |
public static function wc_shortcode_product($query_args, $attr, $type) { |
| 475 |
if ($type === 'product') { |
| 476 |
self::$wc_shortcode_type[$type] = true; |
| 477 |
} |
| 478 |
return $query_args; |
| 479 |
} |
| 480 |
|
| 481 |
public static function wc_shortcode_product_page() { |
| 482 |
self::$wc_shortcode_type['product'] = true; |
| 483 |
} |
| 484 |
|
| 485 |
public static function wc_shortcode_checkout() { |
| 486 |
self::$wc_shortcode_type['checkout'] = true; |
| 487 |
} |
| 488 |
|
| 489 |
public static function wc_shortcode_account($msg = '') { |
| 490 |
self::$wc_shortcode_type['account'] = true; |
| 491 |
return $msg; |
| 492 |
} |
| 493 |
|
| 494 |
public static function js_localize() { |
| 495 |
global $wp_scripts; |
| 496 |
if ( ! isset( $wp_scripts->registered['themify-main-script'] ) ) { |
| 497 |
/* either something has gone horribly wrong, or the script is intentionally removed; bail. */ |
| 498 |
return; |
| 499 |
} |
| 500 |
|
| 501 |
self::localize_script('themify-main-script', 'themify_vars', apply_filters('themify_main_script_vars', self::$localiztion)); |
| 502 |
if(!is_admin()){ |
| 503 |
global $wp_scripts; |
| 504 |
$inline_js=$wp_scripts->registered['themify-main-script']->extra['data']; |
| 505 |
if(!empty(self::$wc_data)){ |
| 506 |
$inline_js.=implode('',self::$wc_data); |
| 507 |
} |
| 508 |
?> |
| 509 |
<!--googleoff:all--> |
| 510 |
<!--noindex--> |
| 511 |
<!--noptimize--> |
| 512 |
<script id="tf_vars" data-no-optimize="1" data-noptimize="1" data-no-minify="1" data-cfasync="false" defer="defer" src="data:text/javascript;base64,<?php echo base64_encode($inline_js)?>"></script> |
| 513 |
<!--/noptimize--> |
| 514 |
<!--/noindex--> |
| 515 |
<!--googleon:all--> |
| 516 |
<?php |
| 517 |
$wp_scripts->registered['themify-main-script']->extra['data'] = $inline_js=self::$wc_data=null; |
| 518 |
do_action('tf_load_styles'); |
| 519 |
self::$isFooter = true; |
| 520 |
} |
| 521 |
else { |
| 522 |
self::loadIcons(); |
| 523 |
} |
| 524 |
self::$localiztion = array(); |
| 525 |
} |
| 526 |
|
| 527 |
/** |
| 528 |
* Copy of WP_Scripts::localize() except it uses JSON_UNESCAPED_SLASHES |
| 529 |
* |
| 530 |
* @documented in wp-includes/class.wp.scripts.php |
| 531 |
*/ |
| 532 |
public static function localize_script(string $handle,string $object_name,array $l10n) { |
| 533 |
global $wp_scripts; |
| 534 |
|
| 535 |
if ('jquery' === $handle) { |
| 536 |
$handle = 'jquery-core'; |
| 537 |
} |
| 538 |
|
| 539 |
if (is_array($l10n) && isset($l10n['l10n_print_after'])) { // back compat, preserve the code in 'l10n_print_after' if present. |
| 540 |
$after = $l10n['l10n_print_after']; |
| 541 |
unset($l10n['l10n_print_after']); |
| 542 |
} |
| 543 |
|
| 544 |
foreach ((array) $l10n as $key => $value) { |
| 545 |
if (!is_scalar($value)) { |
| 546 |
continue; |
| 547 |
} |
| 548 |
|
| 549 |
$l10n[$key] = html_entity_decode((string) $value, ENT_QUOTES, 'UTF-8'); |
| 550 |
} |
| 551 |
|
| 552 |
$script = "var $object_name = " . wp_json_encode($l10n, JSON_UNESCAPED_SLASHES) . ';'; |
| 553 |
|
| 554 |
if (!empty($after)) { |
| 555 |
$script .= "\n$after;"; |
| 556 |
} |
| 557 |
|
| 558 |
$data = $wp_scripts->get_data($handle, 'data'); |
| 559 |
|
| 560 |
if (!empty($data)) { |
| 561 |
$script = "$data\n$script"; |
| 562 |
} |
| 563 |
|
| 564 |
return $wp_scripts->add_data($handle, 'data', $script); |
| 565 |
} |
| 566 |
|
| 567 |
public static function before_footer() { |
| 568 |
if (themify_is_woocommerce_active()) { |
| 569 |
remove_action('wp_footer', 'wc_no_js'); |
| 570 |
} |
| 571 |
if (self::$themeVersion !== null && !is_admin()) { |
| 572 |
self::add_css('theme-style', THEME_URI . '/style.css', null, self::$themeVersion); |
| 573 |
if (self::$mediaMaxWidth !== false) { |
| 574 |
self::add_css('themify-media-queries', THEME_URI . '/media-queries.css', null, self::$themeVersion, '(max-width:' . self::$mediaMaxWidth . 'px)'); |
| 575 |
} |
| 576 |
if (isset(self::$theme_css_support['wc'])) { |
| 577 |
self::add_css('tf_theme_wc', THEME_URI . '/styles/wc/woocommerce.css', null, self::$themeVersion); |
| 578 |
if (isset(self::$theme_css_support['wc_single_product']) && (isset(self::$wc_shortcode_type['product']) || is_product())) { |
| 579 |
self::loadThemeWCStyleModule('single/product'); |
| 580 |
} |
| 581 |
if ((isset(self::$theme_css_support['wc_account']) || isset(self::$theme_css_support['wc_register_form'])) && (isset(self::$wc_shortcode_type['account']) || is_account_page())) { |
| 582 |
if (is_user_logged_in()) { |
| 583 |
if(isset(self::$theme_css_support['wc_account'])){ |
| 584 |
self::loadThemeWCStyleModule('pages/account'); |
| 585 |
} |
| 586 |
} elseif(isset(self::$theme_css_support['wc_register_form'])) { |
| 587 |
self::loadThemeWCStyleModule('pages/register-form'); |
| 588 |
} |
| 589 |
} |
| 590 |
if (isset(self::$theme_css_support['wc_checkout']) && (isset(self::$wc_shortcode_type['checkout']) || is_checkout())) { |
| 591 |
self::loadThemeWCStyleModule('pages/checkout'); |
| 592 |
} |
| 593 |
if (isset(self::$theme_css_support['wc_cart']) && is_cart()) { |
| 594 |
self::loadThemeWCStyleModule('pages/cart'); |
| 595 |
} |
| 596 |
} |
| 597 |
self::$wc_shortcode_type = null; |
| 598 |
if (function_exists('themify_theme_enqueue_footer')) { |
| 599 |
themify_theme_enqueue_footer(); |
| 600 |
} |
| 601 |
if (is_rtl() && isset(self::$theme_css_support['rtl'])) { |
| 602 |
self::add_css('theme-style-rtl', THEME_URI . '/rtl.css', null, self::$themeVersion); |
| 603 |
} |
| 604 |
themify_enqueue_framework_assets(); |
| 605 |
// Themify child base styling |
| 606 |
if (is_child_theme()) { |
| 607 |
$modified = filemtime(get_stylesheet_directory() . '/style.css'); |
| 608 |
if ($modified === false) { |
| 609 |
$modified = ''; |
| 610 |
} |
| 611 |
self::add_css('theme-style-child', get_stylesheet_uri(), null, self::$themeVersion . $modified); |
| 612 |
} |
| 613 |
// User stylesheet |
| 614 |
$custom_css = get_template_directory() . '/custom_style.css'; |
| 615 |
if (is_file($custom_css)) { |
| 616 |
$modified = filemtime($custom_css); |
| 617 |
if ($modified === false) { |
| 618 |
$modified = ''; |
| 619 |
} |
| 620 |
self::add_css('custom-style', THEME_URI . '/custom_style.css', null, THEMIFY_VERSION . $modified); |
| 621 |
} |
| 622 |
unset($custom_css); |
| 623 |
if (is_admin_bar_showing() && is_file(self::$THEME_CSS_MODULES_DIR . 'admin-bar.css')) { |
| 624 |
self::loadThemeStyleModule('admin-bar', false, true); |
| 625 |
} |
| 626 |
if (class_exists('Themify_Builder',false) && Themify_Builder_Model::is_front_builder_activate() === true && is_file(self::$THEME_CSS_MODULES_DIR . 'builder-active.css')) { |
| 627 |
self::loadThemeStyleModule('builder-active', false, true); |
| 628 |
} |
| 629 |
} |
| 630 |
} |
| 631 |
|
| 632 |
public static function wp_footer() { |
| 633 |
if (!empty(self::$css['in_footer'])) { |
| 634 |
foreach (self::$css['in_footer'] as $k => $v) { |
| 635 |
$m = isset($v['m']) ? ' media="' . esc_attr( $v['m'] ) . '"' : ''; |
| 636 |
$href = esc_url( $v['s'] ); |
| 637 |
if (!empty($v['v'])) { |
| 638 |
$href .= strpos($href, '?') === false ? '?' : '&'; |
| 639 |
$href .= 'ver=' . rawurlencode( $v['v'] ); |
| 640 |
} |
| 641 |
?> |
| 642 |
<link rel="preload" href="<?php echo $href; ?>" as="style"<?php echo $m; ?>><link id="<?php echo esc_attr( $k ); ?>-css" rel="stylesheet" href="<?php echo $href; ?>"<?php echo $m; ?>> |
| 643 |
<?php |
| 644 |
} |
| 645 |
} |
| 646 |
if (self::$themeVersion !== null) { |
| 647 |
echo "\n\n", themify_get('setting-footer_html', '', true); |
| 648 |
} |
| 649 |
add_action('shutdown',array(__CLASS__,'buffer_end'),PHP_INT_MAX); |
| 650 |
} |
| 651 |
|
| 652 |
public static function buffer_end():void{ |
| 653 |
while (ob_get_level() > self::$bufferLevel) { |
| 654 |
ob_end_flush(); |
| 655 |
} |
| 656 |
|
| 657 |
if (ob_get_level() === self::$bufferLevel) { |
| 658 |
ob_end_flush(); |
| 659 |
} |
| 660 |
} |
| 661 |
|
| 662 |
private static function minify_concate_css_should_preserve_comment(string $inner):bool { |
| 663 |
$inner = trim($inner); |
| 664 |
if ($inner === '') { |
| 665 |
return false; |
| 666 |
} |
| 667 |
if (preg_match('/^(.+\s+)?framework\s+[\w.+-]+$/i', $inner) === 1) { |
| 668 |
return true; |
| 669 |
} |
| 670 |
if (preg_match('/\.css$/i', $inner) === 1) { |
| 671 |
return true; |
| 672 |
} |
| 673 |
return false; |
| 674 |
} |
| 675 |
|
| 676 |
/** |
| 677 |
* Strip block comments; leaves quoted strings unchanged (handles \\ escapes). |
| 678 |
* Keeps theme/framework version and per-file path comments from getBuffer(). |
| 679 |
*/ |
| 680 |
private static function minify_concate_css_strip_comments(string $css):string { |
| 681 |
$len = strlen($css); |
| 682 |
$out = ''; |
| 683 |
for ($i = 0; $i < $len; $i++) { |
| 684 |
$c = $css[$i]; |
| 685 |
if ($c === '"' || $c === "'") { |
| 686 |
$q = $c; |
| 687 |
$out .= $q; |
| 688 |
for ($i++; $i < $len; $i++) { |
| 689 |
$c = $css[$i]; |
| 690 |
$out .= $c; |
| 691 |
if ($c === '\\' && $i + 1 < $len) { |
| 692 |
$out .= $css[++$i]; |
| 693 |
continue; |
| 694 |
} |
| 695 |
if ($c === $q) { |
| 696 |
break; |
| 697 |
} |
| 698 |
} |
| 699 |
continue; |
| 700 |
} |
| 701 |
if ($c === '/' && $i + 1 < $len && $css[$i + 1] === '*') { |
| 702 |
$commentStart = $i; |
| 703 |
$innerStart = $i + 2; |
| 704 |
for ($i += 2; $i < $len; $i++) { |
| 705 |
if ($css[$i] === '*' && $i + 1 < $len && $css[$i + 1] === '/') { |
| 706 |
$inner = substr($css, $innerStart, $i - $innerStart); |
| 707 |
if (self::minify_concate_css_should_preserve_comment($inner)) { |
| 708 |
$out .= substr($css, $commentStart, $i - $commentStart + 2); |
| 709 |
} |
| 710 |
$i++; |
| 711 |
break; |
| 712 |
} |
| 713 |
} |
| 714 |
continue; |
| 715 |
} |
| 716 |
$out .= $c; |
| 717 |
} |
| 718 |
return $out; |
| 719 |
} |
| 720 |
|
| 721 |
/** |
| 722 |
* Compress whitespace and braces/semicolons in concatenated cache CSS. |
| 723 |
* |
| 724 |
* Only normalizes whitespace runs to a single space, then trims around { } ; — we do not |
| 725 |
* strip spaces around :, commas, +, ~, or >. That keeps transition/animation/background/ |
| 726 |
* grid-template shorthands, !important, and multi-token values intact. |
| 727 |
* |
| 728 |
* Avoids stripping around > (child combinator): the same character appears in @container |
| 729 |
* (width > 700px), @supports selector(...), and arbitrary custom-property values. |
| 730 |
* |
| 731 |
* Native CSS nesting (&) is unchanged by comment removal; avoid adding combinator-only |
| 732 |
* regex passes without tracking parens/at-rules if minification is extended later. |
| 733 |
*/ |
| 734 |
private static function minify_concate_css(string $css):string { |
| 735 |
if ($css === '') { |
| 736 |
return ''; |
| 737 |
} |
| 738 |
if (strncmp($css, "\xEF\xBB\xBF", 3) === 0) { |
| 739 |
$css = substr($css, 3); |
| 740 |
} |
| 741 |
$css = self::minify_concate_css_strip_comments($css); |
| 742 |
if ($css === '') { |
| 743 |
return ''; |
| 744 |
} |
| 745 |
$quoted = array(); |
| 746 |
$css = preg_replace_callback( |
| 747 |
'/"(?:\\\\.|[^\\\\"])*"|\'(?:\\\\.|[^\\\\\'])*\'/', |
| 748 |
static function (array $m) use (&$quoted): string { |
| 749 |
$quoted[] = $m[0]; |
| 750 |
return '##TFQ' . (count($quoted) - 1) . '##'; |
| 751 |
}, |
| 752 |
$css |
| 753 |
); |
| 754 |
if (!is_string($css)) { |
| 755 |
return ''; |
| 756 |
} |
| 757 |
$css = preg_replace('/\s+/', ' ', $css); |
| 758 |
$css = preg_replace('/\s*{\s*/', '{', $css); |
| 759 |
$css = preg_replace('/\s*;\s*/', ';', $css); |
| 760 |
$css = preg_replace('/\s*}\s*/', '}', $css); |
| 761 |
$css = trim($css); |
| 762 |
for ($i = count($quoted) - 1; $i >= 0; $i--) { |
| 763 |
$css = str_replace('##TFQ' . $i . '##', $quoted[$i], $css); |
| 764 |
} |
| 765 |
return $css; |
| 766 |
} |
| 767 |
|
| 768 |
private static function getBuffer(string $body):string{ |
| 769 |
$key = ''; |
| 770 |
$exist = $hasFonts = false; |
| 771 |
self::$css = apply_filters('themify_main_concate', self::$css); |
| 772 |
self::$css['mobile_concate'] = apply_filters('themify_mobile_concate', self::$css['mobile_concate']); |
| 773 |
foreach (self::$css as $k => $v) { |
| 774 |
if ($k !== 'in_footer' && $k !== 'mobile_concate') { |
| 775 |
$key .= $k . $v['v']; |
| 776 |
} |
| 777 |
} |
| 778 |
$output = ''; |
| 779 |
if ($key !== '') { |
| 780 |
if (isset(self::$css['woocommerce-general']) && strpos($body, 'star-rating') !== false) { |
| 781 |
self::addPreLoadMedia(dirname(self::$css['woocommerce-general']['s'],2) . '/fonts/star.woff', 'preload', 'font', null, null, 'high'); |
| 782 |
} |
| 783 |
$isDevMode=themify_is_dev_mode() && (!class_exists('Themify_Builder_Model',false) || !Themify_Builder_Model::is_front_builder_activate()); |
| 784 |
$isConcateDisabled = themify_is_concate_disabled(); |
| 785 |
$regenerate = false; |
| 786 |
if(self::$concateFile===null || $isConcateDisabled===true){ |
| 787 |
$isDevMode=true; |
| 788 |
$exist=false; |
| 789 |
$key=''; |
| 790 |
} |
| 791 |
else{ |
| 792 |
$key .= implode('', array_keys(self::$css['mobile_concate'])); |
| 793 |
$key = crc32($key); |
| 794 |
self::$concateFile .= 'themify-' . $key . '.css'; |
| 795 |
$exist = Themify_Filesystem::is_file(self::$concateFile); |
| 796 |
if ($exist === true) { |
| 797 |
$regenerate = !apply_filters('themify_concate_css', !$isDevMode, self::$concateFile); //opposite logic for backward compatibility |
| 798 |
$isDeleted = Themify_Filesystem::is_file(self::$concateFile . 'del'); |
| 799 |
$regenerate = $regenerate === true || $isDeleted === true; |
| 800 |
if ($regenerate === true) { |
| 801 |
if ($isDeleted === true) { |
| 802 |
Themify_Filesystem::delete(self::$concateFile . 'del','f'); |
| 803 |
} |
| 804 |
$exist = false; |
| 805 |
} |
| 806 |
unset($isDeleted); |
| 807 |
} |
| 808 |
} |
| 809 |
if ($exist === false) { |
| 810 |
if (!isset($str)) { |
| 811 |
$str = ''; |
| 812 |
} |
| 813 |
// Add theme and fw version |
| 814 |
$theme_name = ''; |
| 815 |
$replace = array(THEMIFY_URI, home_url()); |
| 816 |
if (self::$themeVersion !== null) { |
| 817 |
$theme = wp_get_theme(); |
| 818 |
$theme_name = (is_child_theme() ? $theme->parent()->Name : $theme->display('Name')) . ' ' . self::$themeVersion . ' '; |
| 819 |
$replace[] = THEME_URI; |
| 820 |
$theme = null; |
| 821 |
} |
| 822 |
$str = PHP_EOL . '/* ' . $theme_name . 'framework ' . THEMIFY_VERSION . ' */' . $str . PHP_EOL; |
| 823 |
$str = '@charset "UTF-8";' . $str; |
| 824 |
unset($theme_name); |
| 825 |
if(self::$themeVersion!==null && (self::$concateFile===null || $isConcateDisabled===true)){ |
| 826 |
$key=''; |
| 827 |
} |
| 828 |
foreach (self::$css as $k => $v) { |
| 829 |
if ($k !== 'in_footer' && $k !== 'mobile_concate') { |
| 830 |
$content = $key !== ''? Themify_Filesystem::get_file_content($v['s']) : null; |
| 831 |
if (!empty($content)) { |
| 832 |
$dir = dirname($v['s']); |
| 833 |
$content = strtr($content, |
| 834 |
array( |
| 835 |
'@charset "UTF-8";'=>'', |
| 836 |
'..'=>dirname($dir), |
| 837 |
"url('fonts/"=>"url({'$dir}/fonts/", |
| 838 |
"url('images/"=>"url('{$dir}/images/", |
| 839 |
"url(fonts/"=>"url({$dir}/fonts/", |
| 840 |
"url(images/"=>"url({$dir}/images/" |
| 841 |
)); |
| 842 |
if ($k === 'woocommerce-general') { |
| 843 |
$content = str_replace('@font-face{', '@font-face{font-display:swap;', $content); |
| 844 |
} |
| 845 |
if (isset($v['m'])) { |
| 846 |
$content = '@media ' . $v['m'] . '{' . PHP_EOL . $content . PHP_EOL . '}'; |
| 847 |
} |
| 848 |
$str .= PHP_EOL . '/*' . str_replace($replace, '', $v['s']) . '*/' . PHP_EOL . $content; |
| 849 |
} |
| 850 |
elseif (!Themify_Filesystem::get_file_content($v['s'], true)) { |
| 851 |
$key = $str = ''; |
| 852 |
} |
| 853 |
if (isset(self::$preLoadMedia[$k])) { |
| 854 |
unset(self::$preLoadMedia[$k]); |
| 855 |
} |
| 856 |
$media = isset($v['m'])?' media="'.$v['m'].'"':''; |
| 857 |
$output .= '<link rel="preload" href="' . $v['s'] . '?ver=' . $v['v'] . '" as="style"'.$media.'>' . "\n" . '<link id="' . $k . '-css" rel="stylesheet" href="' . $v['s'] . '?ver=' . $v['v'] . '"'.$media.'>' . "\n"; |
| 858 |
} |
| 859 |
} |
| 860 |
unset($content); |
| 861 |
if (!empty(self::$css['mobile_concate'])) { |
| 862 |
$media = 'screen and (max-width:' . self::$mobileMenuActive . 'px)'; |
| 863 |
$mobileStr = PHP_EOL . '/* START MOBILE MENU CSS */' . PHP_EOL . '@media ' . $media . '{'; |
| 864 |
foreach (self::$css['mobile_concate'] as $k => $v) { |
| 865 |
$content = $key !== '' ? Themify_Filesystem::get_file_content($v) : null; |
| 866 |
if (!empty($content)) { |
| 867 |
$mobileStr .= PHP_EOL . '/*' . str_replace($replace, '', $v) . '*/' . PHP_EOL . trim($content); |
| 868 |
} else { |
| 869 |
$mobileStr = $key = ''; |
| 870 |
} |
| 871 |
if (isset(self::$preLoadMedia[$k])) { |
| 872 |
unset(self::$preLoadMedia[$k]); |
| 873 |
} |
| 874 |
$output .= '<link rel="preload" href="' . $v . '?ver=' . self::$themeVersion . '" media="' . $media . '" as="style"><link id="tf-mobile-' . $k . '-css" rel="stylesheet" href="' . $v . '?ver=' . self::$themeVersion . '" media="' . $media . '">'; |
| 875 |
} |
| 876 |
unset(self::$css['mobile_concate'], $content); |
| 877 |
if ($mobileStr !== '') { |
| 878 |
$mobileStr .= PHP_EOL . '}' . PHP_EOL . '/* END MOBILE MENU CSS */'; |
| 879 |
$str .= $mobileStr; |
| 880 |
unset($mobileStr); |
| 881 |
} |
| 882 |
} |
| 883 |
if ($key !== '' && (empty(self::$concateFile) || (($regenerate === true || !Themify_Filesystem::is_file(self::$concateFile))))) { |
| 884 |
if (apply_filters('themify_minify_concate_css', !$isDevMode)) { |
| 885 |
$str = self::minify_concate_css($str); |
| 886 |
} |
| 887 |
if(!file_put_contents(self::$concateFile.'tmp', $str) || Themify_Filesystem::rename(self::$concateFile.'tmp',self::$concateFile)===false){//tmp file need because file_put_contents isn't atomic(another process can read not ready file),locking file(LOCK_EX) is slow,that is why we are using rename(it is atomic) |
| 888 |
$key = ''; |
| 889 |
Themify_Filesystem::delete(self::$concateFile.'tmp','f'); |
| 890 |
} |
| 891 |
} |
| 892 |
unset($str, $replace); |
| 893 |
} |
| 894 |
} |
| 895 |
if ( true === apply_filters( 'themify_enable_lazyload', true ) ) { |
| 896 |
$body = themify_make_lazy($body); |
| 897 |
} |
| 898 |
$path = self::getPreLoad(); |
| 899 |
if (self::$disableGoogleFontsLoad === null) { |
| 900 |
$path.= self::loadGoogleFonts(); |
| 901 |
} |
| 902 |
if (!themify_is_amp() && !preg_match('/<html[^>]*\s(?:amp|âš¡)(?:=|[\s>])/i', $body)) { |
| 903 |
if ($key !== '') { |
| 904 |
$upload_dir = themify_upload_dir(); |
| 905 |
$href = str_replace($upload_dir['basedir'], $upload_dir['baseurl'], self::$concateFile); |
| 906 |
unset($upload_dir); |
| 907 |
$path .= '<link rel="preload" fetchpriority="high" href="' . $href . '" as="style"><link fetchpriority="high" id="themify_concate-css" rel="stylesheet" href="' . $href . '">'; |
| 908 |
} else { |
| 909 |
$path .= $output; |
| 910 |
// Placeholder for generate-style.js in dev mode; empty style tags invalidate AMP. |
| 911 |
if ($output !== '' || themify_is_dev_mode()) { |
| 912 |
$path .= '<style id="themify_concate-css"></style>'; |
| 913 |
} |
| 914 |
} |
| 915 |
} |
| 916 |
unset($output); |
| 917 |
self::$concateFile = null; |
| 918 |
if (strpos($body, 'fonts.googleapis.com') !== false) { |
| 919 |
$path .= '<link rel="dns-prefetch" href="https://fonts.gstatic.com">'; |
| 920 |
} |
| 921 |
if (strpos($body, '//www.youtube.com/embed') !== false) { |
| 922 |
$path .= '<link rel="preconnect" href="https://www.youtube.com">'; |
| 923 |
} |
| 924 |
if (strpos($body, '//player.vimeo.com/video') !== false) { |
| 925 |
$path .= '<link rel="preconnect" href="https://player.vimeo.com">'; |
| 926 |
} |
| 927 |
if (themify_get('setting-ga_m_id', '', true) !== '' || strpos($body, 'googletagmanager.com') !== false) { |
| 928 |
$path .= '<link rel="preconnect" href="https://www.google-analytics.com">'; |
| 929 |
} |
| 930 |
if ( class_exists( 'TF_SV_Framework', false ) ) { |
| 931 |
$path .= TF_SV_Framework::get_frontend_head_fragment(); |
| 932 |
} |
| 933 |
if (self::$themeVersion !== null && ($custom_css = themify_get('setting-custom_css', false, true))) { |
| 934 |
$path.='<!--custom css:start--><style>'. $custom_css.'</style><!--custom css:end-->'; |
| 935 |
} |
| 936 |
self::$css = self::$googleFonts = self::$preLoadMedia = $rep=array(); |
| 937 |
if(strpos($body,'<!--tf_svg_holder-->')!==false){ |
| 938 |
$rep['<!--tf_svg_holder-->']=self::loadIcons(false); |
| 939 |
} |
| 940 |
else{ |
| 941 |
$rep['</body>']=self::loadIcons(false).'</body>'; |
| 942 |
} |
| 943 |
if(strpos($body,'<!--tf_css_position-->')!==false){ |
| 944 |
$rep['<!--tf_css_position-->']=$path; |
| 945 |
} |
| 946 |
else{ |
| 947 |
$rep['</head>']=$path.'</head>'; |
| 948 |
} |
| 949 |
return strtr($body,$rep); |
| 950 |
} |
| 951 |
|
| 952 |
public static function loadIcons(bool $echo = true) { |
| 953 |
$fonts = Themify_Icon_Font::get_used_icons(); |
| 954 |
$svg = '<svg id="tf_svg" style="display:none"><defs>'; |
| 955 |
if (!empty($fonts)) { |
| 956 |
$st = ''; |
| 957 |
foreach ($fonts as $k => $v) { |
| 958 |
if ( $v === false ) { |
| 959 |
continue; |
| 960 |
} |
| 961 |
$w = isset($v['vw']) ? $v['vw'] : '32'; |
| 962 |
$h = isset($v['vh']) ? $v['vh'] : '32'; |
| 963 |
$p = isset($v['is_fontello']) ? ' transform="matrix(1 0 0 -1 0 ' . $h . ')"' : ''; |
| 964 |
$svg .= '<symbol id="tf-' . $k . '" viewBox="0 0 ' . $w . ' ' . $h . '"><path d="' . $v['p'] . '"' . $p . '/></symbol>'; |
| 965 |
if (isset($v['w'])) { |
| 966 |
$st .= '.tf_fa.tf-' . $k . '{width:' . $v['w'] . 'em}'; |
| 967 |
} |
| 968 |
} |
| 969 |
if ($st !== '') { |
| 970 |
$svg .= '<style id="tf_fonts_style">' . $st . '</style>'; |
| 971 |
$st = null; |
| 972 |
} |
| 973 |
} |
| 974 |
$svg .= '</defs></svg>'; |
| 975 |
$fonts = null; |
| 976 |
if ($echo === false) { |
| 977 |
return $svg; |
| 978 |
} |
| 979 |
echo $svg; |
| 980 |
} |
| 981 |
|
| 982 |
private static function get_webp_support():string { |
| 983 |
return PHP_EOL . '#BEGIN_WEBP_OUTPUT_BY_THEMIFY |
| 984 |
<IfModule mod_rewrite.c> |
| 985 |
RewriteEngine On |
| 986 |
# serves a .webp image instead of jpg/png |
| 987 |
RewriteCond %{HTTP_ACCEPT} image/webp |
| 988 |
RewriteCond %{REQUEST_FILENAME} ^(.+)\.(jpe?g|jpg|png|gif)$ |
| 989 |
RewriteCond %1\.webp -f |
| 990 |
RewriteRule ^(.+)\.(jpe?g|jpg|png|gif)$ $1.webp [T=image/webp,E=accept:1] |
| 991 |
</IfModule> |
| 992 |
<IfModule mod_headers.c> |
| 993 |
Header append Vary Accept env=REQUEST_image |
| 994 |
</IfModule> |
| 995 |
<IfModule mod_mime.c> |
| 996 |
AddType image/webp .webp |
| 997 |
</IfModule> |
| 998 |
#END_WEBP_OUTPUT_BY_THEMIFY |
| 999 |
' . PHP_EOL; |
| 1000 |
} |
| 1001 |
|
| 1002 |
private static function get_gzip_htaccess():string { |
| 1003 |
return PHP_EOL . '#BEGIN_GZIP_OUTPUT_BY_THEMIFY |
| 1004 |
<IfModule mod_rewrite.c> |
| 1005 |
<Files *.js.gz> |
| 1006 |
AddType "text/javascript" .gz |
| 1007 |
AddEncoding gzip .gz |
| 1008 |
</Files> |
| 1009 |
<Files *.css.gz> |
| 1010 |
AddType "text/css" .gz |
| 1011 |
AddEncoding gzip .gz |
| 1012 |
</Files> |
| 1013 |
<Files *.svg.gz> |
| 1014 |
AddType "image/svg+xml" .gz |
| 1015 |
AddEncoding gzip .gz |
| 1016 |
</Files> |
| 1017 |
<Files *.json.gz> |
| 1018 |
AddType "application/json" .gz |
| 1019 |
AddEncoding gzip .gz |
| 1020 |
</Files> |
| 1021 |
# Serve pre-compressed gzip assets |
| 1022 |
RewriteCond %{HTTP:Accept-Encoding} gzip |
| 1023 |
RewriteCond %{REQUEST_FILENAME}.gz -f |
| 1024 |
RewriteRule ^(.*)$ $1.gz [QSA,L] |
| 1025 |
</IfModule> |
| 1026 |
#END_GZIP_OUTPUT_BY_THEMIFY |
| 1027 |
' . PHP_EOL; |
| 1028 |
} |
| 1029 |
|
| 1030 |
private static function get_mod_rewrite():string { |
| 1031 |
return PHP_EOL . '#BEGIN_GZIP_COMPRESSION_BY_THEMIFY |
| 1032 |
<IfModule mod_deflate.c> |
| 1033 |
#add content typing |
| 1034 |
AddType application/x-gzip .gz .tgz |
| 1035 |
AddEncoding x-gzip .gz .tgz |
| 1036 |
# Insert filters |
| 1037 |
AddOutputFilterByType DEFLATE text/plain |
| 1038 |
AddOutputFilterByType DEFLATE text/html |
| 1039 |
AddOutputFilterByType DEFLATE text/xml |
| 1040 |
AddOutputFilterByType DEFLATE text/css |
| 1041 |
AddOutputFilterByType DEFLATE application/xml |
| 1042 |
AddOutputFilterByType DEFLATE application/xhtml+xml |
| 1043 |
AddOutputFilterByType DEFLATE application/rss+xml |
| 1044 |
AddOutputFilterByType DEFLATE application/javascript |
| 1045 |
AddOutputFilterByType DEFLATE application/x-javascript |
| 1046 |
AddOutputFilterByType DEFLATE application/x-httpd-php |
| 1047 |
AddOutputFilterByType DEFLATE application/x-httpd-fastphp |
| 1048 |
AddOutputFilterByType DEFLATE image/svg+xml |
| 1049 |
AddOutputFilterByType DEFLATE image/svg |
| 1050 |
<IfModule mod_headers.c> |
| 1051 |
# Make sure proxies don\'t deliver the wrong content |
| 1052 |
Header append Vary User-Agent env=!dont-vary |
| 1053 |
</IfModule> |
| 1054 |
</IfModule> |
| 1055 |
# END GZIP COMPRESSION |
| 1056 |
## EXPIRES CACHING ## |
| 1057 |
<IfModule mod_expires.c> |
| 1058 |
ExpiresActive On |
| 1059 |
ExpiresByType image/jpg "access plus 1 year" |
| 1060 |
ExpiresByType image/jpeg "access plus 1 year" |
| 1061 |
ExpiresByType image/gif "access plus 1 year" |
| 1062 |
ExpiresByType image/png "access plus 1 year" |
| 1063 |
ExpiresByType image/webp "access plus 1 year" |
| 1064 |
ExpiresByType image/apng "access plus 1 year" |
| 1065 |
ExpiresByType image/svg+xml "access plus 1 year" |
| 1066 |
ExpiresByType image/svg "access plus 1 year" |
| 1067 |
ExpiresByType image/ico "access plus 1 year" |
| 1068 |
ExpiresByType image/x-icon "access plus 1 year" |
| 1069 |
ExpiresByType application/gzip "access plus 1 year" |
| 1070 |
ExpiresByType text/css "access plus 1 year" |
| 1071 |
ExpiresByType text/x-component "access plus 1 year" |
| 1072 |
ExpiresByType text/javascript "access plus 1 year" |
| 1073 |
ExpiresByType text/x-javascript "access plus 1 year" |
| 1074 |
ExpiresByType application/pdf "access plus 1 month" |
| 1075 |
ExpiresByType application/javascript "access plus 1 year" |
| 1076 |
ExpiresByType application/x-javascript "access plus 1 year" |
| 1077 |
ExpiresByType application/json "access plus 1 year" |
| 1078 |
ExpiresByType application/ld+json "access plus 1 year" |
| 1079 |
ExpiresByType application/xml "access plus 0 seconds" |
| 1080 |
ExpiresByType text/xml "access plus 0 seconds" |
| 1081 |
ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds" |
| 1082 |
ExpiresByType text/cache-manifest "access plus 0 seconds" |
| 1083 |
ExpiresByType audio/ogg "access plus 4 months" |
| 1084 |
ExpiresByType audio/mp3 "access plus 4 months" |
| 1085 |
ExpiresByType video/mp4 "access plus 4 months" |
| 1086 |
ExpiresByType video/ogg "access plus 4 months" |
| 1087 |
ExpiresByType video/webm "access plus 4 months" |
| 1088 |
ExpiresByType application/atom+xml "access plus 1 day" |
| 1089 |
ExpiresByType application/rss+xml "access plus 1 day" |
| 1090 |
ExpiresByType application/font-woff "access plus 1 year" |
| 1091 |
ExpiresByType application/vnd.ms-fontobject "access plus 1 year" |
| 1092 |
ExpiresByType application/x-font-ttf "access plus 1 year" |
| 1093 |
ExpiresByType font/opentype "access plus 1 year" |
| 1094 |
ExpiresByType font/woff "access plus 1 year" |
| 1095 |
ExpiresByType font/woff2 "access plus 1 year" |
| 1096 |
ExpiresByType font/application/x-font-woff2 "access plus 1 year" |
| 1097 |
ExpiresByType application/font-woff2 "access plus 1 year" |
| 1098 |
</IfModule> |
| 1099 |
#Alternative caching using Apache`s "mod_headers", if it`s installed. |
| 1100 |
#Caching of common files - ENABLED |
| 1101 |
<IfModule mod_headers.c> |
| 1102 |
<FilesMatch "\.(pdf|xls|rar|zip|tgz|tar|html|txt)$"> |
| 1103 |
Header set Cache-Control "max-age=2628000, public" |
| 1104 |
</FilesMatch> |
| 1105 |
<FilesMatch "\.(jpg|jpeg|gif|png|webp|apng|svg|js|mjs|css|mp3|ogg|mpe?g|avi|gz|woff|woff2|eot|ttf|mp4|doc|ico|ogv|svgz|otf|rss|ppt|mid|midi|wav|bmp|rtf|json|jsonld)$"> |
| 1106 |
Header set Cache-Control "max-age=31536000, public" |
| 1107 |
</FilesMatch> |
| 1108 |
# Set Keep Alive Header |
| 1109 |
Header set Connection keep-alive |
| 1110 |
</IfModule> |
| 1111 |
|
| 1112 |
<IfModule mod_gzip.c> |
| 1113 |
mod_gzip_on Yes |
| 1114 |
mod_gzip_dechunk Yes |
| 1115 |
mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$ |
| 1116 |
mod_gzip_item_include handler ^cgi-script$ |
| 1117 |
mod_gzip_item_include mime ^text/.* |
| 1118 |
mod_gzip_item_include mime ^application/x-javascript.* |
| 1119 |
mod_gzip_item_exclude mime ^image/.* |
| 1120 |
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.* |
| 1121 |
</IfModule> |
| 1122 |
|
| 1123 |
# If your server don`t support ETags deactivate with "None" (and remove header) |
| 1124 |
<IfModule mod_expires.c> |
| 1125 |
<IfModule mod_headers.c> |
| 1126 |
Header unset ETag |
| 1127 |
</IfModule> |
| 1128 |
FileETag None |
| 1129 |
</IfModule> |
| 1130 |
## EXPIRES CACHING ## |
| 1131 |
#END_GZIP_COMPRESSION_BY_THEMIFY' . PHP_EOL; |
| 1132 |
} |
| 1133 |
|
| 1134 |
public static function rewrite_htaccess($gzip = false, $webp = false,$browser=false) { |
| 1135 |
$htaccess_file = self::getHtaccessFile(); |
| 1136 |
if (is_file($htaccess_file) && Themify_Filesystem::is_writable($htaccess_file)) { |
| 1137 |
if (themify_get_server() === 'iis') {//for iis we need to add webp mimeType |
| 1138 |
$iis_config = get_home_path() . 'web.config'; |
| 1139 |
if (is_file($iis_config) && Themify_Filesystem::is_writable($iis_config)) { |
| 1140 |
$rules = trim(Themify_Filesystem::get_contents($iis_config)); |
| 1141 |
if (!empty($rules) && strpos($rules, 'mimeType="image/webp"') === false) { |
| 1142 |
$replace = '<!--BEGIN_WEBP_OUTPUT_BY_THEMIFY--> |
| 1143 |
<mimeMap fileExtension=".webp" mimeType="image/webp"/> |
| 1144 |
<!--END_WEBP_OUTPUT_BY_THEMIFY-->'; |
| 1145 |
if (preg_match_all('#\<staticContent\>#', $rules) > 0) { |
| 1146 |
$rules = preg_replace('#\<staticContent\>#', '<staticContent>' . $replace, $rules, 1); |
| 1147 |
} else { |
| 1148 |
$rules = preg_replace('#\<rewrite\>#', '<staticContent>' . $replace . '</staticContent><rewrite>', $rules, 1); |
| 1149 |
} |
| 1150 |
unset($replace); |
| 1151 |
Themify_Filesystem::put_contents($iis_config, trim($rules)); |
| 1152 |
} |
| 1153 |
} |
| 1154 |
unset($iis_config); |
| 1155 |
} |
| 1156 |
$rules = trim(Themify_Filesystem::get_contents($htaccess_file)); |
| 1157 |
$startOutputTag = '#BEGIN_GZIP_OUTPUT_BY_THEMIFY'; |
| 1158 |
$endOutputTag = '#END_GZIP_OUTPUT_BY_THEMIFY'; |
| 1159 |
|
| 1160 |
$startGzipTag = '#BEGIN_GZIP_COMPRESSION_BY_THEMIFY'; |
| 1161 |
$endGzipTag = '#END_GZIP_COMPRESSION_BY_THEMIFY'; |
| 1162 |
|
| 1163 |
$startWebTag = '#BEGIN_WEBP_OUTPUT_BY_THEMIFY'; |
| 1164 |
$endWebTag = '#END_WEBP_OUTPUT_BY_THEMIFY'; |
| 1165 |
$hasChange = false; |
| 1166 |
|
| 1167 |
if ($webp === false) { |
| 1168 |
if (strpos($rules, $startWebTag) === false) { |
| 1169 |
$rules = self::get_webp_support() . $rules; |
| 1170 |
$hasChange = true; |
| 1171 |
} |
| 1172 |
} elseif (strpos($rules, $startWebTag) !== false) { |
| 1173 |
$startsAt = strpos($rules, $startWebTag); |
| 1174 |
$endsAt = strpos($rules, $endWebTag, $startsAt); |
| 1175 |
$textToDelete = substr($rules, $startsAt, ($endsAt + strlen($endWebTag)) - $startsAt); |
| 1176 |
$rules = str_replace($textToDelete, '', $rules); |
| 1177 |
$hasChange = true; |
| 1178 |
} |
| 1179 |
|
| 1180 |
if ($gzip === false) { |
| 1181 |
if (strpos($rules, $startOutputTag) === false) { |
| 1182 |
$rules = self::get_gzip_htaccess() . $rules; |
| 1183 |
$hasChange = true; |
| 1184 |
} |
| 1185 |
} |
| 1186 |
elseif (strpos($rules, $startOutputTag) !== false) { |
| 1187 |
$startsAt = strpos($rules, $startOutputTag); |
| 1188 |
$endsAt = strpos($rules, $endOutputTag, $startsAt); |
| 1189 |
$textToDelete = substr($rules, $startsAt, ($endsAt + strlen($endOutputTag)) - $startsAt); |
| 1190 |
$rules = str_replace($textToDelete, '', $rules); |
| 1191 |
$hasChange = true; |
| 1192 |
} |
| 1193 |
|
| 1194 |
if($browser===false){ |
| 1195 |
if (strpos($rules, 'mod_deflate.c') === false && strpos($rules, 'mod_gzip.c') === false) { |
| 1196 |
$rules .= self::get_mod_rewrite(); |
| 1197 |
$hasChange = true; |
| 1198 |
} |
| 1199 |
} |
| 1200 |
elseif (strpos($rules, $startGzipTag) !== false) { |
| 1201 |
$startsAt = strpos($rules, $startGzipTag); |
| 1202 |
$endsAt = strpos($rules, $endGzipTag, $startsAt); |
| 1203 |
$textToDelete = substr($rules, $startsAt, ($endsAt + strlen($endGzipTag)) - $startsAt); |
| 1204 |
$rules = str_replace($textToDelete, '', $rules); |
| 1205 |
$hasChange = true; |
| 1206 |
} |
| 1207 |
|
| 1208 |
if ($hasChange === true) { |
| 1209 |
return Themify_Filesystem::put_contents($htaccess_file, trim($rules)); |
| 1210 |
} |
| 1211 |
} |
| 1212 |
} |
| 1213 |
|
| 1214 |
public static function getHtaccessFile():string{ |
| 1215 |
$f=get_home_path() . '.htaccess'; |
| 1216 |
if(!is_file($f)){ |
| 1217 |
$f=ABSPATH . '.htaccess'; |
| 1218 |
} |
| 1219 |
return $f; |
| 1220 |
} |
| 1221 |
|
| 1222 |
public static function addCssToFile(string $handle, string $src,?string $ver = THEMIFY_VERSION, $position = false):bool { |
| 1223 |
if (self::$concateFile === null) { |
| 1224 |
return false; |
| 1225 |
} |
| 1226 |
if (!isset(self::$css[$handle])) { |
| 1227 |
if ($position === false) { |
| 1228 |
self::$css[$handle] = array('s' => $src, 'v' => $ver); |
| 1229 |
} elseif (isset(self::$css[$position])) { |
| 1230 |
$keys = array_keys(self::$css); |
| 1231 |
$index = array_search($position, $keys) + 1; |
| 1232 |
self::$css = array_slice(self::$css, 0, $index) + array($handle => array('s' => $src, 'v' => $ver)) + array_slice(self::$css, $index); |
| 1233 |
} else { |
| 1234 |
return false; |
| 1235 |
} |
| 1236 |
} |
| 1237 |
return true; |
| 1238 |
} |
| 1239 |
|
| 1240 |
public static function addPreLoadJs(string $src,string $ver = THEMIFY_VERSION, string $importance = 'low'):array { |
| 1241 |
return self::addPreLoadMedia($src, 'preload', 'script', $ver, null, $importance); |
| 1242 |
} |
| 1243 |
|
| 1244 |
public static function addPrefetchJs(string $src, string $ver = THEMIFY_VERSION, string $importance = 'low'):array { |
| 1245 |
return self::addPreLoadMedia($src, 'prefetch', 'script', $ver, null, $importance); |
| 1246 |
} |
| 1247 |
|
| 1248 |
public static function addPreLoadCss(string $src, string $ver = THEMIFY_VERSION, $m = 'all', string $importance = ''):array { |
| 1249 |
return self::addPreLoadMedia($src, 'preload', 'style', $ver, $m, $importance); |
| 1250 |
} |
| 1251 |
|
| 1252 |
public static function addPrefetchCss(string $src,string $ver = THEMIFY_VERSION, $m = 'all', string $importance = ''):array { |
| 1253 |
return self::addPreLoadMedia($src, 'prefetch', 'style', $ver, $m, $importance); |
| 1254 |
} |
| 1255 |
|
| 1256 |
public static function addPreLoadMedia(string $src, string $rel = 'preload', string $type = 'image', $ver = '', $m = 'all', string $importance = ''):array { |
| 1257 |
|
| 1258 |
if(!isset(self::$done[$src]) && ($rel!=='prefetch' || !isset(self::$preLoadMedia[$src]))){ |
| 1259 |
self::$preLoadMedia[$src] = array('t' => $type, 'r' => $rel); |
| 1260 |
if ($type !== 'image' && $type !== 'font') { |
| 1261 |
if ($type === 'style') { |
| 1262 |
self::$preLoadMedia[$src]['m'] = $m; |
| 1263 |
} |
| 1264 |
if ($ver !== '') { |
| 1265 |
self::$preLoadMedia[$src]['v'] = $ver; |
| 1266 |
} |
| 1267 |
} |
| 1268 |
elseif($type==='image' && $ver!=='' && $ver!==null && $m!=='' && $m!==null && $m!=='all'){//ver is srcset, m sizes for image |
| 1269 |
self::$preLoadMedia[$src]['srcset'] = $ver; |
| 1270 |
self::$preLoadMedia[$src]['sizes'] = $m; |
| 1271 |
} |
| 1272 |
if ($importance !== '') { |
| 1273 |
self::$preLoadMedia[$src]['i'] = $importance; |
| 1274 |
} |
| 1275 |
} |
| 1276 |
return array('s'=>$src,'v'=>isset(self::$preLoadMedia[$src]['v'])?self::$preLoadMedia[$src]['v']:null); |
| 1277 |
} |
| 1278 |
|
| 1279 |
public static function add_js($handle, $src, $deps, $ver, $in_footer = true) { |
| 1280 |
wp_enqueue_script($handle, $src, $deps, $ver, $in_footer); |
| 1281 |
} |
| 1282 |
|
| 1283 |
public static function getKnownJs():array { |
| 1284 |
static $arr = null; |
| 1285 |
if ($arr === null) { |
| 1286 |
$arr = array(); |
| 1287 |
if (!is_admin()) { |
| 1288 |
$isDefered = self::$themeVersion !== null |
| 1289 |
? (themify_check('setting-jquery', true) ? true : (themify_check('setting-optimize-wc', true) ? false : !themify_check('setting-defer-wc', true))) |
| 1290 |
: !themify_builder_check('setting-defer-wc', 'defer-wc', true); |
| 1291 |
if ($isDefered===true && themify_is_woocommerce_active()) { |
| 1292 |
$arr = array('flexslider', 'wc-single-product', 'woocommerce', 'zoom', themify_wc_get_script_handle('js-cookie'), themify_wc_get_script_handle('wc-jquery-blockui'), 'jquery-cookie', 'jquery-payment', 'prettyPhoto', 'prettyPhoto-init', 'select2', 'selectWoo', 'wc-address-i18n', 'wc-add-payment-method', 'wc-cart', 'wc-cart-fragments', 'wc-checkout', 'wc-country-select', 'wc-credit-card-form', 'wc-add-to-cart', 'wc-add-to-cart-variation', 'wc-geolocation', 'wc-lost-password', 'wc-password-strength-meter', 'photoswipe', 'photoswipe-ui-default', 'wc-add-to-cart-composite'); |
| 1293 |
//Authorize.Net Gateway for WooCommerce |
| 1294 |
if (function_exists('wc_authorize_net_cim')) { |
| 1295 |
$arr[] = 'wc-authorize-net-cim'; |
| 1296 |
$arr[] = 'wc-authorize-net-apple-pay'; |
| 1297 |
$arr[] = 'wc-authorize-net-my-payment-methods'; |
| 1298 |
$arr[] = 'sv-wc-payment-gateway-payment-form-v5_8_1'; |
| 1299 |
$arr[] = 'sv-wc-payment-gateway-my-payment-methods-v5_8_1'; |
| 1300 |
$arr[] = 'sv-wc-jilt-prompt-customers'; |
| 1301 |
$arr[] = 'sv-wc-apple-pay-v5_8_1'; |
| 1302 |
} |
| 1303 |
if (defined('WOOCOMMERCE_GATEWAY_EWAY_VERSION')) {//plugin eWAY WooCommerce gateway |
| 1304 |
$arr[] = 'eway-credit-card-form'; |
| 1305 |
} |
| 1306 |
} |
| 1307 |
if (defined('WPCF7_PLUGIN')) { |
| 1308 |
$arr[] = 'contact-form-7'; |
| 1309 |
} |
| 1310 |
if (defined('SBI_PLUGIN_DIR')) {//plugin instagram feed |
| 1311 |
$arr[] = 'sb_instagram_scripts'; |
| 1312 |
} |
| 1313 |
if (defined('LP_PLUGIN_FILE')) {//plugin learnpress |
| 1314 |
$arr[] = 'lp-global'; |
| 1315 |
$arr[] = 'global'; |
| 1316 |
$arr[] = 'learnpress'; |
| 1317 |
$arr[] = 'lp-plugins-all'; |
| 1318 |
$arr[] = 'learn-press-enroll'; |
| 1319 |
$arr[] = 'quiz'; |
| 1320 |
$arr[] = 'wp-utils'; |
| 1321 |
$arr[] = 'course'; |
| 1322 |
$arr[] = 'checkout'; |
| 1323 |
$arr[] = 'profile-user'; |
| 1324 |
$arr[] = 'become-a-teacher'; |
| 1325 |
$arr[] = 'jquery-caret'; |
| 1326 |
} |
| 1327 |
} |
| 1328 |
} |
| 1329 |
return $arr; |
| 1330 |
} |
| 1331 |
|
| 1332 |
public static function removeWebp($dir = null) { |
| 1333 |
if ($dir === null) { |
| 1334 |
$dir = themify_upload_dir('basedir'); |
| 1335 |
if (!Themify_Filesystem::is_dir($dir) || !Themify_Filesystem::is_readable($dir)) { |
| 1336 |
return array('error' => sprintf(__('The directory %s doesn`t exist or not readable', 'themify'), $dir)); |
| 1337 |
} |
| 1338 |
} |
| 1339 |
$arr = array('.png', '.jpg', '.jpeg','.gif'); |
| 1340 |
$files = scandir($dir,SCANDIR_SORT_NONE); |
| 1341 |
foreach ($files as $value) { |
| 1342 |
$path = realpath($dir . DIRECTORY_SEPARATOR . $value); |
| 1343 |
if (!Themify_Filesystem::is_dir($path)) { |
| 1344 |
if (pathinfo($path, PATHINFO_EXTENSION) === 'webp') { |
| 1345 |
foreach ($arr as $v) { |
| 1346 |
if (Themify_Filesystem::is_file(str_replace('.webp', $v, $path))) { |
| 1347 |
Themify_Filesystem::delete($path,'f'); |
| 1348 |
break; |
| 1349 |
} |
| 1350 |
} |
| 1351 |
} |
| 1352 |
} elseif ($value !== '.' && $value !== '..') { |
| 1353 |
self::removeWebp($path); |
| 1354 |
} |
| 1355 |
} |
| 1356 |
} |
| 1357 |
/** |
| 1358 |
* Load assets required by Themify framework |
| 1359 |
* |
| 1360 |
* @since 1.1.2 |
| 1361 |
*/ |
| 1362 |
public static function loadMainScript() { |
| 1363 |
//Enqueue main js that will load others needed js |
| 1364 |
global $wp_scripts, $wp_version; |
| 1365 |
if (!isset($wp_scripts->registered['themify-main-script']) && empty($_GET['legacy-widget-preview'])) { /* disable in Block widget preview */ |
| 1366 |
$dependencies = []; |
| 1367 |
// if ( themify_is_woocommerce_active() || ! defined( 'THEMIFY_NOJQUERY' ) ) { |
| 1368 |
$dependencies[] = 'jquery'; |
| 1369 |
// } |
| 1370 |
wp_enqueue_script('themify-main-script', THEMIFY_URI . '/js/main.js', $dependencies, THEMIFY_VERSION, true); |
| 1371 |
$args = array( |
| 1372 |
'breakpoints' => themify_get_breakpoints(), |
| 1373 |
'wp' => $wp_version, |
| 1374 |
'ajax_url' => admin_url('admin-ajax.php'), |
| 1375 |
'nonce' => wp_create_nonce( 'tf_nonce' ), |
| 1376 |
'map_key' => wp_strip_all_tags( themify_builder_get('setting-google_map_key', 'builder_settings_google_map_key') ?: '' ), |
| 1377 |
'bing_map_key' =>wp_strip_all_tags( themify_builder_get('setting-bing_map_key', 'builder_settings_bing_map_key') ?: '' ), |
| 1378 |
'azure_key' => wp_strip_all_tags( themify_builder_get('setting-azure_map_key', 'builder_settings_azure_map_key') ?: '' ), |
| 1379 |
'osm_tile_url' => apply_filters( 'themify_builder_osm_tile_url', 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png' ), |
| 1380 |
'osm_tile_attribution' => apply_filters( 'themify_builder_osm_tile_attribution', '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>' ), |
| 1381 |
'menu_tooltips' => [], |
| 1382 |
'plugin_url'=>rtrim(plugins_url(),'/'), |
| 1383 |
'content_url'=>content_url(), |
| 1384 |
'includes_url' => trailingslashit( includes_url() ) |
| 1385 |
); |
| 1386 |
|
| 1387 |
if (!themify_is_lazyloading()) { |
| 1388 |
$args['lz'] = 1; |
| 1389 |
} else { |
| 1390 |
$args['lazy_threshold'] = themify_get('setting-lazy-threshold', 300, true ); |
| 1391 |
} |
| 1392 |
if (self::$themeVersion !== null) { |
| 1393 |
$themeSrc = THEME_URI . '/js/themify-script.js'; |
| 1394 |
$args['theme_v'] = self::$themeVersion; |
| 1395 |
if (!is_admin()) { |
| 1396 |
self::addPrefetchJs($themeSrc, self::$themeVersion); |
| 1397 |
} |
| 1398 |
} |
| 1399 |
if(is_admin()){ |
| 1400 |
$args['is_admin'] = 1; |
| 1401 |
} |
| 1402 |
else{ |
| 1403 |
$args['emailSub']=__('Check this out!', 'themify'); |
| 1404 |
$args['nop']=__('Check this out!', 'themify'); |
| 1405 |
$args['lightbox']=themify_lightbox_vars_init(); |
| 1406 |
if (is_user_logged_in()) { |
| 1407 |
$args['pg_opt_updt'] = __('Update', 'themify'); |
| 1408 |
if (current_user_can('edit_posts')) { |
| 1409 |
$args['lgi'] = __('Your uploaded image is too large (%w x %hpx). Please resize it below 1600px and re-upload it.', 'themify'); |
| 1410 |
} |
| 1411 |
$post_type = get_post_type_object(get_post_type()); |
| 1412 |
$t = $post_type ? $post_type->labels->singular_name : __('Page', 'themify'); |
| 1413 |
$args['pg_opt_t'] = sprintf('%s %s', $t, __('Options', 'themify')); |
| 1414 |
} |
| 1415 |
|
| 1416 |
if (!empty($wp_scripts->registered['wp-embed'])) { |
| 1417 |
$wp_scripts->done[] = 'wp-embed'; |
| 1418 |
} |
| 1419 |
if (self::$themeVersion !== null) { |
| 1420 |
global $wp_styles, $wp_filter; |
| 1421 |
if (isset($wp_filter['wp_head'], $wp_filter['wp_head']->callbacks[7], $wp_filter['wp_head']->callbacks[7]['print_emoji_detection_script'])) { |
| 1422 |
add_filter('wp_resource_hints', array(__CLASS__, 'remove_emoji_prefetch'), 100, 2); |
| 1423 |
if (themify_check('setting-emoji', true)) { |
| 1424 |
$src = apply_filters('script_loader_src', includes_url('js/wp-emoji-release.min.js'), 'concatemoji'); |
| 1425 |
if (!empty($src)) { |
| 1426 |
ob_start(); |
| 1427 |
print_emoji_detection_script(); |
| 1428 |
self::$localiztion['wp_emoji'] = trim(str_replace(array('<script type="text/javascript">', '<script>', '</script>'), array('', ''), ob_get_clean())); |
| 1429 |
} |
| 1430 |
} |
| 1431 |
else { |
| 1432 |
remove_action('wp_print_styles', 'print_emoji_styles'); |
| 1433 |
} |
| 1434 |
remove_action('wp_head', 'print_emoji_detection_script', 7); |
| 1435 |
remove_filter('embed_head', 'print_emoji_detection_script'); |
| 1436 |
} |
| 1437 |
|
| 1438 |
self::$localiztion['menu_point'] = self::$mobileMenuActive; |
| 1439 |
if (is_singular() && comments_open() && get_option('thread_comments') == 1) { |
| 1440 |
self::$localiztion['commentUrl'] = home_url($wp_scripts->registered['comment-reply']->src); |
| 1441 |
$wp_scripts->done[] = 'comment-reply'; |
| 1442 |
} |
| 1443 |
$wp_scripts->done[] = 'wp-playlist'; |
| 1444 |
} |
| 1445 |
} |
| 1446 |
self::$localiztion += $args; |
| 1447 |
unset($args); |
| 1448 |
if (!self::$localiztion['bing_map_key']) { |
| 1449 |
unset(self::$localiztion['bing_map_key']); |
| 1450 |
} |
| 1451 |
if (!self::$localiztion['map_key']) { |
| 1452 |
unset(self::$localiztion['map_key']); |
| 1453 |
} |
| 1454 |
} |
| 1455 |
} |
| 1456 |
|
| 1457 |
|
| 1458 |
public static function remove_emoji_prefetch(array $urls, string $relation_type):array { |
| 1459 |
if ($relation_type === 'dns-prefetch') { |
| 1460 |
remove_filter('wp_resource_hints', array(__CLASS__, 'remove_emoji_prefetch'), 100); |
| 1461 |
foreach ($urls as $k => $v) { |
| 1462 |
if (strpos('core/emoji/', $v) !== false) { |
| 1463 |
unset($urls[$k]); |
| 1464 |
break; |
| 1465 |
} |
| 1466 |
} |
| 1467 |
} |
| 1468 |
return $urls; |
| 1469 |
} |
| 1470 |
|
| 1471 |
public static function addLocalization($key, $val, $type = false, $object_val = true) { |
| 1472 |
if (self::$localiztion !== null) { |
| 1473 |
if (!isset(self::$localiztion[$key])) { |
| 1474 |
if ($type === false) { |
| 1475 |
self::$localiztion[$key] = $val; |
| 1476 |
} else { |
| 1477 |
self::$localiztion[$key] = array(); |
| 1478 |
if ($type === 'arr') { |
| 1479 |
self::$localiztion[$key][] = $val; |
| 1480 |
} else { |
| 1481 |
self::$localiztion[$key][$val] = $object_val; |
| 1482 |
} |
| 1483 |
} |
| 1484 |
} else { |
| 1485 |
if ($type === false) { |
| 1486 |
self::$localiztion[$key] = $val; |
| 1487 |
} elseif ($type === 'arr') { |
| 1488 |
self::$localiztion[$key][] = $val; |
| 1489 |
} else { |
| 1490 |
self::$localiztion[$key][$val] = $object_val; |
| 1491 |
} |
| 1492 |
} |
| 1493 |
} |
| 1494 |
} |
| 1495 |
|
| 1496 |
public static function getLocalization():array { |
| 1497 |
return self::$localiztion; |
| 1498 |
} |
| 1499 |
|
| 1500 |
public static function loadGalleryCss() { |
| 1501 |
self::add_css('tf_wp_gallery', self::THEMIFY_CSS_MODULES_URI . 'gallery.min.css', null, THEMIFY_VERSION); |
| 1502 |
} |
| 1503 |
|
| 1504 |
public static function preFetchMasonry() { |
| 1505 |
self::addPrefetchJs(THEMIFY_URI . '/js/modules/isotop.js'); |
| 1506 |
} |
| 1507 |
|
| 1508 |
public static function loadFluidMasonryCss($in_footer = false) { |
| 1509 |
if (!isset(self::$css['tf_fluid_masonry'])) { |
| 1510 |
self::preFetchMasonry(); |
| 1511 |
self::add_css('tf_fluid_masonry', self::THEMIFY_CSS_MODULES_URI . 'fluid-masonry.css', null, THEMIFY_VERSION, null, $in_footer); |
| 1512 |
self::addLocalization('done', 'tf_fluid_masonry', true); |
| 1513 |
} |
| 1514 |
} |
| 1515 |
|
| 1516 |
public static function loadAutoTilesCss() { |
| 1517 |
self::loadGridCss('auto_tiles'); |
| 1518 |
} |
| 1519 |
|
| 1520 |
public static function loadinfiniteCss() { |
| 1521 |
if (!isset(self::$css['tf_infinite'])) { |
| 1522 |
self::add_css('tf_infinite', self::THEMIFY_CSS_MODULES_URI . 'infinite.css', null, THEMIFY_VERSION, null, true); |
| 1523 |
self::addLocalization('done', 'tf_infinite', true); |
| 1524 |
} |
| 1525 |
} |
| 1526 |
|
| 1527 |
public static function loadThemeStyleModule(string $file, $media = '',bool $in_footer = false) { |
| 1528 |
self::add_css('tf_theme_' . str_replace('/', '_', $file), self::$THEME_CSS_MODULES_URI . $file . '.css', null, self::$themeVersion, $media, $in_footer); |
| 1529 |
} |
| 1530 |
|
| 1531 |
public static function loadThemeWCStyleModule(string $file, $media = '',bool $in_footer = false) { |
| 1532 |
self::add_css('tf_theme_wc_' . str_replace('/', '_', $file), self::$THEME_WC_CSS_MODULES_URI . $file . '.css', null, self::$themeVersion, $media, $in_footer); |
| 1533 |
} |
| 1534 |
|
| 1535 |
public static function loadGridCss(string $grid, bool $in_footer = false) { |
| 1536 |
if (!isset(self::$css['tf_grid_' . $grid]) && in_array($grid, array('list-post', 'grid2-thumb', 'grid2', 'grid3', 'grid4', 'grid5', 'grid6', 'list-large-image', 'list-thumb-image', 'auto_tiles'), true)) { |
| 1537 |
if ($grid === 'auto_tiles') { |
| 1538 |
self::addPrefetchJs(THEMIFY_URI . '/js/modules/auto-tiles.js'); |
| 1539 |
} |
| 1540 |
self::add_css('tf_grid_' . $grid, THEMIFY_URI . '/css/grids/' . $grid . '.css', null, THEMIFY_VERSION, null, $in_footer); |
| 1541 |
if (isset(self::$theme_css_support[$grid]) && self::$THEME_CSS_MODULES_DIR !== null) { |
| 1542 |
self::add_css('tf_grid_theme_' . $grid, self::$THEME_CSS_MODULES_URI . 'grids/' . $grid . '.css', null, self::$themeVersion, null, $in_footer); |
| 1543 |
self::addLocalization('done', 'tf_grid_theme_' . $grid, true); |
| 1544 |
} |
| 1545 |
self::addLocalization('done', 'tf_grid_' . $grid, true); |
| 1546 |
} |
| 1547 |
} |
| 1548 |
|
| 1549 |
public static function loadGoogleFonts() { |
| 1550 |
if (!defined('THEMIFY_GOOGLE_FONTS') || THEMIFY_GOOGLE_FONTS == true) { |
| 1551 |
$fonts = apply_filters('themify_google_fonts', self::$googleFonts); |
| 1552 |
$res = array(); |
| 1553 |
foreach ($fonts as $font) { |
| 1554 |
if (!empty($font) && preg_match('/^\w/', $font)) { |
| 1555 |
/* fix the delimiter with multiple weight variants, it should use `,` and not `:` |
| 1556 |
reset the delimiter between font name and first variant */ |
| 1557 |
$font = preg_replace('/,/', ':', str_replace(':', ',', $font), 1); |
| 1558 |
$key = explode(':', $font)[0]; |
| 1559 |
if (!isset($res[$key])) { |
| 1560 |
$res[$key] = array(); |
| 1561 |
} |
| 1562 |
if (strpos($font, ',') !== false || strpos($font, ':') !== false) { |
| 1563 |
$font = str_replace(array($key . ':', $key), array('', ''), explode(',', $font)); |
| 1564 |
foreach ($font as $f) { |
| 1565 |
$res[$key][] = $f; |
| 1566 |
/* when loading either italic or non-italic variant, make sure other variant is loaded too */ |
| 1567 |
$res[$key][] = strpos( $f, 'i' ) !== false ? (int) $f : $f . 'i'; |
| 1568 |
} |
| 1569 |
} else { |
| 1570 |
$res[$key][] = '400'; |
| 1571 |
$res[$key][] = '400i'; |
| 1572 |
} |
| 1573 |
} |
| 1574 |
} |
| 1575 |
if (!empty($res)) { |
| 1576 |
$fonts = array(); |
| 1577 |
foreach ($res as $k => $v) { |
| 1578 |
$fonts[] = $k . ':' . implode(',', array_keys( array_flip($v))); |
| 1579 |
} |
| 1580 |
$fonts = implode('%7C', $fonts); |
| 1581 |
$path = '://fonts.googleapis.com/css?family=' . $fonts . '&display=swap'; |
| 1582 |
$_key=Themify_Storage::getHash($fonts); |
| 1583 |
$css =Themify_Storage::get($_key,'tf_fg_css_'); |
| 1584 |
$isNew=false; |
| 1585 |
unset($fonts,$res); |
| 1586 |
if(!$css){ |
| 1587 |
$resp = function_exists('themify_safe_remote_get_with_ssl_fallback') |
| 1588 |
? themify_safe_remote_get_with_ssl_fallback( 'https' . $path, array( |
| 1589 |
'httpversion' => '2', |
| 1590 |
'timeout' => 10, |
| 1591 |
'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36' |
| 1592 |
) ) |
| 1593 |
: wp_remote_get( 'https' . $path, array( |
| 1594 |
'sslverify' => false, |
| 1595 |
'httpversion' => '2', |
| 1596 |
'timeout' => 10, |
| 1597 |
'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36' |
| 1598 |
) ); |
| 1599 |
$css = wp_remote_retrieve_body($resp); |
| 1600 |
/* validate response's content type */ |
| 1601 |
$content_type = wp_remote_retrieve_header( $resp, 'content-type' ); |
| 1602 |
if ( is_wp_error( $css ) || strpos( $content_type, 'text/css' ) === false ) { |
| 1603 |
$css=''; |
| 1604 |
} |
| 1605 |
$isNew=true; |
| 1606 |
unset($resp); |
| 1607 |
} |
| 1608 |
if ($css && strpos($css,'fonts.gstatic')!==false) { |
| 1609 |
$donwload=themify_builder_check('setting-gf','setting-gf'); |
| 1610 |
if($donwload){ |
| 1611 |
$gfFonts=array(); |
| 1612 |
$split=explode('@font-face',$css); |
| 1613 |
$css=''; |
| 1614 |
$maximum=10; |
| 1615 |
$i=0; |
| 1616 |
require_once ABSPATH . 'wp-admin/includes/image.php'; |
| 1617 |
require_once ABSPATH . 'wp-admin/includes/file.php'; |
| 1618 |
require_once ABSPATH . 'wp-admin/includes/media.php'; |
| 1619 |
add_filter('wp_handle_sideload_overrides',array(__CLASS__,'sideload_overrides_google_fonts'),9999,1); |
| 1620 |
foreach($split as $v){ |
| 1621 |
$v=trim($v); |
| 1622 |
if($v!=='' && $v[0]==='{'){ |
| 1623 |
$v=explode(';', str_replace(array('{','}'),'',$v)); |
| 1624 |
$arr=array(); |
| 1625 |
foreach($v as $styles){ |
| 1626 |
$styles=trim($styles); |
| 1627 |
if($styles!==''){ |
| 1628 |
$props=explode(':',str_replace('https:','',$styles)); |
| 1629 |
if(isset($props[0],$props[1])){ |
| 1630 |
$prop=trim($props[0]); |
| 1631 |
$value=trim($props[1]); |
| 1632 |
if($prop==='src'){ |
| 1633 |
$value=explode(' ',$value)[0]; |
| 1634 |
$value=trim(str_replace(array('url',')','('),'',trim($value))); |
| 1635 |
} |
| 1636 |
elseif($prop==='unicode-range'){ |
| 1637 |
$value=str_replace(' ', '', $value); |
| 1638 |
} |
| 1639 |
$arr[$prop]=$value; |
| 1640 |
} |
| 1641 |
elseif(isset($props[0])){ |
| 1642 |
$arr['subset']=trim($props[0]); |
| 1643 |
} |
| 1644 |
} |
| 1645 |
} |
| 1646 |
if(!empty($arr['src'])){ |
| 1647 |
if(strpos($arr['src'],'fonts.gstatic')!==false){ |
| 1648 |
$fkey=$arr['font-family']; |
| 1649 |
if(isset($arr['font-style'])){ |
| 1650 |
$fkey.=$arr['font-style']; |
| 1651 |
} |
| 1652 |
if(isset($arr['font-weight'])){ |
| 1653 |
$fkey.=$arr['font-weight']; |
| 1654 |
} |
| 1655 |
if(isset($arr['unicode-range'])){ |
| 1656 |
$fkey.=$arr['unicode-range']; |
| 1657 |
} |
| 1658 |
$googleFontsUrl='https:'.$arr['src']; |
| 1659 |
$slug=Themify_Storage::getHash($fkey); |
| 1660 |
global $wpdb; |
| 1661 |
$query = "SELECT ID FROM $wpdb->posts WHERE post_type='attachment' AND post_parent=0 AND %s LIMIT 1"; |
| 1662 |
$attachment=$wpdb->get_row(sprintf($query,'post_name="'.esc_sql($slug).'"')); |
| 1663 |
if(empty($attachment)){ |
| 1664 |
$filename=basename($googleFontsUrl); |
| 1665 |
$attachment=$wpdb->get_row( sprintf($query, 'guid LIKE "%'.esc_sql($filename).'"')); |
| 1666 |
} |
| 1667 |
$url=!empty($attachment)?wp_get_attachment_url($attachment->ID):false; |
| 1668 |
if($url!==false && !is_file(get_attached_file($attachment->ID))){ |
| 1669 |
$url=false; |
| 1670 |
wp_delete_attachment($attachment->ID,true); |
| 1671 |
} |
| 1672 |
unset($attachment); |
| 1673 |
if($url===false && $i<$maximum && !Themify_Storage::get($slug)){ |
| 1674 |
Themify_Storage::set($slug,1,MINUTE_IN_SECONDS*2);//set a value to block others threads |
| 1675 |
$tmp = download_url($googleFontsUrl,10,false ); |
| 1676 |
|
| 1677 |
if(!is_wp_error( $tmp )){ |
| 1678 |
$file = array( |
| 1679 |
'size' => filesize($tmp), |
| 1680 |
'name'=> $filename, |
| 1681 |
'error'=>0, |
| 1682 |
'tmp_name' => $tmp |
| 1683 |
); |
| 1684 |
$desc=array(trim(str_replace(array('"',"'"),'',$arr['font-family']))); |
| 1685 |
if(!empty($arr['subset'])){ |
| 1686 |
$desc[]=trim(str_replace(array('/','*'),'',$arr['subset'])); |
| 1687 |
} |
| 1688 |
$desc[]=$arr['font-style']; |
| 1689 |
$desc[]=$arr['font-weight']; |
| 1690 |
$attach_id=media_handle_sideload( $file, 0,$filename,array( |
| 1691 |
'post_mime_type'=>'font/woff2', |
| 1692 |
'post_content'=>'Google Font: '.implode('-',$desc), |
| 1693 |
'post_name'=>$slug |
| 1694 |
) ); |
| 1695 |
if(!is_wp_error($attach_id)){ |
| 1696 |
$url=wp_get_attachment_url($attach_id); |
| 1697 |
$gfFonts[$googleFontsUrl]=$url; |
| 1698 |
} |
| 1699 |
unset($desc,$file,$attach_id); |
| 1700 |
} |
| 1701 |
Themify_Storage::delete($slug); |
| 1702 |
Themify_Filesystem::delete($tmp,'f'); |
| 1703 |
} |
| 1704 |
elseif($url!==false){ |
| 1705 |
$gfFonts[$googleFontsUrl]=$url; |
| 1706 |
} |
| 1707 |
$arr['src']=$url===false?$googleFontsUrl:$url; |
| 1708 |
} |
| 1709 |
$css.='@font-face{'; |
| 1710 |
foreach($arr as $prop=>$vv){ |
| 1711 |
if($prop!=='subset'){ |
| 1712 |
if($prop==='src'){ |
| 1713 |
$vv='url('.$vv.') format("woff2")'; |
| 1714 |
} |
| 1715 |
$css.=$prop.':'.$vv.';'; |
| 1716 |
} |
| 1717 |
} |
| 1718 |
$css.='}'; |
| 1719 |
} |
| 1720 |
} |
| 1721 |
} |
| 1722 |
unset($split); |
| 1723 |
remove_filter('wp_handle_sideload_overrides',array(__CLASS__,'sideload_overrides_google_fonts'),9999); |
| 1724 |
} |
| 1725 |
if(($isNew===true && !$donwload) || !empty($gfFonts)){ |
| 1726 |
if(!empty($gfFonts)){ |
| 1727 |
$tmp =Themify_Storage::get($_key,'tf_fg_css_');//maybe another thread has changed it |
| 1728 |
if($tmp){ |
| 1729 |
$css=strtr($tmp,$gfFonts); |
| 1730 |
} |
| 1731 |
unset($gfFonts,$tmp); |
| 1732 |
} |
| 1733 |
if($css!==''){ |
| 1734 |
if($isNew===true){ |
| 1735 |
$css = str_replace(array("\r\n","\n","\r","\t"),'',$css); |
| 1736 |
$css = preg_replace('!\s+!',' ',$css); |
| 1737 |
$css = str_replace(array(' {',' }','{ ','; ',': ',', '),array('{','}','{',';',':',','),$css); |
| 1738 |
$css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css); |
| 1739 |
} |
| 1740 |
$css=str_replace(array('font-style:normal;','font-weight:400;'),'',$css); |
| 1741 |
Themify_Storage::set($_key, $css, MONTH_IN_SECONDS * 6,'tf_fg_css_'); |
| 1742 |
} |
| 1743 |
else{ |
| 1744 |
Themify_Storage::delete($_key,'tf_fg_css_'); |
| 1745 |
} |
| 1746 |
} |
| 1747 |
} |
| 1748 |
if(!$css){ |
| 1749 |
$path = ( is_ssl() ? 'https' : 'http' ) . $path; |
| 1750 |
// Use font-display=optional to prevent FOUT: browser uses fallback font rather than |
| 1751 |
// showing a flash if the font is not cached. Swap &display=swap for &display=optional. |
| 1752 |
$path_optional = str_replace( '&display=swap', '&display=optional', $path ); |
| 1753 |
$preconnect = '<link rel="preconnect" href="https://fonts.googleapis.com">' |
| 1754 |
. '<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>'; |
| 1755 |
$css = $preconnect |
| 1756 |
. '<link rel="preload" fetchpriority="high" as="style" href="' . $path_optional . '">' |
| 1757 |
. '<link fetchpriority="high" id="themify-google-fonts-css" rel="stylesheet" href="' . $path_optional . '">'; |
| 1758 |
} |
| 1759 |
else{ |
| 1760 |
$css='<style id="tf_gf_fonts_style">'.$css.'</style>'; |
| 1761 |
} |
| 1762 |
return $css; |
| 1763 |
} |
| 1764 |
} |
| 1765 |
return null; |
| 1766 |
} |
| 1767 |
|
| 1768 |
public static function sideload_overrides_google_fonts(array $overrides):array{ |
| 1769 |
$overrides['test_size']=$overrides['test_type']=false; |
| 1770 |
return $overrides; |
| 1771 |
} |
| 1772 |
|
| 1773 |
public static function addGoogleFont(array $fonts) { |
| 1774 |
foreach ($fonts as $v) { |
| 1775 |
if(!in_array($v,self::$googleFonts,true)){ |
| 1776 |
self::$googleFonts[] = $v; |
| 1777 |
} |
| 1778 |
} |
| 1779 |
} |
| 1780 |
|
| 1781 |
public static function addMobileMenuCss(string $handler, string $src) { |
| 1782 |
if (!isset(self::$css['mobile_concate'][$handler]) && !isset(self::$done[$src])) { |
| 1783 |
self::$done[$src] = true; |
| 1784 |
self::$css['mobile_concate'][$handler] = $src; |
| 1785 |
} |
| 1786 |
} |
| 1787 |
|
| 1788 |
public static function preLoadAnimtion(bool $only_css = false) { |
| 1789 |
static $is = false; |
| 1790 |
if ($is === false) { |
| 1791 |
self::addPreLoadCss(self::THEMIFY_CSS_MODULES_URI . 'animate.min.css'); |
| 1792 |
if ($only_css === false) { |
| 1793 |
$is = true; |
| 1794 |
self::addPreLoadJs(THEMIFY_URI . '/js/modules/animate.js'); |
| 1795 |
} |
| 1796 |
} |
| 1797 |
} |
| 1798 |
|
| 1799 |
public static function preLoadSwiperJs(string $type = 'prefetch',string $only = 'all') { |
| 1800 |
$url = THEMIFY_URI . '/js/modules/themify-carousel.js'; |
| 1801 |
$sw_url = THEMIFY_URI . '/js/modules/swiper/swiper.min.js'; |
| 1802 |
$sw_css = self::THEMIFY_CSS_MODULES_URI . 'swiper/swiper.css'; |
| 1803 |
if ($type === 'prefetch') { |
| 1804 |
if ($only === 'all' || $only === 'css') { |
| 1805 |
self::addPrefetchCss($sw_css); |
| 1806 |
} |
| 1807 |
if ($only === 'all' || $only === 'js') { |
| 1808 |
self::addPrefetchJs($url); |
| 1809 |
self::addPrefetchJs($sw_url); |
| 1810 |
} |
| 1811 |
} else { |
| 1812 |
if ($only === 'all' || $only === 'css') { |
| 1813 |
self::addPreLoadCss($sw_css); |
| 1814 |
} |
| 1815 |
if ($only === 'all' || $only === 'js') { |
| 1816 |
self::addPreLoadJs($url); |
| 1817 |
self::addPreLoadJs($sw_url); |
| 1818 |
} |
| 1819 |
} |
| 1820 |
} |
| 1821 |
|
| 1822 |
public static function preFetchFixedHeaderJs(string $type = 'prefetch') { |
| 1823 |
$url = THEMIFY_URI . '/js/modules/fixedheader.js'; |
| 1824 |
if ($type === 'prefetch') { |
| 1825 |
self::addPrefetchJs($url); |
| 1826 |
} else { |
| 1827 |
self::addPreLoadJs($url); |
| 1828 |
} |
| 1829 |
} |
| 1830 |
|
| 1831 |
public static function preFetchSideMenuJs(string $type = 'prefetch') { |
| 1832 |
$url = THEMIFY_URI . '/js/modules/themify-sidemenu.js'; |
| 1833 |
if ($type === 'prefetch') { |
| 1834 |
self::addPrefetchJs($url); |
| 1835 |
} else { |
| 1836 |
self::addPreLoadJs($url); |
| 1837 |
} |
| 1838 |
} |
| 1839 |
|
| 1840 |
public static function preFetchAnimtion(bool $only_css = false) { |
| 1841 |
static $is = false; |
| 1842 |
if ($is === false) { |
| 1843 |
self::addPrefetchCss(self::THEMIFY_CSS_MODULES_URI . 'animate.min.css'); |
| 1844 |
if ($only_css === false) { |
| 1845 |
$is = true; |
| 1846 |
self::addPrefetchJs(THEMIFY_URI . '/js/modules/animate.js'); |
| 1847 |
} |
| 1848 |
} |
| 1849 |
} |
| 1850 |
|
| 1851 |
public static function clearConcateCss($blog_id = false) { |
| 1852 |
$cache_type = $blog_id === 'all' && is_multisite()? 'all' : 'blog'; |
| 1853 |
$dir = self::getCurrentVersionFolder(($cache_type === 'all' ? false : $blog_id)); |
| 1854 |
clearstatcache(); |
| 1855 |
if ($cache_type === 'all') { |
| 1856 |
$concate_dir = '/themify-concate/'; |
| 1857 |
$dir=dirname(str_replace($concate_dir, '', $dir)); |
| 1858 |
if(strpos($dir,'/blogs.dir/')!==false){ |
| 1859 |
$dir=dirname($dir); |
| 1860 |
$concate_dir='/files'.$concate_dir; |
| 1861 |
} |
| 1862 |
$dir = rtrim($dir, '/') . '/'; |
| 1863 |
if (Themify_Filesystem::is_dir($dir) && ($handle = opendir($dir))) { |
| 1864 |
set_time_limit(0); |
| 1865 |
while (false !== ($f = readdir($handle))) { |
| 1866 |
if ($f !== '.' && $f !== '..') { |
| 1867 |
$f = $dir . $f . $concate_dir; |
| 1868 |
if (Themify_Filesystem::is_dir($f)) { |
| 1869 |
self::markAsDeleteCssFile($f); |
| 1870 |
} |
| 1871 |
} |
| 1872 |
} |
| 1873 |
closedir($handle); |
| 1874 |
} |
| 1875 |
} else { |
| 1876 |
self::markAsDeleteCssFile($dir); |
| 1877 |
} |
| 1878 |
TFCache::remove_cache($cache_type, false, $blog_id); |
| 1879 |
TFCache::clear_3rd_plugins_cache(); |
| 1880 |
} |
| 1881 |
|
| 1882 |
private static function markAsDeleteCssFile(string $dir) { |
| 1883 |
if (is_dir($dir) && ($handle = opendir($dir))) { |
| 1884 |
$dir = rtrim($dir, '/') . '/'; |
| 1885 |
while (false !== ($f = readdir($handle))) { |
| 1886 |
if ($f !== '.' && $f !== '..') { |
| 1887 |
if (is_dir($dir . $f)) { |
| 1888 |
self::markAsDeleteCssFile($dir . $f); |
| 1889 |
} else { |
| 1890 |
$ext = pathinfo($f, PATHINFO_EXTENSION); |
| 1891 |
$f = $dir . $f . 'del'; |
| 1892 |
if ($ext !== 'cssdel' && strpos($ext, 'cssdel') === false && !Themify_Filesystem::is_file($f)) { |
| 1893 |
$fd = fopen($f, 'w'); |
| 1894 |
fclose($fd); |
| 1895 |
} |
| 1896 |
} |
| 1897 |
} |
| 1898 |
} |
| 1899 |
closedir($handle); |
| 1900 |
} |
| 1901 |
} |
| 1902 |
|
| 1903 |
public static function wp_media_playlist(string $html,array $attr, $instance):string { |
| 1904 |
if (!isset($attr['type']) || $attr['type'] === 'audio') { |
| 1905 |
return self::audio_playlist($attr); |
| 1906 |
} |
| 1907 |
if($attr['type']==='video' && themify_is_ajax()){ |
| 1908 |
remove_filter('post_playlist', array(__CLASS__, 'wp_media_playlist'), 100); |
| 1909 |
$html= themify_make_lazy(wp_playlist_shortcode($attr)); |
| 1910 |
add_filter('post_playlist', array(__CLASS__, 'wp_media_playlist'), 100,3); |
| 1911 |
} |
| 1912 |
return $html; |
| 1913 |
} |
| 1914 |
|
| 1915 |
public static function audio_playlist(array $attr):string { |
| 1916 |
|
| 1917 |
$post = get_post(); |
| 1918 |
$atts = shortcode_atts( |
| 1919 |
array( |
| 1920 |
'order' => 'ASC', |
| 1921 |
'orderby' => 'menu_order ID', |
| 1922 |
'id' => $post ? $post->ID : 0, |
| 1923 |
'include' => '', |
| 1924 |
'exclude' => '', |
| 1925 |
'tracklist' => true, |
| 1926 |
'tracknumbers' => true, |
| 1927 |
'images' => true, |
| 1928 |
'artists' => true |
| 1929 |
), |
| 1930 |
$attr, |
| 1931 |
'playlist' |
| 1932 |
); |
| 1933 |
$atts['type'] = 'audio'; |
| 1934 |
unset($post); |
| 1935 |
$showImages = !empty($atts['images']); |
| 1936 |
if (empty($attr['tracks'])) { |
| 1937 |
$id = (int) $atts['id']; |
| 1938 |
$args = array( |
| 1939 |
'post_status' => 'inherit', |
| 1940 |
'post_type' => 'attachment', |
| 1941 |
'post_mime_type' => $atts['type'], |
| 1942 |
'order' => $atts['order'], |
| 1943 |
'orderby' => $atts['orderby'], |
| 1944 |
'no_found_rows' => true |
| 1945 |
); |
| 1946 |
|
| 1947 |
if (!empty($atts['include'])) { |
| 1948 |
$args['include'] = $atts['include']; |
| 1949 |
$_attachments = get_posts($args); |
| 1950 |
$attachments = array(); |
| 1951 |
foreach ($_attachments as $val) { |
| 1952 |
$attachments[$val->ID] = $val; |
| 1953 |
} |
| 1954 |
unset($_attachments); |
| 1955 |
} else { |
| 1956 |
$args['post_parent'] = $id; |
| 1957 |
if (!empty($atts['exclude'])) { |
| 1958 |
$args['exclude'] = $atts['exclude']; |
| 1959 |
} |
| 1960 |
$attachments = get_children($args); |
| 1961 |
} |
| 1962 |
unset($args); |
| 1963 |
if (empty($attachments)) { |
| 1964 |
return '<div></div>'; |
| 1965 |
} |
| 1966 |
|
| 1967 |
if (is_feed()) { |
| 1968 |
$output = "\n"; |
| 1969 |
foreach ($attachments as $att_id => $attachment) { |
| 1970 |
$output .= wp_get_attachment_link($att_id) . "\n"; |
| 1971 |
} |
| 1972 |
return $output; |
| 1973 |
} |
| 1974 |
|
| 1975 |
$tracks = array(); |
| 1976 |
$mime_types = wp_get_mime_types(); |
| 1977 |
$metaArr = array('artist', 'album', 'length_formatted'); |
| 1978 |
foreach ($attachments as $attachment) { |
| 1979 |
$url = wp_get_attachment_url($attachment->ID); |
| 1980 |
$ftype = wp_check_filetype($url, $mime_types); |
| 1981 |
$track = array( |
| 1982 |
'src' => trim($url), |
| 1983 |
'type' => $ftype['type'], |
| 1984 |
'title' => $attachment->post_title, |
| 1985 |
'caption' => $attachment->post_excerpt |
| 1986 |
); |
| 1987 |
$meta = wp_get_attachment_metadata($attachment->ID); |
| 1988 |
if (!empty($meta)) { |
| 1989 |
$track['meta'] = array(); |
| 1990 |
foreach ($metaArr as $m) { |
| 1991 |
if (!empty($meta[$m])) { |
| 1992 |
$track['meta'][$m] = $meta[$m]; |
| 1993 |
} |
| 1994 |
} |
| 1995 |
} |
| 1996 |
if ($showImages === true) { |
| 1997 |
$thumb_id = get_post_thumbnail_id($attachment->ID); |
| 1998 |
if (!empty($thumb_id)) { |
| 1999 |
list( $src, $width, $height ) = wp_get_attachment_image_src($thumb_id, 'thumbnail'); |
| 2000 |
} else { |
| 2001 |
$src = wp_mime_type_icon($attachment->ID); |
| 2002 |
$width = 48; |
| 2003 |
$height = 64; |
| 2004 |
} |
| 2005 |
$track['thumb'] = array('src' => $src, 'width' => $width, 'height' => $height); |
| 2006 |
} |
| 2007 |
|
| 2008 |
$tracks[] = $track; |
| 2009 |
} |
| 2010 |
$mime_types = $metaArr = $attachments = null; |
| 2011 |
} else { |
| 2012 |
$tracks = $attr['tracks']; |
| 2013 |
} |
| 2014 |
$data = array( |
| 2015 |
'type' => 'audio', |
| 2016 |
'tracklist' => $atts['tracklist'] ? 1 : 0, |
| 2017 |
'tracknumbers' => $atts['tracknumbers'] ? 1 : 0, |
| 2018 |
'images' => $showImages === true ? 1 : 0, |
| 2019 |
'artists' => $atts['artists'] ? 1 : 0, |
| 2020 |
'tracks' => $tracks |
| 2021 |
); |
| 2022 |
$autoplay = !empty($attr['autoplay']) ? ' data-autoplay="1"' : ''; |
| 2023 |
$loop = !empty($attr['loop']) ? ' data-loop' : ''; |
| 2024 |
$loop .= !empty($attr['muted']) ? ' muted' : ''; |
| 2025 |
$tracks = $atts = null; |
| 2026 |
$output = '<div class="wp-audio-playlist">' . themify_make_lazy('<audio controls="controls" preload="none"' . $autoplay . $loop . '></audio>'); |
| 2027 |
$output .= '<script type="application/json" class="tf-playlist-script">' . wp_json_encode($data) . '</script></div>'; |
| 2028 |
return $output; |
| 2029 |
} |
| 2030 |
|
| 2031 |
public static function widget_css($instance, $thiz, $args) { |
| 2032 |
$id = $thiz->id_base; |
| 2033 |
if ($id) { |
| 2034 |
if ($id === 'themify-most-commented') { |
| 2035 |
$id = 'themify-feature-posts'; |
| 2036 |
} |
| 2037 |
elseif ($id === 'themify-social-links') { |
| 2038 |
self::add_css('tf_theme_social_links', self::THEMIFY_CSS_MODULES_URI . 'social-links.css', null, THEMIFY_VERSION); |
| 2039 |
self::addLocalization('done', 'tf_theme_social_links', true); |
| 2040 |
} |
| 2041 |
if(isset(self::$theme_css_support['widget_'.$id])){ |
| 2042 |
$k = 'tf_theme_widget_' . str_replace('-', '_', $id); |
| 2043 |
if (!isset(self::$css[$k])) { |
| 2044 |
self::add_css($k, self::$THEME_CSS_MODULES_URI . 'widgets/' . $id . '.css', null, self::$themeVersion); |
| 2045 |
self::addLocalization('done', $k, true); |
| 2046 |
} |
| 2047 |
} |
| 2048 |
} |
| 2049 |
return $instance; |
| 2050 |
} |
| 2051 |
|
| 2052 |
public static function allow_lazy_protocols(array $protocols):array { |
| 2053 |
$protocols[] = 'data'; |
| 2054 |
return $protocols; |
| 2055 |
} |
| 2056 |
|
| 2057 |
public static function audio_shortcode(string $html, array $attr, $media, $post_id, $library):string { |
| 2058 |
return $library === 'tf_lazy' ? themify_make_lazy($html) : $html; |
| 2059 |
} |
| 2060 |
|
| 2061 |
public static function embed(string $cached_html, $url, $attr, $post_id):string { |
| 2062 |
return str_replace('data-secret','data-lazy data-secret',$cached_html); |
| 2063 |
} |
| 2064 |
|
| 2065 |
public static function disable_playlist_template($type){ |
| 2066 |
remove_action( 'wp_playlist_scripts', 'wp_playlist_scripts' ); |
| 2067 |
} |
| 2068 |
|
| 2069 |
public static function video_shortcode(string $html,array $attr, string $content, $instance):string { |
| 2070 |
if (apply_filters('wp_video_shortcode_library', 'mediaelement') === 'tf_lazy') { |
| 2071 |
$html_atts = array( |
| 2072 |
'preload' => 'none', |
| 2073 |
'playsinline'=>1, |
| 2074 |
'webkit-playsinline'=>1 |
| 2075 |
); |
| 2076 |
if (!empty($attr['src'])) { |
| 2077 |
$video_url = parse_url($attr['src']); |
| 2078 |
if (isset($video_url['host']) && ($video_url['host'] === 'www.youtube.com' || $video_url['host'] === 'youtube.com' || $video_url['host'] === 'youtu.be' || $video_url['host'] === 'www.vimeo.com' || $video_url['host'] === 'vimeo.com' || $video_url['host'] === 'player.vimeo.com')) { |
| 2079 |
return $html; |
| 2080 |
} |
| 2081 |
unset($video_url); |
| 2082 |
$html_atts['src'] = esc_url($attr['src']); |
| 2083 |
} |
| 2084 |
if(!empty($attr['disable_lazy'])){ |
| 2085 |
$html_atts['data-skip'] = 1; |
| 2086 |
} |
| 2087 |
if (!empty($attr['id'])) { |
| 2088 |
$html_atts['id'] = $attr['id']; |
| 2089 |
} |
| 2090 |
if (!empty($attr['loop'])) { |
| 2091 |
$html_atts['loop'] = 1; |
| 2092 |
} |
| 2093 |
if (!empty($attr['autoplay'])) { |
| 2094 |
$html_atts['data-autoplay'] = 1; |
| 2095 |
} |
| 2096 |
if (!empty($attr['class'])) { |
| 2097 |
$cl = trim(str_replace('wp-video-shortcode', '', $attr['class'])); |
| 2098 |
if ($cl !== '') { |
| 2099 |
$html_atts['class'] = $cl; |
| 2100 |
} |
| 2101 |
} |
| 2102 |
if (!empty($attr['width'])) { |
| 2103 |
$html_atts['width'] = $attr['width']; |
| 2104 |
} |
| 2105 |
if (!empty($attr['height'])) { |
| 2106 |
$html_atts['height'] = $attr['height']; |
| 2107 |
} |
| 2108 |
if (!empty($attr['poster'])) { |
| 2109 |
$html_atts['data-poster'] = esc_url($attr['poster']); |
| 2110 |
} |
| 2111 |
$muted = isset( $attr['muted'] ) ? wp_validate_boolean( $attr['muted'] ) : false; |
| 2112 |
if ( $muted ) { |
| 2113 |
$html_atts['muted'] = 1; |
| 2114 |
} |
| 2115 |
$source=''; |
| 2116 |
$default_types = wp_get_video_extensions(); |
| 2117 |
$default_types[] = 'mov'; |
| 2118 |
$mimes=array(); |
| 2119 |
foreach ( $default_types as $ext ) { |
| 2120 |
if (isset($attr[$ext])) { |
| 2121 |
if(empty($mimes)){ |
| 2122 |
$mimes = wp_get_mime_types(); |
| 2123 |
} |
| 2124 |
if(!isset($html_atts['src']) || !isset($mimes[$ext])){ |
| 2125 |
$type=wp_check_filetype($attr[$ext], $mimes); |
| 2126 |
} |
| 2127 |
if (isset($mimes[$ext])) { |
| 2128 |
$m = $mimes[$ext]; |
| 2129 |
} |
| 2130 |
else { |
| 2131 |
$m = isset($type['type'])?$type['type']:null; |
| 2132 |
} |
| 2133 |
if ($m) { |
| 2134 |
$source .= sprintf('<source type="%s" src="%s"/>', $m, esc_url($attr[$ext])); |
| 2135 |
} |
| 2136 |
if (!isset($html_atts['src']) && isset($type['ext']) && strtolower( $type['ext'] ) === $ext ) { |
| 2137 |
$html_atts['src'] = $attr[ $ext ]; |
| 2138 |
} |
| 2139 |
} |
| 2140 |
} |
| 2141 |
if (!empty( $html_atts['src'] ) ) { |
| 2142 |
unset($mimes,$default_types); |
| 2143 |
if(!isset($html_atts['width']) || !isset($html_atts['height'])){ |
| 2144 |
/* find video by their media type attribute */ |
| 2145 |
$size=themify_get_video_size($html_atts['src']); |
| 2146 |
if($size!==null){ |
| 2147 |
if(!isset($html_atts['width']) && $size['w']!==''){ |
| 2148 |
$html_atts['width'] = $size['w']; |
| 2149 |
} |
| 2150 |
if(!isset($html_atts['height'])&& $size['h']!==''){ |
| 2151 |
$html_atts['height'] = $size['h']; |
| 2152 |
} |
| 2153 |
} |
| 2154 |
} |
| 2155 |
if(isset($html_atts['width'],$html_atts['height']) && $html_atts['width']>0 && $html_atts['height']>0){ |
| 2156 |
$html_atts['style']='aspect-ratio:'.($html_atts['width']/$html_atts['height']); |
| 2157 |
} |
| 2158 |
$html = '<video ' . themify_get_element_attributes($html_atts) . '>'.$source. '</video>' . trim($content); |
| 2159 |
} |
| 2160 |
} |
| 2161 |
return $html; |
| 2162 |
} |
| 2163 |
|
| 2164 |
public static function media_shortcode_library($library):string { |
| 2165 |
return 'tf_lazy'; |
| 2166 |
} |
| 2167 |
|
| 2168 |
public static function load_loop_css($class, $post_type, $layout, $type, $moduleArgs = array(), $slug = false) { |
| 2169 |
global $themify; |
| 2170 |
if (self::$themeVersion !== null) {//only in themify theme |
| 2171 |
if (!empty($themify->post_layout_type) && $themify->post_layout_type !== 'default') { |
| 2172 |
$class[] = $themify->post_layout_type; |
| 2173 |
} |
| 2174 |
if ($post_type === 'product' && themify_is_woocommerce_active() && $type !== 'builder') { |
| 2175 |
global $woocommerce_loop; |
| 2176 |
if ((isset($woocommerce_loop['name']) && in_array( $woocommerce_loop['name'], [ 'up-sells', 'cross-sells', 'related' ], true ) ) || wc_get_loop_prop('is_shortcode')) { |
| 2177 |
$layout = (int) wc_get_loop_prop('columns'); |
| 2178 |
$index = array_search('columns-' . $layout, $class, true); |
| 2179 |
if ($index !== false) { |
| 2180 |
unset($class[$index]); |
| 2181 |
} |
| 2182 |
$index = array_search('masonry', $class, true); |
| 2183 |
if ($index !== false) { |
| 2184 |
unset($class[$index]); |
| 2185 |
} |
| 2186 |
$index = array_search('infinite', $class, true); |
| 2187 |
if ($index !== false) { |
| 2188 |
unset($class[$index]); |
| 2189 |
} |
| 2190 |
$index = array_search('no-gutter', $class, true); |
| 2191 |
if ($index !== false) { |
| 2192 |
unset($class[$index]); |
| 2193 |
} |
| 2194 |
$layout = $layout === 1 ? 'list-post' : 'grid' . $layout; |
| 2195 |
} |
| 2196 |
} |
| 2197 |
} |
| 2198 |
self::loadGridCss($layout); |
| 2199 |
if (in_array('masonry', $class, true)) { |
| 2200 |
if (!in_array($layout, array('slider', 'auto_tiles'), true) || (!empty($themify->post_filter) && $themify->post_filter !== 'no')) { |
| 2201 |
$class[] = 'tf_rel'; |
| 2202 |
if (in_array('tf_fluid', $class, true)) { |
| 2203 |
self::loadFluidMasonryCss(); |
| 2204 |
} else { |
| 2205 |
self::preFetchMasonry(); |
| 2206 |
} |
| 2207 |
} else { |
| 2208 |
$index = array_search('masonry', $class, true); |
| 2209 |
if ($index !== false) { |
| 2210 |
unset($class[$index]); |
| 2211 |
} |
| 2212 |
} |
| 2213 |
} |
| 2214 |
$class[] = $layout; |
| 2215 |
return array_keys( array_flip($class)); |
| 2216 |
} |
| 2217 |
|
| 2218 |
public static function get_css():array { |
| 2219 |
return self::$css; |
| 2220 |
} |
| 2221 |
|
| 2222 |
/** |
| 2223 |
* Check if the file belongs to themify(plugin, FW, theme and etc.) |
| 2224 |
* |
| 2225 |
* return boolean |
| 2226 |
*/ |
| 2227 |
public static function is_themify_file(string $file, string $handler):bool { |
| 2228 |
return strpos($file, 'maps.google.com') === false && (strpos($handler, 'themify') !== false || strpos($handler, 'builder-') === 0 || strpos($handler, 'tf-') === 0 || strpos($handler, 'tb_builder') === 0|| strpos($handler, 'tbp') === 0 || (defined('THEME_URI') && strpos($file, THEME_URI) !== false) || preg_match('/themify[\.\-][^\/]*\.js/', $file));// match "themify.*.js" or "themify-*.js" |
| 2229 |
} |
| 2230 |
|
| 2231 |
public static function loadGuttenbergCss($parsed_block, $source_block) { |
| 2232 |
remove_filter('render_block_data', array(__CLASS__, 'loadGuttenbergCss'), PHP_INT_MAX); |
| 2233 |
if (!empty(self::$guttenbergCss)) { |
| 2234 |
global $wp_styles, $wp_version; |
| 2235 |
foreach (self::$guttenbergCss as $k => $src) { |
| 2236 |
if (isset($wp_styles->registered[$k])) { |
| 2237 |
$ver = $wp_styles->registered[$k]->ver; |
| 2238 |
if (empty($ver)) { |
| 2239 |
$ver = $wp_version; |
| 2240 |
} |
| 2241 |
if (strpos($src, 'http') === false) { |
| 2242 |
$src = get_site_url(null, $src); |
| 2243 |
} |
| 2244 |
self::add_css($k, $src, $wp_styles->registered[$k]->deps, $ver, $wp_styles->registered[$k]->args); |
| 2245 |
} |
| 2246 |
} |
| 2247 |
self::$guttenbergCss = null; |
| 2248 |
} |
| 2249 |
return $parsed_block; |
| 2250 |
} |
| 2251 |
|
| 2252 |
public static function getCurrentVersionFolder($blog_id = false):string { |
| 2253 |
global $wp_version; |
| 2254 |
$object = wp_get_theme(); |
| 2255 |
$globalKey = THEMIFY_VERSION . $wp_version . $object->get('Name'); |
| 2256 |
$globalKey .= self::$themeVersion !== null ? self::$themeVersion : $object->get('Version'); |
| 2257 |
if (themify_is_woocommerce_active()) { |
| 2258 |
if (defined('WC_VERSION')) { |
| 2259 |
$globalKey .= WC_VERSION; |
| 2260 |
} elseif (function_exists('WC')) { |
| 2261 |
$wc = WC(); |
| 2262 |
if (is_object($wc) && !empty($wc->version)) { |
| 2263 |
$globalKey .= $wc->version; |
| 2264 |
} |
| 2265 |
} |
| 2266 |
} |
| 2267 |
$globalKey = (string) crc32($globalKey); |
| 2268 |
return themify_upload_dir('basedir') . '/themify-concate/' . $globalKey . '/'; |
| 2269 |
} |
| 2270 |
|
| 2271 |
/** Add schedule four_week |
| 2272 |
* array $schedules |
| 2273 |
* |
| 2274 |
* return array |
| 2275 |
*/ |
| 2276 |
public static function cron_schedules(array $schedules):array { |
| 2277 |
$schedules['four_week'] = array( |
| 2278 |
'interval' => WEEK_IN_SECONDS * 4, |
| 2279 |
'display' => '4 weeks' |
| 2280 |
); |
| 2281 |
return $schedules; |
| 2282 |
} |
| 2283 |
|
| 2284 |
/** Cron job to remove old concate css files and customizer css files |
| 2285 |
* return void |
| 2286 |
*/ |
| 2287 |
public static function cron() { |
| 2288 |
|
| 2289 |
$path = pathinfo(self::getCurrentVersionFolder()); |
| 2290 |
$dir = $path['dirname'] . '/'; |
| 2291 |
if(!class_exists('Themify_Filesystem',false)){ |
| 2292 |
require_once THEMIFY_DIR . '/class-themify-filesystem.php'; |
| 2293 |
} |
| 2294 |
clearstatcache(); |
| 2295 |
if (Themify_Filesystem::is_dir($dir) && ($handle = opendir($dir))) { |
| 2296 |
$found=false; |
| 2297 |
$currentFolder = $path['filename']; |
| 2298 |
$globalKey = '-' . $currentFolder . '-'; //Need for Backward Compatibility, can be removed 11.05.2021 |
| 2299 |
while (false !== ($f = readdir($handle))) { |
| 2300 |
if ($f !== '.' && $f !== '..' && $currentFolder !== $f && strpos($f, $globalKey, 5) === false) { |
| 2301 |
Themify_Filesystem::delete($dir . $f); |
| 2302 |
$found=true; |
| 2303 |
} |
| 2304 |
} |
| 2305 |
closedir($handle); |
| 2306 |
unset($currentFolder, $dir, $globalKey); |
| 2307 |
if($found===true){ |
| 2308 |
TFCache::clear_3rd_plugins_cache(); |
| 2309 |
TFCache::remove_cache(); |
| 2310 |
} |
| 2311 |
} |
| 2312 |
unset($path); |
| 2313 |
$upload_dir = themify_upload_dir('basedir').'/'; |
| 2314 |
$deperecated=$upload_dir.'tf_images_sizes/'; |
| 2315 |
if(Themify_Filesystem::is_dir($deperecated)){ |
| 2316 |
Themify_Filesystem::delete($deperecated); |
| 2317 |
} |
| 2318 |
$deperecated=$upload_dir.'tf_image_ids/'; |
| 2319 |
if(Themify_Filesystem::is_dir($deperecated)){ |
| 2320 |
Themify_Filesystem::delete($deperecated); |
| 2321 |
} |
| 2322 |
if (self::$themeVersion !== null && Themify_Filesystem::is_dir($upload_dir) && ($handle = opendir($upload_dir))) {//remove old customizer css |
| 2323 |
$cssFile = THEMIFY_VERSION . '-' . self::$themeVersion; |
| 2324 |
while (false !== ($f = readdir($handle))) { |
| 2325 |
if ($f !== '.' && $f !== '..' && strpos($f, 'themify-customizer-') === 0 && strpos($f, $cssFile, 10) === false) { |
| 2326 |
Themify_Filesystem::delete($upload_dir . $f,'f'); |
| 2327 |
} |
| 2328 |
} |
| 2329 |
closedir($handle); |
| 2330 |
} |
| 2331 |
Themify_Storage::cleanDb(); |
| 2332 |
} |
| 2333 |
|
| 2334 |
private static function getPreLoad():string { |
| 2335 |
$return = ''; |
| 2336 |
if(!empty(self::$preLoadMedia)){ |
| 2337 |
foreach (self::$preLoadMedia as $src => $arr) { |
| 2338 |
$type=$arr['t']; |
| 2339 |
$rel=$arr['r']; |
| 2340 |
// Preload only above-the-fold assets |
| 2341 |
if($type==='image' && $rel==='preload'){ |
| 2342 |
// Keep preload only when explicitly marked high priority. |
| 2343 |
if(!isset($arr['i']) || $arr['i']!=='high'){ |
| 2344 |
$rel='prefetch'; |
| 2345 |
unset($arr['i']); |
| 2346 |
} |
| 2347 |
} |
| 2348 |
elseif($type==='style' && $rel==='preload' && isset($arr['i']) && $arr['i']==='low'){ |
| 2349 |
$rel='prefetch'; |
| 2350 |
unset($arr['i']); |
| 2351 |
} |
| 2352 |
|
| 2353 |
$type=$arr['t']; |
| 2354 |
if ($type === 'style' && isset(self::$css[$src])) { |
| 2355 |
continue; |
| 2356 |
} |
| 2357 |
if (isset($arr['v'])) { |
| 2358 |
$src = $src . '?ver=' . $arr['v']; |
| 2359 |
} |
| 2360 |
$extra=''; |
| 2361 |
if($type === 'font'){ |
| 2362 |
$extra=' type="font/' . strtok(pathinfo($src, PATHINFO_EXTENSION), '?') . '" crossorigin'; |
| 2363 |
} |
| 2364 |
elseif($type === 'image' && isset($arr['srcset'])){ |
| 2365 |
$extra=' imagesrcset="'.$arr['srcset'].'" imagesizes="'.$arr['sizes'].'"'; |
| 2366 |
} |
| 2367 |
elseif($type=== 'json'){ |
| 2368 |
$extra=' type="application/json" crossorigin="anonymous"'; |
| 2369 |
$type='fetch'; |
| 2370 |
} |
| 2371 |
if($rel==='prefetch'){ |
| 2372 |
// For prefetch, omit `as` to avoid incorrect type signalling and warnings. |
| 2373 |
$return .= sprintf('<link rel="prefetch" href="%s">', $src); |
| 2374 |
} |
| 2375 |
else{ |
| 2376 |
$return .= sprintf('<link rel="%s" href="%s" as="%s"%s%s>', |
| 2377 |
$rel, |
| 2378 |
$src, |
| 2379 |
$type, |
| 2380 |
$extra, |
| 2381 |
(isset($arr['i']) ? ' fetchpriority="' . $arr['i'] . '"' : '') |
| 2382 |
); |
| 2383 |
} |
| 2384 |
} |
| 2385 |
} |
| 2386 |
return $return; |
| 2387 |
} |
| 2388 |
|
| 2389 |
public static function get_version($url, $ver) { |
| 2390 |
return $ver; |
| 2391 |
} |
| 2392 |
|
| 2393 |
public static function load_search_form_css() { |
| 2394 |
remove_action('pre_get_search_form', array(__CLASS__, 'load_search_form_css'), 9); |
| 2395 |
self::add_css('tf_search_form', self::THEMIFY_CSS_MODULES_URI . 'search-form.css', null, THEMIFY_VERSION); |
| 2396 |
self::addLocalization('done', 'tf_search_form', true); |
| 2397 |
} |
| 2398 |
|
| 2399 |
public static function body_open(){ |
| 2400 |
echo '<!--tf_svg_holder-->','<script> </script>'; |
| 2401 |
$ga=themify_get('setting-ga_m_id', '', true); |
| 2402 |
if($ga!==''){ |
| 2403 |
echo '<noscript><iframe data-no-script src="https://www.googletagmanager.com/ns.html?id=GTM-'.$ga.'" height="0" width="0" style="display:none"></iframe></noscript>', |
| 2404 |
'<script async data-no-optimize="1" data-noptimize="1" data-cfasync="false" data-ga="'.$ga.'" src="data:text/javascript;base64,KGE9PntmdW5jdGlvbiBlKCl7YS5kYXRhTGF5ZXIucHVzaChhcmd1bWVudHMpfWEuZGF0YUxheWVyPWEuZGF0YUxheWVyfHxbXSxlKCJqcyIsbmV3IERhdGUpLGUoImNvbmZpZyIsZG9jdW1lbnQuY3VycmVudFNjcmlwdC5kYXRhc2V0LmdhKSxlKCJldmVudCIsInBhZ2VfdmlldyIpfSkod2luZG93KTs="></script>', |
| 2405 |
'<script async data-no-optimize="1" data-noptimize="1" data-cfasync="false" src="https://www.googletagmanager.com/gtag/js?id='.$ga.'"></script>'; |
| 2406 |
} |
| 2407 |
} |
| 2408 |
|
| 2409 |
public static function add_theme_support_css($css) { |
| 2410 |
self::$theme_css_support[$css]=true; |
| 2411 |
} |
| 2412 |
|
| 2413 |
public static function remove_theme_support_css($css) { |
| 2414 |
unset(self::$theme_css_support[$css]); |
| 2415 |
} |
| 2416 |
|
| 2417 |
public static function has_theme_support_css($css) { |
| 2418 |
return isset(self::$theme_css_support[$css]); |
| 2419 |
} |
| 2420 |
|
| 2421 |
public static function exclude_main_js( $exclude) { |
| 2422 |
if(current_filter()==='autoptimize_filter_js_consider_minified'){ |
| 2423 |
if($exclude===false){ |
| 2424 |
$exclude=''; |
| 2425 |
} |
| 2426 |
if($exclude!=='' && is_array($exclude)){ |
| 2427 |
$exclude[]='themify/'; |
| 2428 |
} |
| 2429 |
else{ |
| 2430 |
$exclude.='themify/'; |
| 2431 |
} |
| 2432 |
} |
| 2433 |
elseif(is_array($exclude)){ |
| 2434 |
$exclude[] = 'themify-main-script'; |
| 2435 |
$exclude[] = 'themify/'; |
| 2436 |
$exclude[] = 'tf_vars'; |
| 2437 |
} |
| 2438 |
else{ |
| 2439 |
$exclude.= ',themify/'; |
| 2440 |
} |
| 2441 |
return $exclude; |
| 2442 |
} |
| 2443 |
|
| 2444 |
/** |
| 2445 |
* Exclude Themify scripts from being concatenated in Page Optimize plugin |
| 2446 |
* @link https://wordpress.org/plugins/page-optimize/ |
| 2447 |
* |
| 2448 |
* @return bool |
| 2449 |
*/ |
| 2450 |
public static function Automattic_page_optimize_js_exclude(bool $do_concat,string $handle ):bool { |
| 2451 |
if (strpos( $handle, 'themify' ) !== false|| strpos( $handle, 'tb_' ) !== false) { |
| 2452 |
return false; |
| 2453 |
} |
| 2454 |
return $do_concat; |
| 2455 |
} |
| 2456 |
} |
| 2457 |
add_action( 'init', [ 'Themify_Enqueue_Assets', 'init' ] ); |
| 2458 |
|