: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Check if WPML plugin is active.
function et_core_is_wpml_plugin_active() {
return class_exists( 'SitePress' );
if ( ! function_exists( 'et_is_product_taxonomy' ) ):
* Wraps {@see is_product_taxonomy()} to check for its existence before calling.
function et_is_product_taxonomy() {
return function_exists( 'is_product_taxonomy' ) && is_product_taxonomy();
if ( ! function_exists( 'et_core_add_allowed_protocols' ) ) :
* Extend the allowlist of allowed URL protocols
* @param array $protocols List of URL protocols allowed by WordPress.
* @return array Our extended list of URL protocols.
function et_core_add_allowed_protocols( $protocols = array() ) {
'skype', // Add Skype messaging protocol
'sms', // Add SMS text messaging protocol
$protocols = array_unique( array_merge( $protocols, $additional ) );
add_filter( 'kses_allowed_protocols', 'et_core_add_allowed_protocols' );
if ( ! function_exists( 'et_is_responsive_images_enabled' ) ):
* Get the responsive images setting whether is enabled or not
function et_is_responsive_images_enabled() {
static $enable_responsive_images;
if ( null === $enable_responsive_images ) {
$enable_responsive_images = et_get_option( "{$shortname}_enable_responsive_images", 'on' );
return 'on' === $enable_responsive_images;
if ( ! function_exists( 'et_screen_sizes' ) ) :
function et_screen_sizes() {
if ( ! function_exists( 'et_image_get_responsive_size' ) ) :
* Get images responsive sizes.
* @param int $orig_width Original image's width.
* @param int $orig_height Original image's height.
* @param string $breakpoint Screen breakpont. See et_screen_sizes().
* @return array|boolean Image responsive width & height. False on failure.
function et_image_get_responsive_size( $orig_width, $orig_height, $breakpoint ) {
$et_screen_sizes = et_screen_sizes();
if ( ! isset( $et_screen_sizes[ $breakpoint ] ) ) {
$new_width = $et_screen_sizes[ $breakpoint ];
if ( $new_width >= $orig_width ) {
$ratio = ( $orig_width * 1.0 ) / $orig_height;
$new_height = round( ( $new_width / $ratio ) );
if ( ! function_exists( 'et_image_add_srcset_and_sizes' ) ) :
* Add ‘srcset’ and ‘sizes’ attributes to an existing ‘img’ element.
* @param string $image Image HTML markup.
* @param boolean $echo Is print the output?
function et_image_add_srcset_and_sizes( $image, $echo = false ) {
static $srcset_and_sizes_cached = array();
// Check if option is enabled.
if ( ! et_is_responsive_images_enabled() ) {
echo et_core_intentionally_unescaped( $image, 'html' );
$src = et_get_src_from_img_tag( $image );
$cache_key = $src ? $src : 'empty-src';
if ( isset( $srcset_and_sizes_cached[ $cache_key ] ) ) {
$image = $srcset_and_sizes_cached[ $cache_key ];
// Only process if src attribute is not empty.
$attachment_id = et_get_attachment_id_by_url( $src );
$image_meta = wp_get_attachment_metadata( $attachment_id );
$image = wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id );
$srcset_and_sizes_cached[ $cache_key ] = $image;
echo et_core_intentionally_unescaped( $image, 'html' );
if ( ! function_exists( 'et_get_attachment_id_by_url_sql' ) ) :
* Generate SQL query syntax to compute attachment ID by URL.
* @param string $url The URL being looked up.
* @return string SQL query syntax.
function et_get_attachment_id_by_url_sql( $normalized_url ) {
// Strip the HTTP/S protocol.
$cleaned_url = preg_replace( '/^https?:/i', '', $normalized_url );
// Remove any thumbnail size suffix from the filename and use that as a fallback.
$fallback_url = preg_replace( '/-(\d+)x(\d+)\.(jpg|jpeg|gif|png)$/', '.$3', $cleaned_url );
if ( $cleaned_url === $fallback_url ) {
$attachments_query = $wpdb->prepare(
AND `guid` IN ( %s, %s )",
esc_url_raw( "https:{$cleaned_url}" ),
esc_url_raw( "http:{$cleaned_url}" )
// Scenario: Trying to find the attachment for a file called x-150x150.jpg.
// 1. Since WordPress adds the -150x150 suffix for thumbnail sizes we cannot be
// sure if this is an attachment or an attachment's generated thumbnail.
// 2. Since both x.jpg and x-150x150.jpg can be uploaded as separate attachments
// we must decide which is a better match.
// 3. The above is why we order by guid length and use the first result.
$attachments_query = $wpdb->prepare(
AND `guid` IN ( %s, %s, %s, %s )
ORDER BY CHAR_LENGTH( `guid` ) DESC",
esc_url_raw( "https:{$cleaned_url}" ),
esc_url_raw( "https:{$fallback_url}" ),
esc_url_raw( "http:{$cleaned_url}" ),
esc_url_raw( "http:{$fallback_url}" )
return $attachments_query;
if ( ! function_exists( 'et_get_attachment_id_by_url' ) ) :
* Tries to get attachment ID by URL.
* @param string $url The URL being looked up.
* @return int The attachment ID found, or 0 on failure.
function et_get_attachment_id_by_url( $url ) {
* Filters the attachment ID.
* @param bool $attachment_id_pre Default value. Default is false.
* @param string $url URL of the image need to query.
$attachment_id_pre = apply_filters( 'et_get_attachment_id_by_url_pre', false, $url );
if ( false !== $attachment_id_pre ) {
return $attachment_id_pre;
* Filters the attachment GUID.
* This filter intended to get the actual attachment guid URL in case the URL has been filtered before.
* For example the URL has been modified to use CDN URL.
* @param string $url URL of the image need to query.
$url = apply_filters( 'et_get_attachment_id_by_url_guid', $url );
$normalized_url = et_attachment_normalize_url( $url );
// Bail early if the url is invalid.
if ( ! $normalized_url ) {
// Load cached data for attachment_id_by_url.
$cache = ET_Core_Cache_File::get( 'attachment_id_by_url' );
if ( isset( $cache[ $normalized_url ] ) ) {
if ( et_core_is_uploads_dir_url( $normalized_url ) ) {
return $cache[ $normalized_url ];
unset( $cache[ $normalized_url ] );
ET_Core_Cache_File::set( 'attachment_id_by_url', $cache );
$attachments_sql_query = et_get_attachment_id_by_url_sql( $normalized_url );
$attachment_id = (int) $wpdb->get_var( $attachments_sql_query );
// There is this new feature in WordPress 5.3 that allows users to upload big image file
// (threshold being either width or height of 2560px) and the core will scale it down.
// This causing the GUID URL info stored is no more relevant since the WordPress core system
// will append "-scaled." string into the image URL when serving it in the frontend.
// Hence we run another query as fallback in case the attachment ID is not found and
// there is "-scaled." string appear in the image URL
// @see https://make.wordpress.org/core/2019/10/09/introducing-handling-of-big-images-in-wordpress-5-3/
// @see https://wordpress.org/support/topic/media-images-renamed-to-xyz-scaled-jpg/
if ( ! $attachment_id && false !== strpos( $normalized_url, '-scaled.' ) ) {
$normalized_url_not_scaled = str_replace( '-scaled.', '.', $normalized_url );
$attachments_sql_query = et_get_attachment_id_by_url_sql( $normalized_url_not_scaled );
$attachment_id = (int) $wpdb->get_var( $attachments_sql_query );
// There is a case the GUID image URL stored differently with the URL
// served in the frontend for a featured image, so the query will always fail.
// Hence we add another fallback query to the _wp_attached_file value in
// the postmeta table to match with the image relative path.
if ( ! $attachment_id ) {
$uploads = wp_get_upload_dir();
$uploads_baseurl = trailingslashit( $uploads['baseurl'] );
if ( 0 === strpos( $normalized_url, $uploads_baseurl ) ) {
$file_path = str_replace( $uploads_baseurl, '', $normalized_url );
$file_path_no_resize = preg_replace( '/-(\d+)x(\d+)\.(jpg|jpeg|gif|png)$/', '.$3', $file_path );
if ( $file_path === $file_path_no_resize ) {
$attachments_sql_query = $wpdb->prepare(
// Scenario: Trying to find the attachment for a file called x-150x150.jpg.
// 1. Since WordPress adds the -150x150 suffix for thumbnail sizes we cannot be
// sure if this is an attachment or an attachment's generated thumbnail.
// 2. Since both x.jpg and x-150x150.jpg can be uploaded as separate attachments
// we must decide which is a better match.
// 3. The above is why we order by meta_value length and use the first result.
$attachments_sql_query = $wpdb->prepare(
AND `meta_value` IN ( %s, %s )
ORDER BY CHAR_LENGTH( `meta_value` ) DESC",
$attachment_id = (int) $wpdb->get_var( $attachments_sql_query );
// Cache data only if attachment ID is found.
if ( $attachment_id && et_core_is_uploads_dir_url( $normalized_url ) ) {
$cache[ $normalized_url ] = $attachment_id;
ET_Core_Cache_File::set( 'attachment_id_by_url', $cache );
if ( ! function_exists( 'et_get_attachment_size_by_url' ) ) :
* Tries to get attachment size by URL.
* @param string $url The URL being looked up.
* @param string $default_size Default size name on failure.
* @return array|string Detected image size width and height or 'full' on failure.
function et_get_attachment_size_by_url( $url, $default_size = 'full' ) {
$normalized_url = et_attachment_normalize_url( $url );
// Bail early if URL is invalid.
if ( ! $normalized_url ) {
$cache = ET_Core_Cache_File::get( 'attachment_size_by_url' );
if ( isset( $cache[ $normalized_url ] ) ) {
if ( et_core_is_uploads_dir_url( $normalized_url ) ) {
return $cache[ $normalized_url ];
unset( $cache[ $normalized_url ] );
ET_Core_Cache_File::set( 'attachment_size_by_url', $cache );
$attachment_id = et_get_attachment_id_by_url( $url );
if ( ! $attachment_id ) {
$metadata = wp_get_attachment_metadata( $attachment_id );
if ( strpos( $url, $metadata['file'] ) === ( strlen( $url ) - strlen( $metadata['file'] ) ) ) {
$size = array( $metadata['width'], $metadata['height'] );
} else if ( preg_match( '/-(\d+)x(\d+)\.(jpg|jpeg|gif|png)$/', $url, $match ) ) {
// Get the image width and height.
// Example: https://regex101.com/r/7JwGz7/1.
$size = array( $match[1], $match[2] );
// Cache data only if size is found.
if ( $size !== $default_size && et_core_is_uploads_dir_url( $normalized_url ) ) {
$cache[ $normalized_url ] = $size;
ET_Core_Cache_File::set( 'attachment_size_by_url', $cache );
if ( ! function_exists( 'et_get_image_srcset_sizes' ) ) :
* Get image srcset & sizes attributes.
* @param string $url Image source attribute value.
* @return (array|bool) Associative array of srcset & sizes attributes. False on failure.
function et_get_image_srcset_sizes( $url ) {
$normalized_url = et_attachment_normalize_url( $url );
// Bail early if URL is invalid.
if ( ! $normalized_url ) {
$cache = ET_Core_Cache_File::get( 'image_srcset_sizes' );
if ( isset( $cache[ $normalized_url ] ) ) {
if ( et_core_is_uploads_dir_url( $normalized_url ) ) {
return $cache[ $normalized_url ];
unset( $cache[ $normalized_url ] );
ET_Core_Cache_File::set( 'image_srcset_sizes', $cache );
$attachment_id = et_get_attachment_id_by_url( $url );
if ( ! $attachment_id ) {
$image_size = et_get_attachment_size_by_url( $url );
$srcset = wp_get_attachment_image_srcset( $attachment_id, $image_size );
$sizes = wp_get_attachment_image_sizes( $attachment_id, $image_size );
if ( ! $srcset || ! $sizes ) {
if ( et_core_is_uploads_dir_url( $normalized_url ) ) {
$cache[ $normalized_url ] = $data;
ET_Core_Cache_File::set( 'image_srcset_sizes', $cache );
if ( ! function_exists( 'et_attachment_normalize_url' ) ) :
* Tries to normalize attachment URL
* @param string $url The URL being looked up.
* @return string|bool Normalized image URL or false on failure.
function et_attachment_normalize_url( $url ) {
// Remove URL query and string after
list( $url ) = explode( '?', $url );