forked from tevko/wp-tevko-responsive-images
-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Content filter: try parsing the HTML before a DB query #175
Closed
Closed
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
567a2c3
Get all attachments at once
peterwilsoncc b7286db
Content filter: try parsing the HTML before a DB query
joemcgill 7fcb70d
Remove requirement for removed class-srcset-callback.php
joemcgill 915d8c3
Updated the filter logic and tests
joemcgill b29c09b
Sanity check value of incoming $image variable
joemcgill 07ffe14
Update docs for tevkori_filter_content_images and callback
joemcgill bbcb69b
Filter: Make closing space and slash optional in regex pattern.
joemcgill 758f6e9
Follow WP standards for inline docs
joemcgill 75f99ad
Content filter: Try getting medata using an ID.
joemcgill 8bb2f33
Cast as integer when retrieving from class name
joemcgill b5b0484
Replace '// List includes' that was removed
joemcgill 610974c
Content filter: Bail early if `srcset` present.
joemcgill b774f40
Tests: Account for all content filter patterns
joemcgill 334141b
Tests: Add test for preexisting srcset attribute
joemcgill File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -301,75 +301,129 @@ function tevkori_get_src_sizes( $id, $size = 'thumbnail' ) { | |
} | ||
|
||
/** | ||
* Filter for the_content to add sizes and srcset attributes to images. | ||
* Filters images in post content to add `srcset` and `sizes`. | ||
* | ||
* @since 3.0 | ||
* | ||
* @param string $content The raw post content to be filtered. | ||
* @return string Converted content with `srcset` and `sizes` added to images. | ||
*/ | ||
function tevkori_filter_content_images( $content ) { | ||
return preg_replace_callback( | ||
'/<img\s([^>]+)>/i', | ||
// Don't use an anonymous callback function because it isn't supported by PHP 5.2. | ||
'tevkori_filter_content_images_callback', | ||
$content | ||
); | ||
// Only match images in our uploads directory. | ||
$uploads_dir = wp_upload_dir(); | ||
$path_to_upload_dir = $uploads_dir['baseurl']; | ||
|
||
$content = preg_replace_callback( '|<img ([^>]+' . $path_to_upload_dir . '[^>]+)[\s?][\/?]>|i', '_tevkori_filter_content_images_callback', $content ); | ||
|
||
return $content; | ||
} | ||
add_filter( 'the_content', 'tevkori_filter_content_images', 5, 1 ); | ||
|
||
/** | ||
* Callback function for tevkori_filter_content_images. | ||
* Private preg_replace callback used in tevkori_filter_content_images() | ||
* | ||
* @since 3.0 | ||
* | ||
* @see tevkori_filter_content_images | ||
* @param array $matches Array containing the regular expression matches. | ||
* @access private | ||
* @since 3.0.0 | ||
*/ | ||
function tevkori_filter_content_images_callback( $matches ) { | ||
$atts = $matches[1]; | ||
$sizes = $srcset = ''; | ||
|
||
// Check if srcset attribute is not already present. | ||
if ( false !== strpos( 'srcset="', $atts ) ) { | ||
|
||
// Get the url of the original image. | ||
preg_match( '/src="(.+?)(\-([0-9]+)x([0-9]+))?(\.[a-zA-Z]{3,4})"/i', $atts, $url_matches ); | ||
|
||
$url = $url_matches[1] . $url_matches[5]; | ||
|
||
// Get the image ID. | ||
$id = attachment_url_to_postid( $url ); | ||
|
||
if ( $id ) { | ||
|
||
// Use the width and height from the image url. | ||
if ( $url_matches[3] && $url_matches[4] ) { | ||
$size = array( | ||
(int) $url_matches[3], | ||
(int) $url_matches[4] | ||
); | ||
} else { | ||
$size = 'full'; | ||
} | ||
function _tevkori_filter_content_images_callback( $image ) { | ||
if ( empty( $image ) ) { | ||
return false; | ||
} | ||
|
||
list( $image_html, $atts ) = $image; | ||
$id = $size = false; | ||
|
||
// Bail early if a `srcset` attribute already exists. | ||
if ( false !== strpos( $atts, 'srcset=' ) ) { | ||
return $image_html; | ||
} | ||
|
||
// Grab ID and size info from core classes. | ||
if ( preg_match( '/wp-image-([0-9]+)/i', $atts, $class_id ) ) { | ||
(int) $id = $class_id[1]; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add empty line |
||
if ( preg_match( '/size-([^\s|"]+)/i', $atts, $class_size ) ) { | ||
$size = $class_size[1]; | ||
} | ||
|
||
// Get the srcset string. | ||
$srcset_string = tevkori_get_srcset_string( $id, $size ); | ||
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] | ||
); | ||
} | ||
|
||
if ( $srcset_string ) { | ||
$srcset = ' ' . $srcset_string; | ||
/* | ||
* If attempts to get values for `id` and `size` failed, use the | ||
* src to query for matching values in `_wp_attachment_metadata` | ||
*/ | ||
if ( false === $id || false === $size ) { | ||
preg_match( '/src="([^"]+)"/', $atts, $url ); | ||
|
||
if ( ! $url[1] ) { | ||
return $image_html; | ||
} | ||
|
||
// Get the sizes string. | ||
$sizes_string = tevkori_get_sizes_string( $id, $size ); | ||
$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. | ||
*/ | ||
if ( ! empty( $id ) ) { | ||
$meta = wp_get_attachment_metadata( $id ); | ||
} 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; | ||
} | ||
} | ||
|
||
if ( $sizes_string && ! preg_match( '/sizes="([^"]+)"/i', $atts ) ) { | ||
$sizes = ' ' . $sizes_string; | ||
/* | ||
* 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 itermediate 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; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
return '<img ' . $atts . $sizes . $srcset . '>'; | ||
|
||
// 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 ); | ||
$image_html = "<img " . $atts . " " . $srcset . " " . $sizes . " />"; | ||
}; | ||
|
||
return $image_html; | ||
} | ||
|
||
/** | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should bail here if there is already a
srcset
attribute in the markup.if ( false !== strpos( 'srcset="', $atts ) ) { ...}