| 1 |
<?php |
| 2 |
|
| 3 |
/* * ************************************************************************* |
| 4 |
* |
| 5 |
* ---------------------------------------------------------------------- |
| 6 |
* DO NOT EDIT THIS FILE |
| 7 |
* ---------------------------------------------------------------------- |
| 8 |
* |
| 9 |
* Copyright (C) Themify |
| 10 |
* |
| 11 |
* ---------------------------------------------------------------------- |
| 12 |
* |
| 13 |
* ************************************************************************* */ |
| 14 |
|
| 15 |
if (!defined('ABSPATH')) |
| 16 |
exit; // Exit if accessed directly |
| 17 |
|
| 18 |
/* Utilities |
| 19 |
/************************************************************************** */ |
| 20 |
|
| 21 |
function themify_clear_menu_cache() { |
| 22 |
global $wpdb; |
| 23 |
$wpdb->query("DELETE FROM $wpdb->options WHERE `option_name` LIKE ('_transient_tf_menu_%')"); |
| 24 |
return Themify_Storage::deleteByPrefix('tf_menu_'); |
| 25 |
} |
| 26 |
|
| 27 |
|
| 28 |
/** |
| 29 |
* Image Helper - Echoes themify_get_image |
| 30 |
* @param string $args Format string. |
| 31 |
*/ |
| 32 |
function themify_image($args) {//deprecated use themify_get_image |
| 33 |
echo themify_get_image($args); |
| 34 |
} |
| 35 |
|
| 36 |
function themify_find_nearest_image_size(?int $attachment_id,int $width,int $height ) : string { |
| 37 |
$image_meta = wp_get_attachment_metadata( $attachment_id ); |
| 38 |
$size = ''; |
| 39 |
if ( ! empty( $image_meta['sizes'] ) ) { |
| 40 |
$last_pixel_count = 0; |
| 41 |
foreach ( $image_meta['sizes'] as $key => $value ) { |
| 42 |
/* image size is smaller than what we need, skip */ |
| 43 |
if ( $width > $value['width'] || $height > $value['height'] ) { |
| 44 |
continue; |
| 45 |
} |
| 46 |
|
| 47 |
/* find smallest size */ |
| 48 |
$pixels = $value['width'] * $value['height']; |
| 49 |
if ( $last_pixel_count === 0 || $pixels < $last_pixel_count ) { |
| 50 |
$last_pixel_count = $pixels; |
| 51 |
$size = $key; |
| 52 |
} |
| 53 |
} |
| 54 |
} |
| 55 |
|
| 56 |
return $size; |
| 57 |
} |
| 58 |
|
| 59 |
/** |
| 60 |
* Returns the post image, either from Themify Custom Panel fields or from WordPress Featured Image. |
| 61 |
* @param string|array $args Format string. |
| 62 |
* @return string String with <img> tag and optional content prepended and/or appended |
| 63 |
*/ |
| 64 |
function themify_get_image($args):string { |
| 65 |
global $themify; |
| 66 |
/** |
| 67 |
* List of parameters |
| 68 |
* @var array |
| 69 |
*/ |
| 70 |
$defaults = array( |
| 71 |
'src' => '', |
| 72 |
'class' => '', |
| 73 |
'style' => '', |
| 74 |
'preload' => false, |
| 75 |
'prefetch' => false, |
| 76 |
'lazy_load' => true, |
| 77 |
'is_slider' => false, |
| 78 |
'disable_responsive' => false, |
| 79 |
'w' => '', // width |
| 80 |
'h' => '', // height |
| 81 |
'before' => '', |
| 82 |
'after' => '', |
| 83 |
'alt' => '', |
| 84 |
'alt_fallback' => true, |
| 85 |
'title' => '', |
| 86 |
'crop' => true, |
| 87 |
'field_name' => 'post_image,image,wp_thumb,feature_image', |
| 88 |
'urlonly' => false, |
| 89 |
'image_size' => '', |
| 90 |
'image_meta' => false, |
| 91 |
'f_image' => false, |
| 92 |
'attr' => array(), |
| 93 |
'fallback' => ''//when there is no image |
| 94 |
); |
| 95 |
if (is_string($args)) { |
| 96 |
$arr = array(); |
| 97 |
parse_str($args, $arr); |
| 98 |
$args = array(); |
| 99 |
foreach ($arr as $k => $v) { |
| 100 |
if ($v === 'true') { |
| 101 |
$args[$k] = true; |
| 102 |
} elseif ($v === 'false') { |
| 103 |
$args[$k] = false; |
| 104 |
} else { |
| 105 |
$args[$k] = $v; |
| 106 |
} |
| 107 |
} |
| 108 |
} |
| 109 |
$args+=$defaults; |
| 110 |
unset($defaults); |
| 111 |
/** |
| 112 |
* Post ID for single, query or archive views. |
| 113 |
* Page ID is stored separately in $themify->page_id. |
| 114 |
* @var string |
| 115 |
*/ |
| 116 |
$post_id = get_the_ID(); |
| 117 |
|
| 118 |
/** |
| 119 |
* URL of the image to use |
| 120 |
* @var string |
| 121 |
*/ |
| 122 |
$img_url = ''; |
| 123 |
|
| 124 |
/** |
| 125 |
* Image width |
| 126 |
* @var string |
| 127 |
*/ |
| 128 |
$width = $args['w']; |
| 129 |
if ($width !== '') { |
| 130 |
$width = (int) $width; |
| 131 |
} |
| 132 |
/** |
| 133 |
* Image height |
| 134 |
* @var string |
| 135 |
*/ |
| 136 |
$height = $args['h']; |
| 137 |
if ($height !== '') { |
| 138 |
$height = (int) $height; |
| 139 |
} |
| 140 |
|
| 141 |
$attachment_id = 0; |
| 142 |
|
| 143 |
$is_disabled = themify_is_image_script_disabled(); |
| 144 |
if (is_numeric($args['src'])) { |
| 145 |
$attachment_id = $args['src']; |
| 146 |
$img = wp_get_attachment_image_src($attachment_id, 'large'); |
| 147 |
$args['src'] = !empty($img[0]) ? $img[0] : ''; |
| 148 |
unset($img); |
| 149 |
} elseif ($args['fallback'] !== '' && empty($args['src']) && !has_post_thumbnail()) { |
| 150 |
$args['src'] = $args['fallback']; |
| 151 |
} |
| 152 |
if ($is_disabled === true) { // Use WP standard image sizes |
| 153 |
if (!empty($args['image_size'])) { // If image_size parameter is set |
| 154 |
$feature_size = $args['image_size']; |
| 155 |
} elseif (!empty($themify->image_size)) { // or if Themify::image_size is set |
| 156 |
$feature_size = $themify->image_size; |
| 157 |
} elseif (empty($themify->is_shortcode) && in_the_loop()) { // Main query area |
| 158 |
if (is_single()) { |
| 159 |
$feature_size = get_post_meta($post_id, 'feature_size', true); |
| 160 |
if (empty($feature_size) || 'blank' === $feature_size) { |
| 161 |
$feature_size = themify_get('setting-image_post_single_feature_size', null, true); |
| 162 |
} |
| 163 |
} elseif (!empty($themify->page_id) && !empty($themify->query_post_type) && themify_is_query_page()) { |
| 164 |
$feature_size = get_post_meta($themify->page_id, $themify->query_post_type . 'feature_size_page', true); |
| 165 |
if (empty($feature_size)) { |
| 166 |
$feature_size = null; |
| 167 |
} |
| 168 |
} elseif (is_archive() || is_tax() || is_search() || is_home()) { |
| 169 |
$feature_size = themify_get('setting-image_post_feature_size', null, true); |
| 170 |
} |
| 171 |
} |
| 172 |
if (!empty($args['src'])) { |
| 173 |
$attachment_id = themify_get_attachment_id_from_url($args['src']); |
| 174 |
} |
| 175 |
if (!isset($feature_size) || 'blank' === $feature_size) { |
| 176 |
$feature_size = $attachment_id && ! empty( $width ) && ! empty( $height ) ? themify_find_nearest_image_size( $attachment_id, $width, $height ) : ''; |
| 177 |
if ( $feature_size === '' ) { |
| 178 |
$feature_size = apply_filters('themify_global_feature_size', themify_get('setting-global_feature_size', 'large', true)); |
| 179 |
} |
| 180 |
} |
| 181 |
if (!empty($attachment_id)) { |
| 182 |
$tmp = wp_get_attachment_image_src($attachment_id, $feature_size); |
| 183 |
if (!empty($tmp)) { |
| 184 |
$img_url = $tmp[0]; |
| 185 |
} |
| 186 |
unset($tmp); |
| 187 |
} |
| 188 |
if ($img_url === '') { |
| 189 |
// Set URL to use for final output. |
| 190 |
$img_url = empty($args['src']) ? themify_image_url(false, $feature_size) : $args['src']; |
| 191 |
$img_url = trim($img_url); |
| 192 |
// Fix for showing feature_image when Themify Image Script is disabled |
| 193 |
if ('' === $img_url) { |
| 194 |
foreach (explode(',', $args['field_name']) as $field) { |
| 195 |
if ($img_url = get_post_meta($post_id, trim($field), true)) |
| 196 |
break; |
| 197 |
} |
| 198 |
} |
| 199 |
} |
| 200 |
} else { // Use Image Script |
| 201 |
if (empty($args['src'])) { |
| 202 |
if (has_post_thumbnail()) { |
| 203 |
$img_url = $width !== '' && $height !== '' ? ((int) get_post_thumbnail_id()) : get_the_post_thumbnail_url(); /* Image script works with thumbnail IDs as well as URLs, use ID which is faster */ |
| 204 |
} elseif ('attachment' === get_post_type()) { |
| 205 |
$img_url = wp_get_attachment_url($post_id); |
| 206 |
} else { |
| 207 |
foreach (explode(',', $args['field_name']) as $field) { |
| 208 |
if ($img_url = get_post_meta($post_id, trim($field), true)) { |
| 209 |
break; |
| 210 |
} |
| 211 |
} |
| 212 |
} |
| 213 |
} else { |
| 214 |
$img_url = $args['src']; |
| 215 |
} |
| 216 |
if ($height !== '' && 0 === ((int) $height )) { |
| 217 |
$height = 0; |
| 218 |
$args['crop'] = false; |
| 219 |
} |
| 220 |
/** filter $img_url before it goes off to themify_do_img for processing * */ |
| 221 |
$img_url = apply_filters('themify_get_image_before_do_img', $img_url, $width, $height, $args); |
| 222 |
|
| 223 |
// Set URL to use for final output. |
| 224 |
$temp = themify_do_img((empty($attachment_id) ? $img_url : $attachment_id), $width, $height, (bool) $args['crop']); |
| 225 |
$img_url = $temp['url']; |
| 226 |
if ($temp['width'] !== '' && $temp['height'] !== '') { |
| 227 |
$width = (int) $temp['width']; |
| 228 |
$height = (int) $temp['height']; |
| 229 |
} |
| 230 |
// Get title/alt text by attachment id if it was returned. |
| 231 |
if (!$attachment_id && isset($temp['attachment_id'])) { |
| 232 |
$attachment_id = $temp['attachment_id']; |
| 233 |
} |
| 234 |
} |
| 235 |
|
| 236 |
if ($attachment_id) { |
| 237 |
$attachment_id = themify_maybe_translate_object_id($attachment_id); |
| 238 |
} |
| 239 |
|
| 240 |
// No image was defined, parse content to find the first image. |
| 241 |
if (empty($img_url) && ($args['f_image'] || themify_check('setting-auto_featured_image', true) )) { |
| 242 |
|
| 243 |
$content = get_the_content(); |
| 244 |
$upload_dir = themify_upload_dir('baseurl'); |
| 245 |
foreach ( [ 'img', 'iframe' ] as $tag) { |
| 246 |
$count = substr_count($content, '<' . $tag); |
| 247 |
if ($count >= 1) { |
| 248 |
$start = strpos($content, '<' . $tag, 0); |
| 249 |
$pos = substr($content, $start); |
| 250 |
$end = strpos($pos, '>'); |
| 251 |
$temp = themify_prep_image(substr($pos, 0, $end + 1)); |
| 252 |
$src = $temp['src']; |
| 253 |
$parse = parse_url($src); |
| 254 |
if (!empty($parse['query'])) { |
| 255 |
$src = str_replace('?' . $parse['query'], '', $src); |
| 256 |
} |
| 257 |
$auto_image_url = isset($temp['src']) ? $temp['src'] : ''; |
| 258 |
if (isset($temp['class'])) { |
| 259 |
$args['class'] .= ' ' . $temp['class']; |
| 260 |
} |
| 261 |
$args['alt'] = $temp['alt']; |
| 262 |
if ($is_disabled === true) { |
| 263 |
$img_url = themify_image_url(false, $feature_size, themify_get_attachment_id_from_url($auto_image_url, $upload_dir)); |
| 264 |
if (empty($img_url)) { |
| 265 |
$img_url = esc_url($auto_image_url); |
| 266 |
} |
| 267 |
} elseif ($temp = themify_do_img($auto_image_url, $width, $height, (bool) $args['crop'])) { |
| 268 |
$img_url = $temp['url']; |
| 269 |
} |
| 270 |
break; |
| 271 |
} |
| 272 |
} |
| 273 |
unset($content, $upload_dir); |
| 274 |
} |
| 275 |
|
| 276 |
if (!empty($img_url)) { |
| 277 |
if (isset($temp['is_large']) && current_user_can('edit_post', $post_id)) { |
| 278 |
$args['class'] .= ' tf_large_img'; |
| 279 |
} else { |
| 280 |
if ($args['preload'] !== false || $args['prefetch'] !== false) { |
| 281 |
Themify_Enqueue_Assets::addPreLoadMedia($img_url, $args['preload'] !== false ? 'preload' : 'prefetch'); |
| 282 |
} |
| 283 |
themify_generateWebp($img_url); |
| 284 |
} |
| 285 |
unset($temp); |
| 286 |
if ($args['urlonly']) { |
| 287 |
$out = $img_url; |
| 288 |
} else { |
| 289 |
// Build final image |
| 290 |
$out = '<img src="' . $img_url . '"'; |
| 291 |
if ($width !== '' && $width !== 0) { |
| 292 |
$out .= ' width="' . $width . '"'; |
| 293 |
} |
| 294 |
if ($height !== '' && $height !== 0) { |
| 295 |
$out .= ' height="' . $height . '"'; |
| 296 |
} |
| 297 |
if ($attachment_id != 0) { |
| 298 |
$args['class'] .= ' wp-post-image wp-image-' . $attachment_id; /* add attachment_id class to img tag */ |
| 299 |
} |
| 300 |
if ($args['class'] !== '') { |
| 301 |
$out .= ' class="' . trim($args['class']) . '"'; |
| 302 |
} |
| 303 |
if ($args['style'] !== '') { |
| 304 |
$out .= ' style="' . $args['style'] . '"'; |
| 305 |
} |
| 306 |
$title = ''; |
| 307 |
if (!empty($args['alt'])) { |
| 308 |
$out_alt = $args['alt']; |
| 309 |
} else { |
| 310 |
$out_alt = $attachment_id ? get_post_meta($attachment_id, '_wp_attachment_image_alt', true) : ''; |
| 311 |
if (!$out_alt && $args['alt_fallback'] !== false) { |
| 312 |
$out_alt = !empty($args['title']) ? $args['title'] : ''; |
| 313 |
if (!$out_alt && $attachment_id) { |
| 314 |
$p = get_post($attachment_id); |
| 315 |
$out_alt = !empty($p) ? $p->post_title : ''; |
| 316 |
$p = null; |
| 317 |
} |
| 318 |
if (!$out_alt) { |
| 319 |
$out_alt = the_title_attribute('echo=0'); |
| 320 |
} |
| 321 |
$title = $out_alt; |
| 322 |
} |
| 323 |
} |
| 324 |
if($args['title'] !== false ){ |
| 325 |
if ($title === '') { |
| 326 |
if (!empty($args['title'])) { |
| 327 |
$title = $args['title']; |
| 328 |
} elseif ($attachment_id) { |
| 329 |
$p = get_post($attachment_id); |
| 330 |
if (!empty($p)) { |
| 331 |
$title = $p->post_title; |
| 332 |
} |
| 333 |
$p = null; |
| 334 |
} |
| 335 |
} |
| 336 |
// Add title attribute only if explicitly set in $args |
| 337 |
if (!empty($title)) { |
| 338 |
$out .= ' title="' . esc_attr($title) . '"'; |
| 339 |
} |
| 340 |
} |
| 341 |
if ($args['lazy_load'] === false || $args['lazy_load'] === 'eager') { |
| 342 |
$out .= ' data-tf-not-load="1"'; |
| 343 |
if ($args['lazy_load'] === 'eager') { |
| 344 |
$out .= ' loading="eager" decoding="auto"'; |
| 345 |
} |
| 346 |
} |
| 347 |
if (!empty($args['attr'])) { |
| 348 |
foreach ($args['attr'] as $k => $v) { |
| 349 |
$out .= ' ' . $k . '="' . esc_attr($v) . '"'; |
| 350 |
} |
| 351 |
} |
| 352 |
$out .= ' alt="' . esc_attr( (string) $out_alt ) . '"'; |
| 353 |
$out .= '>'; |
| 354 |
if ($attachment_id && $args['disable_responsive'] === false) { |
| 355 |
$out = function_exists('wp_filter_content_tags') ? wp_img_tag_add_srcset_and_sizes_attr($out, null, $attachment_id) // WP 5.5 |
| 356 |
: wp_make_content_images_responsive($out); |
| 357 |
} |
| 358 |
if (($args['is_slider'] === true || $themify->post_layout === 'slider') && $args['lazy_load'] === true) { |
| 359 |
$out = themify_make_lazy($out, false); |
| 360 |
} |
| 361 |
if ($args['image_meta'] == true) { |
| 362 |
$out .= "<meta itemprop=\"width\" content=\"{$width}\"><meta itemprop=\"height\" content=\"{$height}\"><meta itemprop=\"url\" content=\"{$img_url}\">" . $out; |
| 363 |
} |
| 364 |
$out = $args['before'] . $out . $args['after']; |
| 365 |
} |
| 366 |
} else { |
| 367 |
$out = ''; |
| 368 |
} |
| 369 |
|
| 370 |
return $out; |
| 371 |
} |
| 372 |
|
| 373 |
if (!function_exists('themify_edit_link')) { |
| 374 |
|
| 375 |
function themify_edit_link(string $title = '') : bool { |
| 376 |
static $is = null; |
| 377 |
if ($is === null) { |
| 378 |
$is = is_user_logged_in() && (!class_exists('Themify_Builder_Model',false) || !Themify_Builder::$frontedit_active === true) && !themify_is_rest(); |
| 379 |
} |
| 380 |
if ($is === true) { |
| 381 |
if ($title === '') { |
| 382 |
$title = sprintf( __('Edit %s', 'themify'), '<span class="tf_hide">' . get_post_type_object( get_post_type() )->labels->singular_name . '</span>' ); |
| 383 |
} |
| 384 |
edit_post_link($title, '<span class="edit-button tf_edit_post_' . get_the_ID() . '">', '</span>'); |
| 385 |
} |
| 386 |
|
| 387 |
return $is; |
| 388 |
} |
| 389 |
|
| 390 |
} |
| 391 |
|
| 392 |
if (!function_exists('themify_image_url')) { |
| 393 |
|
| 394 |
/** |
| 395 |
* Returns the featured image url |
| 396 |
* @param bool $echo Specify to echo or return the url |
| 397 |
* @param string $size The image size to return |
| 398 |
* @param null|int $attachment_id ID of image to load. |
| 399 |
* @return void|string |
| 400 |
*/ |
| 401 |
function themify_image_url(bool $echo = false, string $size = 'full', $attachment_id = null):string { |
| 402 |
$url = ''; |
| 403 |
if (has_post_thumbnail()) { |
| 404 |
$image = wp_get_attachment_image_src(get_post_thumbnail_id(), $size); |
| 405 |
$url = $image === false ? '' : $image[0]; |
| 406 |
} elseif ($attachment_id !== null) { |
| 407 |
$image = wp_get_attachment_image_src($attachment_id, $size); |
| 408 |
if ($image) { |
| 409 |
$url = $image[0]; |
| 410 |
} |
| 411 |
} |
| 412 |
$url = apply_filters('themify_image_url', $url); |
| 413 |
if ($echo) { |
| 414 |
echo esc_url($url); |
| 415 |
return ''; |
| 416 |
} |
| 417 |
return $url; |
| 418 |
} |
| 419 |
|
| 420 |
} |
| 421 |
|
| 422 |
/** |
| 423 |
* Image Helper - Prep Image |
| 424 |
* @param $tag |
| 425 |
* @return array |
| 426 |
*/ |
| 427 |
function themify_prep_image(string $tag):array { |
| 428 |
$image = []; |
| 429 |
preg_match_all( '/(alt|title|src|class)=(("|\')[^("|\')]*("|\'))/i', $tag, $image_reg ); |
| 430 |
foreach ( $image_reg[1] as $index => $attribute ) { |
| 431 |
$image[ $attribute ] = substr( $image_reg[2][ $index ], 1, -1 ); |
| 432 |
} |
| 433 |
$image += [ 'src' => '', 'alt' => '', 'title' => '' ]; |
| 434 |
|
| 435 |
if (strpos($image['src'], 'youtube.com') !== false || strpos($image['src'], 'vimeo.com') !== false) { |
| 436 |
$image['src'] = themify_video_image($image['src']); |
| 437 |
} |
| 438 |
|
| 439 |
$image['src'] = preg_replace('/(-\d+x\d+)(?=\.\w{3,4})/', '', $image['src']); |
| 440 |
|
| 441 |
return $image; |
| 442 |
} |
| 443 |
|
| 444 |
/** |
| 445 |
* Vimeo / Youtube Thumbnail grab |
| 446 |
* |
| 447 |
* @param $url |
| 448 |
* |
| 449 |
* @return string |
| 450 |
*/ |
| 451 |
function themify_video_image(string $url):string { |
| 452 |
$image_url = parse_url($url); |
| 453 |
$return_url = ''; |
| 454 |
if ($image_url['host'] === 'www.youtube.com' || $image_url['host'] === 'youtube.com') { |
| 455 |
parse_str($image_url['query'], $query); |
| 456 |
if (!empty($query['v'])) { |
| 457 |
$id = $query['v']; |
| 458 |
} else { |
| 459 |
$path = explode('/', $image_url['path']); |
| 460 |
$id = $path[count($path) - 1]; |
| 461 |
} |
| 462 |
$return_url = 'https://img.youtube.com/vi/' . $id . '/hqdefault.jpg'; |
| 463 |
} elseif ($image_url['host'] === 'www.vimeo.com' || $image_url['host'] === 'vimeo.com' || $image_url['host'] === 'player.vimeo.com') { |
| 464 |
parse_str($image_url['query'], $query); |
| 465 |
if (!empty($query['clip_id'])) { |
| 466 |
$id = $query['clip_id']; |
| 467 |
} else { |
| 468 |
$path = explode('/', $image_url['path']); |
| 469 |
$id = $path[(count($path) - 1)]; |
| 470 |
} |
| 471 |
$content = Themify_Filesystem::get_contents('https://vimeo.com/api/v2/video/' . $id . '.php'); |
| 472 |
if (!empty($content)) { |
| 473 |
$hash = themify_maybe_unserialize( $content ); |
| 474 |
if ( ! is_array( $hash ) ) { |
| 475 |
$hash = array(); |
| 476 |
} |
| 477 |
if (!empty($hash[0])) { |
| 478 |
$return_url = $hash[0]["thumbnail_large"]; |
| 479 |
} |
| 480 |
} |
| 481 |
} |
| 482 |
return $return_url; |
| 483 |
} |
| 484 |
|
| 485 |
/** |
| 486 |
* Checks if a value referenced by $var exists in theme settings or post meta data. |
| 487 |
* @param $var |
| 488 |
* @return bool |
| 489 |
*/ |
| 490 |
function themify_check(string $var, bool $data_only = false):bool { |
| 491 |
$val = themify_get($var, null, $data_only); |
| 492 |
return $val !== null && $val !== '' && $val !== 'off'; |
| 493 |
} |
| 494 |
|
| 495 |
/** |
| 496 |
* Returns a value referenced by $var checking in theme settings or post meta data. |
| 497 |
* @param $var |
| 498 |
* @return mixed |
| 499 |
*/ |
| 500 |
function themify_get(string $var, $default = null, bool $data_only = false) { |
| 501 |
$data = themify_get_data(); |
| 502 |
if (isset($data[$var]) && $data[$var] !== '') { |
| 503 |
return $data[$var]; |
| 504 |
} elseif ($data_only !== true) { |
| 505 |
global $post; |
| 506 |
|
| 507 |
if (themify_is_shop() && !in_the_loop()) { |
| 508 |
$id = themify_shop_pageId(); |
| 509 |
} elseif (is_object($post)) { |
| 510 |
$id = $post->ID; |
| 511 |
} else { |
| 512 |
$id = false; |
| 513 |
} |
| 514 |
|
| 515 |
$val = ( $id !== false && $id !== 0 ) ? get_post_meta($id, $var, true) : ''; |
| 516 |
|
| 517 |
if ($val !== '') { |
| 518 |
return $val; |
| 519 |
} |
| 520 |
} |
| 521 |
|
| 522 |
return $default; |
| 523 |
} |
| 524 |
|
| 525 |
/** |
| 526 |
* Returns a value referenced by $meta,$var checking in theme settings or post meta data. |
| 527 |
* @param $meta - post meta |
| 528 |
* @param $var - theme settings |
| 529 |
* @param $default |
| 530 |
* @return mixed |
| 531 |
*/ |
| 532 |
function themify_get_both(string $meta, string $var, $default = null) { |
| 533 |
$val = themify_get($meta); |
| 534 |
if ($val === null || $val === 'default') { |
| 535 |
$val = themify_get($var, $default, true); |
| 536 |
} |
| 537 |
return $val; |
| 538 |
} |
| 539 |
|
| 540 |
/** |
| 541 |
* Get a color value, uses themify_get and sanitizes the value |
| 542 |
* |
| 543 |
* @return string |
| 544 |
*/ |
| 545 |
function themify_get_color_both(string $meta, string $var, $default = null) { |
| 546 |
$val = themify_get_color($meta); |
| 547 |
if ($val === null || $val === 'default') { |
| 548 |
$val = themify_get_color($var, $default, true); |
| 549 |
} |
| 550 |
return $val; |
| 551 |
} |
| 552 |
|
| 553 |
/** |
| 554 |
* Returns a value referenced by $meta,$var checking in theme settings or post meta data. |
| 555 |
* @param $meta - post meta |
| 556 |
* @param $var - theme settings |
| 557 |
* @return mixed |
| 558 |
*/ |
| 559 |
function themify_check_both(string $meta, string $var):bool { |
| 560 |
$val = themify_get($meta, null); |
| 561 |
if ($val === null || $val === 'default') { |
| 562 |
$val = themify_get($var, null, true); |
| 563 |
} |
| 564 |
return $val !== null && $val !== '' && $val !== 'off'; |
| 565 |
} |
| 566 |
|
| 567 |
function themify_shop_pageId() { |
| 568 |
static $id = null; |
| 569 |
if ($id === null) { |
| 570 |
if (themify_is_woocommerce_active() && function_exists( 'wc_get_page_id' ) ) { |
| 571 |
$id = wc_get_page_id('shop'); |
| 572 |
if ($id <= 0) {//wc bug, page id isn't from wc settings,the default should be page with slug 'shop' |
| 573 |
$page = get_page_by_path('shop'); |
| 574 |
$id = !empty($page) ? (int) $page->ID : false; |
| 575 |
} |
| 576 |
} else { |
| 577 |
$id = false; |
| 578 |
} |
| 579 |
} |
| 580 |
return $id; |
| 581 |
} |
| 582 |
|
| 583 |
/** |
| 584 |
* Get a color value, uses themify_get and sanitizes the value |
| 585 |
* |
| 586 |
* @return string |
| 587 |
*/ |
| 588 |
function themify_get_color(string $var, $default = null, bool $data_only = false) { |
| 589 |
$value = themify_get($var, $default, $data_only); |
| 590 |
if ( $value === null || false === $value || '' === $value ) { |
| 591 |
return $value; |
| 592 |
} |
| 593 |
$value = trim( (string) $value ); |
| 594 |
if ( '' === $value ) { |
| 595 |
return $value; |
| 596 |
} |
| 597 |
if ( 0 === stripos( $value, 'var(' ) ) { |
| 598 |
return $value; |
| 599 |
} |
| 600 |
if ( 0 === strpos( $value, '--' ) ) { |
| 601 |
return 'var(' . $value . ')'; |
| 602 |
} |
| 603 |
return themify_sanitize_hex_color( $value ); |
| 604 |
} |
| 605 |
|
| 606 |
/** |
| 607 |
* Sanitize a string to ensure it's valid hex color code |
| 608 |
* |
| 609 |
* @since 3.1.2 |
| 610 |
*/ |
| 611 |
function themify_sanitize_hex_color($value) { |
| 612 |
if ($value===null || false === $value) { |
| 613 |
return $value; |
| 614 |
} |
| 615 |
$value = ltrim($value, '#'); |
| 616 |
/* match 3 to 6 hex digits */ |
| 617 |
if (preg_match('|^([A-Fa-f0-9]{3}){1,2}$|', $value)) { |
| 618 |
$value = '#' . $value; |
| 619 |
} |
| 620 |
|
| 621 |
return $value; |
| 622 |
} |
| 623 |
|
| 624 |
/** |
| 625 |
* Sanitize space-separated CSS class names for safe HTML class attributes. |
| 626 |
* |
| 627 |
* @since 7.0 |
| 628 |
*/ |
| 629 |
function themify_sanitize_css_classes( $classes ) { |
| 630 |
if ( $classes === '' || $classes === null ) { |
| 631 |
return ''; |
| 632 |
} |
| 633 |
if ( ! is_string( $classes ) ) { |
| 634 |
return ''; |
| 635 |
} |
| 636 |
$parts = preg_split( '/\s+/', trim( $classes ) ); |
| 637 |
$sanitized = array(); |
| 638 |
foreach ( $parts as $part ) { |
| 639 |
if ( $part === '' ) { |
| 640 |
continue; |
| 641 |
} |
| 642 |
$clean = sanitize_html_class( $part ); |
| 643 |
if ( $clean !== '' ) { |
| 644 |
$sanitized[] = $clean; |
| 645 |
} |
| 646 |
} |
| 647 |
return implode( ' ', $sanitized ); |
| 648 |
} |
| 649 |
|
| 650 |
/** |
| 651 |
* Sanitize a CSS length value with an allowed unit. |
| 652 |
* |
| 653 |
* @since 7.0 |
| 654 |
*/ |
| 655 |
function themify_sanitize_css_size( $value, $unit = 'px' ) { |
| 656 |
$value = preg_replace( '/[^0-9.]/', '', (string) $value ); |
| 657 |
if ( $value === '' ) { |
| 658 |
return ''; |
| 659 |
} |
| 660 |
$allowed_units = array( 'px', '%', 'em', 'rem', 'vw', 'vh', 'vmin', 'vmax' ); |
| 661 |
if ( ! in_array( $unit, $allowed_units, true ) ) { |
| 662 |
$unit = 'px'; |
| 663 |
} |
| 664 |
return $value . $unit; |
| 665 |
} |
| 666 |
|
| 667 |
/** |
| 668 |
* Sanitize a CSS unit token. |
| 669 |
* |
| 670 |
* @since 7.0 |
| 671 |
*/ |
| 672 |
function themify_sanitize_css_unit( $unit, $default = 'px' ) { |
| 673 |
$allowed_units = array( 'px', '%', 'em', 'rem', 'vw', 'vh', 'vmin', 'vmax' ); |
| 674 |
$unit = strtolower( trim( (string) $unit ) ); |
| 675 |
if ( ! in_array( $unit, $allowed_units, true ) ) { |
| 676 |
$unit = in_array( $default, $allowed_units, true ) ? $default : 'px'; |
| 677 |
} |
| 678 |
return $unit; |
| 679 |
} |
| 680 |
|
| 681 |
/** |
| 682 |
* Sanitize slider height option for data-height attributes. |
| 683 |
* |
| 684 |
* @since 7.0 |
| 685 |
*/ |
| 686 |
function themify_sanitize_slider_height( $value ) { |
| 687 |
$value = (string) $value; |
| 688 |
if ( in_array( $value, array( 'variable', 'auto', '' ), true ) ) { |
| 689 |
return $value; |
| 690 |
} |
| 691 |
if ( preg_match( '/^([0-9.]+)(px|%|em|rem|vw|vh|vmin|vmax)$/i', $value, $matches ) ) { |
| 692 |
return themify_sanitize_css_size( $matches[1], strtolower( $matches[2] ) ); |
| 693 |
} |
| 694 |
return 'variable'; |
| 695 |
} |
| 696 |
|
| 697 |
/** |
| 698 |
* Sanitize CSS border-style values. |
| 699 |
* |
| 700 |
* @since 7.0 |
| 701 |
*/ |
| 702 |
function themify_sanitize_border_style( $value, $default = 'solid' ) { |
| 703 |
$allowed = array( 'solid', 'dashed', 'dotted', 'double', 'none' ); |
| 704 |
$value = strtolower( trim( (string) $value ) ); |
| 705 |
return in_array( $value, $allowed, true ) ? $value : $default; |
| 706 |
} |
| 707 |
|
| 708 |
/** |
| 709 |
* Sanitize inline CSS declarations for style attributes. |
| 710 |
* |
| 711 |
* @since 7.0 |
| 712 |
*/ |
| 713 |
function themify_sanitize_inline_css( $css ) { |
| 714 |
if ( $css === '' || $css === null ) { |
| 715 |
return ''; |
| 716 |
} |
| 717 |
$css = wp_strip_all_tags( (string) $css ); |
| 718 |
$css = preg_replace( '/expression\s*\(/i', '', $css ); |
| 719 |
$css = preg_replace( '/javascript\s*:/i', '', $css ); |
| 720 |
$css = preg_replace( '/@import/i', '', $css ); |
| 721 |
$css = preg_replace( '/<\/?style/i', '', $css ); |
| 722 |
return trim( $css ); |
| 723 |
} |
| 724 |
|
| 725 |
/** |
| 726 |
* Sanitize builder custom CSS before writing to a stylesheet file. |
| 727 |
* |
| 728 |
* @since 7.0 |
| 729 |
*/ |
| 730 |
function themify_sanitize_builder_custom_css( $css ) { |
| 731 |
if ( ! is_string( $css ) || $css === '' ) { |
| 732 |
return ''; |
| 733 |
} |
| 734 |
$css = preg_replace( '/<\/style/i', '', $css ); |
| 735 |
$css = preg_replace( '/<script/i', '', $css ); |
| 736 |
return $css; |
| 737 |
} |
| 738 |
|
| 739 |
/** |
| 740 |
* Sanitize builder custom JS before printing on the page. |
| 741 |
* |
| 742 |
* @since 7.0 |
| 743 |
*/ |
| 744 |
function themify_sanitize_builder_custom_js( $js ) { |
| 745 |
if ( ! is_string( $js ) || $js === '' ) { |
| 746 |
return ''; |
| 747 |
} |
| 748 |
$js = preg_replace( '/<\/script/i', '', $js ); |
| 749 |
return $js; |
| 750 |
} |
| 751 |
|
| 752 |
if (!function_exists('themify_get_image_sizes_list')) { |
| 753 |
|
| 754 |
/** |
| 755 |
* Return list of image sizes with labels for translation. |
| 756 |
* @param bool $nested |
| 757 |
* @return mixed|void |
| 758 |
* @since 1.6.8 |
| 759 |
*/ |
| 760 |
function themify_get_image_sizes_list(bool $nested = true) { |
| 761 |
$size_names = apply_filters('image_size_names_choose', |
| 762 |
array( |
| 763 |
'thumbnail' => __('Thumbnail', 'themify'), |
| 764 |
'medium' => __('Medium', 'themify'), |
| 765 |
'large' => __('Large', 'themify'), |
| 766 |
'full' => __('Original Image', 'themify') |
| 767 |
) |
| 768 |
); |
| 769 |
$out = array( |
| 770 |
array('value' => 'blank', 'name' => ''), |
| 771 |
); |
| 772 |
foreach ($size_names as $size => $label) { |
| 773 |
$out[] = array('value' => $size, 'name' => $label); |
| 774 |
} |
| 775 |
return apply_filters('themify_get_image_sizes_list', $nested ? $out : $size_names, $nested); |
| 776 |
} |
| 777 |
|
| 778 |
} |
| 779 |
|
| 780 |
/** |
| 781 |
* Check if the site is using an HTTPS scheme and returns the proper url |
| 782 |
* @param String $url requested url |
| 783 |
* @return String |
| 784 |
* @since 1.1.5 |
| 785 |
*/ |
| 786 |
function themify_https_esc(string $url = ''):string { |
| 787 |
if (is_ssl()) { |
| 788 |
$url = str_replace('http:', 'https:', $url); |
| 789 |
} |
| 790 |
return $url; |
| 791 |
} |
| 792 |
|
| 793 |
/** |
| 794 |
* Returns an array with the post types managed by Themify, |
| 795 |
* where the Themify Custom Panel is initialized. |
| 796 |
* Filterable using themify_post_types |
| 797 |
* @param Array $types additional post types |
| 798 |
* @return Array |
| 799 |
* @since 1.1.5 |
| 800 |
*/ |
| 801 |
function themify_post_types(array $types = array()):array { |
| 802 |
$defaults = array_merge(array('post', 'page'), apply_filters('themify_specific_post_types', array('menu', 'slider', 'highlight', 'portfolio', 'testimonial', 'section')), $types); |
| 803 |
if (themify_is_themify_theme() && themify_is_woocommerce_active() && is_file(THEME_DIR . '/admin/post-type-product.php')) { |
| 804 |
$defaults[] = 'product'; |
| 805 |
} |
| 806 |
return array_keys(array_flip(apply_filters('themify_post_types', $defaults))); |
| 807 |
} |
| 808 |
|
| 809 |
if (!function_exists('themify_options_module')) { |
| 810 |
|
| 811 |
/** |
| 812 |
* Returns list of <option> |
| 813 |
* @param array $options List of options |
| 814 |
* @param string $key |
| 815 |
* @param bool $associative |
| 816 |
* @param string $default |
| 817 |
* @return string |
| 818 |
* @since 1.3.5 |
| 819 |
*/ |
| 820 |
function themify_options_module($options = array(), $key = '', $associative = true, $default = ''):string { |
| 821 |
$data = themify_get_data(); |
| 822 |
$sel = isset($data[$key]) ? $data[$key] : $default; |
| 823 |
$data = null; |
| 824 |
$output = ''; |
| 825 |
if (true === $associative) { |
| 826 |
foreach ($options as $option) { |
| 827 |
$output .= '<option ' . selected($option['value'], $sel, false) . ' value="' . esc_attr($option['value']) . '">' . esc_html($option['name']) . '</option>'; |
| 828 |
} |
| 829 |
} else { |
| 830 |
foreach ($options as $option) { |
| 831 |
$option = esc_attr($option); |
| 832 |
$selected = $sel === $option ? ' selected="selected"' : ''; |
| 833 |
$output .= '<option value="' . $option . '"' . $selected . '>' . esc_html($option) . '</option>'; |
| 834 |
} |
| 835 |
} |
| 836 |
return $output; |
| 837 |
} |
| 838 |
|
| 839 |
} |
| 840 |
|
| 841 |
if (!function_exists('themify_lightbox_vars_init')) { |
| 842 |
|
| 843 |
/** |
| 844 |
* Post Gallery lightbox/fullscreen and single lightbox definition |
| 845 |
* @return array Lightbox/Fullscreen galleries initialization parameters |
| 846 |
*/ |
| 847 |
function themify_lightbox_vars_init():array { |
| 848 |
$gallery_lightbox = themify_get('setting-gallery_lightbox', 'lightbox', true); |
| 849 |
// Lightbox default settings |
| 850 |
$overlay_args = array(); |
| 851 |
if (themify_check('setting-lightbox_content_images', true)) { |
| 852 |
$overlay_args['contentImagesAreas'] = '.post, .type-page, .type-highlight, .type-slider'; |
| 853 |
} |
| 854 |
if (themify_check('setting-lightbox_disable_share', true)) { |
| 855 |
$overlay_args['disable_sharing'] = true; |
| 856 |
} |
| 857 |
if ($gallery_lightbox === 'none') { |
| 858 |
$overlay_args['gallerySelector'] = ''; |
| 859 |
} |
| 860 |
|
| 861 |
$overlay_args = apply_filters('themify_gallery_plugins_args', $overlay_args); |
| 862 |
// sanitize contentImagesAreas, ensure it's a valid CSS selector |
| 863 |
if (isset($overlay_args['contentImagesAreas'])) { |
| 864 |
$overlay_args['contentImagesAreas'] = trim($overlay_args['contentImagesAreas'], ','); |
| 865 |
} |
| 866 |
$overlay_args['i18n'] = array( |
| 867 |
'tCounter' => __('%curr% of %total%', 'themify'), |
| 868 |
); |
| 869 |
|
| 870 |
return $overlay_args; |
| 871 |
} |
| 872 |
|
| 873 |
} |
| 874 |
|
| 875 |
if (!function_exists('themify_get_shortcode_template')) { |
| 876 |
|
| 877 |
/** |
| 878 |
* Returns markup |
| 879 |
* @param $posts |
| 880 |
* @param string $slug |
| 881 |
* @param string $name |
| 882 |
* @return mixed|void |
| 883 |
*/ |
| 884 |
function themify_get_shortcode_template($posts, string $slug = 'includes/loop', string $name = 'index', array $args = array()):string { |
| 885 |
global $post, $themify; |
| 886 |
Themify_Enqueue_Assets::loadGridCss($themify->post_layout); |
| 887 |
|
| 888 |
if (is_object($post)){ |
| 889 |
$saved_post = clone $post; |
| 890 |
} |
| 891 |
if(property_exists($themify, 'is_shortcode')){ |
| 892 |
$isShortcode = $themify->is_shortcode === true; |
| 893 |
$themify->is_shortcode = true; |
| 894 |
} |
| 895 |
|
| 896 |
// Add flag that template loop is in builder loop |
| 897 |
if (class_exists('\Themify_Builder',false)) { |
| 898 |
$isLoop = Themify_Builder::$is_loop; |
| 899 |
Themify_Builder::$is_loop = true; |
| 900 |
} |
| 901 |
|
| 902 |
// get_template_part, defined in wp-includes/general-template.php |
| 903 |
$templates = array(); |
| 904 |
if ('' !== $name) { |
| 905 |
$templates[] = "{$slug}-{$name}.php"; |
| 906 |
} |
| 907 |
$templates[] = "{$slug}.php"; |
| 908 |
$template_file = apply_filters('themify_get_shortcode_template_file', locate_template($templates, false, false), $slug, $name); |
| 909 |
$isSlider = $themify->post_layout === 'slider' || (isset($args['isSlider']) && $args['isSlider'] === true); |
| 910 |
ob_start(); |
| 911 |
if (!empty($template_file)) { |
| 912 |
$before = isset($args['before_post']) ? $args['before_post'] : ''; |
| 913 |
$after = isset($args['after_post']) ? $args['after_post'] : ''; |
| 914 |
foreach ($posts as $p) { |
| 915 |
$post=$p; |
| 916 |
setup_postdata($post); |
| 917 |
if ($isSlider === true) { |
| 918 |
echo '<div class="tf_lazy tf_swiper-slide">'; |
| 919 |
} |
| 920 |
echo $before; |
| 921 |
include $template_file; |
| 922 |
echo $after; |
| 923 |
if ($isSlider === true) { |
| 924 |
echo '</div>'; |
| 925 |
} |
| 926 |
} |
| 927 |
$posts = null; |
| 928 |
} |
| 929 |
|
| 930 |
if (isset($saved_post)) { |
| 931 |
$post = $saved_post; |
| 932 |
setup_postdata($saved_post); |
| 933 |
unset($saved_post); |
| 934 |
} |
| 935 |
// Add flag that template loop is in builder loop |
| 936 |
if (isset($isLoop)) { |
| 937 |
Themify_Builder::$is_loop = $isLoop; |
| 938 |
} |
| 939 |
if(isset($isShortcode)){ |
| 940 |
$themify->is_shortcode = $isShortcode; |
| 941 |
} |
| 942 |
$res=ob_get_clean(); |
| 943 |
return $res?$res:''; |
| 944 |
} |
| 945 |
|
| 946 |
} |
| 947 |
|
| 948 |
if (!function_exists('themify_resolve_gallery_shortcode_string')) { |
| 949 |
|
| 950 |
/** |
| 951 |
* Expand wrapper shortcodes (e.g. ACF) that return a literal [gallery ids="..."] string. |
| 952 |
* Stops before WordPress would render [gallery] to HTML. |
| 953 |
* |
| 954 |
* @param string|null $shortcode Raw field value from Builder (may be [acf_...] or [gallery ...]). |
| 955 |
* @return string String containing [gallery ... ids=...] when resolvable, otherwise original/expanded text. |
| 956 |
*/ |
| 957 |
function themify_resolve_gallery_shortcode_string(?string $shortcode): string { |
| 958 |
if ($shortcode === null || $shortcode === '') { |
| 959 |
return ''; |
| 960 |
} |
| 961 |
$shortcode = trim($shortcode); |
| 962 |
if (strpos($shortcode, '[') === false) { |
| 963 |
return $shortcode; |
| 964 |
} |
| 965 |
// Already a gallery shortcode with ids — do not run do_shortcode() or core will output HTML. |
| 966 |
if (preg_match('/\[gallery\s+[^\]]*ids\s*=/i', $shortcode)) { |
| 967 |
return $shortcode; |
| 968 |
} |
| 969 |
$prev = ''; |
| 970 |
for ($i = 0; $i < 8; ++$i) { |
| 971 |
if ($shortcode === $prev) { |
| 972 |
break; |
| 973 |
} |
| 974 |
$prev = $shortcode; |
| 975 |
$next = do_shortcode($shortcode); |
| 976 |
if ($next === $shortcode) { |
| 977 |
break; |
| 978 |
} |
| 979 |
$shortcode = $next; |
| 980 |
if (preg_match('/\[gallery\s+[^\]]*ids\s*=/i', $shortcode)) { |
| 981 |
break; |
| 982 |
} |
| 983 |
} |
| 984 |
return $shortcode; |
| 985 |
} |
| 986 |
} |
| 987 |
|
| 988 |
if (!function_exists('themify_get_gallery_shortcode')) { |
| 989 |
|
| 990 |
/** |
| 991 |
* Get images from gallery shortcode |
| 992 |
* @return object |
| 993 |
*/ |
| 994 |
function themify_get_gallery_shortcode(?string $shortcode):array { |
| 995 |
if ($shortcode) { |
| 996 |
$shortcode = themify_resolve_gallery_shortcode_string($shortcode); |
| 997 |
preg_match('/\[gallery.*ids.*?=.(.*).\]/si', $shortcode, $ids); |
| 998 |
if (isset($ids[1])) { |
| 999 |
$ids = trim($ids[1], '\\'); |
| 1000 |
$ids = trim($ids, '"'); |
| 1001 |
$image_ids = explode(',', $ids); |
| 1002 |
|
| 1003 |
// Check if post has more than one image in gallery |
| 1004 |
return get_posts(array( |
| 1005 |
'post__in' => $image_ids, |
| 1006 |
'post_type' => 'attachment', |
| 1007 |
'post_mime_type' => 'image', |
| 1008 |
'numberposts' => -1, |
| 1009 |
'no_found_rows' => true, |
| 1010 |
'cache_results' => false, |
| 1011 |
'update_post_term_cache' => false, |
| 1012 |
'update_post_meta_cache' => false, |
| 1013 |
'orderby' => themify_get_gallery_shortcode_params($shortcode, 'orderby', 'post__in'), |
| 1014 |
'order' => themify_get_gallery_shortcode_params($shortcode, 'order', 'ASC') |
| 1015 |
)); |
| 1016 |
} |
| 1017 |
} |
| 1018 |
return array(); |
| 1019 |
} |
| 1020 |
|
| 1021 |
} |
| 1022 |
|
| 1023 |
if (!function_exists('themify_get_gallery_shortcode_params')) { |
| 1024 |
|
| 1025 |
/** |
| 1026 |
* Get gallery shortcode options |
| 1027 |
* @param $shortcode |
| 1028 |
* @param $param |
| 1029 |
*/ |
| 1030 |
function themify_get_gallery_shortcode_params(string $shortcode, string $param = 'link', $default = '') { |
| 1031 |
$shortcode = themify_resolve_gallery_shortcode_string($shortcode); |
| 1032 |
$pattern = '/\[gallery .*?(?=' . $param . ')' . $param . '=.([^\']+)./si'; |
| 1033 |
preg_match($pattern, $shortcode, $out); |
| 1034 |
$out = isset($out[1]) ? explode('"', $out[1]) : array(''); |
| 1035 |
return $out[0] !== '' ? $out[0] : $default; |
| 1036 |
} |
| 1037 |
|
| 1038 |
} |
| 1039 |
|
| 1040 |
function themify_get_additional_image_sizes(string $size = 'all', $default = false) { |
| 1041 |
$allSizes = wp_get_additional_image_sizes(); |
| 1042 |
if ($size === 'all') { |
| 1043 |
return $allSizes; |
| 1044 |
} |
| 1045 |
return isset($allSizes[$size]) ? $allSizes[$size] : $default; |
| 1046 |
} |
| 1047 |
|
| 1048 |
if (!function_exists('themify_get_all_terms_ids')) { |
| 1049 |
|
| 1050 |
/** |
| 1051 |
* Returns all IDs from the given taxonomy |
| 1052 |
* @param string $tax Taxonomy to retrieve terms from. |
| 1053 |
* @return array $term_ids Array of all taxonomy terms |
| 1054 |
* @since 1.5.6 |
| 1055 |
*/ |
| 1056 |
function themify_get_all_terms_ids(string $tax = 'category') { |
| 1057 |
if (!$term_ids = wp_cache_get('all_' . $tax . '_ids', $tax)) { |
| 1058 |
$term_ids = get_terms(array('taxonomy' => $tax, 'fields' => 'ids', 'get' => 'all')); |
| 1059 |
wp_cache_add('all_' . $tax . '_ids', $term_ids, $tax); |
| 1060 |
} |
| 1061 |
return $term_ids; |
| 1062 |
} |
| 1063 |
|
| 1064 |
} |
| 1065 |
|
| 1066 |
if (!function_exists('themify_is_touch')) { |
| 1067 |
|
| 1068 |
/** |
| 1069 |
* According to what $check parameter specifies to check, returns true if it's a phone, tablet, or both. |
| 1070 |
* @param string $check |
| 1071 |
* @return mixed |
| 1072 |
* @since 1.6.8 |
| 1073 |
*/ |
| 1074 |
function themify_is_touch($check = 'all') { |
| 1075 |
static $arr = array(); |
| 1076 |
|
| 1077 |
if (!isset($arr[$check])) { |
| 1078 |
if (!class_exists('Themify_Mobile_Detect',false)) { |
| 1079 |
require_once 'class-themify-mobile-detect.php'; |
| 1080 |
} |
| 1081 |
$detect = new Themify_Mobile_Detect(); |
| 1082 |
$is_tablet = isset($arr['tablet']) ? $arr['tablet'] : $detect->isTablet(); |
| 1083 |
$is_mobile = isset($arr['phone']) ? $arr['phone'] : (wp_is_mobile() || $detect->isMobile()); |
| 1084 |
$arr = array( |
| 1085 |
'phone' => $is_mobile && !$is_tablet, |
| 1086 |
'tablet' => $is_tablet, |
| 1087 |
'all' => $is_mobile |
| 1088 |
); |
| 1089 |
$detect = null; |
| 1090 |
} |
| 1091 |
|
| 1092 |
return $arr[$check]; |
| 1093 |
} |
| 1094 |
|
| 1095 |
} |
| 1096 |
|
| 1097 |
/** |
| 1098 |
* Checks that status of the image script. |
| 1099 |
* @return bool |
| 1100 |
* @since 1.7.4 |
| 1101 |
*/ |
| 1102 |
function themify_is_image_script_disabled():bool { |
| 1103 |
static $is = null; |
| 1104 |
if ($is === null) { |
| 1105 |
$is = wp_image_editor_supports() ? themify_check('setting-img_settings_use', true) : false; |
| 1106 |
} |
| 1107 |
|
| 1108 |
return $is; |
| 1109 |
} |
| 1110 |
|
| 1111 |
|
| 1112 |
if (!function_exists('themify_get_available_menus')) { |
| 1113 |
|
| 1114 |
/** |
| 1115 |
* Returns available navigation menus. |
| 1116 |
* |
| 1117 |
* @since 1.9.5 |
| 1118 |
* |
| 1119 |
* @return array |
| 1120 |
*/ |
| 1121 |
function themify_get_available_menus():array { |
| 1122 |
$out = array(array('name' => '', 'value' => '', 'selected' => true)); |
| 1123 |
$menus = get_terms(array( |
| 1124 |
'taxonomy' => 'nav_menu', |
| 1125 |
'hide_empty' => false, |
| 1126 |
)); |
| 1127 |
if (!empty($menus) && !is_wp_error($menus)) { |
| 1128 |
foreach ($menus as $menu) { |
| 1129 |
$out[] = array('name' => $menu->name, 'value' => $menu->slug); |
| 1130 |
} |
| 1131 |
} |
| 1132 |
return apply_filters('themify_get_available_menus', $out); |
| 1133 |
} |
| 1134 |
|
| 1135 |
} |
| 1136 |
|
| 1137 |
/** |
| 1138 |
* Returns true if the active theme is using Themify framework |
| 1139 |
* |
| 1140 |
* @since 2.2.5 |
| 1141 |
* @return bool |
| 1142 |
*/ |
| 1143 |
function themify_is_themify_theme():bool { |
| 1144 |
static $is = null; |
| 1145 |
if ($is === null) { |
| 1146 |
$is = is_file(trailingslashit(get_template_directory()) . 'themify/themify-utils.php'); |
| 1147 |
} |
| 1148 |
|
| 1149 |
return $is; |
| 1150 |
} |
| 1151 |
|
| 1152 |
if (!function_exists('themify_is_woocommerce_active')) { |
| 1153 |
|
| 1154 |
/** |
| 1155 |
* Checks if Woocommerce plugin is active and returns the proper value |
| 1156 |
* @return bool |
| 1157 |
* @since 1.4.6 |
| 1158 |
*/ |
| 1159 |
function themify_is_woocommerce_active():bool { |
| 1160 |
static $is = null; |
| 1161 |
if ($is === null) { |
| 1162 |
$plugin = 'woocommerce/woocommerce.php'; |
| 1163 |
include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); |
| 1164 |
return is_plugin_active($plugin) |
| 1165 |
// validate if $plugin actually exists, the plugin might be active however not installed. |
| 1166 |
&& is_file(trailingslashit(WP_PLUGIN_DIR) . $plugin); |
| 1167 |
} |
| 1168 |
return $is; |
| 1169 |
} |
| 1170 |
|
| 1171 |
} |
| 1172 |
|
| 1173 |
/** |
| 1174 |
* Calls is_shop() in a safe manner |
| 1175 |
* |
| 1176 |
* @note: this function should not be called before template_redirect. |
| 1177 |
* |
| 1178 |
* @since 2.9.0 |
| 1179 |
*/ |
| 1180 |
function themify_is_shop($pageId = false):bool { |
| 1181 |
static $is = null; |
| 1182 |
if ($is === null) { |
| 1183 |
$is = themify_is_woocommerce_active(); |
| 1184 |
if ($is === true) { |
| 1185 |
$is = is_post_type_archive('product') || ($pageId > 0 && $pageId === themify_shop_pageId()); //don't use shop function will give error |
| 1186 |
if ($is === false) { |
| 1187 |
$shop_url = themify_get_shop_permalink(); //wc bug, page id isn't set from wc settings,the default should be page with slug 'shop' |
| 1188 |
if ($shop_url !== '') { |
| 1189 |
$current_url = 'http'; |
| 1190 |
if (is_ssl()) { |
| 1191 |
$current_url .= 's'; |
| 1192 |
} |
| 1193 |
$current_url .= '://'; |
| 1194 |
if (isset($_SERVER['HTTP_HOST'])) { |
| 1195 |
$current_url .= $_SERVER['HTTP_HOST']; |
| 1196 |
} else { |
| 1197 |
$host = parse_url(home_url(), PHP_URL_HOST); |
| 1198 |
if ($host !== false) { |
| 1199 |
$current_url .= $host; |
| 1200 |
} |
| 1201 |
unset($host); |
| 1202 |
} |
| 1203 |
$current_url .= strtok($_SERVER['REQUEST_URI'], '?'); |
| 1204 |
$is = $current_url === $shop_url; |
| 1205 |
} else { |
| 1206 |
$is = false; |
| 1207 |
} |
| 1208 |
} |
| 1209 |
} |
| 1210 |
} |
| 1211 |
return $is; |
| 1212 |
} |
| 1213 |
|
| 1214 |
/** |
| 1215 |
* Modified version of wp_parse_args which adds filters to modify the args |
| 1216 |
* |
| 1217 |
* @return array |
| 1218 |
* @since 2.7.7 |
| 1219 |
*/ |
| 1220 |
function themify_parse_args($args, $defaults = '', $filter_key = '') { |
| 1221 |
// Setup a temporary array from $args |
| 1222 |
if (is_object($args)) { |
| 1223 |
$r = get_object_vars($args); |
| 1224 |
} elseif (is_array($args)) { |
| 1225 |
$r = & $args; |
| 1226 |
} else { |
| 1227 |
wp_parse_str($args, $r); |
| 1228 |
} |
| 1229 |
// Passively filter the args before the parse |
| 1230 |
if (!empty($filter_key)) { |
| 1231 |
$r = apply_filters('themify_before_' . $filter_key . '_parse_args', $r); |
| 1232 |
} |
| 1233 |
// Parse |
| 1234 |
if (is_array($defaults)) { |
| 1235 |
$r = array_merge($defaults, $r); |
| 1236 |
} |
| 1237 |
// Aggressively filter the args after the parse |
| 1238 |
if (!empty($filter_key)) { |
| 1239 |
$r = apply_filters('themify_after_' . $filter_key . '_parse_args', $r); |
| 1240 |
} |
| 1241 |
// Return the parsed results |
| 1242 |
return $r; |
| 1243 |
} |
| 1244 |
|
| 1245 |
/** |
| 1246 |
* Display the Builder's backend editor in Themify Custom Panel |
| 1247 |
* |
| 1248 |
* @return null |
| 1249 |
* @since 2.8.8 |
| 1250 |
*/ |
| 1251 |
function themify_meta_field_page_builder() { |
| 1252 |
do_action('themify_builder_metabox'); |
| 1253 |
} |
| 1254 |
|
| 1255 |
/** |
| 1256 |
* Get an array of key => value pairs and outputs them as HTML attributes |
| 1257 |
* |
| 1258 |
* @since 2.9.1 |
| 1259 |
* @return string |
| 1260 |
*/ |
| 1261 |
function themify_get_element_attributes(array $props):string { |
| 1262 |
$out = ''; |
| 1263 |
foreach ($props as $k => $v) { |
| 1264 |
$out .= ' ' . $k . '="' . esc_attr($v) . '"'; |
| 1265 |
} |
| 1266 |
|
| 1267 |
return $out; |
| 1268 |
} |
| 1269 |
|
| 1270 |
|
| 1271 |
/** |
| 1272 |
* Get breakpoints settings |
| 1273 |
* if it's framework return customizer breakpoints,else if it's builder plugin builder breakpoints |
| 1274 |
* @since 3.0.0 |
| 1275 |
* @return mixed array/int |
| 1276 |
*/ |
| 1277 |
function themify_get_breakpoints(string $select = 'all', bool $max_min = false) { |
| 1278 |
static $res = array(); |
| 1279 |
if (($select === 'all' && empty($res)) || (empty($res[$select]))) { |
| 1280 |
$breakpoints = array( |
| 1281 |
'tablet_landscape' => array(769, 1280), |
| 1282 |
'tablet' => array(681, 768), |
| 1283 |
'mobile' => 680 |
| 1284 |
); |
| 1285 |
if ($max_min === true) { |
| 1286 |
return $breakpoints; |
| 1287 |
} |
| 1288 |
foreach ($breakpoints as $bp => $value) { |
| 1289 |
$v = themify_builder_get('setting-customizer_responsive_design_' . $bp, 'builder_responsive_design_' . $bp); |
| 1290 |
if ('' != $v) { |
| 1291 |
if (is_array($value)) { |
| 1292 |
$res[$bp] = array(); |
| 1293 |
$res[$bp][0] = $value[0]; |
| 1294 |
$res[$bp][1] = (int) $v; |
| 1295 |
} else { |
| 1296 |
$res[$bp] = (int) $v; |
| 1297 |
} |
| 1298 |
} else { |
| 1299 |
$res[$bp] = $value; |
| 1300 |
} |
| 1301 |
} |
| 1302 |
$res['tablet'][0] = $res['mobile'] + 1; |
| 1303 |
$res['tablet_landscape'][0] = $res['tablet'][1] + 1; |
| 1304 |
} |
| 1305 |
return 'all' === $select ? $res : $res[$select]; |
| 1306 |
} |
| 1307 |
|
| 1308 |
/** |
| 1309 |
* Unserialize data if it is serialized |
| 1310 |
* |
| 1311 |
* If PHP supports it disables unserializing PHP objects in order to prevent object injection. |
| 1312 |
* |
| 1313 |
* @param string $original Maybe unserialized original, if is needed. |
| 1314 |
* @return mixed Unserialized data can be any type. |
| 1315 |
*/ |
| 1316 |
function themify_maybe_unserialize(string $original) { |
| 1317 |
if (is_serialized($original)) { // don't attempt to unserialize data that wasn't serialized going in |
| 1318 |
return @unserialize($original, array('allowed_classes' => false)); |
| 1319 |
} |
| 1320 |
|
| 1321 |
return $original; |
| 1322 |
} |
| 1323 |
|
| 1324 |
/** |
| 1325 |
* Display the post video |
| 1326 |
* Must be used inside the loop |
| 1327 |
* |
| 1328 |
* @since 2.7.3 |
| 1329 |
*/ |
| 1330 |
function themify_post_video(string $url = '', bool $echo = true) { |
| 1331 |
$video_file = $url ? $url : themify_get('video_url'); |
| 1332 |
$output = ''; |
| 1333 |
if (!empty($video_file)) { |
| 1334 |
if ('mp4' !== pathinfo($video_file, PATHINFO_EXTENSION)) { |
| 1335 |
global $wp_embed; |
| 1336 |
$output = $wp_embed->run_shortcode('[embed]' . $video_file . '[/embed]'); |
| 1337 |
} else { |
| 1338 |
$output = '<div class="post-video">'; |
| 1339 |
$output .= do_shortcode('[video src="' . $video_file . '"]'); |
| 1340 |
$output .= '</div>'; |
| 1341 |
} |
| 1342 |
} |
| 1343 |
if ($echo === true) { |
| 1344 |
echo $output; |
| 1345 |
} else { |
| 1346 |
return $output; |
| 1347 |
} |
| 1348 |
} |
| 1349 |
|
| 1350 |
function themify_get_embed(string $url, array $args):string { |
| 1351 |
$reg = '#(vimeo\.com|youtu(be\.com|\.be|be))\/(shorts\/|video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?\/?([A-Za-z0-9._%-]*)(\&\S+)?#i'; |
| 1352 |
preg_match($reg, $url, $m); |
| 1353 |
if (!empty($m) && isset($m[1], $m[4])) { |
| 1354 |
$type = ($m[1] === 'youtube.com' || strpos($m[1], 'youtu') !== false) ? 'youtube' : ($m[1] === 'vimeo.com' || strpos($m[1], 'vimeo') ? 'vimeo' : false); |
| 1355 |
if ($type !== false) { |
| 1356 |
$id = $m[4]; |
| 1357 |
$query_args = array(); |
| 1358 |
if ($type !== 'youtube' && isset($m[6])) {//h query argument should be first in vimeo |
| 1359 |
$query_args['h'] = $m[6]; |
| 1360 |
} |
| 1361 |
$query_args += array( |
| 1362 |
'pip' => 1, |
| 1363 |
'playsinline' => 1 |
| 1364 |
); |
| 1365 |
$params = parse_url($url); |
| 1366 |
if (!empty($params['query'])) { |
| 1367 |
parse_str($params['query'], $output); |
| 1368 |
unset($output['v']); |
| 1369 |
$query_args += $output; |
| 1370 |
unset($output); |
| 1371 |
} |
| 1372 |
if ($type === 'youtube') { |
| 1373 |
$allow = 'accelerometer;encrypted-media;gyroscope;picture-in-picture;fullscreen'; |
| 1374 |
$src = 'https://www.youtube'; |
| 1375 |
if (!empty($args['privacy'])) { |
| 1376 |
$src .= '-nocookie'; |
| 1377 |
} |
| 1378 |
$src .= '.com/embed/' . $id; |
| 1379 |
if (!empty($args['start']) ) { |
| 1380 |
$query_args['start'] = (float) $args['start']; |
| 1381 |
} |
| 1382 |
elseif (!empty($params['fragment'])) { |
| 1383 |
$query_args['start'] = (float) $params['fragment']; |
| 1384 |
if(empty($query_args['start'])){ |
| 1385 |
unset($query_args['start']); |
| 1386 |
} |
| 1387 |
} |
| 1388 |
if (!empty($args['end'])) { |
| 1389 |
$query_args['end'] = (float) $args['end']; |
| 1390 |
} |
| 1391 |
} |
| 1392 |
else { |
| 1393 |
|
| 1394 |
$allow = 'fullscreen'; |
| 1395 |
$src = 'https://player.vimeo.com/video/' . $id; |
| 1396 |
if (!empty($args['start'])) { |
| 1397 |
$src .= '#t=' . $args['start']; |
| 1398 |
} elseif (!empty($params['fragment'])) { |
| 1399 |
$src .= '#' . $params['fragment']; |
| 1400 |
} |
| 1401 |
if (!empty($args['privacy'])) { |
| 1402 |
$query_args['dnt'] = 1; |
| 1403 |
} |
| 1404 |
$query_args['byline'] =$query_args['title'] = $query_args['portrait'] = 0; |
| 1405 |
} |
| 1406 |
unset( |
| 1407 |
$params, |
| 1408 |
$query_args['modestbranding'], |
| 1409 |
$query_args['controls'], |
| 1410 |
$query_args['loop'], |
| 1411 |
$query_args['mute'], |
| 1412 |
$query_args['muted'] |
| 1413 |
); |
| 1414 |
if (!empty($args['hide_controls'])) { |
| 1415 |
$query_args['controls'] = 0; |
| 1416 |
} |
| 1417 |
|
| 1418 |
if (!empty($args['loop'])) { |
| 1419 |
$query_args['loop'] = 1; |
| 1420 |
if (!isset($query_args['playlist'])) { |
| 1421 |
$query_args['playlist'] = $id; |
| 1422 |
} |
| 1423 |
} |
| 1424 |
if (!empty($args['autoplay']) || !empty($query_args['autoplay'])) { |
| 1425 |
$allow .= ';autoplay'; |
| 1426 |
$query_args['autoplay'] = 1; |
| 1427 |
} |
| 1428 |
if (!empty($args['muted'])) { |
| 1429 |
if ($type === 'youtube') { |
| 1430 |
$query_args['mute'] = 1; |
| 1431 |
} else { |
| 1432 |
$query_args['muted'] = 1; |
| 1433 |
} |
| 1434 |
} |
| 1435 |
$lazy = !empty($args['disable_lazy']) ? ' data-no-script' : ''; |
| 1436 |
$src .= '?' . http_build_query($query_args); |
| 1437 |
$class=isset($args['class'])?$args['class']:'tf_abs tf_w tf_h'; |
| 1438 |
return '<iframe' . $lazy . ' src="' . esc_url( $src ) . '" allow="' . $allow . '" class="'.$class.'"></iframe>'; |
| 1439 |
} |
| 1440 |
} |
| 1441 |
return ''; |
| 1442 |
} |
| 1443 |
|
| 1444 |
function themify_enque_style(string $handle,string $src = '',?array $deps = array(),?string $ver = THEMIFY_VERSION,?string $media = 'all', bool $in_footer = false) { |
| 1445 |
Themify_Enqueue_Assets::add_css($handle, $src, $deps, $ver, $media, $in_footer); |
| 1446 |
} |
| 1447 |
|
| 1448 |
function themify_enque_script(string $handle, string $src = '', string $ver = THEMIFY_VERSION,?array $deps = array(), bool $in_footer = true) { |
| 1449 |
Themify_Enqueue_Assets::add_js($handle, $src, $deps, $ver, $in_footer); |
| 1450 |
} |
| 1451 |
|
| 1452 |
if (!function_exists('themify_get_query_categories')) { |
| 1453 |
|
| 1454 |
function themify_get_query_categories():array { |
| 1455 |
global $themify; |
| 1456 |
|
| 1457 |
$taxes = $themify->query_category == '0' ? themify_get_all_terms_ids($themify->query_taxonomy) : explode(',', str_replace(' ', '', $themify->query_category)); |
| 1458 |
if (empty($taxes) || is_wp_error($taxes)) { |
| 1459 |
$taxes= array(); |
| 1460 |
} |
| 1461 |
return $taxes; |
| 1462 |
} |
| 1463 |
|
| 1464 |
} |
| 1465 |
|
| 1466 |
/** |
| 1467 |
* Returns the URL to the WooCommerce Shop page |
| 1468 |
* |
| 1469 |
* @return string |
| 1470 |
* @since 4.5.7 |
| 1471 |
*/ |
| 1472 |
function themify_get_shop_permalink():string { |
| 1473 |
static $link = null; |
| 1474 |
if ($link === null) { |
| 1475 |
$id = themify_shop_pageId(); |
| 1476 |
$link = !empty($id) ? get_permalink($id) : ''; |
| 1477 |
} |
| 1478 |
return $link; |
| 1479 |
} |
| 1480 |
|
| 1481 |
function themify_is_login_page():bool { |
| 1482 |
static $is = null; |
| 1483 |
if ($is === null) { |
| 1484 |
global $pagenow; |
| 1485 |
$is = !empty($pagenow) && in_array($pagenow, array('wp-login.php', 'wp-register.php'), true); |
| 1486 |
} |
| 1487 |
return $is; |
| 1488 |
} |
| 1489 |
|
| 1490 |
function themify_is_ajax():bool { |
| 1491 |
static $is = null; |
| 1492 |
if ($is === null) { |
| 1493 |
$is = defined('DOING_AJAX') || (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'); |
| 1494 |
} |
| 1495 |
return $is; |
| 1496 |
} |
| 1497 |
|
| 1498 |
function themify_is_rest():bool { |
| 1499 |
static $is = null; |
| 1500 |
if ($is === null) { |
| 1501 |
$is = (defined('REST_REQUEST') && REST_REQUEST) || strpos($_SERVER['REQUEST_URI'], '/wp-json/') !== false; |
| 1502 |
} |
| 1503 |
return $is; |
| 1504 |
} |
| 1505 |
|
| 1506 |
function themify_is_lazyloading():bool { |
| 1507 |
static $is = null; |
| 1508 |
if ($is === null) { |
| 1509 |
$is = !themify_builder_check('setting-disable-lazy', 'performance-disable-lazy', true); |
| 1510 |
if ($is === true) { |
| 1511 |
global $wp_customize; |
| 1512 |
$is = !is_admin() && themify_is_ajax() === false && !isset($_GET['tf-scroll']) && !isset($_GET['post_in_lightbox']) && themify_is_prefetch_request() === false && (!class_exists('Themify_Builder',false) || !Themify_Builder_Model::is_front_builder_activate()) && !( $wp_customize instanceof WP_Customize_Manager && $wp_customize->is_preview()); |
| 1513 |
if ($is === true) { |
| 1514 |
$is = apply_filters('tf_lazy_enable', true); |
| 1515 |
} |
| 1516 |
} else { |
| 1517 |
add_filter('wp_lazy_loading_enabled', '__return_false', 100); |
| 1518 |
} |
| 1519 |
} |
| 1520 |
return $is; |
| 1521 |
} |
| 1522 |
|
| 1523 |
function themify_make_lazy(?string $html, bool $load = true):?string {//@todo move to class |
| 1524 |
if (isset($html) && (strpos($html, ' src=') !== false || strpos($html, '<audio') !== false || strpos($html, '<video') !== false)) { |
| 1525 |
$tags = array( |
| 1526 |
'img' => '<img.+?>', |
| 1527 |
'iframe' => '<iframe.+?>.*?<\/iframe>', |
| 1528 |
'audio' => '<audio.+?>.*?<\/audio>', |
| 1529 |
'video' => '<video.+?>.*?<\/video>' |
| 1530 |
); |
| 1531 |
$hasLazy = themify_is_lazyloading(); |
| 1532 |
if($hasLazy===false){ |
| 1533 |
unset($tags['img'],$tags['iframe']); |
| 1534 |
} |
| 1535 |
foreach ($tags as $k => $v) { |
| 1536 |
if (strpos($html, '<' . $k) === false) { |
| 1537 |
unset($tags[$k]); |
| 1538 |
} |
| 1539 |
} |
| 1540 |
if (empty($tags)) { |
| 1541 |
return $html; |
| 1542 |
} |
| 1543 |
if (isset($tags['img']) || isset($tags['iframe'])) {//skip noscript img/iframe |
| 1544 |
preg_match_all('/<noscript>.*?<\/noscript>/is', $html, $m); |
| 1545 |
if (!empty($m[0])) { |
| 1546 |
$search = $replace = array(); |
| 1547 |
$m = !is_array($m[0]) ? array($m[0]) : $m[0]; |
| 1548 |
foreach ($m as $item) { |
| 1549 |
$orig = $item; |
| 1550 |
$item = str_replace(array("\r" . 'src=', "\n" . 'src='), ' src=', $item); |
| 1551 |
if (strpos($item, ' src=') !== false && strpos($item, 'data-no-script') === false && (strpos($item, '<img') !== false || strpos($item, '<iframe') !== false)) { |
| 1552 |
$search[] = $orig; |
| 1553 |
$replace[] = str_replace(' src=', ' data-no-script src=', $item); |
| 1554 |
} |
| 1555 |
} |
| 1556 |
unset($m); |
| 1557 |
if (!empty($search)) { |
| 1558 |
$html = str_replace($search, $replace, $html); |
| 1559 |
} |
| 1560 |
} |
| 1561 |
} |
| 1562 |
|
| 1563 |
$reg = '/' . implode('|', $tags) . '/is'; |
| 1564 |
preg_match_all($reg, $html, $matches); |
| 1565 |
unset($reg); |
| 1566 |
if (!empty($matches[0])) { |
| 1567 |
$svgRows=4; |
| 1568 |
$svgStep=round(100/$svgRows,2); |
| 1569 |
$count = 0; |
| 1570 |
$search = $replace = array(); |
| 1571 |
$matches = !is_array($matches[0]) ? array($matches[0]) : $matches[0]; |
| 1572 |
$tags = array_keys($tags); |
| 1573 |
$extCount = count($tags) - 1; |
| 1574 |
$placeHolder="data:image/svg+xml,%3Csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20width='{w}'%20height='{h}'%20viewBox=%270%200%20{w}%20{h}%27%3E%3C/svg%3E"; |
| 1575 |
if ($load === false) {//$load need for some modules,which should be init and than load images(e.g slider) |
| 1576 |
$stopLazy = false; |
| 1577 |
$useJs = $isJsLazy=true; |
| 1578 |
} |
| 1579 |
else{ |
| 1580 |
$_WITHOUTLAZY_ =2; |
| 1581 |
$stopLazy = $useJs =$isJsLazy= false; |
| 1582 |
} |
| 1583 |
foreach ($matches as $item) { |
| 1584 |
if (!empty($item) && strpos($item, 'data-lazy', 4) === false && strpos($item, 'data-tf-src', 4) === false && strpos($item, 'data-no-script', 4) === false && strpos($item, 'data:image/', 4) === false && strpos($item, 'display:none', 4) === false && strpos($item, 'application/x-mpegURL', 4) === false && strpos($item, 'display: none', 4) === false && ($count !== 0 || strpos($item, 'gravatar.com', 4) === false)) { |
| 1585 |
if (strpos($item, 'data-tf-not-load', 4) === false) { |
| 1586 |
for ($i = $extCount; $i > -1; --$i) { |
| 1587 |
if (strpos($item, '<' . $tags[$i]) !== false) { |
| 1588 |
$ext = $tags[$i]; |
| 1589 |
break; |
| 1590 |
} |
| 1591 |
} |
| 1592 |
if (!isset($ext)) { |
| 1593 |
continue; |
| 1594 |
} |
| 1595 |
$orig = $item; |
| 1596 |
$item = preg_replace('/\s+/', ' ', $item); |
| 1597 |
if (($ext === 'audio' || $ext === 'video') && (strpos($item, 'wcmp-player') !== false || strpos($item, 'data-lazyloading=') !== false || strpos($item, 'mejs__player') !== false || strpos($item, 'vjs-tech') !== false || strpos($item, 'product_video_gallery_for_wc') !== false)) { |
| 1598 |
continue; |
| 1599 |
} |
| 1600 |
if ($ext !== 'audio') { |
| 1601 |
preg_match('/ src=["\']([^"]+?)["\']/', $item, $image_src,0,4); |
| 1602 |
} |
| 1603 |
if ($ext === 'audio' || $ext === 'video' || !empty($image_src[1])) { |
| 1604 |
$url = $ext === 'audio' ? true : (isset($image_src[1]) ? trim($image_src[1]) : ''); |
| 1605 |
unset($image_src); |
| 1606 |
if ($url === '' && $ext === 'video') { |
| 1607 |
$url = true; |
| 1608 |
} |
| 1609 |
if ($url !== '') { |
| 1610 |
if ($url !== true && $url[0] === '{') { |
| 1611 |
continue; |
| 1612 |
} |
| 1613 |
if ($ext === 'img') {//skip large images converting,otherwise can crash the site |
| 1614 |
if (strpos($item, ' srcset', 4) !== false) { |
| 1615 |
preg_match('/ srcset=["\']([^"]+?)["\']/', $item, $srcset,0,4); |
| 1616 |
$srcset=$srcset[1]??''; |
| 1617 |
}else{ |
| 1618 |
$srcset=''; |
| 1619 |
} |
| 1620 |
if ($count === 0) { |
| 1621 |
$srcSetSizes=''; |
| 1622 |
if ($srcset!=='') { |
| 1623 |
preg_match('/ sizes=["\']([^"]+?)["\']/', $item, $srcSetSizes,0,4); |
| 1624 |
$srcSetSizes = $srcSetSizes[1] ?? ''; |
| 1625 |
} |
| 1626 |
Themify_Enqueue_Assets::addPreLoadMedia($url, 'preload', 'image', $srcset, $srcSetSizes, 'high'); //load the first images in the page with preload for fast LCP |
| 1627 |
unset($srcSetSizes); |
| 1628 |
} |
| 1629 |
if(strpos($item, 'tf_large_img') === false){ |
| 1630 |
themify_generateWebp($url); |
| 1631 |
if ($srcset!=='') { |
| 1632 |
foreach ( explode(',', trim($srcset)) as $_src) { |
| 1633 |
$tmpS = trim(explode(' ', trim($_src))[0]); |
| 1634 |
if ($tmpS !== '' && strpos($tmpS, 'data:image') === false) { |
| 1635 |
themify_generateWebp($tmpS); |
| 1636 |
} |
| 1637 |
} |
| 1638 |
unset($tmpS,$srcset,$_src); |
| 1639 |
} |
| 1640 |
if (strpos($item, ' data-src', 4) !== false) { |
| 1641 |
preg_match('/ data-src=["\']([^"]+?)["\']/', $item, $tmpsrc,0,4); |
| 1642 |
if (!empty($tmpsrc[1])) { |
| 1643 |
themify_generateWebp($tmpsrc[1]); |
| 1644 |
} |
| 1645 |
$tmpsrc = null; |
| 1646 |
} |
| 1647 |
} |
| 1648 |
} |
| 1649 |
if (strpos($item, 'data-src', 4) !== false || ($hasLazy === false && $ext !== 'audio' && $ext !== 'video')) { |
| 1650 |
continue; |
| 1651 |
} |
| 1652 |
$s = ''; |
| 1653 |
if ($ext === 'audio' || $ext === 'video') { |
| 1654 |
$s = ' data-lazy="1"'; |
| 1655 |
if (strpos($item, 'preload="none"', 6) === false) { |
| 1656 |
$s .= ' preload="none"'; |
| 1657 |
$item = str_replace(array('preload="auto"', 'preload="metadata"'), '', $item); |
| 1658 |
} |
| 1659 |
} else { |
| 1660 |
if($isJsLazy===false) { |
| 1661 |
$stopLazy = $count < $_WITHOUTLAZY_; /* skip the first $_WITHOUTLAZY_ matches, assume they're above the fold */ |
| 1662 |
$useJs = $count > 9; |
| 1663 |
++$count; |
| 1664 |
} |
| 1665 |
if ($ext === 'iframe') { |
| 1666 |
if ($stopLazy === false) { |
| 1667 |
if (strpos($item, ' loading=', 6) === false) { |
| 1668 |
$s .= ' loading="lazy"'; |
| 1669 |
} |
| 1670 |
if ($isJsLazy === true) { |
| 1671 |
$s .= ' data-lazy="1" src="about:blank" data-tf-not-load="1"'; |
| 1672 |
$class = 'tf_iframe_lazy'; |
| 1673 |
if (strpos($item, 'class=', 6) === false) { |
| 1674 |
$s .= ' class="' . $class . '"'; |
| 1675 |
} else { |
| 1676 |
$item = str_replace(' class="', ' class="' . $class . ' ', $item); |
| 1677 |
} |
| 1678 |
$item = strtr($item, array(' src=' => ' data-tf-src=')); |
| 1679 |
} |
| 1680 |
} |
| 1681 |
else { |
| 1682 |
$s .= ' data-tf-not-load="1"'; |
| 1683 |
} |
| 1684 |
} |
| 1685 |
elseif ($ext === 'img') { |
| 1686 |
$sizes = themify_get_image_size($url,false,$stopLazy===false && $useJs===true?$svgRows:0); |
| 1687 |
if ($stopLazy === false) { |
| 1688 |
$useJs = $isJsLazy === true || $useJs === true; |
| 1689 |
if (strpos($item, ' loading=', 4) === false) { |
| 1690 |
$s .= ' loading="lazy"'; |
| 1691 |
} |
| 1692 |
if ($useJs === true) { |
| 1693 |
$s .= ' data-lazy="1"'; |
| 1694 |
if($isJsLazy===true){ |
| 1695 |
$s .= ' data-tf-not-load="1"'; |
| 1696 |
} |
| 1697 |
$class = 'tf_svg_lazy'; |
| 1698 |
if (strpos($item, ' class=', 4) === false) { |
| 1699 |
$s .= ' class="' . $class . '"'; |
| 1700 |
} else { |
| 1701 |
$item = str_replace(' class="', ' class="' . $class . ' ', $item); |
| 1702 |
} |
| 1703 |
$width=$height=0; |
| 1704 |
if(!empty($sizes)){ |
| 1705 |
$width=$sizes['w']; |
| 1706 |
$height=$sizes['h']; |
| 1707 |
if(!empty($sizes['c'])){ |
| 1708 |
$color=''; |
| 1709 |
foreach($sizes['c'] as $i=>$c){ |
| 1710 |
if($i%$svgRows===0){ |
| 1711 |
$j=1; |
| 1712 |
if($color!==''){ |
| 1713 |
$color.='),'; |
| 1714 |
} |
| 1715 |
$color.='linear-gradient(to right'; |
| 1716 |
} |
| 1717 |
$color.=',#'.$c; |
| 1718 |
if($j!==1 ){ |
| 1719 |
$color.=' '.($j-1)*$svgStep.'%'; |
| 1720 |
} |
| 1721 |
if($j!==$svgRows){ |
| 1722 |
$color.=' '.$j*$svgStep.'%'; |
| 1723 |
} |
| 1724 |
++$j; |
| 1725 |
} |
| 1726 |
$color='background:'.$color.')'; |
| 1727 |
if (strpos($item, ' style=', 4) === false) { |
| 1728 |
$s .= ' style="'.$color.'"'; |
| 1729 |
} else { |
| 1730 |
$item = str_replace(' style="', ' style="' . $color . ';', $item); |
| 1731 |
} |
| 1732 |
} |
| 1733 |
}else{ |
| 1734 |
if(strpos($item, ' width=', 4)!==false){ |
| 1735 |
preg_match('/ width=["\']([^"]+?)["\']/', $item, $w,0,4); |
| 1736 |
if(!empty($w[1])){ |
| 1737 |
$width=$w[1]; |
| 1738 |
unset($w); |
| 1739 |
} |
| 1740 |
} |
| 1741 |
if (strpos($item, ' height=', 4) === false) { |
| 1742 |
preg_match('/ height=["\']([^"]+?)["\']/', $item, $h,0,4); |
| 1743 |
$height=!empty($h[1])?$h[1]:$width; |
| 1744 |
unset($h); |
| 1745 |
} |
| 1746 |
elseif(!empty($width)){ |
| 1747 |
$height=$width; |
| 1748 |
} |
| 1749 |
} |
| 1750 |
$item = strtr($item, array(' srcset=' => ' data-tf-srcset=', ' sizes=' => ' data-tf-sizes=', ' src=' => ' data-tf-src=')); //sizes need to be replaced to pass html validation |
| 1751 |
$s = ' src="' . strtr($placeHolder, array('{w}'=>$width,'{h}'=>$height)) . '"' . $s; |
| 1752 |
} |
| 1753 |
} |
| 1754 |
else { |
| 1755 |
$s = ' data-tf-not-load="1"'; |
| 1756 |
if ($count === 1) { |
| 1757 |
if (strpos($s, 'fetchpriority=') === false) { |
| 1758 |
$s .= ' fetchpriority="high"'; |
| 1759 |
} |
| 1760 |
$s .= ' loading="auto" decoding="auto"'; |
| 1761 |
} |
| 1762 |
} |
| 1763 |
if (strpos($item, ' decoding=', 4) === false) { |
| 1764 |
$s .= ' decoding="async"'; |
| 1765 |
} |
| 1766 |
if(!empty($sizes)){ |
| 1767 |
if (strpos($item, ' width=', 4) === false) { |
| 1768 |
$s .= ' width="' . $sizes['w'] . '"'; |
| 1769 |
} |
| 1770 |
if (strpos($item, ' height=', 4) === false) { |
| 1771 |
$s .= ' height="' . $sizes['h'] . '"'; |
| 1772 |
} |
| 1773 |
} |
| 1774 |
unset($sizes); |
| 1775 |
} |
| 1776 |
} |
| 1777 |
$item = str_replace('<' . $ext, '<' . $ext . $s, $item); |
| 1778 |
if ($ext === 'audio' || $ext === 'video') { |
| 1779 |
$c = 'tf_lazy tf_' . ($ext === 'video' ? 'vd' : $ext) . '_lazy tf_w tf_rel tf_box'; |
| 1780 |
$r = array(); |
| 1781 |
if (strpos($item, ' data-lazy') !== false) { |
| 1782 |
$r['<' . $ext] = '<' . $ext . ' data-lazy="1"'; |
| 1783 |
} |
| 1784 |
if ($ext === 'video') { |
| 1785 |
$c .= ' tf_rel tf_overflow'; |
| 1786 |
themify_get_icon('fas volume-mute', 'fa'); |
| 1787 |
themify_get_icon('fas volume-up', 'fa'); |
| 1788 |
//themify_get_icon('fas undo', 'fa'); |
| 1789 |
//themify_get_icon('fas redo', 'fa'); |
| 1790 |
//themify_get_icon('far closed-captioning', 'fa'); |
| 1791 |
themify_get_icon('fas external-link-alt', 'fa'); |
| 1792 |
themify_get_icon('fas airplay', 'fa'); |
| 1793 |
themify_get_icon('fas expand', 'fa'); |
| 1794 |
themify_get_icon('fas download', 'fa'); |
| 1795 |
if (strpos($item, ' poster') !== false) { |
| 1796 |
$r[' poster'] = ' data-poster'; |
| 1797 |
} |
| 1798 |
if ($url && $url !== true && strpos($item, ' width') === false || strpos($item, ' height') === false) { |
| 1799 |
$size = themify_get_video_size($url); |
| 1800 |
if ($size !== null) { |
| 1801 |
$sv = ''; |
| 1802 |
if ($size['w'] !== '' && strpos($item, ' width') === false) { |
| 1803 |
$sv = ' width="' . $size['w'] . '"'; |
| 1804 |
} |
| 1805 |
if ($size['h'] !== '' && strpos($item, ' height') === false) { |
| 1806 |
$sv .= ' height="' . $size['h'] . '"'; |
| 1807 |
} |
| 1808 |
if ($sv !== '') { |
| 1809 |
$r[' preload'] = $sv . ' preload'; |
| 1810 |
} |
| 1811 |
$sv = null; |
| 1812 |
} |
| 1813 |
} |
| 1814 |
} |
| 1815 |
if (strpos($item, ' autoplay') !== false) { |
| 1816 |
$r[' autoplay'] = ' data-autoplay'; |
| 1817 |
} |
| 1818 |
if (!empty($r)) { |
| 1819 |
$item = strtr($item, $r); |
| 1820 |
} |
| 1821 |
unset($r); |
| 1822 |
$item = '<div class="' . $c . '" data-playtitle="' . esc_attr__( 'Play/Pause', 'themify' ) . '" data-next="' . esc_attr__( 'Next', 'themify' ) . '" data-prev="' . esc_attr__( 'Previous', 'themify' ) . '" data-timeslider="' . esc_attr__( 'Time Slider', 'themify' ) . '">' . $item . '</div>'; |
| 1823 |
$c = null; |
| 1824 |
} |
| 1825 |
$part = $item; |
| 1826 |
if ($ext === 'img' && $stopLazy === false && $useJs === true) { |
| 1827 |
$part .= '<noscript>' . strtr($orig, array(' src=' => ' data-tf-not-load src=')) . '</noscript>'; |
| 1828 |
} |
| 1829 |
$search[] = $orig; |
| 1830 |
$replace[] = $part; |
| 1831 |
} |
| 1832 |
} |
| 1833 |
} else { |
| 1834 |
++$count; |
| 1835 |
} |
| 1836 |
} |
| 1837 |
} |
| 1838 |
unset($matches, $tags, $extCount); |
| 1839 |
$html = str_replace($search, $replace, $html); |
| 1840 |
} |
| 1841 |
} |
| 1842 |
return $html; |
| 1843 |
} |
| 1844 |
|
| 1845 |
function themify_upload_dir(string $mode = 'all', bool $reinit = false) { |
| 1846 |
static $dir = null; |
| 1847 |
if ($dir === null || $reinit === true) { |
| 1848 |
/* foolproof the paths, in case they mistakenly have trailing slash */ |
| 1849 |
$dir = array_map('untrailingslashit', wp_get_upload_dir()); |
| 1850 |
$dir['baseurl'] = themify_https_esc($dir['baseurl']); |
| 1851 |
} |
| 1852 |
|
| 1853 |
return $mode === 'all' ? $dir : $dir[$mode]; |
| 1854 |
} |
| 1855 |
|
| 1856 |
function themify_generateWebp(string $url):string { |
| 1857 |
if (empty($url)) { |
| 1858 |
return $url; |
| 1859 |
} |
| 1860 |
static $is = null; |
| 1861 |
if ($is === null) { |
| 1862 |
$is = !themify_builder_check('setting-webp', 'performance-webp', true) ? true : (is_admin() && !themify_is_ajax()); |
| 1863 |
} |
| 1864 |
if ($is === true) { |
| 1865 |
return $url; |
| 1866 |
} |
| 1867 |
return themify_create_webp($url); |
| 1868 |
} |
| 1869 |
|
| 1870 |
function themify_is_prefetch_request():bool { |
| 1871 |
static $is = null; |
| 1872 |
if ($is === null) { |
| 1873 |
if (isset($_SERVER['HTTP_PURPOSE'])) { |
| 1874 |
$prev = 'HTTP_PURPOSE'; |
| 1875 |
} elseif (isset($_SERVER["HTTP_X_PURPOSE"])) { |
| 1876 |
$prev = 'HTTP_X_PURPOSE'; |
| 1877 |
} elseif (isset($_SERVER['HTTP_X_MOZ'])) { |
| 1878 |
$prev = 'HTTP_X_MOZ'; |
| 1879 |
} else { |
| 1880 |
$prev = false; |
| 1881 |
} |
| 1882 |
if ($prev !== false) { |
| 1883 |
$prev = strtolower($_SERVER[$prev]); |
| 1884 |
$is = $prev === 'prefetch' || $prev === 'preview'; |
| 1885 |
} else { |
| 1886 |
$is = false; |
| 1887 |
} |
| 1888 |
} |
| 1889 |
return $is; |
| 1890 |
} |
| 1891 |
|
| 1892 |
function themify_is_dev_mode():bool { |
| 1893 |
static $is = null; |
| 1894 |
if ($is === null) { |
| 1895 |
$is = themify_check('setting-dev-mode', true) || (defined('THEMIFY_DEV') && THEMIFY_DEV); |
| 1896 |
$is = apply_filters('themify_dev_mode', $is); |
| 1897 |
} |
| 1898 |
return $is; |
| 1899 |
} |
| 1900 |
|
| 1901 |
function themify_is_concate_disabled():bool { |
| 1902 |
$disable_dev_concate = themify_check('setting-dev-mode-concate', true) || (defined('THEMIFY_DEV') && THEMIFY_DEV); |
| 1903 |
$dev_context = themify_check('setting-dev-mode', true) |
| 1904 |
|| (defined('THEMIFY_DEV') && THEMIFY_DEV) |
| 1905 |
|| (class_exists('Themify_Builder_Model', false) && Themify_Builder_Model::is_front_builder_activate()); |
| 1906 |
$is_disabled = themify_check('setting-disable-concate-css', true) |
| 1907 |
|| (defined('THEMIFY_DISABLE_CONCATE_CSS') && THEMIFY_DISABLE_CONCATE_CSS) |
| 1908 |
|| ($disable_dev_concate && $dev_context); |
| 1909 |
|
| 1910 |
return apply_filters('themify_disable_concate_css', $is_disabled); |
| 1911 |
} |
| 1912 |
|
| 1913 |
function themify_is_amp():bool { |
| 1914 |
static $is = null; |
| 1915 |
if ($is !== null) { |
| 1916 |
return $is; |
| 1917 |
} |
| 1918 |
$is = false; |
| 1919 |
if ((function_exists('amp_is_request') && amp_is_request()) |
| 1920 |
|| (function_exists('is_amp_endpoint') && is_amp_endpoint()) |
| 1921 |
|| (function_exists('ampforwp_is_amp_endpoint') && ampforwp_is_amp_endpoint())) { |
| 1922 |
$is = true; |
| 1923 |
} |
| 1924 |
return (bool) apply_filters('themify_is_amp', $is); |
| 1925 |
} |
| 1926 |
|
| 1927 |
function themify_disable_other_lazy() { |
| 1928 |
add_filter('wp_lazy_loading_enabled', '__return_false', 100); |
| 1929 |
add_filter('lazyload_is_enabled', '__return_false', 1, 100); //disable jetpack lazy load |
| 1930 |
add_filter('rocket_use_native_lazyload', '__return_false', 1, 100); |
| 1931 |
} |
| 1932 |
|
| 1933 |
function themify_get_server():string { |
| 1934 |
static $is = null; |
| 1935 |
if ($is === null) { |
| 1936 |
$is = 'apache'; |
| 1937 |
if (!empty($_SERVER['SERVER_SOFTWARE'])) { |
| 1938 |
$is = explode('/', $_SERVER['SERVER_SOFTWARE']); |
| 1939 |
$is = str_replace('microsoft-', '', strtolower($is[0])); |
| 1940 |
} elseif (is_file(get_home_path() . 'web.config')) { |
| 1941 |
$is = 'iis'; |
| 1942 |
} elseif (!is_file(Themify_Enqueue_Assets::getHtaccessFile()) || is_file('/etc/nginx/nginx.conf')) { |
| 1943 |
$is = 'nginx'; |
| 1944 |
} |
| 1945 |
} |
| 1946 |
return $is; |
| 1947 |
} |
| 1948 |
|
| 1949 |
/** |
| 1950 |
* Help tooltip Module |
| 1951 |
*/ |
| 1952 |
function themify_help(string $content):string { |
| 1953 |
return sprintf('<span class="tf_help"><i tabindex="-1" class="icon" onclick="return false;">%s</i><span class="tf_help_content">%s</span></span>', |
| 1954 |
themify_get_icon('ti-help', 'ti'), |
| 1955 |
$content |
| 1956 |
); |
| 1957 |
} |
| 1958 |
|
| 1959 |
/** |
| 1960 |
* Search $subject for $search and replace the first occurrence of it. |
| 1961 |
* |
| 1962 |
* @return string |
| 1963 |
*/ |
| 1964 |
function themify_str_replace_first(string $search, string $replace,string $subject):string { |
| 1965 |
return implode($replace, explode($search, $subject, 2)); |
| 1966 |
} |
| 1967 |
|
| 1968 |
/** |
| 1969 |
* Search $subject for $search and replace the last occurrence of it. |
| 1970 |
* |
| 1971 |
* @return string |
| 1972 |
*/ |
| 1973 |
function themify_str_replace_last(string $search, string $replace, string $subject):string { |
| 1974 |
if (( $pos = strrpos($subject, $search) ) !== false) { |
| 1975 |
$subject = substr_replace($subject, $replace, $pos, strlen($search)); |
| 1976 |
} |
| 1977 |
|
| 1978 |
return $subject; |
| 1979 |
} |
| 1980 |
|
| 1981 |
/** |
| 1982 |
* Gets the ID of an object (post or term) and returns that object ID in current language. |
| 1983 |
* |
| 1984 |
* @return int|mixed |
| 1985 |
*/ |
| 1986 |
function themify_maybe_translate_object_id(?int $id, string $type = 'page'):?int { |
| 1987 |
if (!empty($id)) { |
| 1988 |
if (defined('ICL_SITEPRESS_VERSION')) { |
| 1989 |
$id = apply_filters('wpml_object_id', $id, $type, true); |
| 1990 |
} elseif (defined('POLYLANG_VERSION') && function_exists('pll_get_post')) { |
| 1991 |
$translatedpageid = pll_get_post($id); |
| 1992 |
if (!empty($translatedpageid) && 'publish' === get_post_status($translatedpageid)) { |
| 1993 |
$id = $translatedpageid; |
| 1994 |
} |
| 1995 |
} |
| 1996 |
} |
| 1997 |
|
| 1998 |
return $id; |
| 1999 |
} |
| 2000 |
|
| 2001 |
/** |
| 2002 |
* Returns and caches URL to the homepage, properly filtered for multilingual setups |
| 2003 |
* |
| 2004 |
* @return string |
| 2005 |
*/ |
| 2006 |
function themify_home_url():string { |
| 2007 |
static $url = null; |
| 2008 |
if ($url === null) { |
| 2009 |
$url = function_exists('pll_home_url') ? pll_home_url() : home_url(); |
| 2010 |
} |
| 2011 |
return $url; |
| 2012 |
} |
| 2013 |
|
| 2014 |
/** |
| 2015 |
* Download file from external URL and returns the file |
| 2016 |
* |
| 2017 |
* @param $post_id Attachments may be associated with a parent post or page. |
| 2018 |
* |
| 2019 |
* @return WP_Error|int ID of created attachment, or WP_Error |
| 2020 |
*/ |
| 2021 |
function tf_fetch_remote_file($url, $post_id = null, $title = '') { |
| 2022 |
|
| 2023 |
// extract the file name and extension from the url |
| 2024 |
$file_name = basename($url); |
| 2025 |
|
| 2026 |
// get placeholder file in the upload dir with a unique, sanitized filename |
| 2027 |
$upload = wp_upload_bits($file_name, 0, ''); |
| 2028 |
if ($upload['error']) |
| 2029 |
return new WP_Error('upload_dir_error', $upload['error']); |
| 2030 |
|
| 2031 |
// fetch the remote url and write it to the placeholder file |
| 2032 |
$remote_response = wp_safe_remote_get($url, array( |
| 2033 |
'timeout' => 300, |
| 2034 |
'stream' => true, |
| 2035 |
'filename' => $upload['file'], |
| 2036 |
)); |
| 2037 |
|
| 2038 |
$headers = wp_remote_retrieve_headers($remote_response); |
| 2039 |
|
| 2040 |
// request failed |
| 2041 |
if (!$headers) { |
| 2042 |
@unlink($upload['file']); |
| 2043 |
return new WP_Error('import_file_error', __('Remote server did not respond', 'themify')); |
| 2044 |
} |
| 2045 |
|
| 2046 |
$remote_response_code = wp_remote_retrieve_response_code($remote_response); |
| 2047 |
|
| 2048 |
// make sure the fetch was successful |
| 2049 |
if ($remote_response_code != '200') { |
| 2050 |
@unlink($upload['file']); |
| 2051 |
return new WP_Error('import_file_error', sprintf(__('Remote server returned error response %1$d %2$s', 'themify'), esc_html($remote_response_code), get_status_header_desc($remote_response_code))); |
| 2052 |
} |
| 2053 |
|
| 2054 |
$filesize = filesize($upload['file']); |
| 2055 |
|
| 2056 |
if (0 == $filesize) { |
| 2057 |
@unlink($upload['file']); |
| 2058 |
return new WP_Error('import_file_error', __('Zero size file downloaded', 'themify')); |
| 2059 |
} |
| 2060 |
|
| 2061 |
$post = array( |
| 2062 |
'post_title' => $title, |
| 2063 |
'post_content' => '', |
| 2064 |
'post_status' => 'inherit', |
| 2065 |
); |
| 2066 |
if ($info = wp_check_filetype($upload['file'])) |
| 2067 |
$post['post_mime_type'] = $info['type']; |
| 2068 |
else |
| 2069 |
return new WP_Error('mime_type_error', __('Invalid file type', 'themify')); |
| 2070 |
|
| 2071 |
$attach_id = wp_insert_attachment($post, $upload['file'], $post_id); |
| 2072 |
wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $upload['file'])); |
| 2073 |
|
| 2074 |
return $attach_id; |
| 2075 |
} |
| 2076 |
|
| 2077 |
/** |
| 2078 |
* Mimics get_template_part but loads a template from THEMIFY_DIR |
| 2079 |
* |
| 2080 |
* @since 5.5.3 |
| 2081 |
*/ |
| 2082 |
function themify_get_template(string $slug, string $name = '', array $args = array()) { |
| 2083 |
$base_dir = THEMIFY_DIR; |
| 2084 |
$templates = array(); |
| 2085 |
$located = ''; |
| 2086 |
if ($name !== null && '' !== $name) { |
| 2087 |
$templates[] = "{$base_dir}/{$slug}-{$name}.php"; |
| 2088 |
} |
| 2089 |
|
| 2090 |
$templates[] = "{$base_dir}/{$slug}.php"; |
| 2091 |
|
| 2092 |
foreach ($templates as $template) { |
| 2093 |
if (is_file($template)) { |
| 2094 |
$located = $template; |
| 2095 |
break; |
| 2096 |
} |
| 2097 |
} |
| 2098 |
|
| 2099 |
if ($located !== '') { |
| 2100 |
load_template($located, false, $args); |
| 2101 |
} |
| 2102 |
} |
| 2103 |
|
| 2104 |
/* Map assigned terms to filter taxonomy term IDs (matches by slug across taxonomies). */ |
| 2105 |
if ( ! function_exists( 'themify_map_term_to_filter_taxonomy' ) ) : |
| 2106 |
function themify_map_term_to_filter_taxonomy( $term, $filter_taxonomy ) { |
| 2107 |
if ( ! $term || is_wp_error( $term ) || ! taxonomy_exists( $filter_taxonomy ) ) { |
| 2108 |
return false; |
| 2109 |
} |
| 2110 |
if ( $term->taxonomy === $filter_taxonomy ) { |
| 2111 |
return $term; |
| 2112 |
} |
| 2113 |
$slug = $term->slug; |
| 2114 |
while ( $slug !== '' ) { |
| 2115 |
$match = get_term_by( 'slug', $slug, $filter_taxonomy ); |
| 2116 |
if ( $match && ! is_wp_error( $match ) ) { |
| 2117 |
return $match; |
| 2118 |
} |
| 2119 |
$pos = strrpos( $slug, '-' ); |
| 2120 |
if ( false === $pos ) { |
| 2121 |
break; |
| 2122 |
} |
| 2123 |
$slug = substr( $slug, 0, $pos ); |
| 2124 |
} |
| 2125 |
return false; |
| 2126 |
} |
| 2127 |
endif; |
| 2128 |
|
| 2129 |
if ( ! function_exists( 'themify_get_cross_taxonomy_term_ids' ) ) : |
| 2130 |
function themify_get_cross_taxonomy_term_ids( $filter_term, $object_taxonomy ): array { |
| 2131 |
if ( ! $filter_term || is_wp_error( $filter_term ) || ! taxonomy_exists( $object_taxonomy ) ) { |
| 2132 |
return array(); |
| 2133 |
} |
| 2134 |
if ( $filter_term->taxonomy === $object_taxonomy ) { |
| 2135 |
return array( (int) $filter_term->term_id ); |
| 2136 |
} |
| 2137 |
$ids = array(); |
| 2138 |
foreach ( array_unique( array( $filter_term->slug, $filter_term->slug . '-product' ) ) as $slug ) { |
| 2139 |
$term = get_term_by( 'slug', $slug, $object_taxonomy ); |
| 2140 |
if ( ! $term || is_wp_error( $term ) ) { |
| 2141 |
continue; |
| 2142 |
} |
| 2143 |
$ids[] = (int) $term->term_id; |
| 2144 |
$children = get_term_children( $term->term_id, $object_taxonomy ); |
| 2145 |
if ( ! is_wp_error( $children ) && ! empty( $children ) ) { |
| 2146 |
$ids = array_merge( $ids, array_map( 'intval', $children ) ); |
| 2147 |
} |
| 2148 |
} |
| 2149 |
return array_values( array_unique( $ids ) ); |
| 2150 |
} |
| 2151 |
endif; |
| 2152 |
|
| 2153 |
if ( ! function_exists( 'themify_normalize_filter_taxonomy' ) ) : |
| 2154 |
function themify_normalize_filter_taxonomy( $taxonomy, $post_type, $fallback = '' ) { |
| 2155 |
$taxonomy = sanitize_key( (string) $taxonomy ); |
| 2156 |
$fallback = sanitize_key( (string) $fallback ); |
| 2157 |
if ( is_array( $post_type ) ) { |
| 2158 |
$post_type = reset( $post_type ); |
| 2159 |
} |
| 2160 |
$post_type = sanitize_key( (string) $post_type ); |
| 2161 |
if ( $post_type === 'product' ) { |
| 2162 |
if ( $taxonomy === 'category' || ( $taxonomy === '' && ( $fallback === 'category' || $fallback === '' ) ) ) { |
| 2163 |
return 'product_cat'; |
| 2164 |
} |
| 2165 |
if ( $taxonomy === 'tag' || ( $taxonomy === '' && $fallback === 'tag' ) ) { |
| 2166 |
return 'product_tag'; |
| 2167 |
} |
| 2168 |
if ( $taxonomy === '' ) { |
| 2169 |
return $fallback !== '' ? $fallback : 'product_cat'; |
| 2170 |
} |
| 2171 |
return $taxonomy; |
| 2172 |
} |
| 2173 |
if ( $taxonomy === '' ) { |
| 2174 |
return $fallback !== '' ? $fallback : 'category'; |
| 2175 |
} |
| 2176 |
return $taxonomy; |
| 2177 |
} |
| 2178 |
endif; |
| 2179 |
|
| 2180 |
if ( ! function_exists( 'themify_get_post_filter_classes' ) ) : |
| 2181 |
function themify_get_post_filter_classes( $object_id, $filter_taxonomy ): array { |
| 2182 |
$classes = array(); |
| 2183 |
if ( ! taxonomy_exists( $filter_taxonomy ) ) { |
| 2184 |
return $classes; |
| 2185 |
} |
| 2186 |
$post_type = get_post_type( $object_id ); |
| 2187 |
if ( ! $post_type ) { |
| 2188 |
return $classes; |
| 2189 |
} |
| 2190 |
$added = array(); |
| 2191 |
foreach ( get_object_taxonomies( $post_type, 'names' ) as $taxonomy ) { |
| 2192 |
$terms = wp_get_object_terms( $object_id, $taxonomy ); |
| 2193 |
if ( is_wp_error( $terms ) || empty( $terms ) ) { |
| 2194 |
continue; |
| 2195 |
} |
| 2196 |
foreach ( $terms as $term ) { |
| 2197 |
$filter_term = themify_map_term_to_filter_taxonomy( $term, $filter_taxonomy ); |
| 2198 |
if ( $filter_term && ! isset( $added[ $filter_term->term_id ] ) ) { |
| 2199 |
$classes[] = 'cat-' . $filter_term->term_id; |
| 2200 |
$added[ $filter_term->term_id ] = true; |
| 2201 |
} |
| 2202 |
} |
| 2203 |
} |
| 2204 |
return $classes; |
| 2205 |
} |
| 2206 |
endif; |
| 2207 |
|
| 2208 |
if ( ! function_exists( 'themify_build_filter_tax_query' ) ) : |
| 2209 |
function themify_build_filter_tax_query( $filter_taxonomy, $term_id, $post_type ): array { |
| 2210 |
$term_id = (int) $term_id; |
| 2211 |
if ( $term_id <= 0 || ! taxonomy_exists( $filter_taxonomy ) ) { |
| 2212 |
return array(); |
| 2213 |
} |
| 2214 |
if ( is_array( $post_type ) ) { |
| 2215 |
$post_type = reset( $post_type ); |
| 2216 |
} |
| 2217 |
$filter_term = get_term( $term_id, $filter_taxonomy ); |
| 2218 |
if ( ! $filter_term || is_wp_error( $filter_term ) ) { |
| 2219 |
return array( |
| 2220 |
array( |
| 2221 |
'taxonomy' => $filter_taxonomy, |
| 2222 |
'field' => 'term_id', |
| 2223 |
'terms' => $term_id, |
| 2224 |
'operator' => 'IN', |
| 2225 |
), |
| 2226 |
); |
| 2227 |
} |
| 2228 |
$queries = array(); |
| 2229 |
foreach ( get_object_taxonomies( $post_type, 'names' ) as $taxonomy ) { |
| 2230 |
if ( $taxonomy === $filter_taxonomy ) { |
| 2231 |
$queries[] = array( |
| 2232 |
'taxonomy' => $taxonomy, |
| 2233 |
'field' => 'term_id', |
| 2234 |
'terms' => (int) $filter_term->term_id, |
| 2235 |
'operator' => 'IN', |
| 2236 |
); |
| 2237 |
continue; |
| 2238 |
} |
| 2239 |
$term_ids = themify_get_cross_taxonomy_term_ids( $filter_term, $taxonomy ); |
| 2240 |
if ( ! empty( $term_ids ) ) { |
| 2241 |
$queries[] = array( |
| 2242 |
'taxonomy' => $taxonomy, |
| 2243 |
'field' => 'term_id', |
| 2244 |
'terms' => $term_ids, |
| 2245 |
'operator' => 'IN', |
| 2246 |
); |
| 2247 |
} |
| 2248 |
} |
| 2249 |
if ( empty( $queries ) ) { |
| 2250 |
return array( |
| 2251 |
array( |
| 2252 |
'taxonomy' => $filter_taxonomy, |
| 2253 |
'field' => 'term_id', |
| 2254 |
'terms' => $term_id, |
| 2255 |
'operator' => 'IN', |
| 2256 |
), |
| 2257 |
); |
| 2258 |
} |
| 2259 |
if ( count( $queries ) === 1 ) { |
| 2260 |
return $queries; |
| 2261 |
} |
| 2262 |
return array_merge( array( 'relation' => 'OR' ), $queries ); |
| 2263 |
} |
| 2264 |
endif; |
| 2265 |
|
| 2266 |
/* Add category id class in post loop for Masonry filter */ |
| 2267 |
if ( ! function_exists( 'themify_post_filter_class' ) ) : |
| 2268 |
function themify_post_filter_class(array $classes, $class, $post_id):array { |
| 2269 |
$filter_tax = get_query_var( 'tf_query_tax', 'category' ); |
| 2270 |
foreach ( themify_get_post_filter_classes( $post_id, $filter_tax ) as $cat_class ) { |
| 2271 |
$classes[] = ' ' . $cat_class; |
| 2272 |
} |
| 2273 |
if ( true === get_query_var( 'tf_ajax_filter', false ) ) { |
| 2274 |
if ( isset( $_POST['action'], $_POST['tax'] ) && $_POST['action'] === 'themify_ajax_load_more' ) { |
| 2275 |
$classes[] = 'ajax-cat-' . (int) $_POST['tax']; |
| 2276 |
} else { |
| 2277 |
$classes[] = 'initial-cat'; |
| 2278 |
} |
| 2279 |
} |
| 2280 |
return $classes; |
| 2281 |
} |
| 2282 |
endif; |
| 2283 |
|
| 2284 |
function themify_custom_except($excerpt) { |
| 2285 |
if (has_excerpt()) { |
| 2286 |
$excerpt = wp_trim_words(get_the_excerpt(), apply_filters('excerpt_length', 55)); |
| 2287 |
} |
| 2288 |
return $excerpt; |
| 2289 |
} |
| 2290 |
|
| 2291 |
function themify_set_headers(array $headers) { |
| 2292 |
if (!headers_sent()) { |
| 2293 |
$list = headers_list(); |
| 2294 |
foreach ($list as $h) { |
| 2295 |
$head = strtoupper(trim(explode(':', $h)[0])); |
| 2296 |
if (isset($headers[$head])) { |
| 2297 |
$vals = trim(trim(str_ireplace($head, '', $h)), ':'); |
| 2298 |
if ($head === 'CONTENT-SECURITY-POLICY' || is_array($headers[$head])) { |
| 2299 |
$vals = explode(';', $vals); |
| 2300 |
$policy = $headers[$head]; |
| 2301 |
$hasChange = false; |
| 2302 |
foreach ($vals as $i => $c) { |
| 2303 |
$c = trim($c); |
| 2304 |
if ($c !== '') { |
| 2305 |
$c = preg_replace('!\s+!', ' ', $c); |
| 2306 |
$values = explode(' ', $c); |
| 2307 |
if (isset($policy[$values[0]])) { |
| 2308 |
$none = array_search('none', $values, true); |
| 2309 |
if ($none !== false) { |
| 2310 |
unset($values[$none]); |
| 2311 |
} |
| 2312 |
$values = array_merge($values, explode(' ', $policy[$values[0]])); |
| 2313 |
$vals[$i] = implode(' ', array_keys(array_flip($values))); |
| 2314 |
$hasChange = true; |
| 2315 |
} |
| 2316 |
} else { |
| 2317 |
unset($vals[$i]); |
| 2318 |
} |
| 2319 |
} |
| 2320 |
if ($hasChange === true) { |
| 2321 |
header($head . ':' . implode(';', $vals)); |
| 2322 |
} |
| 2323 |
} elseif ($vals !== $headers[$head]) { |
| 2324 |
header($head . ':' . $headers[$head]); |
| 2325 |
} |
| 2326 |
unset($headers[$head]); |
| 2327 |
if (empty($headers)) { |
| 2328 |
break; |
| 2329 |
} |
| 2330 |
} |
| 2331 |
} |
| 2332 |
} |
| 2333 |
} |
| 2334 |
|
| 2335 |
function themify_get_lottie(array $arr, string $sel = '') { |
| 2336 |
|
| 2337 |
if (!empty($arr['path']) && !empty($arr['seg'])) { |
| 2338 |
$lottie = array( |
| 2339 |
'path' => $arr['path'], |
| 2340 |
'seg' => $arr['seg'] |
| 2341 |
); |
| 2342 |
if (!empty($arr['st'])) { |
| 2343 |
$lottie['st'] = $arr['st']; |
| 2344 |
} |
| 2345 |
if (isset($arr['sp']) && $arr['sp'] != 1) { |
| 2346 |
$lottie['sp'] = $arr['sp']; |
| 2347 |
} |
| 2348 |
if (!empty($arr['dir'])) { |
| 2349 |
$lottie['dir'] = $arr['dir']; |
| 2350 |
} |
| 2351 |
if (!empty($arr['fid'])) { |
| 2352 |
$lottie['fid'] = $arr['fid']; |
| 2353 |
} |
| 2354 |
if (isset($arr['r']) && $arr['r'] !== 'svg') { |
| 2355 |
$lottie['r'] = $arr['r']; |
| 2356 |
} |
| 2357 |
if (isset($arr['count']) && ($arr['count'] > 1 || $arr['count'] == -1)) { |
| 2358 |
$lottie['count'] = $arr['count']; |
| 2359 |
} |
| 2360 |
if ($sel !== '') { |
| 2361 |
$lottie['sel'] = $sel; |
| 2362 |
} |
| 2363 |
if (!isset($arr['lp'])) { |
| 2364 |
$lottie = array('actions' => $lottie, 'loop' => 1); |
| 2365 |
} |
| 2366 |
return sprintf('<tf-lottie data-lazy="1" class="tf_lazy"><template>%s</template></tf-lottie>', json_encode($lottie)); |
| 2367 |
} |
| 2368 |
return ''; |
| 2369 |
} |
| 2370 |
|
| 2371 |
/** |
| 2372 |
* Load/Check minified file is exist |
| 2373 |
*/ |
| 2374 |
function themify_enque(string $url, bool $check = false, bool $cdn = true) {//backward |
| 2375 |
return $check===true?false:$url; |
| 2376 |
} |
| 2377 |
|
| 2378 |
function themify_is_minify_enabled():bool{//backward |
| 2379 |
return false; |
| 2380 |
} |
| 2381 |
|
| 2382 |
function themify_whitelist_tag( string $input, string $default = 'div' ) : string { |
| 2383 |
if ( ! in_array( $input, [ 'div', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'nav' ], true ) ) { |
| 2384 |
return $default; |
| 2385 |
} else { |
| 2386 |
return $input; |
| 2387 |
} |
| 2388 |
} |
| 2389 |
|
| 2390 |
/** |
| 2391 |
* Uses wp_safe_remote_get and retries once with sslverify=false only if the first request fails. |
| 2392 |
* |
| 2393 |
* @since 7.0.0 |
| 2394 |
*/ |
| 2395 |
function themify_safe_remote_get_with_ssl_fallback( string $url, array $args = array() ) { |
| 2396 |
$defaults = array( |
| 2397 |
'timeout' => 5, |
| 2398 |
'redirection' => 3, |
| 2399 |
'sslverify' => true, |
| 2400 |
); |
| 2401 |
$args = wp_parse_args( $args, $defaults ); |
| 2402 |
|
| 2403 |
$resp = wp_safe_remote_get( $url, $args ); |
| 2404 |
if ( is_wp_error( $resp ) ) { |
| 2405 |
// Backward-compatibility: some hosts may still have SSL chain issues. |
| 2406 |
$args['sslverify'] = false; |
| 2407 |
$resp = wp_safe_remote_get( $url, $args ); |
| 2408 |
} |
| 2409 |
return $resp; |
| 2410 |
} |
| 2411 |
|
| 2412 |
|
| 2413 |
if ( ! function_exists( 'themify_safe_gzbase64_decode' ) ) : |
| 2414 |
/** |
| 2415 |
* Safely base64-decode and gzdecode a payload with size limits. |
| 2416 |
* |
| 2417 |
* @param string $payload Base64 string. |
| 2418 |
* @param int $max_decoded_bytes Maximum decoded bytes allowed. |
| 2419 |
* @param int $max_encoded_bytes Maximum base64 string length allowed. |
| 2420 |
* |
| 2421 |
* @return string|false Decoded string on success, false on failure. |
| 2422 |
*/ |
| 2423 |
function themify_safe_gzbase64_decode( $payload, $max_decoded_bytes = 10485760, $max_encoded_bytes = 15728640 ) { |
| 2424 |
if ( ! is_string( $payload ) || $payload === '' ) { |
| 2425 |
return false; |
| 2426 |
} |
| 2427 |
$len = strlen( $payload ); |
| 2428 |
if ( $len > $max_encoded_bytes ) { |
| 2429 |
return false; |
| 2430 |
} |
| 2431 |
|
| 2432 |
$decoded = base64_decode( $payload, true ); |
| 2433 |
if ( $decoded === false ) { |
| 2434 |
return false; |
| 2435 |
} |
| 2436 |
if ( strlen( $decoded ) > $max_decoded_bytes ) { |
| 2437 |
return false; |
| 2438 |
} |
| 2439 |
|
| 2440 |
$out = function_exists( 'gzdecode' ) ? @gzdecode( $decoded ) : false; |
| 2441 |
if ( $out === false ) { |
| 2442 |
return false; |
| 2443 |
} |
| 2444 |
return $out; |
| 2445 |
} |
| 2446 |
endif; |
| 2447 |
|
| 2448 |
|