diff --git a/readme.md b/readme.md
index 80a2ff9..c91a780 100644
--- a/readme.md
+++ b/readme.md
@@ -140,10 +140,21 @@ We use a hook because if you attempt to dequeue a script before it's enqueued, w
## Version
-2.5.1
+2.5.2
## Changelog
+- Numerous performance and usability improvements
+- Pass height and width to `tevkori_get_sizes()
+- Improved regex in display filter
+- Avoid calling `wp_get_attachment_image_src()` in srcset functions
+- Improved coding standards
+- Removed second regular expression in content filter
+- Improved cache warning function
+- Change default `$size` value for all function to 'medium'
+
+**2.5.1**
+
- Query all images in single request before replacing
- Minor fix to prevent a potential undefined variable notice
- Remove third fallback query from the display filter
diff --git a/readme.txt b/readme.txt
index 9b62fb9..b247914 100644
--- a/readme.txt
+++ b/readme.txt
@@ -4,7 +4,7 @@ Donate link: https://app.etapestry.com/hosted/BoweryResidentsCommittee/OnlineDon
Tags: Responsive, Images, Responsive Images, SRCSET, Picturefill
Requires at least: 4.1
Tested up to: 4.3
-Stable tag: 2.5.1
+Stable tag: 2.5.2
License: GPLv2
License URI: http://www.gnu.org/licenses/gpl-2.0.txt
@@ -26,6 +26,16 @@ This plugin works by including all available image sizes for each image upload.
== Changelog ==
+= 2.5.2 =
+* Numerous performance and usability improvements
+* Pass height and width to `tevkori_get_sizes()
+* Improved regex in display filter
+* Avoid calling `wp_get_attachment_image_src()` in srcset functions
+* Improved coding standards
+* Removed second regular expression in content filter
+* Improved cache warning function
+* Change default `$size` value for all function to 'medium'
+
= 2.5.1 =
* Query all images in single request before replacing
* Minor fix to prevent a potential undefined variable notice
diff --git a/tests/test-suite.php b/tests/test-suite.php
index 7821a01..b756f86 100644
--- a/tests/test-suite.php
+++ b/tests/test-suite.php
@@ -198,6 +198,25 @@ function test_tevkori_get_srcset_array() {
$this->assertSame( $expected, $sizes );
}
+ function test_tevkori_get_srcset_array_random_size_name() {
+ // make an image
+ $id = $this->_test_img();
+ $sizes = tevkori_get_srcset_array( $id, 'foo' );
+
+ $year_month = date('Y/m');
+ $image = wp_get_attachment_metadata( $id );
+
+ $expected = array(
+ $image['sizes']['medium']['width'] => 'http://example.org/wp-content/uploads/' . $year_month = date('Y/m') . '/'
+ . $image['sizes']['medium']['file'] . ' ' . $image['sizes']['medium']['width'] . 'w',
+ $image['sizes']['large']['width'] => 'http://example.org/wp-content/uploads/' . $year_month = date('Y/m') . '/'
+ . $image['sizes']['large']['file'] . ' ' . $image['sizes']['large']['width'] . 'w',
+ $image['width'] => 'http://example.org/wp-content/uploads/' . $image['file'] . ' ' . $image['width'] .'w'
+ );
+
+ $this->assertSame( $expected, $sizes );
+ }
+
function test_tevkori_get_srcset_array_no_date_upoads() {
// Save the current setting for uploads folders
$uploads_use_yearmonth_folders = get_option( 'uploads_use_yearmonth_folders' );
@@ -280,7 +299,7 @@ function test_tevkori_get_srcset_array_false() {
function test_tevkori_get_srcset_array_no_width() {
// Filter image_downsize() output.
- add_filter( 'image_downsize', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) );
+ add_filter( 'wp_generate_attachment_metadata', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) );
// Make our attachement.
$id = $this->_test_img();
@@ -290,14 +309,16 @@ function test_tevkori_get_srcset_array_no_width() {
$this->assertFalse( $srcset );
// Remove filter.
- remove_filter( 'image_downsize', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) );
+ remove_filter( 'wp_generate_attachment_metadata', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) );
}
/**
* Helper funtion to filter image_downsize and return zero values for width and height.
*/
- public function _test_tevkori_get_srcset_array_no_width_filter() {
- return array( 'http://example.org/foo.jpg', 0, 0, false );
+ public function _test_tevkori_get_srcset_array_no_width_filter( $meta ) {
+ $meta['sizes']['medium']['width'] = 0;
+ $meta['sizes']['medium']['height'] = 0;
+ return $meta;
}
function test_tevkori_get_srcset_string() {
diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php
index 2915172..e0bf345 100644
--- a/wp-tevko-responsive-images.php
+++ b/wp-tevko-responsive-images.php
@@ -8,7 +8,7 @@
* Plugin Name: RICG Responsive Images
* Plugin URI: http://www.smashingmagazine.com/2015/02/24/ricg-responsive-images-for-wordpress/
* Description: Bringing automatic default responsive images to wordpress
- * Version: 2.5.1
+ * Version: 2.5.2
* Author: The RICG
* Author URI: http://responsiveimages.org/
* License: GPL-2.0+
@@ -54,23 +54,31 @@ function tevkori_get_picturefill() {
* @since 2.2.0
*
* @param int $id Image attachment ID.
- * @param string $size Optional. Name of image size. Default value: 'thumbnail'.
+ * @param string $size Optional. Name of image size. Default value: 'medium'.
* @param array $args {
* Optional. Arguments to retrieve posts.
*
* @type array|string $sizes An array or string containing of size information.
+ * @type int $width A single width value used in the default `sizes` string.
* }
* @return string|bool A valid source size value for use in a 'sizes' attribute or false.
*/
-function tevkori_get_sizes( $id, $size = 'thumbnail', $args = null ) {
+function tevkori_get_sizes( $id, $size = 'medium', $args = null ) {
- // See which image is being returned and bail if none is found.
- if ( ! $img = image_downsize( $id, $size ) ) {
+ // Try to get the image width from `$args` before calling `image_downsize()`.
+ if ( is_array( $args ) && ! empty( $args['width'] ) ) {
+ $img_width = (int) $args['width'];
+ } elseif ( $img = image_downsize( $id, $size ) ) {
+ $img_width = $img[1];
+ }
+
+ // Bail early if ``$image_width` isn't set.
+ if ( ! $img_width ) {
return false;
}
- // Get the image width.
- $img_width = $img[1] . 'px';
+ // Set the image width in pixels.
+ $img_width = $img_width . 'px';
// Set up our default values.
$defaults = array(
@@ -148,15 +156,16 @@ function tevkori_get_sizes( $id, $size = 'thumbnail', $args = null ) {
* @since 2.2.0
*
* @param int $id Image attachment ID.
- * @param string $size Optional. Name of image size. Default value: 'thumbnail'.
+ * @param string $size Optional. Name of image size. Default value: 'medium'.
* @param array $args {
* Optional. Arguments to retrieve posts.
*
* @type array|string $sizes An array or string containing of size information.
+ * @type int $width A single width value used in the default `sizes` string.
* }
* @return string|bool A valid source size list as a 'sizes' attribute or false.
*/
-function tevkori_get_sizes_string( $id, $size = 'thumbnail', $args = null ) {
+function tevkori_get_sizes_string( $id, $size = 'medium', $args = null ) {
$sizes = tevkori_get_sizes( $id, $size, $args );
return $sizes ? 'sizes="' . $sizes . '"' : false;
@@ -166,38 +175,42 @@ function tevkori_get_sizes_string( $id, $size = 'thumbnail', $args = null ) {
* Get an array of image sources candidates for use in a 'srcset' attribute.
*
* @param int $id Image attachment ID.
- * @param string $size Optional. Name of image size. Default value: 'thumbnail'.
+ * @param string $size Optional. Name of image size. Default value: 'medium'.
* @return array|bool An array of of srcset values or false.
*/
-function tevkori_get_srcset_array( $id, $size = 'thumbnail' ) {
+function tevkori_get_srcset_array( $id, $size = 'medium' ) {
$arr = array();
- // See which image is being returned and bail if none is found.
- if ( ! $img = wp_get_attachment_image_src( $id, $size ) ) {
- return false;
- }
+ // Get the intermediate size.
+ $image = image_get_intermediate_size( $id, $size );
+ // Get the post meta.
+ $img_meta = wp_get_attachment_metadata( $id );
- // Break image data into url, width, and height.
- list( $img_url, $img_width, $img_height ) = $img;
+ // Extract the height and width from the intermediate or the full size.
+ $img_width = ( $image ) ? $image['width'] : $img_meta['width'];
+ $img_height = ( $image ) ? $image['height'] : $img_meta['height'];
- // If we have no width to work with, we should bail (see issue #118).
- if ( 0 == $img_width ) {
+ // Bail early if the width isn't greater that zero.
+ if ( ! $img_width > 0 ) {
return false;
}
- // Get the image meta data and bail if none is found.
- if ( ! is_array( $img_meta = wp_get_attachment_metadata( $id ) ) ) {
- return false;
+ // Use the url from the intermediate size or build the url from the metadata.
+ if ( ! empty( $image['url'] ) ) {
+ $img_url = $image['url'];
+ } else {
+ $uploads_dir = wp_upload_dir();
+ $img_file = ( $image ) ? path_join( dirname( $img_meta['file'] ) , $image['file'] ) : $img_meta['file'];
+ $img_url = $uploads_dir['baseurl'] . '/' . $img_file;
}
- // Build an array with image sizes.
$img_sizes = $img_meta['sizes'];
// Add full size to the img_sizes array.
$img_sizes['full'] = array(
'width' => $img_meta['width'],
'height' => $img_meta['height'],
- 'file' => basename( $img_meta['file'] )
+ 'file' => wp_basename( $img_meta['file'] )
);
// Calculate the image aspect ratio.
@@ -205,8 +218,8 @@ function tevkori_get_srcset_array( $id, $size = 'thumbnail' ) {
/*
* Images that have been edited in WordPress after being uploaded will
- * contain a unique hash. We look for that hash and use it later to filter
- * out images that are leftovers from previous renditions.
+ * contain a unique hash. Look for that hash and use it later to filter
+ * out images that are leftovers from previous versions.
*/
$img_edited = preg_match( '/-e[0-9]{13}/', $img_url, $img_edit_hash );
@@ -248,10 +261,10 @@ function tevkori_get_srcset_array( $id, $size = 'thumbnail' ) {
* @since 2.3.0
*
* @param int $id Image attachment ID.
- * @param string $size Optional. Name of image size. Default value: 'thumbnail'.
+ * @param string $size Optional. Name of image size. Default value: 'medium'.
* @return string|bool A 'srcset' value string or false.
*/
-function tevkori_get_srcset( $id, $size = 'thumbnail' ) {
+function tevkori_get_srcset( $id, $size = 'medium' ) {
$srcset_array = tevkori_get_srcset_array( $id, $size );
if ( count( $srcset_array ) <= 1 ) {
@@ -267,10 +280,10 @@ function tevkori_get_srcset( $id, $size = 'thumbnail' ) {
* @since 2.1.0
*
* @param int $id Image attachment ID.
- * @param string $size Optional. Name of image size. Default value: 'thumbnail'.
+ * @param string $size Optional. Name of image size. Default value: 'medium'.
* @return string|bool A full 'srcset' string or false.
*/
-function tevkori_get_srcset_string( $id, $size = 'thumbnail' ) {
+function tevkori_get_srcset_string( $id, $size = 'medium' ) {
$srcset_value = tevkori_get_srcset( $id, $size );
if ( empty( $srcset_value ) ) {
@@ -294,7 +307,9 @@ function tevkori_filter_content_images( $content ) {
$uploads_dir = wp_upload_dir();
$path_to_upload_dir = $uploads_dir['baseurl'];
- preg_match_all( '|]+' . $path_to_upload_dir . '[^>]+)[\s?][\/?]>|i', $content, $matches );
+ // 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 );
$images = $matches[0];
$ids = array();
@@ -302,35 +317,31 @@ function tevkori_filter_content_images( $content ) {
foreach( $images as $image ) {
if ( preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) ) {
(int) $id = $class_id[1];
- if( $id ) {
+ if ( $id ) {
$ids[] = $id;
}
}
}
if ( 0 < count( $ids ) ) {
- /**
+ /*
* Warm object caches for use with wp_get_attachment_metadata.
*
- * To avoid making a database call for each image, WP_Query is called
- * as a single query with the IDs of all images in the post. This warms
- * the object cache with the meta information for all images.
- *
- * This loop is not used directly.
+ * To avoid making a database call for each image, a single query
+ * warms the object cache with the meta information for all images.
**/
- $attachments = new WP_Query(array(
- 'post_type' => 'attachment',
- 'posts_per_page' => '-1',
- 'post_status' => 'inherit',
- 'post__in' => $ids,
- ));
+ _prime_post_caches( $ids, false, true );
}
- $content = preg_replace_callback(
- '|]+' . $path_to_upload_dir . '[^>]+)[\s?][\/?]>|i',
- '_tevkori_filter_content_images_callback',
- $content
- );
+ 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 );
+ }
return $content;
}
@@ -348,7 +359,6 @@ function _tevkori_filter_content_images_callback( $image ) {
}
list( $image_html, $atts ) = $image;
- $id = $size = false;
// Bail early if a 'srcset' attribute already exists.
if ( false !== strpos( $atts, 'srcset=' ) ) {
@@ -366,31 +376,27 @@ function _tevkori_filter_content_images_callback( $image ) {
}
// Grab ID and size info from core classes.
- if ( preg_match( '/wp-image-([0-9]+)/i', $atts, $class_id ) ) {
- (int) $id = $class_id[1];
- }
- if ( preg_match( '/size-([^\s|"]+)/i', $atts, $class_size ) ) {
- $size = $class_size[1];
- }
+ $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;
if ( $id && false === $size ) {
- if ( preg_match( '/ width="([0-9]+)"/', $atts, $width ) && preg_match( '/ height="([0-9]+)"/', $atts, $height ) ) {
- $size = array(
- (int) $width[1],
- (int) $height[1]
- );
- }
+ $size = array(
+ $width,
+ $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' angainst the available sizes for an attachment.
*/
if ( ! $size && ! empty( $id ) && $meta = wp_get_attachment_metadata( $id ) ) {
preg_match( '/src="([^"]+)"/', $atts, $url );
- // Sanity check the `src` value and bail early it doesn't exist.
+ // Sanity check the 'src' value and bail early it doesn't exist.
if ( ! $url[1] ) {
return $image_html;
}
@@ -416,7 +422,18 @@ 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 ) ) {
- $sizes = tevkori_get_sizes_string( $id, $size );
+
+ // Pass height and width to `tevkori_get_sizes_string()`.
+ $args = array(
+ 'width' => $width,
+ 'height' => $height,
+ );
+
+ $sizes = tevkori_get_sizes_string( $id, $size, $args );
+
+ // Strip trailing slashes and whitespaces from the `$atts` string.
+ $atts = trim( rtrim( $atts, '/' ) );
+
$image_html = "";
};