: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$shop_url = themify_get_shop_permalink(); //wc bug, page id isn't set from wc settings,the default should be page with slug 'shop'
if (isset($_SERVER['HTTP_HOST'])) {
$current_url .= $_SERVER['HTTP_HOST'];
$host = parse_url(home_url(), PHP_URL_HOST);
$current_url .= strtok($_SERVER['REQUEST_URI'], '?');
$is = $current_url === $shop_url;
* Modified version of wp_parse_args which adds filters to modify the args
function themify_parse_args($args, $defaults = '', $filter_key = '') {
// Setup a temporary array from $args
$r = get_object_vars($args);
} elseif (is_array($args)) {
// Passively filter the args before the parse
if (!empty($filter_key)) {
$r = apply_filters('themify_before_' . $filter_key . '_parse_args', $r);
if (is_array($defaults)) {
$r = array_merge($defaults, $r);
// Aggressively filter the args after the parse
if (!empty($filter_key)) {
$r = apply_filters('themify_after_' . $filter_key . '_parse_args', $r);
// Return the parsed results
* Display the Builder's backend editor in Themify Custom Panel
function themify_meta_field_page_builder() {
do_action('themify_builder_metabox');
* Get an array of key => value pairs and outputs them as HTML attributes
function themify_get_element_attributes(array $props):string {
foreach ($props as $k => $v) {
$out .= ' ' . $k . '="' . esc_attr($v) . '"';
* Get breakpoints settings
* if it's framework return customizer breakpoints,else if it's builder plugin builder breakpoints
* @return mixed array/int
function themify_get_breakpoints(string $select = 'all', bool $max_min = false) {
if (($select === 'all' && empty($res)) || (empty($res[$select]))) {
'tablet_landscape' => array(769, 1280),
'tablet' => array(681, 768),
foreach ($breakpoints as $bp => $value) {
$v = themify_builder_get('setting-customizer_responsive_design_' . $bp, 'builder_responsive_design_' . $bp);
$res[$bp][0] = $value[0];
$res['tablet'][0] = $res['mobile'] + 1;
$res['tablet_landscape'][0] = $res['tablet'][1] + 1;
return 'all' === $select ? $res : $res[$select];
* Unserialize data if it is serialized
* If PHP supports it disables unserializing PHP objects in order to prevent object injection.
* @param string $original Maybe unserialized original, if is needed.
* @return mixed Unserialized data can be any type.
function themify_maybe_unserialize(string $original) {
if (is_serialized($original)) { // don't attempt to unserialize data that wasn't serialized going in
return @unserialize($original, array('allowed_classes' => false));
* Must be used inside the loop
function themify_post_video(string $url = '', bool $echo = true) {
$video_file = $url ? $url : themify_get('video_url');
if (!empty($video_file)) {
if ('mp4' !== pathinfo($video_file, PATHINFO_EXTENSION)) {
$output = $wp_embed->run_shortcode('[embed]' . $video_file . '[/embed]');
$output = '<div class="post-video">';
$output .= do_shortcode('[video src="' . $video_file . '"]');
function themify_get_embed(string $url, array $args):string {
$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';
preg_match($reg, $url, $m);
if (!empty($m) && isset($m[1], $m[4])) {
$type = ($m[1] === 'youtube.com' || strpos($m[1], 'youtu') !== false) ? 'youtube' : ($m[1] === 'vimeo.com' || strpos($m[1], 'vimeo') ? 'vimeo' : false);
if ($type !== 'youtube' && isset($m[6])) {//h query argument should be first in vimeo
$query_args['h'] = $m[6];
$params = parse_url($url);
if (!empty($params['query'])) {
parse_str($params['query'], $output);
if ($type === 'youtube') {
$allow = 'accelerometer;encrypted-media;gyroscope;picture-in-picture;fullscreen';
$src = 'https://www.youtube';
if (!empty($args['privacy'])) {
$src .= '.com/embed/' . $id;
if (!empty($args['start']) ) {
$query_args['start'] = (float) $args['start'];
elseif (!empty($params['fragment'])) {
$query_args['start'] = (float) $params['fragment'];
if(empty($query_args['start'])){
unset($query_args['start']);
if (!empty($args['end'])) {
$query_args['end'] = (float) $args['end'];
$src = 'https://player.vimeo.com/video/' . $id;
if (!empty($args['start'])) {
$src .= '#t=' . $args['start'];
} elseif (!empty($params['fragment'])) {
$src .= '#' . $params['fragment'];
if (!empty($args['privacy'])) {
$query_args['byline'] =$query_args['title'] = $query_args['portrait'] = 0;
$query_args['modestbranding'],
if (!empty($args['hide_controls'])) {
$query_args['controls'] = 0;
if (!empty($args['loop'])) {
if (!isset($query_args['playlist'])) {
$query_args['playlist'] = $id;
if (!empty($args['autoplay']) || !empty($query_args['autoplay'])) {
$query_args['autoplay'] = 1;
if (!empty($args['muted'])) {
if ($type === 'youtube') {
$query_args['muted'] = 1;
$lazy = !empty($args['disable_lazy']) ? ' data-no-script' : '';
$src .= '?' . http_build_query($query_args);
$class=isset($args['class'])?$args['class']:'tf_abs tf_w tf_h';
return '<iframe' . $lazy . ' src="' . $src . '" allow="' . $allow . '" class="'.$class.'"></iframe>';
function themify_enque_style(string $handle,string $src = '',?array $deps = array(),?string $ver = THEMIFY_VERSION,?string $media = 'all', bool $in_footer = false) {
Themify_Enqueue_Assets::add_css($handle, $src, $deps, $ver, $media, $in_footer);
function themify_enque_script(string $handle, string $src = '', string $ver = THEMIFY_VERSION,?array $deps = array(), bool $in_footer = true) {
Themify_Enqueue_Assets::add_js($handle, $src, $deps, $ver, $in_footer);
if (!function_exists('themify_get_query_categories')) {
function themify_get_query_categories():array {
$taxes = $themify->query_category == '0' ? themify_get_all_terms_ids($themify->query_taxonomy) : explode(',', str_replace(' ', '', $themify->query_category));
if (empty($taxes) || is_wp_error($taxes)) {
* Returns the URL to the WooCommerce Shop page
function themify_get_shop_permalink():string {
$id = themify_shop_pageId();
$link = !empty($id) ? get_permalink($id) : '';
function themify_is_login_page():bool {
$is = !empty($pagenow) && in_array($pagenow, array('wp-login.php', 'wp-register.php'), true);
function themify_is_ajax():bool {
$is = defined('DOING_AJAX') || (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
function themify_is_rest():bool {
$is = (defined('REST_REQUEST') && REST_REQUEST) || strpos($_SERVER['REQUEST_URI'], '/wp-json/') !== false;
function themify_is_lazyloading():bool {
$is = !themify_builder_check('setting-disable-lazy', 'performance-disable-lazy', true);
$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());
$is = apply_filters('tf_lazy_enable', true);
add_filter('wp_lazy_loading_enabled', '__return_false', 100);
function themify_make_lazy(?string $html, bool $load = true):?string {//@todo move to class
if (isset($html) && (strpos($html, ' src=') !== false || strpos($html, '<audio') !== false || strpos($html, '<video') !== false)) {
'iframe' => '<iframe.+?>.*?<\/iframe>',
'audio' => '<audio.+?>.*?<\/audio>',
'video' => '<video.+?>.*?<\/video>'
$hasLazy = themify_is_lazyloading();
unset($tags['img'],$tags['iframe']);
foreach ($tags as $k => $v) {
if (strpos($html, '<' . $k) === false) {
if (isset($tags['img']) || isset($tags['iframe'])) {//skip noscript img/iframe
preg_match_all('/<noscript>.*?<\/noscript>/is', $html, $m);
$search = $replace = array();
$m = !is_array($m[0]) ? array($m[0]) : $m[0];
$item = str_replace(array("\r" . 'src=', "\n" . 'src='), ' src=', $item);
if (strpos($item, ' src=') !== false && strpos($item, 'data-no-script') === false && (strpos($item, '<img') !== false || strpos($item, '<iframe') !== false)) {
$replace[] = str_replace(' src=', ' data-no-script src=', $item);
$html = str_replace($search, $replace, $html);
$reg = '/' . implode('|', $tags) . '/is';
preg_match_all($reg, $html, $matches);
if (!empty($matches[0])) {
$svgStep=round(100/$svgRows,2);
$search = $replace = array();
$matches = !is_array($matches[0]) ? array($matches[0]) : $matches[0];
$tags = array_keys($tags);
$extCount = count($tags) - 1;
$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";
if ($load === false) {//$load need for some modules,which should be init and than load images(e.g slider)
$stopLazy = $useJs =$isJsLazy= false;
foreach ($matches as $item) {
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)) {
if (strpos($item, 'data-tf-not-load', 4) === false) {
for ($i = $extCount; $i > -1; --$i) {
if (strpos($item, '<' . $tags[$i]) !== false) {
$item = preg_replace('/\s+/', ' ', $item);
preg_match('/ src=["\']([^"]+?)["\']/', $item, $image_src,0,4);
if ($ext === 'audio' || $ext === 'video' || !empty($image_src[1])) {
$url = $ext === 'audio' ? true : (isset($image_src[1]) ? trim($image_src[1]) : '');
if ($url === '' && $ext === 'video') {
if ($url !== true && $url[0] === '{') {
if ($ext === 'img') {//skip large images converting,otherwise can crash the site
if (strpos($item, ' srcset', 4) !== false) {
preg_match('/ srcset=["\']([^"]+?)["\']/', $item, $srcset,0,4);
preg_match('/ sizes=["\']([^"]+?)["\']/', $item, $srcSetSizes,0,4);
$srcSetSizes = $srcSetSizes[1] ?? '';
Themify_Enqueue_Assets::addPreLoadMedia($url, 'preload', 'image', $srcset, $srcSetSizes, 'high'); //load the first images in the page with preload for fast LCP
if(strpos($item, 'tf_large_img') === false){
themify_generateWebp($url);
foreach ( explode(',', trim($srcset)) as $_src) {
$tmpS = trim(explode(' ', trim($_src))[0]);
if ($tmpS !== '' && strpos($tmpS, 'data:image') === false) {
themify_generateWebp($tmpS);
unset($tmpS,$srcset,$_src);
if (strpos($item, ' data-src', 4) !== false) {
preg_match('/ data-src=["\']([^"]+?)["\']/', $item, $tmpsrc,0,4);
if (!empty($tmpsrc[1])) {
themify_generateWebp($tmpsrc[1]);
if (strpos($item, 'data-src', 4) !== false || ($hasLazy === false && $ext !== 'audio' && $ext !== 'video')) {
if ($ext === 'audio' || $ext === 'video') {
if (strpos($item, 'preload="none"', 6) === false) {
$item = str_replace(array('preload="auto"', 'preload="metadata"'), '', $item);
$stopLazy = $count < $_WITHOUTLAZY_; /* skip the first $_WITHOUTLAZY_ matches, assume they're above the fold */
if ($stopLazy === false) {
if (strpos($item, ' loading=', 6) === false) {
if ($isJsLazy === true) {
$s .= ' data-lazy="1" src="about:blank" data-tf-not-load="1"';
$class = 'tf_iframe_lazy';
if (strpos($item, 'class=', 6) === false) {
$s .= ' class="' . $class . '"';
$item = str_replace(' class="', ' class="' . $class . ' ', $item);
$item = strtr($item, array(' src=' => ' data-tf-src='));
$s .= ' data-tf-not-load="1"';
elseif ($ext === 'img') {
$sizes = themify_get_image_size($url,false,$stopLazy===false && $useJs===true?$svgRows:0);
if ($stopLazy === false) {
$useJs = $isJsLazy === true || $useJs === true;
if (strpos($item, ' loading=', 4) === false) {