/**
* Bootstrap the plugin.
*
* @since 6.0
* @package Fusion-Core
* @subpackage Core
*/
// Load the instance of the plugin.
if ( ! class_exists( 'FusionCore_Plugin' ) ) {
require_once FUSION_CORE_PATH . '/includes/class-fusioncore-plugin.php';
}
add_action( 'plugins_loaded', [ 'FusionCore_Plugin', 'get_instance' ] );
/**
* Setup Fusion Slider.
*
* @since 3.1
* @return void
*/
function setup_fusion_slider() {
global $fusion_settings;
if ( ! $fusion_settings && class_exists( 'Fusion_Settings' ) ) {
$fusion_settings = Fusion_Settings::get_instance();
}
if ( ! class_exists( 'Fusion_Settings' ) || '0' !== $fusion_settings->get( 'status_fusion_slider' ) ) {
include_once FUSION_CORE_PATH . '/fusion-slider/class-fusion-slider.php';
}
}
// Setup Fusion Slider.
add_action( 'after_setup_theme', 'setup_fusion_slider', 10 );
/**
* Find and include all shortcodes within shortcodes folder.
*
* @since 3.1
* @return void
*/
function fusion_init_shortcodes() {
if ( class_exists( 'Avada' ) ) {
$filenames = glob( FUSION_CORE_PATH . '/shortcodes/*.php', GLOB_NOSORT );
foreach ( $filenames as $filename ) {
require_once wp_normalize_path( $filename );
}
}
}
// Load all shortcode elements.
add_action( 'fusion_builder_shortcodes_init', 'fusion_init_shortcodes' );
/**
* Load portfolio archive template from FC.
*
* @access public
* @since 3.1
* @param string $archive_post_template The post template.
* @return string
*/
function fusion_portfolio_archive_template( $archive_post_template ) {
$archive_portfolio_template = FUSION_CORE_PATH . '/templates/archive-avada_portfolio.php';
// Checks if the archive is portfolio.
if ( is_post_type_archive( 'avada_portfolio' )
|| is_tax( 'portfolio_category' )
|| is_tax( 'portfolio_skills' )
|| is_tax( 'portfolio_tags' ) ) {
if ( file_exists( $archive_portfolio_template ) ) {
fusion_portfolio_scripts();
return $archive_portfolio_template;
}
}
return $archive_post_template;
}
// Provide archive portfolio template via filter.
add_filter( 'archive_template', 'fusion_portfolio_archive_template' );
/**
* Enable Fusion Builder elements on activation.
*
* @access public
* @since 3.1
* @return void
*/
function fusion_core_enable_elements() {
if ( function_exists( 'fusion_builder_auto_activate_element' ) && version_compare( FUSION_BUILDER_VERSION, '1.0.6', '>' ) ) {
fusion_builder_auto_activate_element( 'fusion_portfolio' );
fusion_builder_auto_activate_element( 'fusion_faq' );
fusion_builder_auto_activate_element( 'fusion_fusionslider' );
fusion_builder_auto_activate_element( 'fusion_privacy' );
fusion_builder_auto_activate_element( 'fusion_tb_project_details' );
}
}
register_activation_hook( FUSION_CORE_MAIN_PLUGIN_FILE, 'fusion_core_activation' );
register_deactivation_hook( FUSION_CORE_MAIN_PLUGIN_FILE, 'fusion_core_deactivation' );
/**
* Runs on fusion core activation hook.
*/
function fusion_core_activation() {
// Reset patcher on activation.
fusion_core_reset_patcher_counter();
// Enable fusion core elements on activation.
fusion_core_enable_elements();
}
/**
* Runs on fusion core deactivation hook.
*/
function fusion_core_deactivation() {
// Reset patcher on deactivation.
fusion_core_reset_patcher_counter();
// Delete the option to flush rewrite rules after activation.
delete_option( 'fusion_core_flush_permalinks' );
}
/**
* Resets the patcher counters.
*/
function fusion_core_reset_patcher_counter() {
delete_site_transient( 'fusion_patcher_check_num' );
}
/**
* Instantiate the patcher class.
*/
function fusion_core_patcher_activation() {
if ( class_exists( 'Fusion_Patcher' ) ) {
new Fusion_Patcher(
[
'context' => 'fusion-core',
'version' => FUSION_CORE_VERSION,
'name' => 'Fusion-Core',
'parent_slug' => 'avada',
'page_title' => esc_attr__( 'Fusion Patcher', 'fusion-core' ),
'menu_title' => esc_attr__( 'Fusion Patcher', 'fusion-core' ),
'classname' => 'FusionCore_Plugin',
]
);
}
}
add_action( 'after_setup_theme', 'fusion_core_patcher_activation', 17 );
/**
* Add content filter if WPTouch is active.
*
* @access public
* @since 3.1.1
* @return void
*/
function fusion_wptouch_compatiblity() {
global $wptouch_pro;
if ( true === $wptouch_pro->is_mobile_device ) {
add_filter( 'the_content', 'fusion_remove_orphan_shortcodes', 0 );
}
}
add_action( 'wptouch_pro_loaded', 'fusion_wptouch_compatiblity', 11 );
/**
* Add custom thumnail column.
*
* @since 5.3
* @access public
* @param array $existing_columns Array of existing columns.
* @return array The modified columns array.
*/
function fusion_wp_list_add_column( $existing_columns ) {
if ( ! class_exists( 'Avada' ) ) {
return $existing_columns;
}
$columns = [
'cb' => $existing_columns['cb'],
'tf_thumbnail' => '' . esc_attr__( 'Image', 'fusion-core' ) . '',
];
return array_merge( $columns, $existing_columns );
}
// Add thumbnails to blog, portfolio, FAQs, Fusion Slider and Elastic Slider.
add_filter( 'manage_post_posts_columns', 'fusion_wp_list_add_column', 10 );
add_filter( 'manage_avada_portfolio_posts_columns', 'fusion_wp_list_add_column', 10 );
add_filter( 'manage_avada_faq_posts_columns', 'fusion_wp_list_add_column', 10 );
add_filter( 'manage_slide_posts_columns', 'fusion_wp_list_add_column', 10 );
add_filter( 'manage_themefusion_elastic_posts_columns', 'fusion_wp_list_add_column', 10 );
/**
* Renders the contents of the thumbnail column.
*
* @since 5.3
* @access public
* @param string $column current column name.
* @param int $post_id cureent post ID.
* @return void
*/
function fusion_add_thumbnail_in_column( $column, $post_id ) {
if ( ! class_exists( 'Avada' ) ) {
return;
}
switch ( $column ) {
case 'tf_thumbnail':
echo '';
if ( has_post_thumbnail( $post_id ) ) {
echo get_the_post_thumbnail( $post_id, 'thumbnail' );
} else {
echo '
';
}
echo '';
break;
}
}
add_action( 'manage_post_posts_custom_column', 'fusion_add_thumbnail_in_column', 10, 2 );
add_action( 'manage_avada_portfolio_posts_custom_column', 'fusion_add_thumbnail_in_column', 10, 2 );
add_action( 'manage_avada_faq_posts_custom_column', 'fusion_add_thumbnail_in_column', 10, 2 );
add_action( 'manage_slide_posts_custom_column', 'fusion_add_thumbnail_in_column', 10, 2 );
add_action( 'manage_themefusion_elastic_posts_custom_column', 'fusion_add_thumbnail_in_column', 10, 2 );
/**
* Removes unregistered shortcodes.
*
* @access public
* @since 3.1.1
* @param string $content item content.
* @return string
*/
function fusion_remove_orphan_shortcodes( $content ) {
if ( false === strpos( $content, '[fusion' ) ) {
return $content;
}
global $shortcode_tags;
// Check for active shortcodes.
$active_shortcodes = ( is_array( $shortcode_tags ) && ! empty( $shortcode_tags ) ) ? array_keys( $shortcode_tags ) : [];
// Avoid "/" chars in content breaks preg_replace.
$unique_string_one = md5( microtime() );
$content = str_replace( '[/fusion_', $unique_string_one, $content );
$unique_string_two = md5( microtime() + 1 );
$content = str_replace( '/fusion_', $unique_string_two, $content );
$content = str_replace( $unique_string_one, '[/fusion_', $content );
if ( ! empty( $active_shortcodes ) ) {
// Be sure to keep active shortcodes.
$keep_active = implode( '|', $active_shortcodes );
$content = preg_replace( '~(?:\[/?)(?!(?:' . $keep_active . '))[^/\]]+/?\]~s', '', $content );
} else {
// Strip all shortcodes.
$content = preg_replace( '~(?:\[/?)[^/\]]+/?\]~s', '', $content );
}
// Set "/" back to its place.
$content = str_replace( $unique_string_two, '/', $content );
return $content;
}
/**
* Remove post type from the link selector.
*
* @since 1.0
* @param array $query Default query for link selector.
* @return array $query
*/
function fusion_core_wp_link_query_args( $query ) {
// Get array key for the post type 'slide'.
$slide_post_type_key = array_search( 'slide', $query['post_type'], true );
// Remove the post type from query.
if ( $slide_post_type_key ) {
unset( $query['post_type'][ $slide_post_type_key ] );
}
// Get array key for the post type 'themefusion_elastic'.
$elastic_slider_post_type_key = array_search( 'themefusion_elastic', $query['post_type'], true );
// Remove the post type from query.
if ( $elastic_slider_post_type_key ) {
unset( $query['post_type'][ $elastic_slider_post_type_key ] );
}
// Return updated query.
return $query;
}
add_filter( 'wp_link_query_args', 'fusion_core_wp_link_query_args' );
/**
* Add Template Builder extensions.
*
* @since 2.2
*/
require_once FUSION_CORE_PATH . '/includes/class-fusioncore-template-builder.php';
/**
* Init the languages updater.
*
* @since 4.1
*/
if ( ! class_exists( 'Fusion_Languages_Updater_API' ) ) {
require_once FUSION_CORE_PATH . '/includes/class-fusion-languages-updater-api.php';
}
new Fusion_Languages_Updater_API( 'plugin', 'fusion-core', FUSION_CORE_VERSION );/**
* WooCommerce compatibility functions.
*
* @author ThemeFusion
* @copyright (c) Copyright by ThemeFusion
* @link https://theme-fusion.com
* @package Avada
* @subpackage Core
* @since 5.0.0
*/
if ( ! function_exists( 'fusion_wc_get_page_id' ) ) {
/**
* The woocommerce_get_page_id function was deprecated in WooCommerce 2.7.
* This is a proxy function to ensure Avada works with all WC versions.
*
* @param string $page The page we want to find.
* @return int The page ID.
*/
function fusion_wc_get_page_id( $page ) {
if ( function_exists( 'wc_get_page_id' ) ) {
return wc_get_page_id( $page );
} elseif ( function_exists( 'woocommerce_get_page_id' ) ) {
return woocommerce_get_page_id( $page );
}
}
}
if ( ! function_exists( 'fusion_wc_get_template' ) ) {
/**
* The woocommerce_get_template function was deprecated in WooCommerce 2.7.
* This is a proxy function to ensure Avada works with all WC versions.
*
* @param mixed $slug The template slug.
* @param string $name (default: '').
*/
function fusion_wc_get_template( $slug, $name = '' ) {
if ( function_exists( 'wc_get_template' ) ) {
wc_get_template( $slug, $name );
} elseif ( function_exists( 'woocommerce_get_template' ) ) {
woocommerce_get_template( $slug, $name );
}
}
}
if ( ! function_exists( 'fusion_wc_get_template_part' ) ) {
/**
* The woocommerce_get_template_part function was deprecated in WooCommerce 2.7.
* This is a proxy function to ensure Avada works with all WC versions.
*
* @param mixed $slug The template slug.
* @param string $name (default: '').
*/
function fusion_wc_get_template_part( $slug, $name = '' ) {
if ( function_exists( 'wc_get_template_part' ) ) {
wc_get_template_part( $slug, $name );
} elseif ( function_exists( 'woocommerce_get_template_part' ) ) {
woocommerce_get_template_part( $slug, $name );
}
}
}
if ( ! function_exists( 'fusion_get_product' ) ) {
/**
* The get_product function was deprecated in WooCommerce 2.7.
* This is a proxy function to ensure Avada works with all WC versions.
*
* @param mixed $the_product Post object or post ID of the product.
* @param array $args Previously used to pass arguments to the factory, e.g. to force a type.
* @return WC_Product|null
*/
function fusion_get_product( $the_product = false, $args = [] ) {
if ( function_exists( 'wc_get_product' ) ) {
return wc_get_product( $the_product, $args );
} elseif ( function_exists( 'get_product' ) ) {
return get_product( $the_product, $args );
}
}
}
/* Omit closing PHP tag to avoid "Headers already sent" issues. *//**
* Images handler.
*
* @package Fusion-Library
* @since 1.0.0
*/
/**
* Handle images.
* Includes responsive-images tweaks.
*
* @since 1.0.0
*/
class Fusion_Images {
/**
* The grid image meta.
*
* @static
* @access public
* @var array
*/
public static $grid_image_meta;
/**
* An array of the accepted widths.
*
* @static
* @access public
* @var array
*/
public static $grid_accepted_widths;
/**
* An array of supported layouts.
*
* @static
* @access public
* @var array
*/
public static $supported_grid_layouts;
/**
* Ratio used for masonry calculations.
*
* @static
* @access public
* @var float
*/
public static $masonry_grid_ratio;
/**
* Width used for masonry 2x2 calculations.
*
* @static
* @access public
* @var int
*/
public static $masonry_width_double;
/**
* Whether lazy load is active or not.
*
* @static
* @access public
* @var int
*/
public static $lazy_load;
/**
* Constructor.
*
* @access public
*/
public function __construct() {
global $fusion_settings;
if ( ! $fusion_settings ) {
$fusion_settings = Fusion_Settings::get_instance();
}
self::$grid_image_meta = [];
self::$grid_accepted_widths = [ '200', '400', '600', '800', '1200' ];
self::$supported_grid_layouts = [ 'masonry', 'grid', 'timeline', 'large', 'portfolio_full', 'related-posts' ];
self::$masonry_grid_ratio = $fusion_settings->get( 'masonry_grid_ratio' );
self::$masonry_width_double = $fusion_settings->get( 'masonry_width_double' );
self::$lazy_load = $fusion_settings->get( 'lazy_load' );
add_filter( 'max_srcset_image_width', [ $this, 'set_max_srcset_image_width' ] );
add_filter( 'wp_calculate_image_srcset', [ $this, 'set_largest_image_size' ], 10, 5 );
add_filter( 'wp_calculate_image_srcset', [ $this, 'edit_grid_image_srcset' ], 15, 5 );
add_filter( 'wp_calculate_image_sizes', [ $this, 'edit_grid_image_sizes' ], 10, 5 );
add_filter( 'post_thumbnail_html', [ $this, 'edit_grid_image_src' ], 10, 5 );
add_action( 'delete_attachment', [ $this, 'delete_resized_images' ] );
add_filter( 'wpseo_sitemap_urlimages', [ $this, 'extract_img_src_for_yoast' ], '10', '2' );
add_filter( 'fusion_library_image_base_size_width', [ $this, 'fb_adjust_grid_image_base_size' ], 20, 4 );
add_filter( 'fusion_masonry_element_class', [ $this, 'adjust_masonry_element_class' ], 10, 2 );
add_filter( 'attachment_fields_to_edit', [ $this, 'add_image_meta_fields' ], 10, 2 );
add_filter( 'attachment_fields_to_save', [ $this, 'save_image_meta_fields' ], 10, 2 );
add_action( 'admin_head', [ $this, 'style_image_meta_fields' ] );
add_filter( 'wp_update_attachment_metadata', [ $this, 'remove_dynamically_generated_images' ], 10, 2 );
add_action( 'wp', [ $this, 'enqueue_image_scripts' ] );
add_filter( 'post_thumbnail_html', [ $this, 'apply_lazy_loading' ], 99, 5 );
add_filter( 'wp_get_attachment_image_attributes', [ $this, 'lazy_load_attributes' ], 10, 2 );
add_action( 'the_content', [ $this, 'apply_bulk_lazy_loading' ], 999 );
add_filter( 'revslider_layer_content', [ $this, 'prevent_rev_lazy_loading' ], 10, 5 );
add_filter( 'layerslider_slider_markup', [ $this, 'prevent_ls_lazy_loading' ], 10, 3 );
add_filter( 'wp_get_attachment_metadata', [ $this, 'map_old_image_size_names' ], 10, 2 );
}
/**
* Adds lightbox attributes to links.
*
* @param string $link The link.
* @param int $attachment_id The attachment ID.
* @param string $size Size of the image. Image size or array of width and height values (in that order).
* Default 'thumbnail'.
* @return string The updated attachment link.
*/
public function prepare_lightbox_links( $link, $attachment_id, $size ) {
if ( ! is_string( $size ) ) {
$size = 'full';
}
$attachment_data = $this->get_attachment_data( $attachment_id, $size );
$title = $attachment_data['title_attribute'];
$caption = $attachment_data['caption_attribute'];
$link = preg_replace( '/ $details ) {
if ( $details['url'] === $image_src ) {
$cropped_image = true;
}
}
if ( ! $cropped_image ) {
$full_image_src = wp_get_attachment_image_src( $attachment_id, 'full' );
$full_size = [
'url' => $full_image_src[0],
'descriptor' => 'w',
'value' => $image_meta['width'],
];
$sources[ $image_meta['width'] ] = $full_size;
}
return $sources;
}
/**
* Filter out all srcset attributes, that do not fit current grid layout.
*
* @since 1.0.0
*
* @param array $sources {
* One or more arrays of source data to include in the 'srcset'.
*
* @type array $width {
* @type string $url The URL of an image source.
* @type string $descriptor The descriptor type used in the image candidate string,
* either 'w' or 'x'.
* @type int $value The source width if paired with a 'w' descriptor, or a
* pixel density value if paired with an 'x' descriptor.
* }
* }
* @param array $size_array Array of width and height values in pixels (in that order).
* @param string $image_src The 'src' of the image.
* @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'.
* @param int $attachment_id Image attachment ID or 0.
*
* @return array $sources One or more arrays of source data to include in the 'srcset'.
*/
public function edit_grid_image_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id ) {
// Only do manipulation for blog images.
if ( ! empty( self::$grid_image_meta ) ) {
// Only include the uncropped sizes in srcset.
foreach ( $sources as $width => $source ) {
// Make sure the original image isn't deleted.
preg_match( '/-\d+x\d+(?=\.(jpg|jpeg|png|gif|tiff|svg)$)/i', $source['url'], $matches );
if ( ! in_array( $width, self::$grid_accepted_widths ) && isset( $matches[0] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
unset( $sources[ $width ] );
}
}
}
ksort( $sources );
return $sources;
}
/**
* Edits the'sizes' attribute for grid images.
*
* @since 1.0.0
*
* @param string $sizes A source size value for use in a 'sizes' attribute.
* @param array|string $size Image size to retrieve. Accepts any valid image size, or an array
* of width and height values in pixels (in that order). Default 'medium'.
* @param string $image_src Optional. The URL to the image file. Default null.
* @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'.
* Default null.
* @param int $attachment_id Optional. Image attachment ID. Either `$image_meta` or `$attachment_id`
* is needed when using the image size name as argument for `$size`. Default 0.
* @return string|bool A valid source size value for use in a 'sizes' attribute or false.
*/
public function edit_grid_image_sizes( $sizes, $size, $image_src, $image_meta, $attachment_id ) {
if ( isset( self::$grid_image_meta['layout'] ) ) {
$content_break_point = apply_filters( 'fusion_library_content_break_point', 1100 );
$content_width = apply_filters( 'fusion_library_content_width', 1170 );
if ( isset( self::$grid_image_meta['gutter_width'] ) ) {
$content_width -= (int) self::$grid_image_meta['gutter_width'] * ( (int) self::$grid_image_meta['columns'] - 1 );
}
// Grid.
if ( in_array( self::$grid_image_meta['layout'], [ 'masonry', 'grid', 'portfolio_full', 'related-posts' ], true ) ) {
$main_break_point = (int) apply_filters( 'fusion_library_grid_main_break_point', 800 );
if ( 640 < $main_break_point ) {
$breakpoint_range = $main_break_point - 640;
} else {
$breakpoint_range = 360;
}
$breakpoint_interval = $breakpoint_range / 5;
$main_image_break_point = apply_filters( 'fusion_library_main_image_breakpoint', $main_break_point );
$break_points = apply_filters(
'fusion_library_image_breakpoints',
[
6 => $main_image_break_point,
5 => $main_image_break_point - $breakpoint_interval,
4 => $main_image_break_point - 2 * $breakpoint_interval,
3 => $main_image_break_point - 3 * $breakpoint_interval,
2 => $main_image_break_point - 4 * $breakpoint_interval,
1 => $main_image_break_point - 5 * $breakpoint_interval,
]
);
$sizes = apply_filters( 'fusion_library_image_grid_initial_sizes', '', $main_break_point, (int) self::$grid_image_meta['columns'] );
$sizes .= '(min-width: 2200px) 100vw, ';
foreach ( $break_points as $columns => $breakpoint ) {
if ( $columns <= (int) self::$grid_image_meta['columns'] ) {
$width = $content_width / $columns;
// For one column layouts where the content width is larger than column breakpoint width, don't reset the width.
if ( $breakpoint < $width && ! ( 1 === (int) self::$grid_image_meta['columns'] && $content_width > $breakpoint + $breakpoint_interval ) ) {
$width = $breakpoint + $breakpoint_interval;
}
$sizes .= '(min-width: ' . round( $breakpoint ) . 'px) ' . round( $width ) . 'px, ';
}
}
} elseif ( 'timeline' === self::$grid_image_meta['layout'] ) { // Timeline.
$width = 40;
$sizes = '(max-width: ' . $content_break_point . 'px) 100vw, ' . $width . 'vw';
// Large Layouts (e.g. person or image element).
} elseif ( false !== strpos( self::$grid_image_meta['layout'], 'large' ) ) {
// If possible, set the correct size for the content width, depending on columns.
if ( $attachment_id ) {
$base_image_size = $this->get_grid_image_base_size( $attachment_id, self::$grid_image_meta['layout'], self::$grid_image_meta['columns'], 'get_closest_ceil' );
if ( is_integer( $base_image_size ) ) {
$content_width = $base_image_size;
} else {
$content_width = $size[0];
}
}
$sizes = '(max-width: ' . $content_break_point . 'px) 100vw, ' . $content_width . 'px';
}
}
return $sizes;
}
/**
* Change the src attribute for grid images.
*
* @since 1.0.0
*
* @param string $html The post thumbnail HTML.
* @param int $post_id The post ID.
* @param string $post_thumbnail_id The post thumbnail ID.
* @param string|array $size The post thumbnail size. Image size or array of width and height
* values (in that order). Default 'post-thumbnail'.
* @param string $attr Query string of attributes.
* @return string The html markup of the image.
*/
public function edit_grid_image_src( $html, $post_id = null, $post_thumbnail_id = null, $size = null, $attr = null ) {
if ( ! $this->is_lazy_load_enabled() && isset( self::$grid_image_meta['layout'] ) && in_array( self::$grid_image_meta['layout'], self::$supported_grid_layouts ) && 'full' === $size ) { // phpcs:ignore WordPress.PHP.StrictInArray
$image_size = $this->get_grid_image_base_size( $post_thumbnail_id, self::$grid_image_meta['layout'], self::$grid_image_meta['columns'] );
$full_image_src = wp_get_attachment_image_src( $post_thumbnail_id, $image_size );
if ( $full_image_src ) {
$html = preg_replace( '@src="([^"]+)"@', 'src="' . $full_image_src[0] . '"', $html );
}
}
return $html;
}
/**
* Get image size based on column size.
*
* @since 1.0.0
*
* @param null|int $post_thumbnail_id Attachment ID.
* @param null|string $layout The layout.
* @param null|int $columns Number of columns.
* @param string $match_basis Use 'get_closest' or 'get_closest_ceil'.
* @return string Image size name.
*/
public function get_grid_image_base_size( $post_thumbnail_id = null, $layout = null, $columns = null, $match_basis = 'get_closest' ) {
global $is_IE;
$sizes = [];
// Get image metadata.
$image_meta = wp_get_attachment_metadata( $post_thumbnail_id );
if ( $image_meta ) {
$image_sizes = [];
if ( isset( $image_meta['sizes'] ) && ! empty( $image_meta['sizes'] ) ) {
$image_sizes = $image_meta['sizes'];
}
if ( $image_sizes && is_array( $image_sizes ) ) {
foreach ( $image_sizes as $name => $image ) {
$size_name = str_replace( 'fusion-', '', $name );
if ( in_array( $size_name, self::$grid_accepted_widths, true ) ) {
// Create accepted sizes array.
if ( $image['width'] ) {
$sizes[ $image['width'] ] = intval( $size_name );
}
}
}
}
if ( isset( $image_meta['width'] ) ) {
$sizes[ $image_meta['width'] ] = 'full';
}
}
$gutter = isset( self::$grid_image_meta['gutter_width'] ) ? self::$grid_image_meta['gutter_width'] : '';
$width = apply_filters( 'fusion_library_image_base_size_width', 1000, $layout, $columns, $gutter );
ksort( $sizes );
$image_size = null;
$size_name = null;
// Find the best match.
foreach ( $sizes as $size => $name ) {
// Find closest size match.
$match_condition = null === $image_size || abs( $width - $image_size ) > abs( $size - $width );
// Find closest match greater than available width.
if ( 'get_closest_ceil' === $match_basis ) {
$match_condition = $size > $width && abs( $width - $image_size ) > abs( $size - $width );
}
if ( $match_condition ) {
$image_size = $size;
$size_name = $name;
}
}
// Fallback to 'full' image size if no match was found or Internet Explorer is used.
if ( ! $size_name || empty( $size_name ) || $is_IE ) {
$size_name = 'full';
}
return $size_name;
}
/**
* Returns adjusted width of an image container.
* Adjustment is made based on Fusion Builder column image container is currently in.
*
* @since 1.0.0
* @access public
* @param int $width The container width in pixels.
* @param string $layout The layout name.
* @param int $columns The number of columns used as a divider.
* @param int $gutter_width The gutter width - in pixels.
* @global array $fusion_col_type The current column padding and type.
* @return int
*/
public function fb_adjust_grid_image_base_size( $width, $layout, $columns = 1, $gutter_width = 30 ) {
global $fusion_col_type;
if ( ! empty( $fusion_col_type['type'] ) ) {
// Do some advanced column size calcs respecting margins for better column width estimation.
if ( ! empty( $fusion_col_type['spacings'] ) ) {
$width = $this->calc_width_respecting_spacing( $width, $fusion_col_type['spacings'] );
}
// Calc the column width.
$coeff = explode( '_', $fusion_col_type['type'] );
$width = absint( $width * $coeff[0] / $coeff[1] );
// Do some advanced column size calcs respecting in column paddings for better column width estimation.
if ( isset( $fusion_col_type['padding'] ) ) {
$padding = explode( ' ', $fusion_col_type['padding'] );
if ( isset( $padding[1] ) && isset( $padding[3] ) ) {
$padding = [ $padding[1], $padding[3] ];
$width = $this->calc_width_respecting_spacing( $width, $padding );
}
}
}
return $width;
}
/**
* Reduces a given width by the amount of spacing set.
*
* @since 1.8.0
* @param int $width The width to be reduced.
* @param array $spacing_array The array of spacings that need subtracted.
* @return int The reduced width.
*/
public function calc_width_respecting_spacing( $width, $spacing_array ) {
global $fusion_settings;
if ( ! $fusion_settings ) {
$fusion_settings = Fusion_Settings::get_instance();
}
$base_font_size = $fusion_settings->get( 'body_typography', 'font-size' );
foreach ( $spacing_array as $spacing ) {
if ( false !== strpos( $spacing, 'px' ) ) {
$width -= (int) $spacing;
} elseif ( false !== strpos( $base_font_size, 'px' ) && false !== strpos( $spacing, 'em' ) ) {
$width -= (int) $base_font_size * (int) $spacing;
} elseif ( false !== strpos( $spacing, '%' ) ) {
$width -= $width * (int) $spacing / 100;
}
}
return $width;
}
/**
* Setter function for the $grid_image_meta variable.
*
* @since 1.0.0
* @param array $grid_image_meta Array containing layout and number of columns.
* @return void
*/
public function set_grid_image_meta( $grid_image_meta ) {
self::$grid_image_meta = $grid_image_meta;
}
/**
* Gets the ID of the "translated" attachment.
*
* @static
* @since 1.2.1
* @param int $attachment_id The base attachment ID.
* @return int The ID of the "translated" attachment.
*/
public static function get_translated_attachment_id( $attachment_id ) {
$wpml_object_id = apply_filters( 'wpml_object_id', $attachment_id, 'attachment' );
$attachment_id = $wpml_object_id ? $wpml_object_id : $attachment_id;
return $attachment_id;
}
/**
* Gets the base URL for an attachment.
*
* @static
* @since 1.2.1
* @param string $attachment_url The url of the used attachment.
* @return string The base URL of the attachment.
*/
public static function get_attachment_base_url( $attachment_url = '' ) {
$attachment_url = set_url_scheme( $attachment_url );
$attachment_base_url = preg_replace( '/-\d+x\d+(?=\.(jpg|jpeg|png|gif|tiff|svg)$)/i', '', $attachment_url );
$attachment_base_url = apply_filters( 'fusion_get_attachment_base_url', $attachment_base_url );
return $attachment_base_url;
}
/**
* Gets the attachment ID from the URL.
*
* @static
* @since 1.0
* @param string $attachment_url The URL of the attachment.
* @return string The attachment ID
*/
public static function get_attachment_id_from_url( $attachment_url = '' ) {
global $wpdb;
$attachment_id = false;
if ( '' === $attachment_url || ! is_string( $attachment_url ) ) {
return '';
}
$upload_dir_paths = wp_upload_dir();
$upload_dir_paths_baseurl = set_url_scheme( $upload_dir_paths['baseurl'] );
// Make sure the upload path base directory exists in the attachment URL, to verify that we're working with a media library image.
if ( false !== strpos( $attachment_url, $upload_dir_paths_baseurl ) ) {
// If this is the URL of an auto-generated thumbnail, get the URL of the original image.
$attachment_url = self::get_attachment_base_url( $attachment_url );
// Remove the upload path base directory from the attachment URL.
$attachment_url = str_replace( $upload_dir_paths_baseurl . '/', '', $attachment_url );
// Get the actual attachment ID.
$attachment_id = attachment_url_to_postid( $attachment_url );
$attachment_id = self::get_translated_attachment_id( $attachment_id );
}
return $attachment_id;
}
/**
* Gets the most important attachment data from the url.
*
* @since 1.0.0
* @param string $attachment_url The url of the used attachment.
* @return array/bool The attachment data of the image, false if the url is empty or attachment not found.
*/
public function get_attachment_data_from_url( $attachment_url = '' ) {
if ( '' === $attachment_url ) {
return false;
}
$attachment_data['id'] = self::get_attachment_id_from_url( $attachment_url );
if ( ! $attachment_data['id'] ) {
return false;
}
$attachment_data = $this->get_attachment_data( $attachment_data['id'], 'full', $attachment_url );
return $attachment_data;
}
/**
* Gets the most important attachment data.
*
* @since 1.2
* @access public
* @param int $attachment_id The ID of the used attachment.
* @param string $size The image size to be returned.
* @param string $attachment_url The URL of the attachment.
* @return array/bool The attachment data of the image,
* false if the url is empty or attachment not found.
*/
public function get_attachment_data( $attachment_id = 0, $size = 'full', $attachment_url = '' ) {
$attachment_data = [
'id' => 0,
'url' => '',
'width' => '',
'height' => '',
'alt' => '',
'caption' => '',
'caption_attribute' => '',
'title' => '',
'title_attribute' => '',
];
$attachment_src = false;
if ( ! $attachment_id && ! $attachment_url ) {
return $attachment_data;
}
if ( ! $attachment_id ) {
$attachment_id = self::get_attachment_id_from_url( $attachment_url );
} else {
$attachment_id = self::get_translated_attachment_id( $attachment_id );
$test_size = ( 'none' === $size ) ? 'full' : $size;
$attachment_src = wp_get_attachment_image_src( $attachment_id, $size );
if ( ! $attachment_src ) {
$attachment_id = self::get_attachment_id_from_url( $attachment_url );
}
}
if ( ! $attachment_id ) {
$attachment_data['url'] = $attachment_url;
return $attachment_data;
}
$attachment_data['id'] = $attachment_id;
if ( 'none' !== $size ) {
$attachment_src = ( $attachment_src ) ? $attachment_src : wp_get_attachment_image_src( $attachment_id, $size );
if ( $attachment_src ) {
$attachment_data['url'] = esc_url( $attachment_src[0] );
if ( $attachment_url && $attachment_data['url'] !== $attachment_url ) {
$attachment_data['url'] = $attachment_url;
preg_match( '/-\d+x\d+(?=\.(jpg|jpeg|png|gif|tiff|svg)$)/i', $attachment_url, $matches );
if ( $matches ) {
$dimensions = explode( 'x', $matches[0] );
if ( 2 <= count( $dimensions ) ) {
$attachment_data['width'] = absint( $dimensions[0] );
$attachment_data['height'] = absint( $dimensions[1] );
}
} else {
$attachment_data['width'] = absint( $attachment_src[1] );
$attachment_data['height'] = absint( $attachment_src[2] );
}
} else {
$attachment_data['width'] = absint( $attachment_src[1] );
$attachment_data['height'] = absint( $attachment_src[2] );
}
}
}
$attachment_data['alt'] = esc_attr( get_post_field( '_wp_attachment_image_alt', $attachment_id ) );
// Check for WP versions prior to 4.6.
if ( function_exists( 'wp_get_attachment_caption' ) ) {
$attachment_data['caption'] = wp_get_attachment_caption( $attachment_id );
} else {
$post = get_post( $attachment_id );
$attachment_data['caption'] = ( $post ) ? $post->post_excerpt : '';
}
$attachment_data['caption_attribute'] = esc_attr( strip_tags( $attachment_data['caption'] ) ); // phpcs:ignore WordPress.WP.AlternativeFunctions
$attachment_data['title'] = get_the_title( $attachment_id );
$attachment_data['title_attribute'] = esc_attr( strip_tags( $attachment_data['title'] ) ); // phpcs:ignore WordPress.WP.AlternativeFunctions
return $attachment_data;
}
/**
* Gets the most important attachment data.
*
* @since 1.2.1
* @access public
* @param string $attachment_id_size The ID and size of the used attachmen in a string separated by |.
* @param string $attachment_url The URL of the attachment.
* @return array/bool The attachment data of the image,
* false if the url is empty or attachment not found.
*/
public function get_attachment_data_by_helper( $attachment_id_size = 0, $attachment_url = '' ) {
$attachment_data = false;
// Image ID is set, so we can get the image data directly.
if ( $attachment_id_size ) {
$attachment_id_size = explode( '|', $attachment_id_size );
// Both image ID and image size are available.
if ( 2 === count( $attachment_id_size ) ) {
$attachment_data = $this->get_attachment_data( $attachment_id_size[0], $attachment_id_size[1], $attachment_url );
} else {
// Only image ID is available.
$attachment_data = $this->get_attachment_data( $attachment_id_size[0], 'full', $attachment_url );
}
} elseif ( $attachment_url ) {
// Fallback, if we don't have the image ID, we have to get the data through the image URL.
$attachment_data = $this->get_attachment_data( 0, 'full', $attachment_url );
}
return $attachment_data;
}
/**
* Deletes the resized images when the original image is deleted from the WordPress Media Library.
* This is necessary in order to handle custom image sizes created from the Fusion_Image_Resizer class.
*
* @access public
* @param int $post_id The post ID.
* @param array $delete_image_sizes Array of images sizes to be deleted. All are deleted if empty.
* @return void
*/
public function delete_resized_images( $post_id, $delete_image_sizes = [] ) {
// Get attachment image metadata.
$metadata = wp_get_attachment_metadata( $post_id );
if ( ! $metadata ) {
return;
}
$wp_filesystem = Fusion_Helper::init_filesystem();
// Do some bailing if we cannot continue.
if ( ! isset( $metadata['file'] ) || ! isset( $metadata['image_meta']['resized_images'] ) ) {
return;
}
$pathinfo = pathinfo( $metadata['file'] );
$resized_images = isset( $metadata['image_meta']['resized_images'] ) ? $metadata['image_meta']['resized_images'] : [];
// Get WordPress uploads directory (and bail if it doesn't exist).
$wp_upload_dir = wp_upload_dir();
$upload_dir = $wp_upload_dir['basedir'];
if ( ! is_dir( $upload_dir ) ) {
return;
}
// Delete the resized images.
foreach ( $resized_images as $handle => $dims ) {
if ( ! empty( $delete_image_sizes ) && ! in_array( $handle, $delete_image_sizes ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
continue;
}
// Get the resized images filename.
$file = $upload_dir . '/' . $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '-' . $dims . '.' . $pathinfo['extension'];
// Delete the resized image.
$wp_filesystem->delete( $file, false, 'f' );
// Get the retina resized images filename.
$retina_file = $upload_dir . '/' . $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '-' . $dims . '@2x.' . $pathinfo['extension'];
// Delete the resized retina image.
$wp_filesystem->delete( $retina_file, false, 'f' );
}
}
/**
* Adds [fusion_imageframe], [fusion_gallery] and [fusion_image_before_after] images to Yoast SEO XML sitemap.
*
* @since 1.0.0
* @param array $images Current post images.
* @param int $post_id The post ID.
*/
public function extract_img_src_for_yoast( $images, $post_id ) {
$post = get_post( $post_id );
$content = $post->post_content;
// For images from fusion_imageframe shortcode.
if ( preg_match_all( '/\[fusion_imageframe(.+?)?\](?:(.+?)?\[\/fusion_imageframe\])?/', $content, $matches ) ) {
foreach ( $matches[0] as $image_frame ) {
$src = '';
if ( false === strpos( $image_frame, '
$src,
];
}
}
}
// For images from newer structure of gallery element.
if ( preg_match_all( '/\[fusion_gallery_image(.+?)?\](?:(.+?)?\[\/fusion_gallery_image\])?/', $content, $matches ) ) {
foreach ( $matches[0] as $item ) {
$atts = shortcode_parse_atts( $item );
if ( isset( $atts['image'] ) && ! empty( $atts['image'] ) ) {
$images[] = [
'src' => $atts['image'],
];
} elseif ( isset( $atts['image_id'] ) && ! empty( $atts['image_id'] ) ) {
$images[] = [
'src' => wp_get_attachment_url( $atts['image_id'] ),
];
}
}
}
// For images from older structure fusion_gallery shortcode.
if ( preg_match_all( '/\[fusion_gallery(.+?)?\](?:(.+?)?\[\/fusion_gallery\])?/', $content, $matches ) ) {
foreach ( $matches[0] as $image_gallery ) {
$atts = shortcode_parse_atts( $image_gallery );
if ( isset( $atts['image_ids'] ) && ! empty( $atts['image_ids'] ) ) {
$image_ids = explode( ',', $atts['image_ids'] );
foreach ( $image_ids as $image_id ) {
$images[] = [
'src' => wp_get_attachment_url( $image_id ),
];
}
}
}
}
// For images from fusion_image_before_after shortcode.
if ( preg_match_all( '/\[fusion_image_before_after(.+?)?\](?:(.+?)?\[\/fusion_image_before_after\])?/', $content, $matches ) ) {
foreach ( $matches[0] as $item ) {
$atts = shortcode_parse_atts( $item );
if ( isset( $atts['before_image'] ) && ! empty( $atts['before_image'] ) ) {
$images[] = [
'src' => $atts['before_image'],
];
}
if ( isset( $atts['after_image'] ) && ! empty( $atts['after_image'] ) ) {
$images[] = [
'src' => $atts['after_image'],
];
}
}
}
return $images;
}
/**
* Returns element orientation class, based on width and height ratio of an attachment image.
*
* @since 1.1
* @param int $attachment_id ID of attachment image.
* @param array $attachment An image attachment array.
* @param float $ratio The aspect ratio threshold.
* @param int $width_double Width above which 2x2 content should be displayed.
* @return string Orientation class.
*/
public function get_element_orientation_class( $attachment_id = '', $attachment = [], $ratio = false, $width_double = false ) {
$element_class = 'fusion-element-grid';
$ratio = $ratio ? $ratio : self::$masonry_grid_ratio;
$width_double = $width_double ? $width_double : self::$masonry_width_double;
if ( empty( $attachment ) && '' !== $attachment_id ) {
$attachment = wp_get_attachment_image_src( $attachment_id, 'full' );
}
if ( isset( $attachment[1] ) && isset( $attachment[2] ) ) {
// Fallback to legacy calcs of Avada 5.4.2 or earlier.
if ( '1.0' === $ratio ) {
$fallback_ratio = 0.8;
$lower_limit = ( $fallback_ratio / 2 ) + ( $fallback_ratio / 4 );
$upper_limit = ( $fallback_ratio * 2 ) - ( $fallback_ratio / 2 );
if ( $lower_limit > $attachment[2] / $attachment[1] ) {
// Landscape image.
$element_class = 'fusion-element-landscape';
} elseif ( $upper_limit < $attachment[2] / $attachment[1] ) {
// Portrait image.
$element_class = 'fusion-element-portrait';
} elseif ( $attachment[1] > $width_double ) {
// 2x2 image.
$element_class = 'fusion-element-landscape fusion-element-portrait';
}
} else {
if ( $ratio < $attachment[1] / $attachment[2] ) {
// Landscape image.
$element_class = 'fusion-element-landscape';
} elseif ( $ratio < $attachment[2] / $attachment[1] ) {
// Portrait image.
$element_class = 'fusion-element-portrait';
} elseif ( $attachment[1] > $width_double ) {
// 2x2 image.
$element_class = 'fusion-element-landscape fusion-element-portrait';
}
}
}
return apply_filters( 'fusion_masonry_element_class', $element_class, $attachment_id );
}
/**
* Returns element orientation class, based on width and height ratio of an attachment image.
*
* @since 1.1
* @param string $element_orientation_class The orientation class.
* @return int|float.
*/
public function get_element_base_padding( $element_orientation_class = '' ) {
$fusion_element_grid_padding = 0.8;
$masonry_element_padding = [
'fusion-element-grid' => $fusion_element_grid_padding,
'fusion-element-landscape' => $fusion_element_grid_padding / 2,
'fusion-element-portrait' => $fusion_element_grid_padding * 2,
];
if ( isset( $masonry_element_padding[ $element_orientation_class ] ) ) {
$fusion_element_grid_padding = $masonry_element_padding[ $element_orientation_class ];
}
return $fusion_element_grid_padding;
}
/**
* Filters element orientation class, based on image meta.
*
* @since 1.5
* @param string $element_class Orientation class.
* @param int $attachment_id ID of attachment image.
* @return string Orientation class.
*/
public function adjust_masonry_element_class( $element_class, $attachment_id = '' ) {
if ( '' !== $attachment_id ) {
$image_meta_layout = get_post_meta( $attachment_id, 'fusion_masonry_element_layout', true );
if ( $image_meta_layout && '' !== $image_meta_layout ) {
$element_class = $image_meta_layout;
}
}
return $element_class;
}
/**
* Add Image meta fields
*
* @param array $form_fields Fields to include in attachment form.
* @param object $post Attachment record in database.
* @return array $form_fields Modified form fields.
*/
public function add_image_meta_fields( $form_fields, $post ) {
if ( wp_attachment_is_image( $post->ID ) ) {
$image_layout = '' !== get_post_meta( $post->ID, 'fusion_masonry_element_layout', true ) ? sanitize_text_field( get_post_meta( $post->ID, 'fusion_masonry_element_layout', true ) ) : '';
$form_fields['fusion_masonry_element_layout'] = [
'label' => __( 'Masonry Image Layout', 'Avada' ),
'input' => 'html',
'html' => '',
'helps' => __( 'Set layout which will be used when image is displayed in masonry.', 'Avada' ),
];
}
return $form_fields;
}
/**
* Save values of Photographer Name and URL in media uploader
*
* @param array $post The post data for database.
* @param array $attachment Attachment fields from $_POST form.
* @return array $post Modified post data.
*/
public function save_image_meta_fields( $post, $attachment ) {
if ( wp_attachment_is_image( $post['ID'] ) ) {
if ( isset( $attachment['fusion_masonry_element_layout'] ) ) {
if ( '' !== $attachment['fusion_masonry_element_layout'] ) {
update_post_meta( $post['ID'], 'fusion_masonry_element_layout', $attachment['fusion_masonry_element_layout'] );
} else {
delete_post_meta( $post['ID'], 'fusion_masonry_element_layout' );
}
}
}
return $post;
}
/**
* Style image meta fields.
*/
public function style_image_meta_fields() {
global $pagenow;
if ( 'post.php' === $pagenow && wp_attachment_is_image( get_the_ID() ) ) {
echo '';
}
}
/**
* Removes dynamically created thumbnails.
*
* @since 1.6
*
* @param array $data Array of updated attachment meta data.
* @param int $attachment_id Attachment post ID.
*
* @return array $data Array of updated attachment meta data.
*/
public function remove_dynamically_generated_images( $data, $attachment_id ) {
if ( ! isset( $data['image_meta']['resized_images']['fusion-500'] ) ) {
$this->delete_resized_images( $attachment_id, [ 'fusion-500' ] );
}
return $data;
}
/**
* Return placeholder image for given dimensions
*
* @static
* @access public
* @since 1.8.0
* @param int $width Width of real image.
* @param int $height Height of real image.
*
* @return string Placeholder html string.
*/
public static function get_lazy_placeholder( $width = 0, $height = 0 ) {
$placeholder = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
if ( isset( $width ) && isset( $height ) && $width && $height ) {
$width = (int) $width;
$height = (int) $height;
return 'data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27' . $width . '%27%20height%3D%27' . $height . '%27%20viewBox%3D%270%200%20' . $width . '%20' . $height . '%27%3E%3Crect%20width%3D%27' . $width . '%27%20height%3D%273' . $height . '%27%20fill-opacity%3D%220%22%2F%3E%3C%2Fsvg%3E';
}
return apply_filters( 'fusion_library_lazy_placeholder', $placeholder, $width, $height );
}
/**
* Filter attributes for the current gallery image tag to add a 'data-full'
* data attribute.
*
* @access public
* @param array $atts Gallery image tag attributes.
* @param mixed $attachment WP_Post object for the attachment or attachment ID.
* @return array (maybe) filtered gallery image tag attributes.
* @since 1.8.0
*/
public function lazy_load_attributes( $atts, $attachment ) {
if ( $this->is_lazy_load_enabled() ) {
$replaced_atts = $atts;
if ( ! isset( $atts['class'] ) ) {
$replaced_atts['class'] = 'lazyload';
} elseif ( false !== strpos( $atts['class'], 'lazyload' ) || false !== strpos( $atts['class'], 'rev-slidebg' ) || false !== strpos( $atts['class'], 'ls-' ) || false !== strpos( $atts['class'], 'attachment-portfolio' ) ) {
return $atts;
} else {
$replaced_atts['class'] .= ' lazyload';
}
if ( isset( $atts['data-ls'] ) ) {
return $atts;
}
// Get image dimensions.
$image_id = is_object( $attachment ) ? $attachment->ID : $attachment;
$meta_data = wp_get_attachment_metadata( $image_id );
$width = isset( $meta_data['width'] ) ? $meta_data['width'] : 0;
$height = isset( $meta_data['height'] ) ? $meta_data['height'] : 0;
// No meta data, but we do have width and height set on tag.
$width = ! $width && isset( $atts['width'] ) ? $atts['width'] : $width;
$height = ! $height && isset( $atts['height'] ) ? $atts['height'] : $height;
$replaced_atts['data-orig-src'] = $atts['src'];
if ( isset( $atts['srcset'] ) ) {
$replaced_atts['srcset'] = self::get_lazy_placeholder( $width, $height );
$replaced_atts['data-srcset'] = $atts['srcset'];
$replaced_atts['data-sizes'] = 'auto';
} else {
$replaced_atts['src'] = self::get_lazy_placeholder( $width, $height );
}
unset( $replaced_atts['sizes'] );
return $replaced_atts;
}
return $atts;
}
/**
* Filter markup for lazy loading.
*
* @since 1.8.0
*
* @param string $html The post thumbnail HTML.
* @param int $post_id The post ID.
* @param string $post_thumbnail_id The post thumbnail ID.
* @param string|array $size The post thumbnail size. Image size or array of width and height
* values (in that order). Default 'post-thumbnail'.
* @param string $attr Query string of attributes.
* @return string The html markup of the image.
*/
public function apply_lazy_loading( $html, $post_id = null, $post_thumbnail_id = null, $size = null, $attr = null ) {
if ( $this->is_lazy_load_enabled() && false === strpos( $html, 'lazyload' ) && false === strpos( $html, 'rev-slidebg' ) && false === strpos( $html, 'fusion-gallery-image-size-fixed' ) ) {
$src = '';
$width = 0;
$height = 0;
// Get the image data from src.
if ( $post_thumbnail_id && 'full' === $size ) {
$full_image_src = wp_get_attachment_image_src( $post_thumbnail_id, 'full' );
// If image found, use the dimensions and src of image.
if ( is_array( $full_image_src ) ) {
$src = isset( $full_image_src[0] ) ? $full_image_src[0] : $src;
$width = isset( $full_image_src[1] ) ? $full_image_src[1] : $width;
$height = isset( $full_image_src[2] ) ? $full_image_src[2] : $height;
}
} else {
// Get src from markup.
preg_match( '@src="([^"]+)"@', $html, $src );
if ( array_key_exists( 1, $src ) ) {
$src = $src[1];
} else {
$src = '';
}
// Get dimensions from markup.
preg_match( '/width="(.*?)"/', $html, $width );
if ( array_key_exists( 1, $width ) ) {
preg_match( '/height="(.*?)"/', $html, $height );
if ( array_key_exists( 1, $height ) ) {
$width = $width[1];
$height = $height[1];
}
} elseif ( $src && '' !== $src ) {
// No dimensions on tag, try to get from image url.
$full_image_src = $this->get_attachment_data_from_url( $src );
if ( is_array( $full_image_src ) ) {
$width = isset( $full_image_src['width'] ) ? $full_image_src['width'] : $width;
$height = isset( $full_image_src['height'] ) ? $full_image_src['height'] : $height;
}
}
}
// If src is a data image, just skip.
if ( false !== strpos( $src, 'data:image' ) ) {
return $html;
}
// Srcset replacement.
if ( strpos( $html, 'srcset' ) ) {
$html = str_replace(
[
' src=',
' srcset=',
' sizes=',
],
[
' src="' . $src . '" data-orig-src=',
' srcset="' . self::get_lazy_placeholder( $width, $height ) . '" data-srcset=',
' data-sizes="auto" data-orig-sizes=',
],
$html
);
} else {
// Simplified non srcset replacement.
$html = str_replace( ' src=', ' src="' . self::get_lazy_placeholder( $width, $height ) . '" data-orig-src=', $html );
}
if ( strpos( $html, ' class=' ) ) {
$html = str_replace( ' class="', ' class="lazyload ', $html );
} else {
$html = str_replace( '
is_lazy_load_enabled() ) {
preg_match_all( '/
]*src="([^"]*)"[^>]*>/isU', $content, $images );
if ( array_key_exists( 1, $images ) ) {
foreach ( $images[0] as $key => $image ) {
$orig = $image;
$image = $this->apply_lazy_loading( $image );
// Replace image.
$content = str_replace( $orig, $image, $content );
}
}
}
return $content;
}
/**
* Disable lazy loading for slider revolution images.
*
* @since 1.8.1
*
* @param string $html Full html string.
* @param string $content Non stripped original content.
* @param object $slider Slider.
* @param object $slide Individual slide.
* @param string $layer Individual layer.
* @return string Altered html markup.
*/
public function prevent_rev_lazy_loading( $html, $content, $slider, $slide, $layer ) {
if ( $this->is_lazy_load_enabled() ) {
preg_match_all( '/
]*src="([^"]*)"[^>]*>/isU', $html, $images );
if ( array_key_exists( 1, $images ) ) {
foreach ( $images[0] as $key => $image ) {
$orig = $image;
$image = $this->prevent_lazy_loading( $image );
// Replace image.
$html = str_replace( $orig, $image, $html );
}
}
}
return $html;
}
/**
* Prevent layerslider lazy loading.
*
* @since 1.8.1
*
* @param string $html The HTML code that contains the slider markup.
* @param array $slider The slider database record as an associative array.
* @param string $id The ID attribute of the slider element.
* @return string Altered html markup.
*/
public function prevent_ls_lazy_loading( $html, $slider = false, $id = false ) {
if ( $this->is_lazy_load_enabled() ) {
preg_match_all( '/
]*src="([^"]*)"[^>]*>/isU', $html, $images );
if ( array_key_exists( 1, $images ) ) {
foreach ( $images[0] as $key => $image ) {
$orig = $image;
$image = $this->prevent_lazy_loading( $image );
// Replace image.
$html = str_replace( $orig, $image, $html );
}
}
}
return $html;
}
/**
* Filter markup to prevent lazyloading.
*
* @since 1.8.0
*
* @param string $html The post thumbnail HTML.
* @return string The html markup of the image.
*/
public function prevent_lazy_loading( $html ) {
if ( $this->is_lazy_load_enabled() && ! strpos( $html, 'disable-lazyload' ) ) {
if ( strpos( $html, ' class=' ) ) {
$html = str_replace( ' class="', ' class="disable-lazyload ', $html );
} else {
$html = str_replace( '
is_lazy_load_enabled() ) {
Fusion_Dynamic_JS::enqueue_script( 'lazysizes' );
}
}
/**
* Determine if we want to lazy-load images or not.
*
* @access public
* @since 1.8.1
* @return bool
*/
public function is_lazy_load_enabled() {
return ( self::$lazy_load && ! Fusion_AMP::is_amp_endpoint() && ! is_admin() );
}
/**
* Maps the old image size names to the new ones.
*
* @access public
* @since 2.2
* @param array $data An array of the image-sizes data.
* @param int $post_id The post-ID.
* @return array
*/
public function map_old_image_size_names( $data, $post_id ) {
$old_sizes = [ 200, 400, 600, 800, 1200 ];
foreach ( $old_sizes as $size ) {
if ( isset( $data['sizes'][ $size ] ) ) {
$data['sizes'][ 'fusion-' . $size ] = $data['sizes'][ $size ];
unset( $data['sizes'][ $size ] );
}
}
return $data;
}
}
/* Omit closing PHP tag to avoid "Headers already sent" issues. */