: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
if(strpos($arr['src'],'fonts.gstatic')!==false){
$fkey=$arr['font-family'];
if(isset($arr['font-style'])){
$fkey.=$arr['font-style'];
if(isset($arr['font-weight'])){
$fkey.=$arr['font-weight'];
if(isset($arr['unicode-range'])){
$fkey.=$arr['unicode-range'];
$googleFontsUrl='https:'.$arr['src'];
$slug=Themify_Storage::getHash($fkey);
$query = "SELECT ID FROM $wpdb->posts WHERE post_type='attachment' AND post_parent=0 AND %s LIMIT 1";
$attachment=$wpdb->get_row(sprintf($query,'post_name="'.esc_sql($slug).'"'));
$filename=basename($googleFontsUrl);
$attachment=$wpdb->get_row( sprintf($query, 'guid LIKE "%'.esc_sql($filename).'"'));
$url=!empty($attachment)?wp_get_attachment_url($attachment->ID):false;
if($url!==false && !is_file(get_attached_file($attachment->ID))){
wp_delete_attachment($attachment->ID,true);
if($url===false && $i<$maximum && !Themify_Storage::get($slug)){
Themify_Storage::set($slug,1,MINUTE_IN_SECONDS*2);//set a value to block others threads
$tmp = download_url($googleFontsUrl,10,false );
if(!is_wp_error( $tmp )){
'size' => filesize($tmp),
$desc=array(trim(str_replace(array('"',"'"),'',$arr['font-family'])));
if(!empty($arr['subset'])){
$desc[]=trim(str_replace(array('/','*'),'',$arr['subset']));
$desc[]=$arr['font-style'];
$desc[]=$arr['font-weight'];
$attach_id=media_handle_sideload( $file, 0,$filename,array(
'post_mime_type'=>'font/woff2',
'post_content'=>'Google Font: '.implode('-',$desc),
if(!is_wp_error($attach_id)){
$url=wp_get_attachment_url($attach_id);
$gfFonts[$googleFontsUrl]=$url;
unset($desc,$file,$attach_id);
Themify_Storage::delete($slug);
Themify_Filesystem::delete($tmp,'f');
$gfFonts[$googleFontsUrl]=$url;
$arr['src']=$url===false?$googleFontsUrl:$url;
foreach($arr as $prop=>$vv){
$vv='url('.$vv.') format("woff2")';
remove_filter('wp_handle_sideload_overrides',array(__CLASS__,'sideload_overrides_google_fonts'),9999);
if(($isNew===true && !$donwload) || !empty($gfFonts)){
$tmp =Themify_Storage::get($_key,'tf_fg_css_');//maybe another thread has changed it
$css=strtr($tmp,$gfFonts);
$css = str_replace(array("\r\n","\n","\r","\t"),'',$css);
$css = preg_replace('!\s+!',' ',$css);
$css = str_replace(array(' {',' }','{ ','; ',': ',', '),array('{','}','{',';',':',','),$css);
$css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
$css=str_replace(array('font-style:normal;','font-weight:400;'),'',$css);
Themify_Storage::set($_key, $css, MONTH_IN_SECONDS * 6,'tf_fg_css_');
Themify_Storage::delete($_key,'tf_fg_css_');
$path = ( is_ssl() ? 'https' : 'http' ) . $path;
$css='<link rel="preload" fetchpriority="high" as="style" href="' . $path . '"><link fetchpriority="high" id="themify-google-fonts-css" rel="stylesheet" href="' . $path . '">';
$css='<style id="tf_gf_fonts_style">'.$css.'</style>';
public static function sideload_overrides_google_fonts(array $overrides):array{
$overrides['test_size']=$overrides['test_type']=false;
public static function addGoogleFont(array $fonts) {
if(!in_array($v,self::$googleFonts,true)){
self::$googleFonts[] = $v;
public static function addMobileMenuCss(string $handler, string $src) {
if (!isset(self::$css['mobile_concate'][$handler]) && !isset(self::$done[$src])) {
self::$done[$src] = true;
self::$css['mobile_concate'][$handler] = $src;
public static function preLoadAnimtion(bool $only_css = false) {
self::addPreLoadCss(self::THEMIFY_CSS_MODULES_URI . 'animate.min.css');
if ($only_css === false) {
self::addPreLoadJs(THEMIFY_URI . '/js/modules/animate.js');
public static function preLoadSwiperJs(string $type = 'prefetch',string $only = 'all') {
$url = THEMIFY_URI . '/js/modules/themify-carousel.js';
$sw_url = THEMIFY_URI . '/js/modules/swiper/swiper.min.js';
$sw_css = self::THEMIFY_CSS_MODULES_URI . 'swiper/swiper.css';
if ($type === 'prefetch') {
if ($only === 'all' || $only === 'css') {
self::addPrefetchCss($sw_css);
if ($only === 'all' || $only === 'js') {
self::addPrefetchJs($url);
self::addPrefetchJs($sw_url);
if ($only === 'all' || $only === 'css') {
self::addPreLoadCss($sw_css);
if ($only === 'all' || $only === 'js') {
self::addPreLoadJs($url);
self::addPreLoadJs($sw_url);
public static function preFetchFixedHeaderJs(string $type = 'prefetch') {
$url = THEMIFY_URI . '/js/modules/fixedheader.js';
if ($type === 'prefetch') {
self::addPrefetchJs($url);
self::addPreLoadJs($url);
public static function preFetchSideMenuJs(string $type = 'prefetch') {
$url = THEMIFY_URI . '/js/modules/themify-sidemenu.js';
if ($type === 'prefetch') {
self::addPrefetchJs($url);
self::addPreLoadJs($url);
public static function preFetchAnimtion(bool $only_css = false) {
self::addPrefetchCss(self::THEMIFY_CSS_MODULES_URI . 'animate.min.css');
if ($only_css === false) {
self::addPrefetchJs(THEMIFY_URI . '/js/modules/animate.js');
public static function clearConcateCss($blog_id = false) {
$cache_type = $blog_id === 'all' && is_multisite()? 'all' : 'blog';
$dir = self::getCurrentVersionFolder(($cache_type === 'all' ? false : $blog_id));
if ($cache_type === 'all') {
$concate_dir = '/themify-concate/';
$dir=dirname(str_replace($concate_dir, '', $dir));
if(strpos($dir,'/blogs.dir/')!==false){
$concate_dir='/files'.$concate_dir;
$dir = rtrim($dir, '/') . '/';
if (Themify_Filesystem::is_dir($dir) && ($handle = opendir($dir))) {
while (false !== ($f = readdir($handle))) {
if ($f !== '.' && $f !== '..') {
$f = $dir . $f . $concate_dir;
if (Themify_Filesystem::is_dir($f)) {
self::markAsDeleteCssFile($f);
self::markAsDeleteCssFile($dir);
TFCache::remove_cache($cache_type, false, $blog_id);
TFCache::clear_3rd_plugins_cache();
private static function markAsDeleteCssFile(string $dir) {
if (is_dir($dir) && ($handle = opendir($dir))) {
$dir = rtrim($dir, '/') . '/';
while (false !== ($f = readdir($handle))) {
if ($f !== '.' && $f !== '..') {
self::markAsDeleteCssFile($dir . $f);
$ext = pathinfo($f, PATHINFO_EXTENSION);
if ($ext !== 'cssdel' && strpos($ext, 'cssdel') === false && !Themify_Filesystem::is_file($f)) {
public static function wp_media_playlist(string $html,array $attr, $instance):string {
if (!isset($attr['type']) || $attr['type'] === 'audio') {
return self::audio_playlist($attr);
if($attr['type']==='video' && themify_is_ajax()){
remove_filter('post_playlist', array(__CLASS__, 'wp_media_playlist'), 100);
$html= themify_make_lazy(wp_playlist_shortcode($attr));
add_filter('post_playlist', array(__CLASS__, 'wp_media_playlist'), 100,3);
public static function audio_playlist(array $attr):string {
'orderby' => 'menu_order ID',
'id' => $post ? $post->ID : 0,
$showImages = !empty($atts['images']);
if (empty($attr['tracks'])) {
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => $atts['type'],
'order' => $atts['order'],
'orderby' => $atts['orderby'],
if (!empty($atts['include'])) {
$args['include'] = $atts['include'];
$_attachments = get_posts($args);
foreach ($_attachments as $val) {
$attachments[$val->ID] = $val;
$args['post_parent'] = $id;
if (!empty($atts['exclude'])) {
$args['exclude'] = $atts['exclude'];
$attachments = get_children($args);
if (empty($attachments)) {
foreach ($attachments as $att_id => $attachment) {
$output .= wp_get_attachment_link($att_id) . "\n";
$mime_types = wp_get_mime_types();
$metaArr = array('artist', 'album', 'length_formatted');
foreach ($attachments as $attachment) {
$url = wp_get_attachment_url($attachment->ID);
$ftype = wp_check_filetype($url, $mime_types);
'type' => $ftype['type'],
'title' => $attachment->post_title,
'caption' => $attachment->post_excerpt
$meta = wp_get_attachment_metadata($attachment->ID);
$track['meta'] = array();
foreach ($metaArr as $m) {
$track['meta'][$m] = $meta[$m];
if ($showImages === true) {
$thumb_id = get_post_thumbnail_id($attachment->ID);
list( $src, $width, $height ) = wp_get_attachment_image_src($thumb_id, 'thumbnail');
$src = wp_mime_type_icon($attachment->ID);
$track['thumb'] = array('src' => $src, 'width' => $width, 'height' => $height);
$mime_types = $metaArr = $attachments = null;
$tracks = $attr['tracks'];
'tracklist' => $atts['tracklist'] ? 1 : 0,
'tracknumbers' => $atts['tracknumbers'] ? 1 : 0,
'images' => $showImages === true ? 1 : 0,
'artists' => $atts['artists'] ? 1 : 0,
$autoplay = !empty($attr['autoplay']) ? ' data-autoplay="1"' : '';
$loop = !empty($attr['loop']) ? ' data-loop' : '';
$loop .= !empty($attr['muted']) ? ' muted' : '';
$output = '<div class="wp-audio-playlist">' . themify_make_lazy('<audio controls="controls" preload="none"' . $autoplay . $loop . '></audio>');
$output .= '<script type="application/json" class="tf-playlist-script">' . wp_json_encode($data) . '</script></div>';
public static function widget_css($instance, $thiz, $args) {
if ($id === 'themify-most-commented') {
$id = 'themify-feature-posts';
elseif ($id === 'themify-social-links') {
self::add_css('tf_theme_social_links', self::THEMIFY_CSS_MODULES_URI . 'social-links.css', null, THEMIFY_VERSION);
self::addLocalization('done', 'tf_theme_social_links', true);
if(isset(self::$theme_css_support['widget_'.$id])){
$k = 'tf_theme_widget_' . str_replace('-', '_', $id);
if (!isset(self::$css[$k])) {
self::add_css($k, self::$THEME_CSS_MODULES_URI . 'widgets/' . $id . '.css', null, self::$themeVersion);
self::addLocalization('done', $k, true);
public static function allow_lazy_protocols(array $protocols):array {
public static function audio_shortcode(string $html, array $attr, $media, $post_id, $library):string {
return $library === 'tf_lazy' ? themify_make_lazy($html) : $html;
public static function embed(string $cached_html, $url, $attr, $post_id):string {
return str_replace('data-secret','data-lazy data-secret',$cached_html);
public static function disable_playlist_template($type){
remove_action( 'wp_playlist_scripts', 'wp_playlist_scripts' );
public static function video_shortcode(string $html,array $attr, string $content, $instance):string {
if (apply_filters('wp_video_shortcode_library', 'mediaelement') === 'tf_lazy') {
if (!empty($attr['src'])) {
$video_url = parse_url($attr['src']);
if (isset($video_url['host']) && ($video_url['host'] === 'www.youtube.com' || $video_url['host'] === 'youtube.com' || $video_url['host'] === 'youtu.be' || $video_url['host'] === 'www.vimeo.com' || $video_url['host'] === 'vimeo.com' || $video_url['host'] === 'player.vimeo.com')) {
$html_atts['src'] = esc_url($attr['src']);
if(!empty($attr['disable_lazy'])){
$html_atts['data-skip'] = 1;
if (!empty($attr['id'])) {
$html_atts['id'] = $attr['id'];
if (!empty($attr['loop'])) {
if (!empty($attr['autoplay'])) {
$html_atts['data-autoplay'] = 1;
if (!empty($attr['class'])) {
$cl = trim(str_replace('wp-video-shortcode', '', $attr['class']));
$html_atts['class'] = $cl;
if (!empty($attr['width'])) {
$html_atts['width'] = $attr['width'];
if (!empty($attr['height'])) {
$html_atts['height'] = $attr['height'];
if (!empty($attr['poster'])) {
$html_atts['data-poster'] = esc_url($attr['poster']);
$muted = isset( $attr['muted'] ) ? wp_validate_boolean( $attr['muted'] ) : false;
$default_types = wp_get_video_extensions();
$default_types[] = 'mov';
foreach ( $default_types as $ext ) {
if (isset($attr[$ext])) {
$mimes = wp_get_mime_types();
if(!isset($html_atts['src']) || !isset($mimes[$ext])){
$type=wp_check_filetype($attr[$ext], $mimes);
if (isset($mimes[$ext])) {
$m = isset($type['type'])?$type['type']:null;
$source .= sprintf('<source type="%s" src="%s"/>', $m, esc_url($attr[$ext]));
if (!isset($html_atts['src']) && isset($type['ext']) && strtolower( $type['ext'] ) === $ext ) {
$html_atts['src'] = $attr[ $ext ];
if (!empty( $html_atts['src'] ) ) {
unset($mimes,$default_types);
if(!isset($html_atts['width']) || !isset($html_atts['height'])){
/* find video by their media type attribute */
$size=themify_get_video_size($html_atts['src']);
if(!isset($html_atts['width']) && $size['w']!==''){
$html_atts['width'] = $size['w'];