From 2e2c15d67fe49aedac4d7127da495f27a86cc7a8 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 25 Sep 2015 01:34:01 +0200 Subject: [PATCH 1/6] Minor fix to prevent a potential undefined variable notice. (and slight improvement to the regex) --- wp-tevko-responsive-images.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index b398c2d..cad8b19 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -342,13 +342,15 @@ function _tevkori_filter_content_images_callback( $image ) { } if ( $id && false === $size ) { - preg_match( '/width="([0-9]+)"/', $atts, $width ); - preg_match( '/height="([0-9]+)"/', $atts, $height ); - - $size = array( - (int) $width[1], - (int) $height[1] - ); + preg_match( '/ width="([0-9]+)"/', $atts, $width ); + preg_match( '/ height="([0-9]+)"/', $atts, $height ); + + if ( isset( $width[1] ) && isset( $height[1] ) ) { + $size = array( + (int) $width[1], + (int) $height[1] + ); + } } /* From ae2bcbf0e427ed66517d4a6f8638363b2f1ebc3d Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 25 Sep 2015 07:31:38 +0200 Subject: [PATCH 2/6] Merge three lines --- wp-tevko-responsive-images.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index cad8b19..d2e8d79 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -342,10 +342,7 @@ function _tevkori_filter_content_images_callback( $image ) { } if ( $id && false === $size ) { - preg_match( '/ width="([0-9]+)"/', $atts, $width ); - preg_match( '/ height="([0-9]+)"/', $atts, $height ); - - if ( isset( $width[1] ) && isset( $height[1] ) ) { + if ( preg_match( '/ width="([0-9]+)"/', $atts, $width ) && preg_match( '/ height="([0-9]+)"/', $atts, $height ) ) { $size = array( (int) $width[1], (int) $height[1] From 482626281ef233a8e482bd1c3df004022a725c26 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Mon, 28 Sep 2015 19:30:06 -0500 Subject: [PATCH 3/6] Don't query the DB directly during content filter. Remove the third fallback in our content filter in order to avoid the expensive query. The tradeoff is that `` elements without a `wp-image-{id}` class will no longer have `srcset` and `sizes` attributes added. Updates tests. --- tests/test-suite.php | 5 ++- wp-tevko-responsive-images.php | 66 ++++++++++------------------------ 2 files changed, 20 insertions(+), 51 deletions(-) diff --git a/tests/test-suite.php b/tests/test-suite.php index b0617f1..7821a01 100644 --- a/tests/test-suite.php +++ b/tests/test-suite.php @@ -385,12 +385,11 @@ function test_tevkori_filter_content_images() { // Function used to build HTML for the editor. $img = get_image_tag( $id, '', '', '', 'medium' ); $img_no_size = str_replace( 'size-', '', $img ); - $img_no_size_id = str_replace( 'wp-attachment-', '', $img_no_size ); + $img_no_size_id = str_replace( 'wp-image-', 'id-', $img_no_size ); // Manually add srcset and sizes to the markup from get_image_tag(); $respimg = preg_replace('|]+) />|', '', $img); $respimg_no_size = preg_replace('|]+) />|', '', $img_no_size); - $respimg_no_size_id = preg_replace('|]+) />|', '', $img_no_size_id); $content = '

Welcome to WordPress! This post contains important information. After you read it, you can make it private to hide it from visitors but still have the information handy for future reference.

First things first:

@@ -421,7 +420,7 @@ function test_tevkori_filter_content_images() { '; $content_unfiltered = sprintf( $content, $img, $img_no_size, $img_no_size_id ); - $content_filtered = sprintf( $content, $respimg, $respimg_no_size, $respimg_no_size_id ); + $content_filtered = sprintf( $content, $respimg, $respimg_no_size, $img_no_size_id ); $this->assertSame( $content_filtered, tevkori_filter_content_images( $content_unfiltered ) ); } diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index d2e8d79..25a5458 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -158,7 +158,7 @@ function tevkori_get_sizes( $id, $size = 'thumbnail', $args = null ) { */ function tevkori_get_sizes_string( $id, $size = 'thumbnail', $args = null ) { $sizes = tevkori_get_sizes( $id, $size, $args ); - + return $sizes ? 'sizes="' . $sizes . '"' : false; } @@ -289,7 +289,7 @@ function tevkori_get_srcset_string( $id, $size = 'thumbnail' ) { * @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']; @@ -320,7 +320,7 @@ function _tevkori_filter_content_images_callback( $image ) { // Bail early if a 'srcset' attribute already exists. if ( false !== strpos( $atts, 'srcset=' ) ) { - + /* * Backward compatibility. * @@ -329,7 +329,7 @@ function _tevkori_filter_content_images_callback( $image ) { * We replace the 'data-sizes' attribute by a 'sizes' attribute. */ $image_html = str_replace( ' data-sizes="', ' sizes="', $image_html ); - + return $image_html; } @@ -351,12 +351,14 @@ function _tevkori_filter_content_images_callback( $image ) { } /* - * If attempts to get values for ID and size failed, use the - * src to query for matching values in '_wp_attachment_metadata'. + * 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. */ - if ( false === $id || false === $size ) { + 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. if ( ! $url[1] ) { return $image_html; } @@ -364,52 +366,20 @@ function _tevkori_filter_content_images_callback( $image ) { $image_filename = basename( $url[1] ); /* - * If we already have an ID, we use it to get the attachment metadata - * using 'wp_get_attachment_metadata()'. Otherwise, we'll use the image - * 'src' url to query the postmeta table for both the attachement ID and - * metadata, which we'll use later to get the size. + * First, see if the file is the full size image. If not, we loop through + * the intermediate sizes until we find a match. */ - if ( ! empty( $id ) ) { - $meta = wp_get_attachment_metadata( $id ); + if ( $image_filename === basename( $meta['file'] ) ) { + $size = 'full'; } else { - global $wpdb; - $meta_object = $wpdb->get_row( $wpdb->prepare( - "SELECT `post_id`, `meta_value` FROM $wpdb->postmeta WHERE `meta_key` = '_wp_attachment_metadata' AND `meta_value` LIKE %s", - '%' . $image_filename . '%' - ) ); - - // If the query is successful, we can determine the ID and size. - if ( is_object( $meta_object ) ) { - $id = $meta_object->post_id; - - // Unserialize the meta_value returned in our query. - $meta = maybe_unserialize( $meta_object->meta_value ); - } else { - $meta = false; - } - } - - /* - * Now that we have the attachment ID and metadata, we can retrieve the - * size by matching the original image's 'src' filename with the sizes - * included in the attachment metadata. - */ - if ( $id && $meta ) { - /* - * First, see if the file is the full size image. If not, we loop through - * the intermediate sizes until we find a match. - */ - if ( $image_filename === basename( $meta['file'] ) ) { - $size = 'full'; - } else { - foreach( $meta['sizes'] as $image_size => $image_size_data ) { - if ( $image_filename === $image_size_data['file'] ) { - $size = $image_size; - break; - } + foreach( $meta['sizes'] as $image_size => $image_size_data ) { + if ( $image_filename === $image_size_data['file'] ) { + $size = $image_size; + break; } } } + } // If we have an ID and size, try for 'srcset' and 'sizes' and update the markup. From 1db1e7e555866cf72ff6d6a3c1be3b3c27f95fd3 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Tue, 29 Sep 2015 14:11:41 +1000 Subject: [PATCH 4/6] Query all images in single request before replacing Content filter now works as follows: * matches images and converts to array of IDs * performs a WP_Query lookup with array of IDs - this causes all images to be cached, including the meta data * loops through each image and replaces meta data. --- wp-tevko-responsive-images.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 25a5458..c9aa436 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -294,6 +294,29 @@ 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 ); + + $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; + } + } + } + + if ( 0 < count( $ids ) ) { + $attachments = new WP_Query(array( + 'post_type' => 'attachment', + 'posts_per_page' => '-1', + 'post_status' => 'inherit', + 'post__in' => $ids, + )); + } + $content = preg_replace_callback( '|]+' . $path_to_upload_dir . '[^>]+)[\s?][\/?]>|i', '_tevkori_filter_content_images_callback', From df0b772644eedba32d04f7989deb4da93d6a497b Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Tue, 29 Sep 2015 22:20:25 +1000 Subject: [PATCH 5/6] Add comment explaining cache warming loop. --- wp-tevko-responsive-images.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index c9aa436..eab7b7b 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -309,6 +309,15 @@ function tevkori_filter_content_images( $content ) { } 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. + **/ $attachments = new WP_Query(array( 'post_type' => 'attachment', 'posts_per_page' => '-1', From 46dfaf24b2ca494694a1a4fe18e194357e304ca8 Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 29 Sep 2015 22:18:59 -0400 Subject: [PATCH 6/6] updating plugin version to 2.5.1 --- readme.md | 10 ++++++++-- readme.txt | 10 ++++++++-- wp-tevko-responsive-images.php | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index 31f0062..80a2ff9 100644 --- a/readme.md +++ b/readme.md @@ -140,16 +140,22 @@ We use a hook because if you attempt to dequeue a script before it's enqueued, w ## Version -2.5.0 +2.5.1 ## Changelog +- 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 + +**2.5.0** + - Responsify all post images by adding `srcset` and `sizes` through a display filter. - Improve method used to build paths in `tevkori_get_srcset_array()` - Adds linthub config files - Returns single source arrays in `tevkori_get_srcset_array()` - Add tests for PHP7 to our Travis matrix -- Add test coverage for `tevkori_filter_attachment_image_attributes()` +- Add test coverage for `tevkori_filter_attachment_image_attributes()` **2.4.0** diff --git a/readme.txt b/readme.txt index 82a9cfc..9b62fb9 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.0 +Stable tag: 2.5.1 License: GPLv2 License URI: http://www.gnu.org/licenses/gpl-2.0.txt @@ -26,13 +26,19 @@ This plugin works by including all available image sizes for each image upload. == Changelog == += 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 + + = 2.5.0 = * Responsify all post images by adding `srcset` and `sizes` through a display filter. * Improve method used to build paths in `tevkori_get_srcset_array()` * Adds linthub config files * Returns single source arrays in `tevkori_get_srcset_array()` * Add tests for PHP7 to our Travis matrix -* Add test coverage for `tevkori_filter_attachment_image_attributes()` +* Add test coverage for `tevkori_filter_attachment_image_attributes()` = 2.4.0 = * Added filter for tevkori_get_sizes, with tests diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index eab7b7b..2915172 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.0 + * Version: 2.5.1 * Author: The RICG * Author URI: http://responsiveimages.org/ * License: GPL-2.0+