diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index f49c325..07ad829 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -301,45 +301,26 @@ function tevkori_get_srcset_string( $id, $size = 'medium' ) { * @return string Converted content with 'srcset' and 'sizes' added to images. */ function tevkori_filter_content_images( $content ) { - - // Only match images in our uploads directory. - $uploads_dir = wp_upload_dir(); - $path_to_upload_dir = $uploads_dir['baseurl']; - - // Pattern for matching all images with a `src` from the uploads directory. - $pattern = '|]+' . preg_quote( $path_to_upload_dir ) . '[^>]+)>|i'; - preg_match_all( $pattern, $content, $matches ); + if ( ! preg_match_all( '/]+ wp-image-([0-9]+)[^>]+>/i', $content, $matches ) ) { + return $content; + } $images = $matches[0]; - $ids = array(); - foreach( $images as $image ) { - if ( preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) ) { - (int) $id = $class_id[1]; - if ( $id ) { - $ids[] = $id; - } - } - } + $attachment_ids = array_unique( $matches[1] ); - if ( 0 < count( $ids ) ) { + if ( 0 < count( $attachment_ids ) ) { /* * Warm object caches for use with wp_get_attachment_metadata. * * To avoid making a database call for each image, a single query * warms the object cache with the meta information for all images. - **/ - _prime_post_caches( $ids, false, true ); + */ + _prime_post_caches( $attachment_ids, false, true ); } - foreach( $matches[0] as $k => $image ) { - $match = array( $image, $matches[1][$k] ); - $needle = $image; - $replacement = _tevkori_filter_content_images_callback( $match ); - if ( false === $replacement ) { - continue; - } - $content = str_replace( $image, $replacement, $content ); + foreach( $images as $image ) { + $content = str_replace( $image, tevkori_img_add_srcset_and_sizes( $image ), $content ); } return $content; @@ -347,65 +328,51 @@ function tevkori_filter_content_images( $content ) { add_filter( 'the_content', 'tevkori_filter_content_images', 5, 1 ); /** - * Private preg_replace callback used in tevkori_filter_content_images() + * Add srcset and sizes to an 'img' element. * - * @access private - * @since 2.5.0 + * @since 2.6.0 + * + * @param string $image An HTML 'img' element to be filtered. + * @return string Converted 'img' element with 'srcset' and 'sizes' added. */ -function _tevkori_filter_content_images_callback( $image ) { - if ( empty( $image ) ) { - return false; +function tevkori_img_add_srcset_and_sizes( $image ) { + // Return early if a 'srcset' attribute already exists. + if ( false !== strpos( $image, ' srcset="' ) ) { + return $image; } - list( $image_html, $atts ) = $image; - - // Bail early if a 'srcset' attribute already exists. - if ( false !== strpos( $atts, 'srcset=' ) ) { - - /* - * Backward compatibility. - * - * Prior to version 2.5 a 'srcset' and 'data-sizes' attribute - * were added to the image while inserting the image in the content. - * We replace the 'data-sizes' attribute by a 'sizes' attribute. - */ - $image_html = str_replace( ' data-sizes="', ' sizes="', $image_html ); - - return $image_html; - } - - // Grab ID and size info from core classes. - $id = preg_match( '/wp-image-([0-9]+)/i', $atts, $class_id ) ? (int) $class_id[1] : false; - $size = preg_match( '/size-([^\s|"]+)/i', $atts, $class_size ) ? $class_size[1] : false; - $width = preg_match( '/ width="([0-9]+)"/', $atts, $atts_width ) ? (int) $atts_width[1] : false; - $height = preg_match( '/ height="([0-9]+)"/', $atts, $atts_height ) ? (int) $atts_height[1] : false; + // Parse id, size, width, and height from the `img` element. + $id = preg_match( '/wp-image-([0-9]+)/i', $image, $match_id ) ? (int) $match_id[1] : false; + $size = preg_match( '/size-([^\s|"]+)/i', $image, $match_size ) ? $match_size[1] : false; + $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? (int) $match_width[1] : false; + $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : false; if ( $id && false === $size ) { $size = array( $width, - $height + $height, ); } /* * If attempts to parse the size value failed, attempt to use the image - * metadata to match the 'src' angainst the available sizes for an attachment. + * metadata to match the 'src' against the available sizes for an attachment. */ if ( ! $size && ! empty( $id ) && $meta = wp_get_attachment_metadata( $id ) ) { + // Parse the image `src` value from the `img` element. + $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : false; - preg_match( '/src="([^"]+)"/', $atts, $url ); - - // Sanity check the 'src' value and bail early it doesn't exist. - if ( ! $url[1] ) { - return $image_html; + // Return early if the `src` value is empty. + if ( ! $src ) { + return $image; } - $image_filename = basename( $url[1] ); - /* * First, see if the file is the full size image. If not, we loop through - * the intermediate sizes until we find a match. + * the intermediate sizes until we find a file that matches. */ + $image_filename = wp_basename( $src ); + if ( $image_filename === basename( $meta['file'] ) ) { $size = 'full'; } else { @@ -420,23 +387,26 @@ function _tevkori_filter_content_images_callback( $image ) { } // If we have an ID and size, try for 'srcset' and 'sizes' and update the markup. - if ( $id && $size && $srcset = tevkori_get_srcset_string( $id, $size ) ) { + if ( $id && $size && $srcset = tevkori_get_srcset( $id, $size ) ) { - // Pass height and width to `tevkori_get_sizes_string()`. + /** + * Pass the 'height' and 'width' to 'wp_get_attachment_image_sizes()' to avoid + * recalculating the image size. + */ $args = array( - 'width' => $width, 'height' => $height, + 'width' => $width, ); + $sizes = tevkori_get_sizes( $id, $size, $args ); - $sizes = tevkori_get_sizes_string( $id, $size, $args ); - - // Strip trailing slashes and whitespaces from the `$atts` string. - $atts = trim( rtrim( $atts, '/' ) ); + // Format the srcset and sizes string and escape attributes. + $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes) ); - $image_html = ""; + // Add srcset and sizes attributes to the image markup. + $image = preg_replace( '/]+)[\s?][\/?]>/', '', $image ); }; - return $image_html; + return $image; } /**