From c77b44138eda1c6ce52673e30f9487523eebba2e Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Sun, 4 Oct 2015 16:41:32 -0500 Subject: [PATCH 01/61] Make callback filter a full utility filter and pass full `img` HTML Now that we're no longer using a `preg_replace_callback` function in `tevkori_filter_content_images()`, it doesn't make as much sense to use the callback function the way we originally set it up. However, rather that merging the two function, this turns the callback into a useful utility function that accepts an `img` element and returns the HTML including `srcset` and `sizes` attributes if we can. Additionally, since we only add `srcset` and `sizes` when we're able to parse the attachment id from the markup, we also no longer need to limit our matches in the content filter by files containing the path to our uploads folder. This resolves #190. --- wp-tevko-responsive-images.php | 113 ++++++++++++++------------------- 1 file changed, 46 insertions(+), 67 deletions(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index e0bf345..d250a66 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -302,45 +302,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; @@ -348,21 +329,16 @@ 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; - } - - list( $image_html, $atts ) = $image; - - // Bail early if a 'srcset' attribute already exists. - if ( false !== strpos( $atts, 'srcset=' ) ) { - +function tevkori_img_add_srcset_and_sizes( $image ) { + // Return early if a 'srcset' attribute already exists. + if ( false !== strpos( $image, ' srcset="' ) ) { /* * Backward compatibility. * @@ -370,43 +346,43 @@ function _tevkori_filter_content_images_callback( $image ) { * 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 ); + $image = str_replace( ' data-sizes="', ' sizes="', $image ); - return $image_html; + return $image; } - // 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 { @@ -421,23 +397,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 'tevkori_get_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; } /** From 2fe97890100da38a42b9ab4c7700d39f1015d764 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Sun, 4 Oct 2015 16:41:19 -0500 Subject: [PATCH 02/61] Don't call `image_downsize()` in sizes functions Following c3057fb, we should also avoid calling `image_downsize()` in `tevkori_get_sizes()`. This commit uses only the useful bits from the internals of the `image_downsize()` function to get the width of an image given and `id` and `size`. --- wp-tevko-responsive-images.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index e0bf345..3da1074 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -64,15 +64,14 @@ function tevkori_get_picturefill() { * @return string|bool A valid source size value for use in a 'sizes' attribute or false. */ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { - - // Try to get the image width from `$args` before calling `image_downsize()`. + // Try to get the image width from `$args` first. if ( is_array( $args ) && ! empty( $args['width'] ) ) { $img_width = (int) $args['width']; - } elseif ( $img = image_downsize( $id, $size ) ) { - $img_width = $img[1]; + } elseif ( $img = image_get_intermediate_size( $id, $size ) ) { + list( $img_width, $img_height ) = image_constrain_size_for_editor( $img['width'], $img['height'], $size ); } - // Bail early if ``$image_width` isn't set. + // Bail early if `$image_width` isn't set. if ( ! $img_width ) { return false; } From 654deca01650ccaefde54f11da00e39191391cfa Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Tue, 6 Oct 2015 17:47:37 +0200 Subject: [PATCH 03/61] Upgrade to Picturefill 3.0.1 Fixes #196 --- js/picturefill.min.js | 9 +++++---- wp-tevko-responsive-images.php | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/js/picturefill.min.js b/js/picturefill.min.js index 26b1d36..5bb1dd8 100755 --- a/js/picturefill.min.js +++ b/js/picturefill.min.js @@ -1,4 +1,5 @@ -/*! Picturefill - v2.3.1 - 2015-04-09 -* http://scottjehl.github.io/picturefill -* Copyright (c) 2015 https://github.com/scottjehl/picturefill/blob/master/Authors.txt; Licensed MIT */ -window.matchMedia||(window.matchMedia=function(){"use strict";var a=window.styleMedia||window.media;if(!a){var b=document.createElement("style"),c=document.getElementsByTagName("script")[0],d=null;b.type="text/css",b.id="matchmediajs-test",c.parentNode.insertBefore(b,c),d="getComputedStyle"in window&&window.getComputedStyle(b,null)||b.currentStyle,a={matchMedium:function(a){var c="@media "+a+"{ #matchmediajs-test { width: 1px; } }";return b.styleSheet?b.styleSheet.cssText=c:b.textContent=c,"1px"===d.width}}}return function(b){return{matches:a.matchMedium(b||"all"),media:b||"all"}}}()),function(a,b,c){"use strict";function d(b){"object"==typeof module&&"object"==typeof module.exports?module.exports=b:"function"==typeof define&&define.amd&&define("picturefill",function(){return b}),"object"==typeof a&&(a.picturefill=b)}function e(a){var b,c,d,e,f,i=a||{};b=i.elements||g.getAllElements();for(var j=0,k=b.length;k>j;j++)if(c=b[j],d=c.parentNode,e=void 0,f=void 0,"IMG"===c.nodeName.toUpperCase()&&(c[g.ns]||(c[g.ns]={}),i.reevaluate||!c[g.ns].evaluated)){if(d&&"PICTURE"===d.nodeName.toUpperCase()){if(g.removeVideoShim(d),e=g.getMatch(c,d),e===!1)continue}else e=void 0;(d&&"PICTURE"===d.nodeName.toUpperCase()||!g.sizesSupported&&c.srcset&&h.test(c.srcset))&&g.dodgeSrcset(c),e?(f=g.processSourceSet(e),g.applyBestCandidate(f,c)):(f=g.processSourceSet(c),(void 0===c.srcset||c[g.ns].srcset)&&g.applyBestCandidate(f,c)),c[g.ns].evaluated=!0}}function f(){function c(){clearTimeout(d),d=setTimeout(h,60)}g.initTypeDetects(),e();var d,f=setInterval(function(){return e(),/^loaded|^i|^c/.test(b.readyState)?void clearInterval(f):void 0},250),h=function(){e({reevaluate:!0})};a.addEventListener?a.addEventListener("resize",c,!1):a.attachEvent&&a.attachEvent("onresize",c)}if(a.HTMLPictureElement)return void d(function(){});b.createElement("picture");var g=a.picturefill||{},h=/\s+\+?\d+(e\d+)?w/;g.ns="picturefill",function(){g.srcsetSupported="srcset"in c,g.sizesSupported="sizes"in c,g.curSrcSupported="currentSrc"in c}(),g.trim=function(a){return a.trim?a.trim():a.replace(/^\s+|\s+$/g,"")},g.makeUrl=function(){var a=b.createElement("a");return function(b){return a.href=b,a.href}}(),g.restrictsMixedContent=function(){return"https:"===a.location.protocol},g.matchesMedia=function(b){return a.matchMedia&&a.matchMedia(b).matches},g.getDpr=function(){return a.devicePixelRatio||1},g.getWidthFromLength=function(a){var c;if(!a||a.indexOf("%")>-1!=!1||!(parseFloat(a)>0||a.indexOf("calc(")>-1))return!1;a=a.replace("vw","%"),g.lengthEl||(g.lengthEl=b.createElement("div"),g.lengthEl.style.cssText="border:0;display:block;font-size:1em;left:0;margin:0;padding:0;position:absolute;visibility:hidden",g.lengthEl.className="helper-from-picturefill-js"),g.lengthEl.style.width="0px";try{g.lengthEl.style.width=a}catch(d){}return b.body.appendChild(g.lengthEl),c=g.lengthEl.offsetWidth,0>=c&&(c=!1),b.body.removeChild(g.lengthEl),c},g.detectTypeSupport=function(b,c){var d=new a.Image;return d.onerror=function(){g.types[b]=!1,e()},d.onload=function(){g.types[b]=1===d.width,e()},d.src=c,"pending"},g.types=g.types||{},g.initTypeDetects=function(){g.types["image/jpeg"]=!0,g.types["image/gif"]=!0,g.types["image/png"]=!0,g.types["image/svg+xml"]=b.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1"),g.types["image/webp"]=g.detectTypeSupport("image/webp","data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=")},g.verifyTypeSupport=function(a){var b=a.getAttribute("type");if(null===b||""===b)return!0;var c=g.types[b];return"string"==typeof c&&"pending"!==c?(g.types[b]=g.detectTypeSupport(b,c),"pending"):"function"==typeof c?(c(),"pending"):c},g.parseSize=function(a){var b=/(\([^)]+\))?\s*(.+)/g.exec(a);return{media:b&&b[1],length:b&&b[2]}},g.findWidthFromSourceSize=function(c){for(var d,e=g.trim(c).split(/\s*,\s*/),f=0,h=e.length;h>f;f++){var i=e[f],j=g.parseSize(i),k=j.length,l=j.media;if(k&&(!l||g.matchesMedia(l))&&(d=g.getWidthFromLength(k)))break}return d||Math.max(a.innerWidth||0,b.documentElement.clientWidth)},g.parseSrcset=function(a){for(var b=[];""!==a;){a=a.replace(/^\s+/g,"");var c,d=a.search(/\s/g),e=null;if(-1!==d){c=a.slice(0,d);var f=c.slice(-1);if((","===f||""===c)&&(c=c.replace(/,+$/,""),e=""),a=a.slice(d+1),null===e){var g=a.indexOf(",");-1!==g?(e=a.slice(0,g),a=a.slice(g+1)):(e=a,a="")}}else c=a,a="";(c||e)&&b.push({url:c,descriptor:e})}return b},g.parseDescriptor=function(a,b){var c,d=b||"100vw",e=a&&a.replace(/(^\s+|\s+$)/g,""),f=g.findWidthFromSourceSize(d);if(e)for(var h=e.split(" "),i=h.length-1;i>=0;i--){var j=h[i],k=j&&j.slice(j.length-1);if("h"!==k&&"w"!==k||g.sizesSupported){if("x"===k){var l=j&&parseFloat(j,10);c=l&&!isNaN(l)?l:1}}else c=parseFloat(parseInt(j,10)/f)}return c||1},g.getCandidatesFromSourceSet=function(a,b){for(var c=g.parseSrcset(a),d=[],e=0,f=c.length;f>e;e++){var h=c[e];d.push({url:h.url,resolution:g.parseDescriptor(h.descriptor,b)})}return d},g.dodgeSrcset=function(a){a.srcset&&(a[g.ns].srcset=a.srcset,a.srcset="",a.setAttribute("data-pfsrcset",a[g.ns].srcset))},g.processSourceSet=function(a){var b=a.getAttribute("srcset"),c=a.getAttribute("sizes"),d=[];return"IMG"===a.nodeName.toUpperCase()&&a[g.ns]&&a[g.ns].srcset&&(b=a[g.ns].srcset),b&&(d=g.getCandidatesFromSourceSet(b,c)),d},g.backfaceVisibilityFix=function(a){var b=a.style||{},c="webkitBackfaceVisibility"in b,d=b.zoom;c&&(b.zoom=".999",c=a.offsetWidth,b.zoom=d)},g.setIntrinsicSize=function(){var c={},d=function(a,b,c){b&&a.setAttribute("width",parseInt(b/c,10))};return function(e,f){var h;e[g.ns]&&!a.pfStopIntrinsicSize&&(void 0===e[g.ns].dims&&(e[g.ns].dims=e.getAttribute("width")||e.getAttribute("height")),e[g.ns].dims||(f.url in c?d(e,c[f.url],f.resolution):(h=b.createElement("img"),h.onload=function(){if(c[f.url]=h.width,!c[f.url])try{b.body.appendChild(h),c[f.url]=h.width||h.offsetWidth,b.body.removeChild(h)}catch(a){}e.src===f.url&&d(e,c[f.url],f.resolution),e=null,h.onload=null,h=null},h.src=f.url)))}}(),g.applyBestCandidate=function(a,b){var c,d,e;a.sort(g.ascendingSort),d=a.length,e=a[d-1];for(var f=0;d>f;f++)if(c=a[f],c.resolution>=g.getDpr()){e=c;break}e&&(e.url=g.makeUrl(e.url),b.src!==e.url&&(g.restrictsMixedContent()&&"http:"===e.url.substr(0,"http:".length).toLowerCase()?void 0!==window.console&&console.warn("Blocked mixed content image "+e.url):(b.src=e.url,g.curSrcSupported||(b.currentSrc=b.src),g.backfaceVisibilityFix(b))),g.setIntrinsicSize(b,e))},g.ascendingSort=function(a,b){return a.resolution-b.resolution},g.removeVideoShim=function(a){var b=a.getElementsByTagName("video");if(b.length){for(var c=b[0],d=c.getElementsByTagName("source");d.length;)a.insertBefore(d[0],c);c.parentNode.removeChild(c)}},g.getAllElements=function(){for(var a=[],c=b.getElementsByTagName("img"),d=0,e=c.length;e>d;d++){var f=c[d];("PICTURE"===f.parentNode.nodeName.toUpperCase()||null!==f.getAttribute("srcset")||f[g.ns]&&null!==f[g.ns].srcset)&&a.push(f)}return a},g.getMatch=function(a,b){for(var c,d=b.childNodes,e=0,f=d.length;f>e;e++){var h=d[e];if(1===h.nodeType){if(h===a)return c;if("SOURCE"===h.nodeName.toUpperCase()){null!==h.getAttribute("src")&&void 0!==typeof console&&console.warn("The `src` attribute is invalid on `picture` `source` element; instead, use `srcset`.");var i=h.getAttribute("media");if(h.getAttribute("srcset")&&(!i||g.matchesMedia(i))){var j=g.verifyTypeSupport(h);if(j===!0){c=h;break}if("pending"===j)return!1}}}}return c},f(),e._=g,d(e)}(window,window.document,new window.Image); +/*! Picturefill - v3.0.1 - 2015-09-30 + * http://scottjehl.github.io/picturefill + * Copyright (c) 2015 https://github.com/scottjehl/picturefill/blob/master/Authors.txt; Licensed MIT + */ +!function(a){var b=navigator.userAgent;a.HTMLPictureElement&&/ecko/.test(b)&&b.match(/rv\:(\d+)/)&&RegExp.$1<41&&addEventListener("resize",function(){var b,c=document.createElement("source"),d=function(a){var b,d,e=a.parentNode;"PICTURE"===e.nodeName.toUpperCase()?(b=c.cloneNode(),e.insertBefore(b,e.firstElementChild),setTimeout(function(){e.removeChild(b)})):(!a._pfLastSize||a.offsetWidth>a._pfLastSize)&&(a._pfLastSize=a.offsetWidth,d=a.sizes,a.sizes+=",100vw",setTimeout(function(){a.sizes=d}))},e=function(){var a,b=document.querySelectorAll("picture > img, img[srcset][sizes]");for(a=0;a2.7?h=c+1:(f=b-c,e=Math.pow(a-.6,1.5),g=f*e,d&&(g+=.1*e),h=a+g):h=c>1?Math.sqrt(a*b):a,h>c}function h(a){var b,c=s.getSet(a),d=!1;"pending"!==c&&(d=r,c&&(b=s.setRes(c),s.applySetCandidate(b,a))),a[s.ns].evaled=d}function i(a,b){return a.res-b.res}function j(a,b,c){var d;return!c&&b&&(c=a[s.ns].sets,c=c&&c[c.length-1]),d=k(b,c),d&&(b=s.makeUrl(b),a[s.ns].curSrc=b,a[s.ns].curCan=d,d.res||_(d,d.set.sizes)),d}function k(a,b){var c,d,e;if(a&&b)for(e=s.parseSet(b),a=s.makeUrl(a),c=0;cc;c++)e=g[c],e[s.ns]=!0,f=e.getAttribute("srcset"),f&&b.push({srcset:f,media:e.getAttribute("media"),type:e.getAttribute("type"),sizes:e.getAttribute("sizes")})}function m(a,b){function c(b){var c,d=b.exec(a.substring(m));return d?(c=d[0],m+=c.length,c):void 0}function e(){var a,c,d,e,f,i,j,k,l,m=!1,o={};for(e=0;el?m=!0:c=l):W.test(j)&&"h"===i?((d||c)&&(m=!0),0===k?m=!0:d=k):m=!0;m||(o.url=g,a&&(o.w=a),c&&(o.d=c),d&&(o.h=d),d||c||a||(o.d=1),1===o.d&&(b.has1x=!0),o.set=b,n.push(o))}function f(){for(c(S),i="",j="in descriptor";;){if(k=a.charAt(m),"in descriptor"===j)if(d(k))i&&(h.push(i),i="",j="after descriptor");else{if(","===k)return m+=1,i&&h.push(i),void e();if("("===k)i+=k,j="in parens";else{if(""===k)return i&&h.push(i),void e();i+=k}}else if("in parens"===j)if(")"===k)i+=k,j="in descriptor";else{if(""===k)return h.push(i),void e();i+=k}else if("after descriptor"===j)if(d(k));else{if(""===k)return void e();j="in descriptor",m-=1}m+=1}}for(var g,h,i,j,k,l=a.length,m=0,n=[];;){if(c(T),m>=l)return n;g=c(U),h=[],","===g.slice(-1)?(g=g.replace(V,""),e()):f()}}function n(a){function b(a){function b(){f&&(g.push(f),f="")}function c(){g[0]&&(h.push(g),g=[])}for(var e,f="",g=[],h=[],i=0,j=0,k=!1;;){if(e=a.charAt(j),""===e)return b(),c(),h;if(k){if("*"===e&&"/"===a[j+1]){k=!1,j+=2,b();continue}j+=1}else{if(d(e)){if(a.charAt(j-1)&&d(a.charAt(j-1))||!f){j+=1;continue}if(0===i){b(),j+=1;continue}e=" "}else if("("===e)i+=1;else if(")"===e)i-=1;else{if(","===e){b(),c(),j+=1;continue}if("/"===e&&"*"===a.charAt(j+1)){k=!0,j+=2;continue}}f+=e,j+=1}}}function c(a){return k.test(a)&&parseFloat(a)>=0?!0:l.test(a)?!0:"0"===a||"-0"===a||"+0"===a?!0:!1}var e,f,g,h,i,j,k=/^(?:[+-]?[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?(?:ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmin|vmax|vw)$/i,l=/^calc\((?:[0-9a-z \.\+\-\*\/\(\)]+)\)$/i;for(f=b(a),g=f.length,e=0;g>e;e++)if(h=f[e],i=h[h.length-1],c(i)){if(j=i,h.pop(),0===h.length)return j;if(h=h.join(" "),s.matchesMedia(h))return j}return"100vw"}b.createElement("picture");var o,p,q,r,s={},t=function(){},u=b.createElement("img"),v=u.getAttribute,w=u.setAttribute,x=u.removeAttribute,y=b.documentElement,z={},A={algorithm:""},B="data-pfsrc",C=B+"set",D=navigator.userAgent,E=/rident/.test(D)||/ecko/.test(D)&&D.match(/rv\:(\d+)/)&&RegExp.$1>35,F="currentSrc",G=/\s+\+?\d+(e\d+)?w/,H=/(\([^)]+\))?\s*(.+)/,I=a.picturefillCFG,J="position:absolute;left:0;visibility:hidden;display:block;padding:0;border:none;font-size:1em;width:1em;overflow:hidden;clip:rect(0px, 0px, 0px, 0px)",K="font-size:100%!important;",L=!0,M={},N={},O=a.devicePixelRatio,P={px:1,"in":96},Q=b.createElement("a"),R=!1,S=/^[ \t\n\r\u000c]+/,T=/^[, \t\n\r\u000c]+/,U=/^[^ \t\n\r\u000c]+/,V=/[,]+$/,W=/^\d+$/,X=/^-?(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/,Y=function(a,b,c,d){a.addEventListener?a.addEventListener(b,c,d||!1):a.attachEvent&&a.attachEvent("on"+b,c)},Z=function(a){var b={};return function(c){return c in b||(b[c]=a(c)),b[c]}},$=function(){var a=/^([\d\.]+)(em|vw|px)$/,b=function(){for(var a=arguments,b=0,c=a[0];++b in a;)c=c.replace(a[b],a[++b]);return c},c=Z(function(a){return"return "+b((a||"").toLowerCase(),/\band\b/g,"&&",/,/g,"||",/min-([a-z-\s]+):/g,"e.$1>=",/max-([a-z-\s]+):/g,"e.$1<=",/calc([^)]+)/g,"($1)",/(\d+[\.]*[\d]*)([a-z]+)/g,"($1 * e.$2)",/^(?!(e.[a-z]|[0-9\.&=|><\+\-\*\(\)\/])).*/gi,"")+";"});return function(b,d){var e;if(!(b in M))if(M[b]=!1,d&&(e=b.match(a)))M[b]=e[1]*P[e[2]];else try{M[b]=new Function("e",c(b))(P)}catch(f){}return M[b]}}(),_=function(a,b){return a.w?(a.cWidth=s.calcListLength(b||"100vw"),a.res=a.w/a.cWidth):a.res=a.d,a},aa=function(a){var c,d,e,f=a||{};if(f.elements&&1===f.elements.nodeType&&("IMG"===f.elements.nodeName.toUpperCase()?f.elements=[f.elements]:(f.context=f.elements,f.elements=null)),c=f.elements||s.qsa(f.context||b,f.reevaluate||f.reselect?s.sel:s.selShort),e=c.length){for(s.setupRun(f),R=!0,d=0;e>d;d++)s.fillImg(c[d],f);s.teardownRun(f)}};o=a.console&&console.warn?function(a){console.warn(a)}:t,F in u||(F="src"),z["image/jpeg"]=!0,z["image/gif"]=!0,z["image/png"]=!0,z["image/svg+xml"]=b.implementation.hasFeature("http://wwwindow.w3.org/TR/SVG11/feature#Image","1.1"),s.ns=("pf"+(new Date).getTime()).substr(0,9),s.supSrcset="srcset"in u,s.supSizes="sizes"in u,s.supPicture=!!a.HTMLPictureElement,s.supSrcset&&s.supPicture&&!s.supSizes&&!function(a){u.srcset="data:,a",a.src="data:,a",s.supSrcset=u.complete===a.complete,s.supPicture=s.supSrcset&&s.supPicture}(b.createElement("img")),s.selShort="picture>img,img[srcset]",s.sel=s.selShort,s.cfg=A,s.supSrcset&&(s.sel+=",img["+C+"]"),s.DPR=O||1,s.u=P,s.types=z,q=s.supSrcset&&!s.supSizes,s.setSize=t,s.makeUrl=Z(function(a){return Q.href=a,Q.href}),s.qsa=function(a,b){return a.querySelectorAll(b)},s.matchesMedia=function(){return a.matchMedia&&(matchMedia("(min-width: 0.1em)")||{}).matches?s.matchesMedia=function(a){return!a||matchMedia(a).matches}:s.matchesMedia=s.mMQ,s.matchesMedia.apply(this,arguments)},s.mMQ=function(a){return a?$(a):!0},s.calcLength=function(a){var b=$(a,!0)||!1;return 0>b&&(b=!1),b},s.supportsType=function(a){return a?z[a]:!0},s.parseSize=Z(function(a){var b=(a||"").match(H);return{media:b&&b[1],length:b&&b[2]}}),s.parseSet=function(a){return a.cands||(a.cands=m(a.srcset,a)),a.cands},s.getEmValue=function(){var a;if(!p&&(a=b.body)){var c=b.createElement("div"),d=y.style.cssText,e=a.style.cssText;c.style.cssText=J,y.style.cssText=K,a.style.cssText=K,a.appendChild(c),p=c.offsetWidth,a.removeChild(c),p=parseFloat(p,10),y.style.cssText=d,a.style.cssText=e}return p||16},s.calcListLength=function(a){if(!(a in N)||A.uT){var b=s.calcLength(n(a));N[a]=b?b:P.width}return N[a]},s.setRes=function(a){var b;if(a){b=s.parseSet(a);for(var c=0,d=b.length;d>c;c++)_(b[c],a.sizes)}return b},s.setRes.res=_,s.applySetCandidate=function(a,b){if(a.length){var c,d,e,f,h,k,l,m,n,o=b[s.ns],p=s.DPR;if(k=o.curSrc||b[F],l=o.curCan||j(b,k,a[0].set),l&&l.set===a[0].set&&(n=E&&!b.complete&&l.res-.1>p,n||(l.cached=!0,l.res>=p&&(h=l))),!h)for(a.sort(i),f=a.length,h=a[f-1],d=0;f>d;d++)if(c=a[d],c.res>=p){e=d-1,h=a[e]&&(n||k!==s.makeUrl(c.url))&&g(a[e].res,c.res,p,a[e].cached)?a[e]:c;break}h&&(m=s.makeUrl(h.url),o.curSrc=m,o.curCan=h,m!==k&&s.setSrc(b,h),s.setSize(b))}},s.setSrc=function(a,b){var c;a.src=b.url,"image/svg+xml"===b.set.type&&(c=a.style.width,a.style.width=a.offsetWidth+1+"px",a.offsetWidth+1&&(a.style.width=c))},s.getSet=function(a){var b,c,d,e=!1,f=a[s.ns].sets;for(b=0;bf?c=setTimeout(e,b-f):(c=null,a())};return function(){d=new Date,c||(c=setTimeout(e,b))}},h=y.clientHeight,i=function(){L=Math.max(a.innerWidth||0,y.clientWidth)!==P.width||y.clientHeight!==h,h=y.clientHeight,L&&s.fillImgs()};Y(a,"resize",g(i,99)),Y(b,"readystatechange",e)}(),s.picturefill=aa,s.fillImgs=aa,s.teardownRun=t,aa._=s,a.picturefillCFG={pf:s,push:function(a){var b=a.shift();"function"==typeof s[b]?s[b].apply(s,a):(A[b]=a[0],R&&s.fillImgs({reselect:!0}))}};for(;I&&I.length;)a.picturefillCFG.push(I.shift());a.picturefill=aa,"object"==typeof module&&"object"==typeof module.exports?module.exports=aa:"function"==typeof define&&define.amd&&define("picturefill",function(){return aa}),s.supPicture||(z["image/webp"]=e("image/webp","data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAABBxAR/Q9ERP8DAABWUDggGAAAADABAJ0BKgEAAQADADQlpAADcAD++/1QAA=="))}(window,document); \ No newline at end of file diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 6f98035..f59cb60 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -44,7 +44,7 @@ function tevkori_wp_image_editors( $editors ) { * Enqueue bundled version of the Picturefill library. */ function tevkori_get_picturefill() { - wp_enqueue_script( 'picturefill', plugins_url( 'js/picturefill.min.js', __FILE__ ), array(), '2.3.1', true ); + wp_enqueue_script( 'picturefill', plugins_url( 'js/picturefill.min.js', __FILE__ ), array(), '3.0.1', true ); } add_action( 'wp_enqueue_scripts', 'tevkori_get_picturefill' ); From 2008dd9196b375c4bb55d66829065124477ba76c Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Mon, 5 Oct 2015 12:05:18 +0200 Subject: [PATCH 04/61] Cleanup inline docs --- wp-tevko-responsive-images.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index f59cb60..361cf6f 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -175,7 +175,7 @@ function tevkori_get_sizes_string( $id, $size = 'medium', $args = null ) { * * @param int $id Image attachment ID. * @param string $size Optional. Name of image size. Default value: 'medium'. - * @return array|bool An array of of srcset values or false. + * @return array|bool An array of `srcset` values or false. */ function tevkori_get_srcset_array( $id, $size = 'medium' ) { $arr = array(); @@ -350,7 +350,7 @@ function tevkori_img_add_srcset_and_sizes( $image ) { return $image; } - // Parse id, size, width, and height from the `img` element. + // 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; @@ -368,10 +368,10 @@ function tevkori_img_add_srcset_and_sizes( $image ) { * 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. + // Parse the image 'src' value from the 'img' element. $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : false; - // Return early if the `src` value is empty. + // Return early if the 'src' value is empty. if ( ! $src ) { return $image; } From eb8b5c8bf8d973f388ebfc30ffad601d591e5b37 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Mon, 5 Oct 2015 12:48:31 +0200 Subject: [PATCH 05/61] Check if wp_get_attachment_metadata returns an array Fixes #208 --- wp-tevko-responsive-images.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 361cf6f..c264867 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -183,7 +183,9 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { // Get the intermediate size. $image = image_get_intermediate_size( $id, $size ); // Get the post meta. - $img_meta = wp_get_attachment_metadata( $id ); + if ( ! is_array( $img_meta = wp_get_attachment_metadata( $id ) ) ) { + return false; + } // Extract the height and width from the intermediate or the full size. $img_width = ( $image ) ? $image['width'] : $img_meta['width']; @@ -367,7 +369,7 @@ function tevkori_img_add_srcset_and_sizes( $image ) { * If attempts to parse the size value failed, attempt to use the image * metadata to match the 'src' against the available sizes for an attachment. */ - if ( ! $size && ! empty( $id ) && $meta = wp_get_attachment_metadata( $id ) ) { + if ( ! $size && ! empty( $id ) && is_array( $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; From ea008071d84f8afbdc38ea1ac9e870da673f07f6 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 6 Oct 2015 20:46:02 -0500 Subject: [PATCH 06/61] Version bump 2.6.0 --- wp-tevko-responsive-images.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index c264867..3cb1c44 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.2 + * Version: 2.6.0 * Author: The RICG * Author URI: http://responsiveimages.org/ * License: GPL-2.0+ From 955780a1844e1b3d141c027d608d9df730a3b17d Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 6 Oct 2015 20:49:13 -0500 Subject: [PATCH 07/61] Update readme files, changelogs. --- readme.md | 10 +++++++++- readme.txt | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index c91a780..b520f7b 100644 --- a/readme.md +++ b/readme.md @@ -140,10 +140,18 @@ We use a hook because if you attempt to dequeue a script before it's enqueued, w ## Version -2.5.2 +2.6.0 ## Changelog +- Turns display filter callback into a general utility function for adding srcset and sizes attributes image HTML. +- Upgrade to Picturefill 3.0.1 +- Avoids calling image_downsize() when calculating sizes attributes to speed things up. +- Fixes a bug when wp_get_attachment_metadata() failed to return an array. +- Clean up inline docs. + +**2.5.2** + - Numerous performance and usability improvements - Pass height and width to `tevkori_get_sizes() - Improved regex in display filter diff --git a/readme.txt b/readme.txt index b247914..3e3b88f 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.2 +Stable tag: 2.6.0 License: GPLv2 License URI: http://www.gnu.org/licenses/gpl-2.0.txt @@ -26,6 +26,14 @@ This plugin works by including all available image sizes for each image upload. == Changelog == += 2.6.0 = +* Turns display filter callback into a general utility function for adding srcset and sizes attributes image HTML. +* Upgrade to Picturefill 3.0.1 +* Avoids calling image_downsize() when calculating sizes attributes to speed things up. +* Fixes a bug when wp_get_attachment_metadata() failed to return an array. +* Clean up inline docs. + + = 2.5.2 = * Numerous performance and usability improvements * Pass height and width to `tevkori_get_sizes() From ca029028cbc1a3b61a2796bc6028c12ea56b8f29 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Sun, 11 Oct 2015 15:54:12 +0200 Subject: [PATCH 08/61] Clear and consistent function descriptions --- wp-tevko-responsive-images.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 3cb1c44..cd9bda6 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -49,7 +49,7 @@ function tevkori_get_picturefill() { add_action( 'wp_enqueue_scripts', 'tevkori_get_picturefill' ); /** - * Return a source size attribute for an image from an array of values. + * Returns the value for a 'sizes' attribute. * * @since 2.2.0 * @@ -96,7 +96,7 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { $args = wp_parse_args( $args, $defaults ); /** - * Filter arguments used to create 'sizes' attribute. + * Filter arguments used to create the 'sizes' attribute value. * * @since 2.4.0 * @@ -150,7 +150,7 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { } /** - * Return a source size list for an image from an array of values. + * Returns a 'sizes' attribute. * * @since 2.2.0 * @@ -171,7 +171,7 @@ function tevkori_get_sizes_string( $id, $size = 'medium', $args = null ) { } /** - * Get an array of image sources candidates for use in a 'srcset' attribute. + * Returns an array of image sources for a 'srcset' attribute. * * @param int $id Image attachment ID. * @param string $size Optional. Name of image size. Default value: 'medium'. @@ -257,7 +257,7 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { } /** - * Get the value for the 'srcset' attribute. + * Returns the value for a 'srcset' attribute. * * @since 2.3.0 * @@ -276,7 +276,7 @@ function tevkori_get_srcset( $id, $size = 'medium' ) { } /** - * Create a 'srcset' attribute. + * Returns a 'srcset' attribute. * * @since 2.1.0 * @@ -295,7 +295,7 @@ function tevkori_get_srcset_string( $id, $size = 'medium' ) { } /** - * Filters images in post content to add 'srcset' and 'sizes'. + * Filter to add 'srcset' and 'sizes' attributes to images in the post content. * * @since 2.5.0 * @@ -330,7 +330,7 @@ function tevkori_filter_content_images( $content ) { add_filter( 'the_content', 'tevkori_filter_content_images', 5, 1 ); /** - * Add srcset and sizes to an 'img' element. + * Adds 'srcset' and 'sizes' attributes to image elements. * * @since 2.6.0 * From a858686d05e0c492b03d13d8b10526ff337691eb Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Sun, 11 Oct 2015 17:49:57 +0200 Subject: [PATCH 09/61] Minor corrections in changelog --- readme.md | 31 ++++++++++++++++--------------- readme.txt | 28 ++++++++++++++-------------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/readme.md b/readme.md index b520f7b..2b24fcc 100644 --- a/readme.md +++ b/readme.md @@ -146,20 +146,20 @@ We use a hook because if you attempt to dequeue a script before it's enqueued, w - Turns display filter callback into a general utility function for adding srcset and sizes attributes image HTML. - Upgrade to Picturefill 3.0.1 -- Avoids calling image_downsize() when calculating sizes attributes to speed things up. -- Fixes a bug when wp_get_attachment_metadata() failed to return an array. +- Avoids calling `image_downsize()` when calculating sizes attributes to speed things up. +- Fixes a bug when `wp_get_attachment_metadata()` failed to return an array. - Clean up inline docs. **2.5.2** - Numerous performance and usability improvements -- Pass height and width to `tevkori_get_sizes() +- 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' +- Change default `$size` value for all functions to 'medium' **2.5.1** @@ -171,14 +171,14 @@ We use a hook because if you attempt to dequeue a script before it's enqueued, w - 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 +- Added 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()` **2.4.0** -- Added filter for tevkori_get_sizes, with tests +- Added filter for `tevkori_get_sizes`, with tests - Added Composer support - Compare aspect ratio in relative values, not absolute values - Cleanup of code style and comments added @@ -193,7 +193,7 @@ We use a hook because if you attempt to dequeue a script before it's enqueued, w - Added 'sudo: false' to travis.ci to use new TravisCI infrastructure - Removing the srcset and sizes attributes if there is only one source present for the image - Use edited image hash to filter out originals from edited images -- Make output of tevkori_get_srcset_array filterable +- Make output of `tevkori_get_srcset_array` filterable **2.3.1** @@ -208,14 +208,14 @@ We use a hook because if you attempt to dequeue a script before it's enqueued, w - Added advanced image compression option (available by adding hook to functions.php) - Duplicate entires now filtered out from srcset array - Upgrade Picturefill to 2.3.1 -- Refactoring plugin JS, including a switch to ajax for updating the srcset value when the image is changed in the editor -- Now using wp_get_attachment_image_attributes filter for post thumbnails +- Refactoring plugin JavaScript, including a switch to ajax for updating the srcset value when the image is changed in the editor +- Now using `wp_get_attachment_image_attributes` filter for post thumbnails - Readme and other general code typo fixes - Gallery images will now contain a srcset attribute **2.2.1** -- JS patch for WordPress +- JavaScript patch for WordPress **2.2.0** @@ -223,18 +223,17 @@ We use a hook because if you attempt to dequeue a script before it's enqueued, w - Updated to Picturefill v2.3.0 - Extensive documentation included in readme - Integrated testing with Travis CLI -- Check if wp.media exists before running JS +- Check if wp.media exists before running JavaScript - Account for rounding variance when matching ascpect ratios **2.1.1** -- Adding in wp-tevko-responsive-images.js after file not found to be in wordpress repository -- Adjusts the aspect ratio check in tevkori_get_srcset_array() to account for rounding variance +- Adding in wp-tevko-responsive-images.js after file not found to be in WordPress repository +- Adjusts the aspect ratio check in `tevkori_get_srcset_array()` to account for rounding variance **2.1.0** -- **This version introduces a breaking change** - there are now two functions. One returns an array of srcset values, and the other returns a string with the ``srcset=".."`` html needed to generate the responsive image. To retrieve the srcset array, use ``tevkori_get_srcset_array( $id, $size )`` - +- **This version introduces a breaking change**: There are now two functions. One returns an array of srcset values, and the other returns a string with the `srcset=".."` html needed to generate the responsive image. To retrieve the srcset array, use `tevkori_get_srcset_array( $id, $size )` - When the image size is changed in the post editor, the srcset values will adjust to match the change. **2.0.2** @@ -242,10 +241,12 @@ We use a hook because if you attempt to dequeue a script before it's enqueued, w - A bugfix correcting a divide by zero error. Some users may have seen this after upgrading to 2.0.1 **2.0.1** + - Only outputs the default WordPress sizes, giving theme developers the option to extend as needed - Added support for featured images **2.0.0** + - Uses [Picturefill 2.2.0 (Beta)](http://scottjehl.github.io/picturefill/) - Scripts are output to footer - Image sizes adjusted diff --git a/readme.txt b/readme.txt index 3e3b88f..9dfc7f5 100644 --- a/readme.txt +++ b/readme.txt @@ -1,5 +1,5 @@ === RICG Responsive Images === -Contributors: tevko, wilto, joemcgill, jaspermdegroot, chriscoyier, Michael McGinnis, ryelle, drrobotnik, nacin , georgestephanis, helen, wordpressdotorg, Bocoup +Contributors: tevko, wilto, joemcgill, jaspermdegroot, chriscoyier, Michael McGinnis, ryelle, drrobotnik, nacin, georgestephanis, helen, wordpressdotorg, Bocoup Donate link: https://app.etapestry.com/hosted/BoweryResidentsCommittee/OnlineDonation.html Tags: Responsive, Images, Responsive Images, SRCSET, Picturefill Requires at least: 4.1 @@ -29,20 +29,20 @@ This plugin works by including all available image sizes for each image upload. = 2.6.0 = * Turns display filter callback into a general utility function for adding srcset and sizes attributes image HTML. * Upgrade to Picturefill 3.0.1 -* Avoids calling image_downsize() when calculating sizes attributes to speed things up. -* Fixes a bug when wp_get_attachment_metadata() failed to return an array. +* Avoids calling `image_downsize()` when calculating sizes attributes to speed things up. +* Fixes a bug when `wp_get_attachment_metadata()` failed to return an array. * Clean up inline docs. = 2.5.2 = * Numerous performance and usability improvements -* Pass height and width to `tevkori_get_sizes() +* 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' +* Change default `$size` value for all functions to 'medium' = 2.5.1 = * Query all images in single request before replacing @@ -53,13 +53,13 @@ This plugin works by including all available image sizes for each image upload. = 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 +* Added 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()` = 2.4.0 = -* Added filter for tevkori_get_sizes, with tests +* Added filter for `tevkori_get_sizes`, with tests * Added Composer support * Compare aspect ratio in relative values, not absolute values * Cleanup of code style and comments added @@ -74,7 +74,7 @@ This plugin works by including all available image sizes for each image upload. * Added 'sudo: false' to travis.ci to use new TravisCI infrastructure * Removing the srcset and sizes attributes if there is only one source present for the image * Use edited image hash to filter out originals from edited images -* Make output of tevkori_get_srcset_array filterable +* Make output of `tevkori_get_srcset_array` filterable = 2.3.1 = * First char no longer stripped from file name if there's no slash @@ -87,28 +87,28 @@ This plugin works by including all available image sizes for each image upload. * Added advanced image compression option (available by adding hook to functions.php) * Duplicate entires now filtered out from srcset array * Upgrade Picturefill to 2.3.1 -* Refactoring plugin JS, including a switch to ajax for updating the srcset value when the image is changed in the editor -* Now using wp_get_attachment_image_attributes filter for post thumbnails +* Refactoring plugin JavaScript, including a switch to ajax for updating the srcset value when the image is changed in the editor +* Now using `wp_get_attachment_image_attributes` filter for post thumbnails * Readme and other general code typo fixes * Gallery images will now contain a srcset attribute = 2.2.1 = -* Patch fixing missing javascript error +* Patch fixing missing JavaScript error = 2.2.0 = * The mandatory sizes attribute is now included on all images * Updated to Picturefill v2.3.0 * Extensive documentation included in readme * Integrated testing with Travis CLI -* Check if wp.media exists before running JS +* Check if wp.media exists before running JavaScript * Account for rounding variance when matching ascpect ratios = 2.1.1 = * Adding in wp-tevko-responsive-images.js after file not found to be in WordPress repository -* Adjusts the aspect ratio check in tevkori_get_srcset_array() to account for rounding variance +* Adjusts the aspect ratio check in `tevkori_get_srcset_array()` to account for rounding variance = 2.1.0 = -* **This version introduces a breaking change** - there are now two functions. One returns an array of srcset values, and the other returns a string with the `srcset=".."` html needed to generate the responsive image. To retrieve the srcset array, us `tevkori_get_srcset_array( $id, $size )` +* **This version introduces a breaking change**: There are now two functions. One returns an array of srcset values, and the other returns a string with the `srcset=".."` html needed to generate the responsive image. To retrieve the srcset array, us `tevkori_get_srcset_array( $id, $size )` * When the image size is changed in the post editor, the srcset values will adjust to match the change. = 2.0.2 = From 9ae7254cd8bda0796c5b3e9a153ca128c0bd2d89 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Sat, 17 Oct 2015 12:19:36 -0500 Subject: [PATCH 10/61] Update install-wp-tests.sh after REST merge See https://github.com/wp-cli/wp-cli/issues/2129 --- bin/install-wp-tests.sh | 60 ++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/bin/install-wp-tests.sh b/bin/install-wp-tests.sh index a3f1184..0aaf09f 100755 --- a/bin/install-wp-tests.sh +++ b/bin/install-wp-tests.sh @@ -14,21 +14,48 @@ WP_VERSION=${5-latest} WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} +download() { + if [ `which curl` ]; then + curl -s "$1" > "$2"; + elif [ `which wget` ]; then + wget -nv -O "$2" "$1" + fi +} + +if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then + WP_TESTS_TAG="tags/$WP_VERSION" +else + # http serves a single offer, whereas https serves multiple. we only want one + download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json + grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json + LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//') + if [[ -z "$LATEST_VERSION" ]]; then + echo "Latest WordPress version could not be found" + exit 1 + fi + WP_TESTS_TAG="tags/$LATEST_VERSION" +fi + set -ex install_wp() { + + if [ -d $WP_CORE_DIR ]; then + return; + fi + mkdir -p $WP_CORE_DIR - if [ $WP_VERSION == 'latest' ]; then + if [ $WP_VERSION == 'latest' ]; then local ARCHIVE_NAME='latest' else local ARCHIVE_NAME="wordpress-$WP_VERSION" fi - wget -nv -O /tmp/wordpress.tar.gz https://wordpress.org/${ARCHIVE_NAME}.tar.gz + download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR - wget -nv -O $WP_CORE_DIR/wp-content/db.php https://raw.github.com/markoheijnen/wp-mysqli/master/db.php + download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php } install_test_suite() { @@ -39,17 +66,24 @@ install_test_suite() { local ioption='-i' fi - # set up testing suite - mkdir -p $WP_TESTS_DIR + # set up testing suite if it doesn't yet exist + if [ ! -d $WP_TESTS_DIR ]; then + # set up testing suite + mkdir -p $WP_TESTS_DIR + svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes + fi + cd $WP_TESTS_DIR - svn co --quiet https://develop.svn.wordpress.org/trunk/tests/phpunit/includes/ - - wget -nv -O wp-tests-config.php https://develop.svn.wordpress.org/trunk/wp-tests-config-sample.php - sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" wp-tests-config.php - sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" wp-tests-config.php - sed $ioption "s/yourusernamehere/$DB_USER/" wp-tests-config.php - sed $ioption "s/yourpasswordhere/$DB_PASS/" wp-tests-config.php - sed $ioption "s|localhost|${DB_HOST}|" wp-tests-config.php + + if [ ! -f wp-tests-config.php ]; then + download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php + fi + } install_db() { From 90da1dc3009eaa5a447a715539812f5ae21c291b Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Tue, 3 Nov 2015 16:37:52 +0100 Subject: [PATCH 11/61] Revert "Version bump 2.6.0" This reverts commit ea008071d84f8afbdc38ea1ac9e870da673f07f6. --- wp-tevko-responsive-images.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index cd9bda6..40abfb9 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.6.0 + * Version: 2.5.2 * Author: The RICG * Author URI: http://responsiveimages.org/ * License: GPL-2.0+ From 2d84ac16199e9513a3376c59af73cdf7e93dcd76 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Tue, 3 Nov 2015 16:42:01 +0100 Subject: [PATCH 12/61] Revert "Update readme files, changelogs." This reverts commit 955780a1844e1b3d141c027d608d9df730a3b17d. --- readme.md | 10 +--------- readme.txt | 10 +--------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/readme.md b/readme.md index 2b24fcc..18a6d16 100644 --- a/readme.md +++ b/readme.md @@ -140,18 +140,10 @@ We use a hook because if you attempt to dequeue a script before it's enqueued, w ## Version -2.6.0 +2.5.2 ## Changelog -- Turns display filter callback into a general utility function for adding srcset and sizes attributes image HTML. -- Upgrade to Picturefill 3.0.1 -- Avoids calling `image_downsize()` when calculating sizes attributes to speed things up. -- Fixes a bug when `wp_get_attachment_metadata()` failed to return an array. -- Clean up inline docs. - -**2.5.2** - - Numerous performance and usability improvements - Pass height and width to `tevkori_get_sizes()` - Improved regex in display filter diff --git a/readme.txt b/readme.txt index 9dfc7f5..0264ebb 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.6.0 +Stable tag: 2.5.2 License: GPLv2 License URI: http://www.gnu.org/licenses/gpl-2.0.txt @@ -26,14 +26,6 @@ This plugin works by including all available image sizes for each image upload. == Changelog == -= 2.6.0 = -* Turns display filter callback into a general utility function for adding srcset and sizes attributes image HTML. -* Upgrade to Picturefill 3.0.1 -* Avoids calling `image_downsize()` when calculating sizes attributes to speed things up. -* Fixes a bug when `wp_get_attachment_metadata()` failed to return an array. -* Clean up inline docs. - - = 2.5.2 = * Numerous performance and usability improvements * Pass height and width to `tevkori_get_sizes()` From cc41e161c4846de196b17655e12db69fe9fd6c5e Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 6 Oct 2015 21:59:41 -0500 Subject: [PATCH 13/61] Post merge cleanup Move all of the core functions into a new file named `wp-tevko-core-functions.php` that is only loaded if `wp_get_attachment_image_srcset()` does not exist. Otherwise, we load a set of compatability shims, `wp-tevko-compat-shims`, for people using our core functions in their themes. --- wp-tevko-compat-shims.php | 158 +++++++++++++ wp-tevko-core-functions.php | 401 ++++++++++++++++++++++++++++++++ wp-tevko-responsive-images.php | 403 +-------------------------------- 3 files changed, 563 insertions(+), 399 deletions(-) create mode 100644 wp-tevko-compat-shims.php create mode 100644 wp-tevko-core-functions.php diff --git a/wp-tevko-compat-shims.php b/wp-tevko-compat-shims.php new file mode 100644 index 0000000..baddd09 --- /dev/null +++ b/wp-tevko-compat-shims.php @@ -0,0 +1,158 @@ + array( + array( + 'size_value' => '100vw', + 'mq_value' => $img_width, + 'mq_name' => 'max-width' + ), + array( + 'size_value' => $img_width + ), + ) + ); + + $args = wp_parse_args( $args, $defaults ); + + /** + * Filter arguments used to create 'sizes' attribute. + * + * @since 2.4.0 + * + * @param array $args An array of arguments used to create a 'sizes' attribute. + * @param int $id Post ID of the original image. + * @param string $size Name of the image size being used. + */ + $args = apply_filters( 'tevkori_image_sizes_args', $args, $id, $size ); + + // If sizes is passed as a string, just use the string. + if ( is_string( $args['sizes'] ) ) { + $size_list = $args['sizes']; + + // Otherwise, breakdown the array and build a sizes string. + } elseif ( is_array( $args['sizes'] ) ) { + + $size_list = ''; + + foreach ( $args['sizes'] as $size ) { + + // Use 100vw as the size value unless something else is specified. + $size_value = ( $size['size_value'] ) ? $size['size_value'] : '100vw'; + + // If a media length is specified, build the media query. + if ( ! empty( $size['mq_value'] ) ) { + + $media_length = $size['mq_value']; + + // Use max-width as the media condition unless min-width is specified. + $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; + + // If a media_length was set, create the media query. + $media_query = '(' . $media_condition . ": " . $media_length . ') '; + + } else { + + // If not meda length was set, $media_query is blank. + $media_query = ''; + } + + // Add to the source size list string. + $size_list .= $media_query . $size_value . ', '; + } + + // Remove the trailing comma and space from the end of the string. + $size_list = substr( $size_list, 0, -2 ); + } + + // If $size_list is defined set the string, otherwise set false. + return ( $size_list ) ? $size_list : false; +} + +/** + * Return a source size list for an image from an array of values. + * + * @since 2.2.0 + * + * @param int $id Image attachment ID. + * @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 = 'medium', $args = null ) { + $sizes = tevkori_get_sizes( $id, $size, $args ); + + return $sizes ? 'sizes="' . $sizes . '"' : false; +} + +/** + * 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: 'medium'. + * @return array|bool An array of `srcset` values or false. + */ +function tevkori_get_srcset_array( $id, $size = 'medium' ) { + $arr = array(); + + // Get the intermediate size. + $image = image_get_intermediate_size( $id, $size ); + // Get the post meta. + if ( ! is_array( $img_meta = wp_get_attachment_metadata( $id ) ) ) { + return false; + } + + // 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']; + + // Bail early if the width isn't greater that zero. + if ( ! $img_width > 0 ) { + 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; + } + + $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' => wp_basename( $img_meta['file'] ) + ); + + // Calculate the image aspect ratio. + $img_ratio = $img_height / $img_width; + + /* + * Images that have been edited in WordPress after being uploaded will + * 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 ); + + /* + * Loop through available images and only use images that are resized + * versions of the same rendition. + */ + foreach ( $img_sizes as $img ) { + + // Filter out images that are leftovers from previous renditions. + if ( $img_edited && ! strpos( $img['file'], $img_edit_hash[0] ) ) { + continue; + } + + // Calculate the new image ratio. + $img_ratio_compare = $img['height'] / $img['width']; + + // If the new ratio differs by less than 0.01, use it. + if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 ) { + $arr[ $img['width'] ] = path_join( dirname( $img_url ), $img['file'] ) . ' ' . $img['width'] .'w'; + } + } + + /** + * Filter the output of tevkori_get_srcset_array(). + * + * @since 2.4.0 + * + * @param array $arr An array of image sources. + * @param int $id Attachment ID for image. + * @param array|string $size Size of image, either array or string. + */ + return apply_filters( 'tevkori_srcset_array', $arr, $id, $size ); +} + +/** + * Get the value for the 'srcset' attribute. + * + * @since 2.3.0 + * + * @param int $id Image attachment ID. + * @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 = 'medium' ) { + $srcset_array = tevkori_get_srcset_array( $id, $size ); + + if ( count( $srcset_array ) <= 1 ) { + return false; + } + + return implode( ', ', $srcset_array ); +} + +/** + * Create a 'srcset' attribute. + * + * @since 2.1.0 + * + * @param int $id Image attachment ID. + * @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 = 'medium' ) { + $srcset_value = tevkori_get_srcset( $id, $size ); + + if ( empty( $srcset_value ) ) { + return false; + } + + return 'srcset="' . $srcset_value . '"'; +} + +/** + * Filters images in post content to add 'srcset' and 'sizes'. + * + * @since 2.5.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 ) { + if ( ! preg_match_all( '/]+ wp-image-([0-9]+)[^>]+>/i', $content, $matches ) ) { + return $content; + } + + $images = $matches[0]; + + $attachment_ids = array_unique( $matches[1] ); + + 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( $attachment_ids, false, true ); + } + + foreach( $images as $image ) { + $content = str_replace( $image, tevkori_img_add_srcset_and_sizes( $image ), $content ); + } + + return $content; +} +add_filter( 'the_content', 'tevkori_filter_content_images', 5, 1 ); + +/** + * Add srcset and sizes to an 'img' element. + * + * @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_img_add_srcset_and_sizes( $image ) { + // Return early if a 'srcset' attribute already exists. + if ( false !== strpos( $image, ' 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 = str_replace( ' data-sizes="', ' sizes="', $image ); + + return $image; + } + + // 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, + ); + } + + /* + * If attempts to parse the size value failed, attempt to use the image + * metadata to match the 'src' against the available sizes for an attachment. + */ + if ( ! $size && ! empty( $id ) && is_array( $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; + + // Return early if the 'src' value is empty. + if ( ! $src ) { + return $image; + } + + /* + * First, see if the file is the full size image. If not, we loop through + * the intermediate sizes until we find a file that matches. + */ + $image_filename = wp_basename( $src ); + + 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; + } + } + } + + } + + // If we have an ID and size, try for 'srcset' and 'sizes' and update the markup. + if ( $id && $size && $srcset = tevkori_get_srcset( $id, $size ) ) { + + /** + * Pass the 'height' and 'width' to 'tevkori_get_sizes()' to avoid + * recalculating the image size. + */ + $args = array( + 'height' => $height, + 'width' => $width, + ); + $sizes = tevkori_get_sizes( $id, $size, $args ); + + // Format the srcset and sizes string and escape attributes. + $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes) ); + + // Add srcset and sizes attributes to the image markup. + $image = preg_replace( '/]+)[\s?][\/?]>/', '', $image ); + }; + + return $image; +} + +/** + * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. + * + * @see wp_get_attachment_image_attributes + * @return array Attributes for image. + */ +function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { + if ( ! isset( $attr['srcset'] ) ) { + $srcset = tevkori_get_srcset( $attachment->ID, $size ); + + // Set the 'srcset' attribute if one was returned. + if ( $srcset ) { + $attr['srcset'] = $srcset; + + if ( ! isset( $attr['sizes'] ) ) { + $sizes = tevkori_get_sizes( $attachment->ID, $size ); + + // Set the 'sizes' attribute if sizes were returned. + if ( $sizes ) { + $attr['sizes'] = $sizes; + } + } + } + } + + return $attr; +} +add_filter( 'wp_get_attachment_image_attributes', 'tevkori_filter_attachment_image_attributes', 0, 3 ); diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 40abfb9..a9d8fc1 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -48,403 +48,8 @@ function tevkori_get_picturefill() { } add_action( 'wp_enqueue_scripts', 'tevkori_get_picturefill' ); -/** - * Returns the value for a 'sizes' attribute. - * - * @since 2.2.0 - * - * @param int $id Image attachment ID. - * @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 = 'medium', $args = null ) { - // Try to get the image width from `$args` first. - if ( is_array( $args ) && ! empty( $args['width'] ) ) { - $img_width = (int) $args['width']; - } elseif ( $img = image_get_intermediate_size( $id, $size ) ) { - list( $img_width, $img_height ) = image_constrain_size_for_editor( $img['width'], $img['height'], $size ); - } - - // Bail early if `$image_width` isn't set. - if ( ! $img_width ) { - return false; - } - - // Set the image width in pixels. - $img_width = $img_width . 'px'; - - // Set up our default values. - $defaults = array( - 'sizes' => array( - array( - 'size_value' => '100vw', - 'mq_value' => $img_width, - 'mq_name' => 'max-width' - ), - array( - 'size_value' => $img_width - ), - ) - ); - - $args = wp_parse_args( $args, $defaults ); - - /** - * Filter arguments used to create the 'sizes' attribute value. - * - * @since 2.4.0 - * - * @param array $args An array of arguments used to create a 'sizes' attribute. - * @param int $id Post ID of the original image. - * @param string $size Name of the image size being used. - */ - $args = apply_filters( 'tevkori_image_sizes_args', $args, $id, $size ); - - // If sizes is passed as a string, just use the string. - if ( is_string( $args['sizes'] ) ) { - $size_list = $args['sizes']; - - // Otherwise, breakdown the array and build a sizes string. - } elseif ( is_array( $args['sizes'] ) ) { - - $size_list = ''; - - foreach ( $args['sizes'] as $size ) { - - // Use 100vw as the size value unless something else is specified. - $size_value = ( $size['size_value'] ) ? $size['size_value'] : '100vw'; - - // If a media length is specified, build the media query. - if ( ! empty( $size['mq_value'] ) ) { - - $media_length = $size['mq_value']; - - // Use max-width as the media condition unless min-width is specified. - $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; - - // If a media_length was set, create the media query. - $media_query = '(' . $media_condition . ": " . $media_length . ') '; - - } else { - - // If not meda length was set, $media_query is blank. - $media_query = ''; - } - - // Add to the source size list string. - $size_list .= $media_query . $size_value . ', '; - } - - // Remove the trailing comma and space from the end of the string. - $size_list = substr( $size_list, 0, -2 ); - } - - // If $size_list is defined set the string, otherwise set false. - return ( $size_list ) ? $size_list : false; -} - -/** - * Returns a 'sizes' attribute. - * - * @since 2.2.0 - * - * @param int $id Image attachment ID. - * @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 = 'medium', $args = null ) { - $sizes = tevkori_get_sizes( $id, $size, $args ); - - return $sizes ? 'sizes="' . $sizes . '"' : false; -} - -/** - * Returns an array of image sources for a 'srcset' attribute. - * - * @param int $id Image attachment ID. - * @param string $size Optional. Name of image size. Default value: 'medium'. - * @return array|bool An array of `srcset` values or false. - */ -function tevkori_get_srcset_array( $id, $size = 'medium' ) { - $arr = array(); - - // Get the intermediate size. - $image = image_get_intermediate_size( $id, $size ); - // Get the post meta. - if ( ! is_array( $img_meta = wp_get_attachment_metadata( $id ) ) ) { - return false; - } - - // 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']; - - // Bail early if the width isn't greater that zero. - if ( ! $img_width > 0 ) { - 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; - } - - $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' => wp_basename( $img_meta['file'] ) - ); - - // Calculate the image aspect ratio. - $img_ratio = $img_height / $img_width; - - /* - * Images that have been edited in WordPress after being uploaded will - * 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 ); - - /* - * Loop through available images and only use images that are resized - * versions of the same rendition. - */ - foreach ( $img_sizes as $img ) { - - // Filter out images that are leftovers from previous renditions. - if ( $img_edited && ! strpos( $img['file'], $img_edit_hash[0] ) ) { - continue; - } - - // Calculate the new image ratio. - $img_ratio_compare = $img['height'] / $img['width']; - - // If the new ratio differs by less than 0.01, use it. - if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 ) { - $arr[ $img['width'] ] = path_join( dirname( $img_url ), $img['file'] ) . ' ' . $img['width'] .'w'; - } - } - - /** - * Filter the output of tevkori_get_srcset_array(). - * - * @since 2.4.0 - * - * @param array $arr An array of image sources. - * @param int $id Attachment ID for image. - * @param array|string $size Size of image, either array or string. - */ - return apply_filters( 'tevkori_srcset_array', $arr, $id, $size ); -} - -/** - * Returns the value for a 'srcset' attribute. - * - * @since 2.3.0 - * - * @param int $id Image attachment ID. - * @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 = 'medium' ) { - $srcset_array = tevkori_get_srcset_array( $id, $size ); - - if ( count( $srcset_array ) <= 1 ) { - return false; - } - - return implode( ', ', $srcset_array ); -} - -/** - * Returns a 'srcset' attribute. - * - * @since 2.1.0 - * - * @param int $id Image attachment ID. - * @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 = 'medium' ) { - $srcset_value = tevkori_get_srcset( $id, $size ); - - if ( empty( $srcset_value ) ) { - return false; - } - - return 'srcset="' . $srcset_value . '"'; -} - -/** - * Filter to add 'srcset' and 'sizes' attributes to images in the post content. - * - * @since 2.5.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 ) { - if ( ! preg_match_all( '/]+ wp-image-([0-9]+)[^>]+>/i', $content, $matches ) ) { - return $content; - } - - $images = $matches[0]; - - $attachment_ids = array_unique( $matches[1] ); - - 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( $attachment_ids, false, true ); - } - - foreach( $images as $image ) { - $content = str_replace( $image, tevkori_img_add_srcset_and_sizes( $image ), $content ); - } - - return $content; -} -add_filter( 'the_content', 'tevkori_filter_content_images', 5, 1 ); - -/** - * Adds 'srcset' and 'sizes' attributes to image elements. - * - * @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_img_add_srcset_and_sizes( $image ) { - // Return early if a 'srcset' attribute already exists. - if ( false !== strpos( $image, ' 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 = str_replace( ' data-sizes="', ' sizes="', $image ); - - return $image; - } - - // 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, - ); - } - - /* - * If attempts to parse the size value failed, attempt to use the image - * metadata to match the 'src' against the available sizes for an attachment. - */ - if ( ! $size && ! empty( $id ) && is_array( $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; - - // Return early if the 'src' value is empty. - if ( ! $src ) { - return $image; - } - - /* - * First, see if the file is the full size image. If not, we loop through - * the intermediate sizes until we find a file that matches. - */ - $image_filename = wp_basename( $src ); - - 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; - } - } - } - - } - - // If we have an ID and size, try for 'srcset' and 'sizes' and update the markup. - if ( $id && $size && $srcset = tevkori_get_srcset( $id, $size ) ) { - - /** - * Pass the 'height' and 'width' to 'tevkori_get_sizes()' to avoid - * recalculating the image size. - */ - $args = array( - 'height' => $height, - 'width' => $width, - ); - $sizes = tevkori_get_sizes( $id, $size, $args ); - - // Format the srcset and sizes string and escape attributes. - $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes) ); - - // Add srcset and sizes attributes to the image markup. - $image = preg_replace( '/]+)[\s?][\/?]>/', '', $image ); - }; - - return $image; -} - -/** - * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. - * - * @see wp_get_attachment_image_attributes - * @return array Attributes for image. - */ -function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { - if ( ! isset( $attr['srcset'] ) ) { - $srcset = tevkori_get_srcset( $attachment->ID, $size ); - - // Set the 'srcset' attribute if one was returned. - if ( $srcset ) { - $attr['srcset'] = $srcset; - - if ( ! isset( $attr['sizes'] ) ) { - $sizes = tevkori_get_sizes( $attachment->ID, $size ); - - // Set the 'sizes' attribute if sizes were returned. - if ( $sizes ) { - $attr['sizes'] = $sizes; - } - } - } - } - - return $attr; +if ( ! function_exists( 'wp_get_attachment_image_srcset' ) ) { + require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-core-functions.php' ); +} else { + require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-compat-shims.php' ); } -add_filter( 'wp_get_attachment_image_attributes', 'tevkori_filter_attachment_image_attributes', 0, 3 ); From 2f92baf14cfa8bb637dcc81d5af9a43f350b9361 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 6 Oct 2015 22:17:37 -0500 Subject: [PATCH 14/61] Version bump 3.0.0 + changelogs * Deprecates core functions that have been merged into WordPress core in 4.4. * Adds compatibility shims for sites using the plugin's internal functions and hooks. --- readme.md | 14 +++++++++++++- readme.txt | 12 ++++++++++-- wp-tevko-responsive-images.php | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 18a6d16..4324040 100644 --- a/readme.md +++ b/readme.md @@ -140,10 +140,22 @@ We use a hook because if you attempt to dequeue a script before it's enqueued, w ## Version -2.5.2 +3.0.0 ## Changelog +**3.0.0** + +- Deprecates core functions that have been merged into WordPress core in 4.4. +- Adds compatibility shims for sites using the plugin's internal functions and hooks. +- Turns display filter callback into a general utility function for adding srcset and sizes attributes image HTML. +- Upgrade to Picturefill 3.0.1 +- Avoids calling `image_downsize()` when calculating sizes attributes to speed things up. +- Fixes a bug when `wp_get_attachment_metadata()` failed to return an array. +- Clean up inline docs. + +**2.5.2** + - Numerous performance and usability improvements - Pass height and width to `tevkori_get_sizes()` - Improved regex in display filter diff --git a/readme.txt b/readme.txt index 0264ebb..52b51ab 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.2 +Stable tag: 3.0.0 License: GPLv2 License URI: http://www.gnu.org/licenses/gpl-2.0.txt @@ -26,6 +26,15 @@ This plugin works by including all available image sizes for each image upload. == Changelog == += 3.0.0 = +* Deprecates core functions that have been merged into WordPress core in 4.4. +* Adds compatibility shims for sites using the plugin's internal functions and hooks. +* Turns display filter callback into a general utility function for adding srcset and sizes attributes image HTML. +* Upgrade to Picturefill 3.0.1 +* Avoids calling `image_downsize()` when calculating sizes attributes to speed things up. +* Fixes a bug when `wp_get_attachment_metadata()` failed to return an array. +* Clean up inline docs. + = 2.5.2 = * Numerous performance and usability improvements * Pass height and width to `tevkori_get_sizes()` @@ -41,7 +50,6 @@ This plugin works by including all available image sizes for each image upload. * 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()` diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index a9d8fc1..5b8603d 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.2 + * Version: 3.0.0 * Author: The RICG * Author URI: http://responsiveimages.org/ * License: GPL-2.0+ From ff7b19bc90bc8dd0e6335cd4cb9316e07cc8aa01 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 6 Oct 2015 22:56:28 -0500 Subject: [PATCH 15/61] Readme edits * Add a notice to the WP.org page about the change to a display filter. * Change minimum required version to 4.0 to match our tests. * Minor typos, whitespace fixes. --- readme.txt | 5 ++++- wp-tevko-responsive-images.php | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/readme.txt b/readme.txt index 52b51ab..b3a6c0f 100644 --- a/readme.txt +++ b/readme.txt @@ -2,7 +2,7 @@ Contributors: tevko, wilto, joemcgill, jaspermdegroot, chriscoyier, Michael McGinnis, ryelle, drrobotnik, nacin, georgestephanis, helen, wordpressdotorg, Bocoup Donate link: https://app.etapestry.com/hosted/BoweryResidentsCommittee/OnlineDonation.html Tags: Responsive, Images, Responsive Images, SRCSET, Picturefill -Requires at least: 4.1 +Requires at least: 4.0 Tested up to: 4.3 Stable tag: 3.0.0 License: GPLv2 @@ -16,6 +16,9 @@ Bringing automatic default responsive images to WordPress. This plugin works by including all available image sizes for each image upload. Whenever WordPress outputs the image through the media uploader, or whenever a featured image is generated, those sizes will be included in the image tag via the srcset attribute. +**Notice** +As of version 2.5.0, the plugin adds `srcset` and `sizes` attributes to images on the front end instead of adding them to the image markup saved in posts. + **Full documentation and contributor guidelines can be found on [Github](https://github.com/ResponsiveImagesCG/wp-tevko-responsive-images)** == Installation == diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 5b8603d..a2b6d6e 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -6,8 +6,8 @@ * * @wordpress-plugin * 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 + * Plugin URI: https://github.com/ResponsiveImagesCG/wp-tevko-responsive-images + * Description: Bringing automatic default responsive images to WordPress * Version: 3.0.0 * Author: The RICG * Author URI: http://responsiveimages.org/ From 80453ec071dba2185792ceae8c95434512779ad5 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Sat, 17 Oct 2015 12:14:09 -0500 Subject: [PATCH 16/61] Update inline docs after #214 --- wp-tevko-compat-shims.php | 14 +++++++------- wp-tevko-core-functions.php | 16 ++++++++-------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/wp-tevko-compat-shims.php b/wp-tevko-compat-shims.php index baddd09..965a73d 100644 --- a/wp-tevko-compat-shims.php +++ b/wp-tevko-compat-shims.php @@ -1,6 +1,6 @@ Date: Thu, 29 Oct 2015 14:54:33 +0100 Subject: [PATCH 17/61] Corrections in inline docs --- wp-tevko-compat-shims.php | 52 +++++++++++++++------------ wp-tevko-core-functions.php | 65 +++++++++++++++++++--------------- wp-tevko-responsive-images.php | 4 +-- 3 files changed, 66 insertions(+), 55 deletions(-) diff --git a/wp-tevko-compat-shims.php b/wp-tevko-compat-shims.php index 965a73d..fbef3dd 100644 --- a/wp-tevko-compat-shims.php +++ b/wp-tevko-compat-shims.php @@ -3,16 +3,17 @@ * Returns the value for a 'sizes' attribute. * * @since 2.2.0 - * @deprecated 3.0 Use wp_get_attachment_image_sizes() - * @see wp_get_attachment_image_sizes() + * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' + * @see 'wp_get_attachment_image_sizes()' - * @param int $id Image attachment ID. - * @param string $size Optional. Name of image size. Default value: 'medium'. - * @param array $args { + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default '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. + * @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. */ @@ -25,16 +26,17 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { * Returns a 'sizes' attribute. * * @since 2.2.0 - * @deprecated 3.0 Use wp_get_attachment_image_sizes() - * @see wp_get_attachment_image_sizes() + * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' + * @see 'wp_get_attachment_image_sizes()' * - * @param int $id Image attachment ID. - * @param string $size Optional. Name of image size. Default value: 'medium'. - * @param array $args { + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default '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. + * @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. */ @@ -49,12 +51,13 @@ function tevkori_get_sizes_string( $id, $size = 'medium', $args = null ) { * Returns an array of image sources for a 'srcset' attribute. * * @since 2.1.0 - * @deprecated 3.0 Use wp_get_attachment_image_srcset_array() - * @see wp_get_attachment_image_srcset_array() + * @deprecated 3.0 Use 'wp_get_attachment_image_srcset_array()' + * @see 'wp_get_attachment_image_srcset_array()' * - * @param int $id Image attachment ID. - * @param string $size Optional. Name of image size. Default value: 'medium'. - * @return array|bool An array of `srcset` values or false. + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default 'medium'. + * @return array|bool An array of 'srcset' values or false. */ function tevkori_get_srcset_array( $id, $size = 'medium' ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset_array()' ); @@ -70,7 +73,7 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { } /** - * Filter the output of tevkori_get_srcset_array(). + * Filter the output of 'tevkori_get_srcset_array()'. * * @since 2.4.0 * @deprecated 3.0 Use 'wp_get_attachment_image_srcset_array' @@ -78,7 +81,8 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { * * @param array $arr An array of image sources. * @param int $id Attachment ID for image. - * @param array|string $size Size of image, either array or string. + * @param array|string $size Image size. Image size or an array of width and height + * values in pixels (in that order). */ return apply_filters( 'tevkori_srcset_array', $arr, $id, $size ); } @@ -90,8 +94,9 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' * @see 'wp_get_attachment_image_srcset()' * - * @param int $id Image attachment ID. - * @param string $size Optional. Name of image size. Default value: 'medium'. + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default 'medium'. * @return string|bool A 'srcset' value string or false. */ function tevkori_get_srcset( $id, $size = 'medium' ) { @@ -112,8 +117,9 @@ function tevkori_get_srcset( $id, $size = 'medium' ) { * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' * @see 'wp_get_attachment_image_srcset()' * - * @param int $id Image attachment ID. - * @param string $size Optional. Name of image size. Default value: 'medium'. + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default 'medium'. * @return string|bool A full 'srcset' string or false. */ function tevkori_get_srcset_string( $id, $size = 'medium' ) { diff --git a/wp-tevko-core-functions.php b/wp-tevko-core-functions.php index 7c3cfed..faa691d 100644 --- a/wp-tevko-core-functions.php +++ b/wp-tevko-core-functions.php @@ -4,25 +4,26 @@ * * @since 2.2.0 * - * @param int $id Image attachment ID. - * @param string $size Optional. Name of image size. Default value: 'medium'. - * @param array $args { + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default '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. + * @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 = 'medium', $args = null ) { - // Try to get the image width from `$args` first. + // Try to get the image width from '$args' first. if ( is_array( $args ) && ! empty( $args['width'] ) ) { $img_width = (int) $args['width']; } elseif ( $img = image_get_intermediate_size( $id, $size ) ) { list( $img_width, $img_height ) = image_constrain_size_for_editor( $img['width'], $img['height'], $size ); } - // Bail early if `$image_width` isn't set. + // Bail early if '$img_width' isn't set. if ( ! $img_width ) { return false; } @@ -51,9 +52,10 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { * * @since 2.4.0 * - * @param array $args An array of arguments used to create a 'sizes' attribute. - * @param int $id Post ID of the original image. - * @param string $size Name of the image size being used. + * @param array $args An array of arguments used to create a 'sizes' attribute. + * @param int $id Post ID of the original image. + * @param array|string $size Image size. Image size or an array of width and height + * values in pixels (in that order). */ $args = apply_filters( 'tevkori_image_sizes_args', $args, $id, $size ); @@ -79,12 +81,12 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { // Use max-width as the media condition unless min-width is specified. $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; - // If a media_length was set, create the media query. + // If a media length was set, create the media query. $media_query = '(' . $media_condition . ": " . $media_length . ') '; } else { - // If not meda length was set, $media_query is blank. + // If no media length was set, '$media_query' is blank. $media_query = ''; } @@ -96,7 +98,7 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { $size_list = substr( $size_list, 0, -2 ); } - // If $size_list is defined set the string, otherwise set false. + // If '$size_list' is defined set the string, otherwise set false. return ( $size_list ) ? $size_list : false; } @@ -105,13 +107,14 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { * * @since 2.2.0 * - * @param int $id Image attachment ID. - * @param string $size Optional. Name of image size. Default value: 'medium'. - * @param array $args { + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default '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. + * @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. */ @@ -124,9 +127,10 @@ function tevkori_get_sizes_string( $id, $size = 'medium', $args = null ) { /** * Returns an array of image sources for a 'srcset' attribute. * - * @param int $id Image attachment ID. - * @param string $size Optional. Name of image size. Default value: 'medium'. - * @return array|bool An array of `srcset` values or false. + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default 'medium'. + * @return array|bool An array of 'srcset' values or false. */ function tevkori_get_srcset_array( $id, $size = 'medium' ) { $arr = array(); @@ -142,12 +146,12 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { $img_width = ( $image ) ? $image['width'] : $img_meta['width']; $img_height = ( $image ) ? $image['height'] : $img_meta['height']; - // Bail early if the width isn't greater that zero. + // Bail early if the width isn't greater than zero. if ( ! $img_width > 0 ) { return false; } - // Use the url from the intermediate size or build the url from the metadata. + // Use the URL from the intermediate size or build the URL from the metadata. if ( ! empty( $image['url'] ) ) { $img_url = $image['url']; } else { @@ -158,7 +162,7 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { $img_sizes = $img_meta['sizes']; - // Add full size to the img_sizes array. + // Add full size to the '$img_sizes' array. $img_sizes['full'] = array( 'width' => $img_meta['width'], 'height' => $img_meta['height'], @@ -196,13 +200,14 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { } /** - * Filter the output of tevkori_get_srcset_array(). + * Filter the output of 'tevkori_get_srcset_array()'. * * @since 2.4.0 * * @param array $arr An array of image sources. * @param int $id Attachment ID for image. - * @param array|string $size Size of image, either array or string. + * @param array|string $size Image size. Image size or an array of width and height + * values in pixels (in that order). */ return apply_filters( 'tevkori_srcset_array', $arr, $id, $size ); } @@ -212,8 +217,9 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { * * @since 2.3.0 * - * @param int $id Image attachment ID. - * @param string $size Optional. Name of image size. Default value: 'medium'. + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default 'medium'. * @return string|bool A 'srcset' value string or false. */ function tevkori_get_srcset( $id, $size = 'medium' ) { @@ -231,8 +237,9 @@ function tevkori_get_srcset( $id, $size = 'medium' ) { * * @since 2.1.0 * - * @param int $id Image attachment ID. - * @param string $size Optional. Name of image size. Default value: 'medium'. + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default 'medium'. * @return string|bool A full 'srcset' string or false. */ function tevkori_get_srcset_string( $id, $size = 'medium' ) { @@ -374,7 +381,7 @@ function tevkori_img_add_srcset_and_sizes( $image ) { /** * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. * - * @see wp_get_attachment_image_attributes + * @see 'wp_get_attachment_image_attributes' * @return array Attributes for image. */ function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index a2b6d6e..2ee37bd 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -40,9 +40,7 @@ function tevkori_wp_image_editors( $editors ) { add_filter( 'wp_image_editors', 'tevkori_wp_image_editors' ); } -/** - * Enqueue bundled version of the Picturefill library. - */ +// Enqueue bundled version of the Picturefill library. function tevkori_get_picturefill() { wp_enqueue_script( 'picturefill', plugins_url( 'js/picturefill.min.js', __FILE__ ), array(), '3.0.1', true ); } From 4a120e43b660f92f18dd8471f550eeacbb692be2 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Thu, 29 Oct 2015 14:53:47 +0100 Subject: [PATCH 18/61] Added a comment to explain which file is included in functions.php --- wp-tevko-responsive-images.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 2ee37bd..83401b7 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -46,8 +46,13 @@ function tevkori_get_picturefill() { } add_action( 'wp_enqueue_scripts', 'tevkori_get_picturefill' ); -if ( ! function_exists( 'wp_get_attachment_image_srcset' ) ) { - require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-core-functions.php' ); -} else { +/* + * If the WordPress version contains the responsive images functions we include + * the functions that show deprecation warnings and point to the new functions. + * Else we include the plugin's responsive images functions. + */ +if ( function_exists( 'wp_get_attachment_image_srcset' ) ) { require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-compat-shims.php' ); +} else { + require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-core-functions.php' ); } From 57110c5b74d0697282e239723d6b2d7c89769623 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Thu, 29 Oct 2015 21:18:53 +0100 Subject: [PATCH 19/61] Changed the order of functions to match with WP core media.php --- wp-tevko-compat-shims.php | 96 +++++++------- wp-tevko-core-functions.php | 250 ++++++++++++++++++------------------ 2 files changed, 173 insertions(+), 173 deletions(-) diff --git a/wp-tevko-compat-shims.php b/wp-tevko-compat-shims.php index fbef3dd..444355c 100644 --- a/wp-tevko-compat-shims.php +++ b/wp-tevko-compat-shims.php @@ -1,52 +1,4 @@ array( - array( - 'size_value' => '100vw', - 'mq_value' => $img_width, - 'mq_name' => 'max-width' - ), - array( - 'size_value' => $img_width - ), - ) - ); - - $args = wp_parse_args( $args, $defaults ); - - /** - * Filter arguments used to create the 'sizes' attribute value. - * - * @since 2.4.0 - * - * @param array $args An array of arguments used to create a 'sizes' attribute. - * @param int $id Post ID of the original image. - * @param array|string $size Image size. Image size or an array of width and height - * values in pixels (in that order). - */ - $args = apply_filters( 'tevkori_image_sizes_args', $args, $id, $size ); - - // If sizes is passed as a string, just use the string. - if ( is_string( $args['sizes'] ) ) { - $size_list = $args['sizes']; - - // Otherwise, breakdown the array and build a sizes string. - } elseif ( is_array( $args['sizes'] ) ) { - - $size_list = ''; - - foreach ( $args['sizes'] as $size ) { - - // Use 100vw as the size value unless something else is specified. - $size_value = ( $size['size_value'] ) ? $size['size_value'] : '100vw'; - - // If a media length is specified, build the media query. - if ( ! empty( $size['mq_value'] ) ) { - - $media_length = $size['mq_value']; - - // Use max-width as the media condition unless min-width is specified. - $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; - - // If a media length was set, create the media query. - $media_query = '(' . $media_condition . ": " . $media_length . ') '; - - } else { - - // If no media length was set, '$media_query' is blank. - $media_query = ''; - } - - // Add to the source size list string. - $size_list .= $media_query . $size_value . ', '; - } - - // Remove the trailing comma and space from the end of the string. - $size_list = substr( $size_list, 0, -2 ); - } - - // If '$size_list' is defined set the string, otherwise set false. - return ( $size_list ) ? $size_list : false; -} - -/** - * Returns a 'sizes' attribute. - * - * @since 2.2.0 - * - * @param int $id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size, or an array of width and height - * values in pixels (in that order). Default '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 = 'medium', $args = null ) { - $sizes = tevkori_get_sizes( $id, $size, $args ); - - return $sizes ? 'sizes="' . $sizes . '"' : false; -} - /** * Returns an array of image sources for a 'srcset' attribute. * @@ -252,6 +127,131 @@ function tevkori_get_srcset_string( $id, $size = 'medium' ) { return 'srcset="' . $srcset_value . '"'; } +/** + * Returns the value for a 'sizes' attribute. + * + * @since 2.2.0 + * + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default '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 = 'medium', $args = null ) { + // Try to get the image width from '$args' first. + if ( is_array( $args ) && ! empty( $args['width'] ) ) { + $img_width = (int) $args['width']; + } elseif ( $img = image_get_intermediate_size( $id, $size ) ) { + list( $img_width, $img_height ) = image_constrain_size_for_editor( $img['width'], $img['height'], $size ); + } + + // Bail early if '$img_width' isn't set. + if ( ! $img_width ) { + return false; + } + + // Set the image width in pixels. + $img_width = $img_width . 'px'; + + // Set up our default values. + $defaults = array( + 'sizes' => array( + array( + 'size_value' => '100vw', + 'mq_value' => $img_width, + 'mq_name' => 'max-width' + ), + array( + 'size_value' => $img_width + ), + ) + ); + + $args = wp_parse_args( $args, $defaults ); + + /** + * Filter arguments used to create the 'sizes' attribute value. + * + * @since 2.4.0 + * + * @param array $args An array of arguments used to create a 'sizes' attribute. + * @param int $id Post ID of the original image. + * @param array|string $size Image size. Image size or an array of width and height + * values in pixels (in that order). + */ + $args = apply_filters( 'tevkori_image_sizes_args', $args, $id, $size ); + + // If sizes is passed as a string, just use the string. + if ( is_string( $args['sizes'] ) ) { + $size_list = $args['sizes']; + + // Otherwise, breakdown the array and build a sizes string. + } elseif ( is_array( $args['sizes'] ) ) { + + $size_list = ''; + + foreach ( $args['sizes'] as $size ) { + + // Use 100vw as the size value unless something else is specified. + $size_value = ( $size['size_value'] ) ? $size['size_value'] : '100vw'; + + // If a media length is specified, build the media query. + if ( ! empty( $size['mq_value'] ) ) { + + $media_length = $size['mq_value']; + + // Use max-width as the media condition unless min-width is specified. + $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; + + // If a media length was set, create the media query. + $media_query = '(' . $media_condition . ": " . $media_length . ') '; + + } else { + + // If no media length was set, '$media_query' is blank. + $media_query = ''; + } + + // Add to the source size list string. + $size_list .= $media_query . $size_value . ', '; + } + + // Remove the trailing comma and space from the end of the string. + $size_list = substr( $size_list, 0, -2 ); + } + + // If '$size_list' is defined set the string, otherwise set false. + return ( $size_list ) ? $size_list : false; +} + +/** + * Returns a 'sizes' attribute. + * + * @since 2.2.0 + * + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default '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 = 'medium', $args = null ) { + $sizes = tevkori_get_sizes( $id, $size, $args ); + + return $sizes ? 'sizes="' . $sizes . '"' : false; +} + /** * Filter to add 'srcset' and 'sizes' attributes to images in the post content. * From 3fa0e23d7b6156001955991c300649830771b4e4 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Thu, 29 Oct 2015 21:22:46 +0100 Subject: [PATCH 20/61] Updated the names of the new functions --- wp-tevko-compat-shims.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/wp-tevko-compat-shims.php b/wp-tevko-compat-shims.php index 444355c..384a887 100644 --- a/wp-tevko-compat-shims.php +++ b/wp-tevko-compat-shims.php @@ -3,8 +3,8 @@ * Returns an array of image sources for a 'srcset' attribute. * * @since 2.1.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset_array()' - * @see 'wp_get_attachment_image_srcset_array()' + * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_srcset()' * * @param int $id Image attachment ID. * @param array|string $size Image size. Accepts any valid image size, or an array of width and height @@ -12,8 +12,8 @@ * @return array|bool An array of 'srcset' values or false. */ function tevkori_get_srcset_array( $id, $size = 'medium' ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset_array()' ); - $srcset_array = wp_get_attachment_image_srcset_array( $id, $size ); + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); + $srcset_array = wp_get_attachment_image_srcset( $id, $size ); // Transform array to pre-core style. $arr = false; @@ -28,8 +28,8 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { * Filter the output of 'tevkori_get_srcset_array()'. * * @since 2.4.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset_array' - * @see 'wp_get_attachment_image_srcset_array' + * @deprecated 3.0 Use 'wp_get_attachment_image_srcset' + * @see 'wp_get_attachment_image_srcset' * * @param array $arr An array of image sources. * @param int $id Attachment ID for image. @@ -152,13 +152,13 @@ function tevkori_filter_content_images( $content ) { * Adds 'srcset' and 'sizes' attributes to image elements. * * @since 2.6.0 - * @deprecated 3.0 Use 'wp_img_add_srcset_and_sizes()' - * @see 'wp_img_add_srcset_and_sizes()' + * @deprecated 3.0 Use 'wp_image_add_srcset_and_sizes()' + * @see 'wp_image_add_srcset_and_sizes()' * * @param string $image An HTML 'img' element to be filtered. * @return string Converted 'img' element with 'srcset' and 'sizes' added. */ function tevkori_img_add_srcset_and_sizes( $image ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_img_add_srcset_and_sizes()' ); - return wp_img_add_srcset_and_sizes( $image ); + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_image_add_srcset_and_sizes()' ); + return wp_image_add_srcset_and_sizes( $image ); } From 9ecba03c0aec892ba281c6fbd3ed044e919c8cab Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Thu, 29 Oct 2015 23:15:18 +0100 Subject: [PATCH 21/61] Keep same behaviour for deprecated functions --- wp-tevko-compat-shims.php | 124 +++++++++++++++++++++++++++++++------- 1 file changed, 103 insertions(+), 21 deletions(-) diff --git a/wp-tevko-compat-shims.php b/wp-tevko-compat-shims.php index 384a887..c5b3917 100644 --- a/wp-tevko-compat-shims.php +++ b/wp-tevko-compat-shims.php @@ -13,15 +13,17 @@ */ function tevkori_get_srcset_array( $id, $size = 'medium' ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); - $srcset_array = wp_get_attachment_image_srcset( $id, $size ); - - // Transform array to pre-core style. - $arr = false; - if ( is_array( $srcset_array ) ) { - $arr = array(); - foreach ( $srcset_array as $source ) { - $arr[ $source['value'] ] = $source['url'] . ' ' . $source['value'] . $source['descriptor']; - } + + $srcset = wp_get_attachment_image_srcset( $id, $size ); + + // Transform the 'srcset' value string to a pre-core style array. + $sources = explode( ', ', $srcset ); + $arr = array(); + + foreach ( $sources as $source ) { + $split = explode( ' ', $source ); + $width = rtrim( $split[1], "w" ); + $arr[ $width ] = $source; } /** @@ -53,13 +55,14 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { */ function tevkori_get_srcset( $id, $size = 'medium' ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); - $srcset_array = tevkori_get_srcset_array( $id, $size ); - if ( count( $srcset_array ) <= 1 ) { - return false; - } + if ( has_filter( 'tevkori_srcset_array' ) ) { + $srcset_array = tevkori_get_srcset_array( $id, $size ); - return implode( ', ', $srcset_array ); + return implode( ', ', $srcset_array ); + } else { + return wp_get_attachment_image_srcset( $id, $size ); + } } /** @@ -76,13 +79,16 @@ function tevkori_get_srcset( $id, $size = 'medium' ) { */ function tevkori_get_srcset_string( $id, $size = 'medium' ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); - $srcset_value = tevkori_get_srcset( $id, $size ); - if ( empty( $srcset_value ) ) { - return false; - } + if ( has_filter( 'tevkori_srcset_array' ) ) { + $srcset_value = tevkori_get_srcset( $id, $size ); - return 'srcset="' . $srcset_value . '"'; + return $srcset_value ? 'srcset="' . $srcset_value . '"' : false; + } else { + $srcset_value = wp_get_attachment_image_srcset( $id, $size ); + + return $srcset_value ? 'srcset="' . $srcset_value . '"' : false; + } } /** @@ -105,7 +111,78 @@ function tevkori_get_srcset_string( $id, $size = 'medium' ) { */ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); - return wp_get_attachment_image_sizes( $id, $size, $args ); + + if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { + /** + * @see 'tevkori_get_sizes()' in wp-tevko-core-functions.php. + */ + if ( is_array( $args ) && ! empty( $args['width'] ) ) { + $img_width = (int) $args['width']; + } elseif ( $img = image_get_intermediate_size( $id, $size ) ) { + list( $img_width, $img_height ) = image_constrain_size_for_editor( $img['width'], $img['height'], $size ); + } + + if ( ! $img_width ) { + return false; + } + + $img_width = $img_width . 'px'; + + $defaults = array( + 'sizes' => array( + array( + 'size_value' => '100vw', + 'mq_value' => $img_width, + 'mq_name' => 'max-width' + ), + array( + 'size_value' => $img_width + ), + ) + ); + + $args = wp_parse_args( $args, $defaults ); + + /** + * Filter arguments used to create the 'sizes' attribute value. + * + * @since 2.4.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_sizes' + * @see 'wp_get_attachment_image_sizes' + * + * @param array $args An array of arguments used to create a 'sizes' attribute. + * @param int $id Post ID of the original image. + * @param array|string $size Image size. Image size or an array of width and height + * values in pixels (in that order). + */ + $args = apply_filters( 'tevkori_image_sizes_args', $args, $id, $size ); + + if ( is_string( $args['sizes'] ) ) { + $size_list = $args['sizes']; + } elseif ( is_array( $args['sizes'] ) ) { + $size_list = ''; + + foreach ( $args['sizes'] as $size ) { + $size_value = ( $size['size_value'] ) ? $size['size_value'] : '100vw'; + + if ( ! empty( $size['mq_value'] ) ) { + $media_length = $size['mq_value']; + $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; + $media_query = '(' . $media_condition . ": " . $media_length . ') '; + } else { + $media_query = ''; + } + + $size_list .= $media_query . $size_value . ', '; + } + + $size_list = substr( $size_list, 0, -2 ); + } + + return ( $size_list ) ? $size_list : false; + } else { + return wp_get_attachment_image_sizes( $size, $id ); + } } /** @@ -128,7 +205,12 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { */ function tevkori_get_sizes_string( $id, $size = 'medium', $args = null ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); - $sizes = wp_get_attachment_image_sizes( $id, $size, $args ); + + if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { + $sizes = tevkori_get_sizes( $id, $size, $arg ); + } else { + $sizes = wp_get_attachment_image_sizes( $size, $id ); + } return $sizes ? 'sizes="' . esc_attr( $sizes ) . '"' : false; } From e4c37d08349348b127107194f77d753c24754f82 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Thu, 29 Oct 2015 23:39:47 +0100 Subject: [PATCH 22/61] Deprecated all plugin core functions --- wp-tevko-core-functions.php | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/wp-tevko-core-functions.php b/wp-tevko-core-functions.php index 6198f9d..520ce54 100644 --- a/wp-tevko-core-functions.php +++ b/wp-tevko-core-functions.php @@ -2,12 +2,18 @@ /** * Returns an array of image sources for a 'srcset' attribute. * + * @since 2.1.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_srcset()' + * * @param int $id Image attachment ID. * @param array|string $size Image size. Accepts any valid image size, or an array of width and height * values in pixels (in that order). Default 'medium'. * @return array|bool An array of 'srcset' values or false. */ function tevkori_get_srcset_array( $id, $size = 'medium' ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); + $arr = array(); // Get the intermediate size. @@ -78,6 +84,8 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { * Filter the output of 'tevkori_get_srcset_array()'. * * @since 2.4.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_srcset' + * @see 'wp_get_attachment_image_srcset' * * @param array $arr An array of image sources. * @param int $id Attachment ID for image. @@ -91,6 +99,8 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { * Returns the value for a 'srcset' attribute. * * @since 2.3.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_srcset()' * * @param int $id Image attachment ID. * @param array|string $size Image size. Accepts any valid image size, or an array of width and height @@ -98,6 +108,8 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { * @return string|bool A 'srcset' value string or false. */ function tevkori_get_srcset( $id, $size = 'medium' ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); + $srcset_array = tevkori_get_srcset_array( $id, $size ); if ( count( $srcset_array ) <= 1 ) { @@ -111,6 +123,8 @@ function tevkori_get_srcset( $id, $size = 'medium' ) { * Returns a 'srcset' attribute. * * @since 2.1.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_srcset()' * * @param int $id Image attachment ID. * @param array|string $size Image size. Accepts any valid image size, or an array of width and height @@ -118,6 +132,8 @@ function tevkori_get_srcset( $id, $size = 'medium' ) { * @return string|bool A full 'srcset' string or false. */ function tevkori_get_srcset_string( $id, $size = 'medium' ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); + $srcset_value = tevkori_get_srcset( $id, $size ); if ( empty( $srcset_value ) ) { @@ -131,6 +147,8 @@ function tevkori_get_srcset_string( $id, $size = 'medium' ) { * Returns the value for a 'sizes' attribute. * * @since 2.2.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' + * @see 'wp_get_attachment_image_sizes()' * * @param int $id Image attachment ID. * @param array|string $size Image size. Accepts any valid image size, or an array of width and height @@ -144,6 +162,8 @@ function tevkori_get_srcset_string( $id, $size = 'medium' ) { * @return string|bool A valid source size value for use in a 'sizes' attribute or false. */ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); + // Try to get the image width from '$args' first. if ( is_array( $args ) && ! empty( $args['width'] ) ) { $img_width = (int) $args['width']; @@ -179,6 +199,8 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { * Filter arguments used to create the 'sizes' attribute value. * * @since 2.4.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_sizes' + * @see 'wp_get_attachment_image_sizes' * * @param array $args An array of arguments used to create a 'sizes' attribute. * @param int $id Post ID of the original image. @@ -234,6 +256,8 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { * Returns a 'sizes' attribute. * * @since 2.2.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' + * @see 'wp_get_attachment_image_sizes()' * * @param int $id Image attachment ID. * @param array|string $size Image size. Accepts any valid image size, or an array of width and height @@ -247,6 +271,8 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { * @return string|bool A valid source size list as a 'sizes' attribute or false. */ function tevkori_get_sizes_string( $id, $size = 'medium', $args = null ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); + $sizes = tevkori_get_sizes( $id, $size, $args ); return $sizes ? 'sizes="' . $sizes . '"' : false; @@ -256,11 +282,15 @@ function tevkori_get_sizes_string( $id, $size = 'medium', $args = null ) { * Filter to add 'srcset' and 'sizes' attributes to images in the post content. * * @since 2.5.0 + * @deprecated 3.0 Use 'wp_make_content_images_responsive()' + * @see 'wp_make_content_images_responsive()' * * @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 ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_make_content_images_responsive()' ); + if ( ! preg_match_all( '/]+ wp-image-([0-9]+)[^>]+>/i', $content, $matches ) ) { return $content; } @@ -291,11 +321,15 @@ function tevkori_filter_content_images( $content ) { * Adds 'srcset' and 'sizes' attributes to image elements. * * @since 2.6.0 + * @deprecated 3.0 Use 'wp_image_add_srcset_and_sizes()' + * @see 'wp_image_add_srcset_and_sizes()' * * @param string $image An HTML 'img' element to be filtered. * @return string Converted 'img' element with 'srcset' and 'sizes' added. */ function tevkori_img_add_srcset_and_sizes( $image ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_image_add_srcset_and_sizes()' ); + // Return early if a 'srcset' attribute already exists. if ( false !== strpos( $image, ' srcset="' ) ) { /* From 58f201e3c6be1e5cfe1a556f4ca2ae25d740d3ee Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Fri, 30 Oct 2015 01:48:32 +0100 Subject: [PATCH 23/61] Bring in the new functions from WP core --- wp-tevko-core-functions.php | 656 ++++++++++++++++++++++++------------ 1 file changed, 443 insertions(+), 213 deletions(-) diff --git a/wp-tevko-core-functions.php b/wp-tevko-core-functions.php index 520ce54..b949082 100644 --- a/wp-tevko-core-functions.php +++ b/wp-tevko-core-functions.php @@ -1,85 +1,236 @@ 0 ) { + // Bail early if image sizes info is not available. + if ( empty( $image_meta['sizes'] ) ) { return false; } - // Use the URL from the intermediate size or build the URL from the metadata. - if ( ! empty( $image['url'] ) ) { - $img_url = $image['url']; + $image_sizes = $image_meta['sizes']; + + // Add full size to the '$image_sizes' array. + $image_sizes['full'] = array( + 'width' => $image_meta['width'], + 'height' => $image_meta['height'], + 'file' => wp_basename( $image_meta['file'] ), + ); + + // Get the width and height of the image. + if ( is_array( $size ) ) { + $size_array = $size; + $image_width = absint( $size[0] ); + $image_height = absint( $size[1] ); + } elseif ( is_string( $size ) ) { + $size_array = _wp_get_image_size_from_meta( $size, $image_meta ); + $image_width = $size_array[0]; + $image_height = $size_array[1]; } 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; + return false; } - $img_sizes = $img_meta['sizes']; + // Bail early if the image has no width. + if ( $image_width < 1 ) { + return false; + } - // Add full size to the '$img_sizes' array. - $img_sizes['full'] = array( - 'width' => $img_meta['width'], - 'height' => $img_meta['height'], - 'file' => wp_basename( $img_meta['file'] ) - ); + // Get the image base URL and directory. + $image_baseurl = _wp_upload_dir_baseurl(); + $dirname = dirname( $image_meta['file'] ); + + if ( $dirname !== '.' ) { + $image_baseurl = path_join( $image_baseurl, $dirname ); + } // Calculate the image aspect ratio. - $img_ratio = $img_height / $img_width; + $image_ratio = $image_height / $image_width; + + // Get the image URL if it's not passed as argument. + if ( ! $image_url ) { + $image = wp_get_attachment_image_src( $attachment_id, $size ); + + if ( ! $image ) { + return false; + } + + $image_url = $image[0]; + } /* * Images that have been edited in WordPress after being uploaded will * 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 ); + $image_edited = preg_match( '/-e[0-9]{13}/', $image_url, $image_edit_hash ); + + /** + * Filter the maximum image width to be included in a 'srcset' attribute. + * + * @since 3.0.0 + * + * @param int $max_width The maximum image width to be included in the 'srcset'. Default '1600'. + * @param array $size_array Array of width and height values in pixels (in that order). + */ + $max_srcset_image_width = apply_filters( 'max_srcset_image_width', 1600, $size_array ); + + // Array to hold URL candidates. + $sources = array(); /* - * Loop through available images and only use images that are resized - * versions of the same rendition. + * Loop through available images. Only use images that are resized + * versions of the same edit. */ - foreach ( $img_sizes as $img ) { + foreach ( $image_sizes as $image ) { + // Filter out images that are from previous edits. + if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) { + continue; + } - // Filter out images that are leftovers from previous renditions. - if ( $img_edited && ! strpos( $img['file'], $img_edit_hash[0] ) ) { + // Filter out images that are wider than '$max_srcset_image_width'. + if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width ) { continue; } + $candidate_url = $image['file']; + // Calculate the new image ratio. - $img_ratio_compare = $img['height'] / $img['width']; + if ( $image['width'] ) { + $image_ratio_compare = $image['height'] / $image['width']; + } else { + $image_ratio_compare = 0; + } // If the new ratio differs by less than 0.01, use it. - if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 ) { - $arr[ $img['width'] ] = path_join( dirname( $img_url ), $img['file'] ) . ' ' . $img['width'] .'w'; + if ( abs( $image_ratio - $image_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) { + // Add the URL, descriptor, and value to the sources array to be returned. + $sources[ $image['width'] ] = array( + 'url' => path_join( $image_baseurl, $candidate_url ), + 'value' => $image['width'], + 'descriptor' => 'w', + ); } } + /** + * Filter the array used to create the 'srcset' value string. + * + * @since 3.0.0 + * + * @param array $sources An array of image URLs, values, and descriptors. + * @param int $attachment_id Image attachment ID. + * @param array|string $size Image size. Image size name, or an array of width and height + * values in pixels (in that order). + * @param string $image_url The URL of the image. + * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. + */ + $sources = apply_filters( 'wp_get_attachment_image_srcset', array_values( $sources ), $attachment_id, $size, $image_url, $image_meta ); + + // Only return a 'srcset' value if there is more than one source. + if ( count( $sources ) < 2 ) { + return false; + } + + // Create the 'srcset' value string. + $srcset = ''; + + foreach ( $sources as $source ) { + $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', '; + } + + return rtrim( $srcset, ', ' ); +} + +/** + * Returns an array of image sources for a 'srcset' attribute. + * + * @since 2.1.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_srcset()' + * + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default 'medium'. + * @return array|bool An array of 'srcset' values or false. + */ +function tevkori_get_srcset_array( $id, $size = 'medium' ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); + + $srcset = wp_get_attachment_image_srcset( $id, $size ); + + // Transform the 'srcset' value string to a pre-core style array. + $sources = explode( ', ', $srcset ); + $arr = array(); + + foreach ( $sources as $source ) { + $split = explode( ' ', $source ); + $width = rtrim( $split[1], "w" ); + $arr[ $width ] = $source; + } + /** * Filter the output of 'tevkori_get_srcset_array()'. * @@ -110,13 +261,13 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { function tevkori_get_srcset( $id, $size = 'medium' ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); - $srcset_array = tevkori_get_srcset_array( $id, $size ); + if ( has_filter( 'tevkori_srcset_array' ) ) { + $srcset_array = tevkori_get_srcset_array( $id, $size ); - if ( count( $srcset_array ) <= 1 ) { - return false; + return implode( ', ', $srcset_array ); + } else { + return wp_get_attachment_image_srcset( $id, $size ); } - - return implode( ', ', $srcset_array ); } /** @@ -134,13 +285,64 @@ function tevkori_get_srcset( $id, $size = 'medium' ) { function tevkori_get_srcset_string( $id, $size = 'medium' ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); - $srcset_value = tevkori_get_srcset( $id, $size ); + if ( has_filter( 'tevkori_srcset_array' ) ) { + $srcset_value = tevkori_get_srcset( $id, $size ); + + return $srcset_value ? 'srcset="' . $srcset_value . '"' : false; + } else { + $srcset_value = wp_get_attachment_image_srcset( $id, $size ); + + return $srcset_value ? 'srcset="' . $srcset_value . '"' : false; + } +} - if ( empty( $srcset_value ) ) { +/** + * Retrieves the value for an image attachment's 'sizes' attribute. + * + * @since 3.0.0 + * + * @param array|string $size Image size. Accepts any valid image size name, or an array of + * width and height values in pixels (in that order). Default 'medium'. + * @param int $attachment_id Optional. Image attachment ID. Required if `$size` is an image size name + * and `$image_meta` is omited. Otherwise used to pass to the filter. + * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. + * @return string|bool A string of size values for use as value in a 'sizes' attribute or false. + */ +function wp_get_attachment_image_sizes( $size = 'medium', $attachment_id = 0, $image_meta = null ) { + $width = 0; + + if ( is_array( $size ) ) { + $width = absint( $size[0] ); + } elseif ( is_string( $size ) ) { + if ( ! $image_meta && $attachment_id ) { + $image_meta = wp_get_attachment_metadata( $attachment_id ); + } + if ( is_array( $image_meta ) ) { + $size_array = _wp_get_image_size_from_meta( $size, $image_meta ); + if ( $size_array ) { + $width = $size_array[0]; + } + } + } else { return false; } - return 'srcset="' . $srcset_value . '"'; + // Setup the default 'sizes' attribute. + $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $width ); + + /** + * Filter the output of 'wp_get_attachment_image_sizes()'. + * + * @since 3.0.0 + * + * @param string $sizes A source size value for use in a 'sizes' attribute. + * @param array|string $size Image size name, or an array of width and height + * values in pixels (in that order). + * @param int $attachment_id Image attachment ID of the original image, or 0. + * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()', + * or null. + */ + return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $size, $attachment_id, $image_meta ); } /** @@ -164,92 +366,96 @@ function tevkori_get_srcset_string( $id, $size = 'medium' ) { function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); - // Try to get the image width from '$args' first. - if ( is_array( $args ) && ! empty( $args['width'] ) ) { - $img_width = (int) $args['width']; - } elseif ( $img = image_get_intermediate_size( $id, $size ) ) { - list( $img_width, $img_height ) = image_constrain_size_for_editor( $img['width'], $img['height'], $size ); - } + if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { + // Try to get the image width from '$args' first. + if ( is_array( $args ) && ! empty( $args['width'] ) ) { + $img_width = (int) $args['width']; + } elseif ( $img = image_get_intermediate_size( $id, $size ) ) { + list( $img_width, $img_height ) = image_constrain_size_for_editor( $img['width'], $img['height'], $size ); + } - // Bail early if '$img_width' isn't set. - if ( ! $img_width ) { - return false; - } + // Bail early if '$img_width' isn't set. + if ( ! $img_width ) { + return false; + } - // Set the image width in pixels. - $img_width = $img_width . 'px'; - - // Set up our default values. - $defaults = array( - 'sizes' => array( - array( - 'size_value' => '100vw', - 'mq_value' => $img_width, - 'mq_name' => 'max-width' - ), - array( - 'size_value' => $img_width - ), - ) - ); + // Set the image width in pixels. + $img_width = $img_width . 'px'; + + // Set up our default values. + $defaults = array( + 'sizes' => array( + array( + 'size_value' => '100vw', + 'mq_value' => $img_width, + 'mq_name' => 'max-width' + ), + array( + 'size_value' => $img_width + ), + ) + ); - $args = wp_parse_args( $args, $defaults ); + $args = wp_parse_args( $args, $defaults ); - /** - * Filter arguments used to create the 'sizes' attribute value. - * - * @since 2.4.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_sizes' - * @see 'wp_get_attachment_image_sizes' - * - * @param array $args An array of arguments used to create a 'sizes' attribute. - * @param int $id Post ID of the original image. - * @param array|string $size Image size. Image size or an array of width and height - * values in pixels (in that order). - */ - $args = apply_filters( 'tevkori_image_sizes_args', $args, $id, $size ); + /** + * Filter arguments used to create the 'sizes' attribute value. + * + * @since 2.4.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_sizes' + * @see 'wp_get_attachment_image_sizes' + * + * @param array $args An array of arguments used to create a 'sizes' attribute. + * @param int $id Post ID of the original image. + * @param array|string $size Image size. Image size or an array of width and height + * values in pixels (in that order). + */ + $args = apply_filters( 'tevkori_image_sizes_args', $args, $id, $size ); + + // If sizes is passed as a string, just use the string. + if ( is_string( $args['sizes'] ) ) { + $size_list = $args['sizes']; - // If sizes is passed as a string, just use the string. - if ( is_string( $args['sizes'] ) ) { - $size_list = $args['sizes']; + // Otherwise, breakdown the array and build a sizes string. + } elseif ( is_array( $args['sizes'] ) ) { - // Otherwise, breakdown the array and build a sizes string. - } elseif ( is_array( $args['sizes'] ) ) { + $size_list = ''; - $size_list = ''; + foreach ( $args['sizes'] as $size ) { - foreach ( $args['sizes'] as $size ) { + // Use 100vw as the size value unless something else is specified. + $size_value = ( $size['size_value'] ) ? $size['size_value'] : '100vw'; - // Use 100vw as the size value unless something else is specified. - $size_value = ( $size['size_value'] ) ? $size['size_value'] : '100vw'; + // If a media length is specified, build the media query. + if ( ! empty( $size['mq_value'] ) ) { - // If a media length is specified, build the media query. - if ( ! empty( $size['mq_value'] ) ) { + $media_length = $size['mq_value']; - $media_length = $size['mq_value']; + // Use max-width as the media condition unless min-width is specified. + $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; - // Use max-width as the media condition unless min-width is specified. - $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; + // If a media length was set, create the media query. + $media_query = '(' . $media_condition . ": " . $media_length . ') '; - // If a media length was set, create the media query. - $media_query = '(' . $media_condition . ": " . $media_length . ') '; + } else { - } else { + // If no media length was set, '$media_query' is blank. + $media_query = ''; + } - // If no media length was set, '$media_query' is blank. - $media_query = ''; + // Add to the source size list string. + $size_list .= $media_query . $size_value . ', '; } - // Add to the source size list string. - $size_list .= $media_query . $size_value . ', '; + // Remove the trailing comma and space from the end of the string. + $size_list = substr( $size_list, 0, -2 ); } - // Remove the trailing comma and space from the end of the string. - $size_list = substr( $size_list, 0, -2 ); + // If '$size_list' is defined set the string, otherwise set false. + return ( $size_list ) ? $size_list : false; + } else { + return wp_get_attachment_image_sizes( $size, $id ); } - - // If '$size_list' is defined set the string, otherwise set false. - return ( $size_list ) ? $size_list : false; } /** @@ -273,143 +479,171 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { function tevkori_get_sizes_string( $id, $size = 'medium', $args = null ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); - $sizes = tevkori_get_sizes( $id, $size, $args ); + if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { + $sizes = tevkori_get_sizes( $id, $size, $arg ); + } else { + $sizes = wp_get_attachment_image_sizes( $size, $id ); + } - return $sizes ? 'sizes="' . $sizes . '"' : false; + return $sizes ? 'sizes="' . esc_attr( $sizes ) . '"' : false; } /** - * Filter to add 'srcset' and 'sizes' attributes to images in the post content. + * Filters 'img' elements in post content to add 'srcset' and 'sizes' attributes. * - * @since 2.5.0 - * @deprecated 3.0 Use 'wp_make_content_images_responsive()' - * @see 'wp_make_content_images_responsive()' + * @since 3.0.0 + * + * @see 'wp_image_add_srcset_and_sizes()' * * @param string $content The raw post content to be filtered. - * @return string Converted content with 'srcset' and 'sizes' added to images. + * @return string Converted content with 'srcset' and 'sizes' attributes added to images. */ -function tevkori_filter_content_images( $content ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_make_content_images_responsive()' ); - - if ( ! preg_match_all( '/]+ wp-image-([0-9]+)[^>]+>/i', $content, $matches ) ) { - return $content; - } + function wp_make_content_images_responsive( $content ) { + $images = get_media_embedded_in_content( $content, 'img' ); - $images = $matches[0]; + $selected_images = $attachment_ids = array(); - $attachment_ids = array_unique( $matches[1] ); + foreach( $images as $image ) { + if ( false === strpos( $image, ' srcset="' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) && + ( $attachment_id = absint( $class_id[1] ) ) ) { + + /* + * If exactly the same image tag is used more than once, overwrite it. + * All identical tags will be replaced later with 'str_replace()'. + */ + $selected_images[ $image ] = $attachment_id; + // Overwrite the ID when the same image is included more than once. + $attachment_ids[ $attachment_id ] = true; + } + } - if ( 0 < count( $attachment_ids ) ) { + if ( count( $attachment_ids ) > 1 ) { /* - * Warm object caches for use with wp_get_attachment_metadata. + * Warm object cache for use with 'get_post_meta()'. * * 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( $attachment_ids, false, true ); + update_meta_cache( 'post', array_keys( $attachment_ids ) ); } - foreach( $images as $image ) { - $content = str_replace( $image, tevkori_img_add_srcset_and_sizes( $image ), $content ); + foreach ( $selected_images as $image => $attachment_id ) { + $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); + $content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content ); } return $content; } -add_filter( 'the_content', 'tevkori_filter_content_images', 5, 1 ); +add_filter( 'the_content', 'wp_make_content_images_responsive', 5, 1 ); /** - * Adds 'srcset' and 'sizes' attributes to image elements. + * Filter to add 'srcset' and 'sizes' attributes to images in the post content. * - * @since 2.6.0 - * @deprecated 3.0 Use 'wp_image_add_srcset_and_sizes()' - * @see 'wp_image_add_srcset_and_sizes()' + * @since 2.5.0 + * @deprecated 3.0 Use 'wp_make_content_images_responsive()' + * @see 'wp_make_content_images_responsive()' * - * @param string $image An HTML 'img' element to be filtered. - * @return string Converted 'img' element with 'srcset' and 'sizes' added. + * @param string $content The raw post content to be filtered. + * @return string Converted content with 'srcset' and 'sizes' added to images. */ -function tevkori_img_add_srcset_and_sizes( $image ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_image_add_srcset_and_sizes()' ); - - // Return early if a 'srcset' attribute already exists. - if ( false !== strpos( $image, ' 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 = str_replace( ' data-sizes="', ' sizes="', $image ); +function tevkori_filter_content_images( $content ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_make_content_images_responsive()' ); + return wp_make_content_images_responsive( $content ); +} +/** + * Adds 'srcset' and 'sizes' attributes to an existing 'img' element. + * + * @since 3.0.0 + * + * @see 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_sizes()' + * + * @param string $image An HTML 'img' element to be filtered. + * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. + * @param int $attachment_id Image attachment ID. + * @return string Converted 'img' element with 'srcset' and 'sizes' attributes added. + */ + function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { + // Ensure the image meta exists. + if ( empty( $image_meta['sizes'] ) ) { return $image; } - // 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; + $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : ''; + list( $image_url ) = explode( '?', $src ); - if ( $id && false === $size ) { - $size = array( - $width, - $height, - ); + // Return early if we couldn't get the image source. + if ( ! $image_url ) { + return $image; } - /* - * If attempts to parse the size value failed, attempt to use the image - * metadata to match the 'src' against the available sizes for an attachment. - */ - if ( ! $size && ! empty( $id ) && is_array( $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; + // Bail early if an image has been inserted and later edited. + if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) && + strpos( wp_basename( $image_url ), $img_edit_hash[0] ) === false ) { - // Return early if the 'src' value is empty. - if ( ! $src ) { - return $image; - } + return $image; + } + + $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? absint( $match_width[1] ) : 0; + $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? absint( $match_height[1] ) : 0; + if ( ! $width || ! $height ) { /* - * First, see if the file is the full size image. If not, we loop through - * the intermediate sizes until we find a file that matches. + * If attempts to parse the size value failed, attempt to use the image meta data to match + * the image file name from 'src' against the available sizes for an attachment. */ - $image_filename = wp_basename( $src ); + $image_filename = wp_basename( $image_url ); - if ( $image_filename === basename( $meta['file'] ) ) { - $size = 'full'; + if ( $image_filename === wp_basename( $image_meta['file'] ) ) { + $width = absint( $image_meta['width'] ); + $height = absint( $image_meta['height'] ); } else { - foreach( $meta['sizes'] as $image_size => $image_size_data ) { + foreach( $image_meta['sizes'] as $image_size_data ) { if ( $image_filename === $image_size_data['file'] ) { - $size = $image_size; + $width = absint( $image_size_data['width'] ); + $height = absint( $image_size_data['height'] ); break; } } } + } + // Return if we don't have a width or height. + if ( ! $width || ! $height ) { + return $image; } - // If we have an ID and size, try for 'srcset' and 'sizes' and update the markup. - if ( $id && $size && $srcset = tevkori_get_srcset( $id, $size ) ) { + $size_array = array( $width, $height ); - /** - * Pass the 'height' and 'width' to 'tevkori_get_sizes()' to avoid - * recalculating the image size. - */ - $args = array( - 'height' => $height, - 'width' => $width, - ); - $sizes = tevkori_get_sizes( $id, $size, $args ); + // Get the 'srcset' and 'sizes' values. + $srcset = wp_get_attachment_image_srcset( $attachment_id, $size_array, $image_url, $image_meta ); + $sizes = wp_get_attachment_image_sizes( $size_array, $attachment_id, $image_meta ); - // Format the srcset and sizes string and escape attributes. - $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes) ); + if ( $srcset && $sizes ) { + // Format the 'srcset' and 'sizes' string and escape attributes. + $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes ) ); - // Add srcset and sizes attributes to the image markup. - $image = preg_replace( '/]+)[\s?][\/?]>/', '', $image ); - }; + // Add 'srcset' and 'sizes' attributes to the image markup. + $image = preg_replace( '/]+?)[\/ ]*>/', '', $image ); + } return $image; + } + +/** + * Adds 'srcset' and 'sizes' attributes to image elements. + * + * @since 2.6.0 + * @deprecated 3.0 Use 'wp_image_add_srcset_and_sizes()' + * @see 'wp_image_add_srcset_and_sizes()' + * + * @param string $image An HTML 'img' element to be filtered. + * @return string Converted 'img' element with 'srcset' and 'sizes' added. + */ +function tevkori_img_add_srcset_and_sizes( $image ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_image_add_srcset_and_sizes()' ); + return wp_image_add_srcset_and_sizes( $image ); } /** @@ -419,20 +653,16 @@ function tevkori_img_add_srcset_and_sizes( $image ) { * @return array Attributes for image. */ function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { - if ( ! isset( $attr['srcset'] ) ) { - $srcset = tevkori_get_srcset( $attachment->ID, $size ); + // Set srcset and sizes if not already present and both were returned. + if ( empty( $attr['srcset'] ) ) { + $srcset = wp_get_attachment_image_srcset( $attachment->ID, $size ); + $sizes = wp_get_attachment_image_sizes( $size, $attachment->ID ); - // Set the 'srcset' attribute if one was returned. - if ( $srcset ) { + if ( $srcset && $sizes ) { $attr['srcset'] = $srcset; - if ( ! isset( $attr['sizes'] ) ) { - $sizes = tevkori_get_sizes( $attachment->ID, $size ); - - // Set the 'sizes' attribute if sizes were returned. - if ( $sizes ) { - $attr['sizes'] = $sizes; - } + if ( empty( $attr['sizes'] ) ) { + $attr['sizes'] = $sizes; } } } From a7fbb3ff8b2b3b338de6161ea2157c06accc344a Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Fri, 30 Oct 2015 09:28:29 +0100 Subject: [PATCH 24/61] Combine code in one file to avoid having same code twice --- wp-tevko-compat-shims.php | 246 ------------ wp-tevko-core-functions.php | 672 -------------------------------- wp-tevko-responsive-images.php | 692 ++++++++++++++++++++++++++++++++- 3 files changed, 684 insertions(+), 926 deletions(-) delete mode 100644 wp-tevko-compat-shims.php delete mode 100644 wp-tevko-core-functions.php diff --git a/wp-tevko-compat-shims.php b/wp-tevko-compat-shims.php deleted file mode 100644 index c5b3917..0000000 --- a/wp-tevko-compat-shims.php +++ /dev/null @@ -1,246 +0,0 @@ - array( - array( - 'size_value' => '100vw', - 'mq_value' => $img_width, - 'mq_name' => 'max-width' - ), - array( - 'size_value' => $img_width - ), - ) - ); - - $args = wp_parse_args( $args, $defaults ); - - /** - * Filter arguments used to create the 'sizes' attribute value. - * - * @since 2.4.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_sizes' - * @see 'wp_get_attachment_image_sizes' - * - * @param array $args An array of arguments used to create a 'sizes' attribute. - * @param int $id Post ID of the original image. - * @param array|string $size Image size. Image size or an array of width and height - * values in pixels (in that order). - */ - $args = apply_filters( 'tevkori_image_sizes_args', $args, $id, $size ); - - if ( is_string( $args['sizes'] ) ) { - $size_list = $args['sizes']; - } elseif ( is_array( $args['sizes'] ) ) { - $size_list = ''; - - foreach ( $args['sizes'] as $size ) { - $size_value = ( $size['size_value'] ) ? $size['size_value'] : '100vw'; - - if ( ! empty( $size['mq_value'] ) ) { - $media_length = $size['mq_value']; - $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; - $media_query = '(' . $media_condition . ": " . $media_length . ') '; - } else { - $media_query = ''; - } - - $size_list .= $media_query . $size_value . ', '; - } - - $size_list = substr( $size_list, 0, -2 ); - } - - return ( $size_list ) ? $size_list : false; - } else { - return wp_get_attachment_image_sizes( $size, $id ); - } -} - -/** - * Returns a 'sizes' attribute. - * - * @since 2.2.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' - * @see 'wp_get_attachment_image_sizes()' - * - * @param int $id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size, or an array of width and height - * values in pixels (in that order). Default '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 = 'medium', $args = null ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); - - if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { - $sizes = tevkori_get_sizes( $id, $size, $arg ); - } else { - $sizes = wp_get_attachment_image_sizes( $size, $id ); - } - - return $sizes ? 'sizes="' . esc_attr( $sizes ) . '"' : false; -} - -/** - * Filter to add 'srcset' and 'sizes' attributes to images in the post content. - * - * @since 2.5.0 - * @deprecated 3.0 Use 'wp_make_content_images_responsive()' - * @see 'wp_make_content_images_responsive()' - * - * @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 ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_make_content_images_responsive()' ); - return wp_make_content_images_responsive( $content ); -} - -/** - * Adds 'srcset' and 'sizes' attributes to image elements. - * - * @since 2.6.0 - * @deprecated 3.0 Use 'wp_image_add_srcset_and_sizes()' - * @see 'wp_image_add_srcset_and_sizes()' - * - * @param string $image An HTML 'img' element to be filtered. - * @return string Converted 'img' element with 'srcset' and 'sizes' added. - */ -function tevkori_img_add_srcset_and_sizes( $image ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_image_add_srcset_and_sizes()' ); - return wp_image_add_srcset_and_sizes( $image ); -} diff --git a/wp-tevko-core-functions.php b/wp-tevko-core-functions.php deleted file mode 100644 index b949082..0000000 --- a/wp-tevko-core-functions.php +++ /dev/null @@ -1,672 +0,0 @@ - $image_meta['width'], - 'height' => $image_meta['height'], - 'file' => wp_basename( $image_meta['file'] ), - ); - - // Get the width and height of the image. - if ( is_array( $size ) ) { - $size_array = $size; - $image_width = absint( $size[0] ); - $image_height = absint( $size[1] ); - } elseif ( is_string( $size ) ) { - $size_array = _wp_get_image_size_from_meta( $size, $image_meta ); - $image_width = $size_array[0]; - $image_height = $size_array[1]; - } else { - return false; - } - - // Bail early if the image has no width. - if ( $image_width < 1 ) { - return false; - } - - // Get the image base URL and directory. - $image_baseurl = _wp_upload_dir_baseurl(); - $dirname = dirname( $image_meta['file'] ); - - if ( $dirname !== '.' ) { - $image_baseurl = path_join( $image_baseurl, $dirname ); - } - - // Calculate the image aspect ratio. - $image_ratio = $image_height / $image_width; - - // Get the image URL if it's not passed as argument. - if ( ! $image_url ) { - $image = wp_get_attachment_image_src( $attachment_id, $size ); - - if ( ! $image ) { - return false; - } - - $image_url = $image[0]; - } - - /* - * Images that have been edited in WordPress after being uploaded will - * contain a unique hash. Look for that hash and use it later to filter - * out images that are leftovers from previous versions. - */ - $image_edited = preg_match( '/-e[0-9]{13}/', $image_url, $image_edit_hash ); - - /** - * Filter the maximum image width to be included in a 'srcset' attribute. - * - * @since 3.0.0 - * - * @param int $max_width The maximum image width to be included in the 'srcset'. Default '1600'. - * @param array $size_array Array of width and height values in pixels (in that order). - */ - $max_srcset_image_width = apply_filters( 'max_srcset_image_width', 1600, $size_array ); - - // Array to hold URL candidates. - $sources = array(); - - /* - * Loop through available images. Only use images that are resized - * versions of the same edit. - */ - foreach ( $image_sizes as $image ) { - // Filter out images that are from previous edits. - if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) { - continue; - } - - // Filter out images that are wider than '$max_srcset_image_width'. - if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width ) { - continue; - } - - $candidate_url = $image['file']; - - // Calculate the new image ratio. - if ( $image['width'] ) { - $image_ratio_compare = $image['height'] / $image['width']; - } else { - $image_ratio_compare = 0; - } - - // If the new ratio differs by less than 0.01, use it. - if ( abs( $image_ratio - $image_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) { - // Add the URL, descriptor, and value to the sources array to be returned. - $sources[ $image['width'] ] = array( - 'url' => path_join( $image_baseurl, $candidate_url ), - 'value' => $image['width'], - 'descriptor' => 'w', - ); - } - } - - /** - * Filter the array used to create the 'srcset' value string. - * - * @since 3.0.0 - * - * @param array $sources An array of image URLs, values, and descriptors. - * @param int $attachment_id Image attachment ID. - * @param array|string $size Image size. Image size name, or an array of width and height - * values in pixels (in that order). - * @param string $image_url The URL of the image. - * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. - */ - $sources = apply_filters( 'wp_get_attachment_image_srcset', array_values( $sources ), $attachment_id, $size, $image_url, $image_meta ); - - // Only return a 'srcset' value if there is more than one source. - if ( count( $sources ) < 2 ) { - return false; - } - - // Create the 'srcset' value string. - $srcset = ''; - - foreach ( $sources as $source ) { - $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', '; - } - - return rtrim( $srcset, ', ' ); -} - -/** - * Returns an array of image sources for a 'srcset' attribute. - * - * @since 2.1.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' - * @see 'wp_get_attachment_image_srcset()' - * - * @param int $id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size, or an array of width and height - * values in pixels (in that order). Default 'medium'. - * @return array|bool An array of 'srcset' values or false. - */ -function tevkori_get_srcset_array( $id, $size = 'medium' ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); - - $srcset = wp_get_attachment_image_srcset( $id, $size ); - - // Transform the 'srcset' value string to a pre-core style array. - $sources = explode( ', ', $srcset ); - $arr = array(); - - foreach ( $sources as $source ) { - $split = explode( ' ', $source ); - $width = rtrim( $split[1], "w" ); - $arr[ $width ] = $source; - } - - /** - * Filter the output of 'tevkori_get_srcset_array()'. - * - * @since 2.4.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset' - * @see 'wp_get_attachment_image_srcset' - * - * @param array $arr An array of image sources. - * @param int $id Attachment ID for image. - * @param array|string $size Image size. Image size or an array of width and height - * values in pixels (in that order). - */ - return apply_filters( 'tevkori_srcset_array', $arr, $id, $size ); -} - -/** - * Returns the value for a 'srcset' attribute. - * - * @since 2.3.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' - * @see 'wp_get_attachment_image_srcset()' - * - * @param int $id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size, or an array of width and height - * values in pixels (in that order). Default 'medium'. - * @return string|bool A 'srcset' value string or false. - */ -function tevkori_get_srcset( $id, $size = 'medium' ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); - - if ( has_filter( 'tevkori_srcset_array' ) ) { - $srcset_array = tevkori_get_srcset_array( $id, $size ); - - return implode( ', ', $srcset_array ); - } else { - return wp_get_attachment_image_srcset( $id, $size ); - } -} - -/** - * Returns a 'srcset' attribute. - * - * @since 2.1.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' - * @see 'wp_get_attachment_image_srcset()' - * - * @param int $id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size, or an array of width and height - * values in pixels (in that order). Default 'medium'. - * @return string|bool A full 'srcset' string or false. - */ -function tevkori_get_srcset_string( $id, $size = 'medium' ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); - - if ( has_filter( 'tevkori_srcset_array' ) ) { - $srcset_value = tevkori_get_srcset( $id, $size ); - - return $srcset_value ? 'srcset="' . $srcset_value . '"' : false; - } else { - $srcset_value = wp_get_attachment_image_srcset( $id, $size ); - - return $srcset_value ? 'srcset="' . $srcset_value . '"' : false; - } -} - -/** - * Retrieves the value for an image attachment's 'sizes' attribute. - * - * @since 3.0.0 - * - * @param array|string $size Image size. Accepts any valid image size name, or an array of - * width and height values in pixels (in that order). Default 'medium'. - * @param int $attachment_id Optional. Image attachment ID. Required if `$size` is an image size name - * and `$image_meta` is omited. Otherwise used to pass to the filter. - * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. - * @return string|bool A string of size values for use as value in a 'sizes' attribute or false. - */ -function wp_get_attachment_image_sizes( $size = 'medium', $attachment_id = 0, $image_meta = null ) { - $width = 0; - - if ( is_array( $size ) ) { - $width = absint( $size[0] ); - } elseif ( is_string( $size ) ) { - if ( ! $image_meta && $attachment_id ) { - $image_meta = wp_get_attachment_metadata( $attachment_id ); - } - if ( is_array( $image_meta ) ) { - $size_array = _wp_get_image_size_from_meta( $size, $image_meta ); - if ( $size_array ) { - $width = $size_array[0]; - } - } - } else { - return false; - } - - // Setup the default 'sizes' attribute. - $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $width ); - - /** - * Filter the output of 'wp_get_attachment_image_sizes()'. - * - * @since 3.0.0 - * - * @param string $sizes A source size value for use in a 'sizes' attribute. - * @param array|string $size Image size name, or an array of width and height - * values in pixels (in that order). - * @param int $attachment_id Image attachment ID of the original image, or 0. - * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()', - * or null. - */ - return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $size, $attachment_id, $image_meta ); -} - -/** - * Returns the value for a 'sizes' attribute. - * - * @since 2.2.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' - * @see 'wp_get_attachment_image_sizes()' - * - * @param int $id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size, or an array of width and height - * values in pixels (in that order). Default '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 = 'medium', $args = null ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); - - if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { - // Try to get the image width from '$args' first. - if ( is_array( $args ) && ! empty( $args['width'] ) ) { - $img_width = (int) $args['width']; - } elseif ( $img = image_get_intermediate_size( $id, $size ) ) { - list( $img_width, $img_height ) = image_constrain_size_for_editor( $img['width'], $img['height'], $size ); - } - - // Bail early if '$img_width' isn't set. - if ( ! $img_width ) { - return false; - } - - // Set the image width in pixels. - $img_width = $img_width . 'px'; - - // Set up our default values. - $defaults = array( - 'sizes' => array( - array( - 'size_value' => '100vw', - 'mq_value' => $img_width, - 'mq_name' => 'max-width' - ), - array( - 'size_value' => $img_width - ), - ) - ); - - $args = wp_parse_args( $args, $defaults ); - - /** - * Filter arguments used to create the 'sizes' attribute value. - * - * @since 2.4.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_sizes' - * @see 'wp_get_attachment_image_sizes' - * - * @param array $args An array of arguments used to create a 'sizes' attribute. - * @param int $id Post ID of the original image. - * @param array|string $size Image size. Image size or an array of width and height - * values in pixels (in that order). - */ - $args = apply_filters( 'tevkori_image_sizes_args', $args, $id, $size ); - - // If sizes is passed as a string, just use the string. - if ( is_string( $args['sizes'] ) ) { - $size_list = $args['sizes']; - - // Otherwise, breakdown the array and build a sizes string. - } elseif ( is_array( $args['sizes'] ) ) { - - $size_list = ''; - - foreach ( $args['sizes'] as $size ) { - - // Use 100vw as the size value unless something else is specified. - $size_value = ( $size['size_value'] ) ? $size['size_value'] : '100vw'; - - // If a media length is specified, build the media query. - if ( ! empty( $size['mq_value'] ) ) { - - $media_length = $size['mq_value']; - - // Use max-width as the media condition unless min-width is specified. - $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; - - // If a media length was set, create the media query. - $media_query = '(' . $media_condition . ": " . $media_length . ') '; - - } else { - - // If no media length was set, '$media_query' is blank. - $media_query = ''; - } - - // Add to the source size list string. - $size_list .= $media_query . $size_value . ', '; - } - - // Remove the trailing comma and space from the end of the string. - $size_list = substr( $size_list, 0, -2 ); - } - - // If '$size_list' is defined set the string, otherwise set false. - return ( $size_list ) ? $size_list : false; - } else { - return wp_get_attachment_image_sizes( $size, $id ); - } -} - -/** - * Returns a 'sizes' attribute. - * - * @since 2.2.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' - * @see 'wp_get_attachment_image_sizes()' - * - * @param int $id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size, or an array of width and height - * values in pixels (in that order). Default '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 = 'medium', $args = null ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); - - if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { - $sizes = tevkori_get_sizes( $id, $size, $arg ); - } else { - $sizes = wp_get_attachment_image_sizes( $size, $id ); - } - - return $sizes ? 'sizes="' . esc_attr( $sizes ) . '"' : false; -} - -/** - * Filters 'img' elements in post content to add 'srcset' and 'sizes' attributes. - * - * @since 3.0.0 - * - * @see 'wp_image_add_srcset_and_sizes()' - * - * @param string $content The raw post content to be filtered. - * @return string Converted content with 'srcset' and 'sizes' attributes added to images. - */ - function wp_make_content_images_responsive( $content ) { - $images = get_media_embedded_in_content( $content, 'img' ); - - $selected_images = $attachment_ids = array(); - - foreach( $images as $image ) { - if ( false === strpos( $image, ' srcset="' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) && - ( $attachment_id = absint( $class_id[1] ) ) ) { - - /* - * If exactly the same image tag is used more than once, overwrite it. - * All identical tags will be replaced later with 'str_replace()'. - */ - $selected_images[ $image ] = $attachment_id; - // Overwrite the ID when the same image is included more than once. - $attachment_ids[ $attachment_id ] = true; - } - } - - if ( count( $attachment_ids ) > 1 ) { - /* - * Warm object cache for use with 'get_post_meta()'. - * - * To avoid making a database call for each image, a single query - * warms the object cache with the meta information for all images. - */ - update_meta_cache( 'post', array_keys( $attachment_ids ) ); - } - - foreach ( $selected_images as $image => $attachment_id ) { - $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); - $content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content ); - } - - return $content; -} -add_filter( 'the_content', 'wp_make_content_images_responsive', 5, 1 ); - -/** - * Filter to add 'srcset' and 'sizes' attributes to images in the post content. - * - * @since 2.5.0 - * @deprecated 3.0 Use 'wp_make_content_images_responsive()' - * @see 'wp_make_content_images_responsive()' - * - * @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 ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_make_content_images_responsive()' ); - return wp_make_content_images_responsive( $content ); -} - -/** - * Adds 'srcset' and 'sizes' attributes to an existing 'img' element. - * - * @since 3.0.0 - * - * @see 'wp_get_attachment_image_srcset()' - * @see 'wp_get_attachment_image_sizes()' - * - * @param string $image An HTML 'img' element to be filtered. - * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. - * @param int $attachment_id Image attachment ID. - * @return string Converted 'img' element with 'srcset' and 'sizes' attributes added. - */ - function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { - // Ensure the image meta exists. - if ( empty( $image_meta['sizes'] ) ) { - return $image; - } - - $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : ''; - list( $image_url ) = explode( '?', $src ); - - // Return early if we couldn't get the image source. - if ( ! $image_url ) { - return $image; - } - - // Bail early if an image has been inserted and later edited. - if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) && - strpos( wp_basename( $image_url ), $img_edit_hash[0] ) === false ) { - - return $image; - } - - $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? absint( $match_width[1] ) : 0; - $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? absint( $match_height[1] ) : 0; - - if ( ! $width || ! $height ) { - /* - * If attempts to parse the size value failed, attempt to use the image meta data to match - * the image file name from 'src' against the available sizes for an attachment. - */ - $image_filename = wp_basename( $image_url ); - - if ( $image_filename === wp_basename( $image_meta['file'] ) ) { - $width = absint( $image_meta['width'] ); - $height = absint( $image_meta['height'] ); - } else { - foreach( $image_meta['sizes'] as $image_size_data ) { - if ( $image_filename === $image_size_data['file'] ) { - $width = absint( $image_size_data['width'] ); - $height = absint( $image_size_data['height'] ); - break; - } - } - } - } - - // Return if we don't have a width or height. - if ( ! $width || ! $height ) { - return $image; - } - - $size_array = array( $width, $height ); - - // Get the 'srcset' and 'sizes' values. - $srcset = wp_get_attachment_image_srcset( $attachment_id, $size_array, $image_url, $image_meta ); - $sizes = wp_get_attachment_image_sizes( $size_array, $attachment_id, $image_meta ); - - if ( $srcset && $sizes ) { - // Format the 'srcset' and 'sizes' string and escape attributes. - $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes ) ); - - // Add 'srcset' and 'sizes' attributes to the image markup. - $image = preg_replace( '/]+?)[\/ ]*>/', '', $image ); - } - - return $image; - } - -/** - * Adds 'srcset' and 'sizes' attributes to image elements. - * - * @since 2.6.0 - * @deprecated 3.0 Use 'wp_image_add_srcset_and_sizes()' - * @see 'wp_image_add_srcset_and_sizes()' - * - * @param string $image An HTML 'img' element to be filtered. - * @return string Converted 'img' element with 'srcset' and 'sizes' added. - */ -function tevkori_img_add_srcset_and_sizes( $image ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_image_add_srcset_and_sizes()' ); - return wp_image_add_srcset_and_sizes( $image ); -} - -/** - * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. - * - * @see 'wp_get_attachment_image_attributes' - * @return array Attributes for image. - */ -function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { - // Set srcset and sizes if not already present and both were returned. - if ( empty( $attr['srcset'] ) ) { - $srcset = wp_get_attachment_image_srcset( $attachment->ID, $size ); - $sizes = wp_get_attachment_image_sizes( $size, $attachment->ID ); - - if ( $srcset && $sizes ) { - $attr['srcset'] = $srcset; - - if ( empty( $attr['sizes'] ) ) { - $attr['sizes'] = $sizes; - } - } - } - - return $attr; -} -add_filter( 'wp_get_attachment_image_attributes', 'tevkori_filter_attachment_image_attributes', 0, 3 ); diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 83401b7..baed6bc 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -46,13 +46,689 @@ function tevkori_get_picturefill() { } add_action( 'wp_enqueue_scripts', 'tevkori_get_picturefill' ); -/* - * If the WordPress version contains the responsive images functions we include - * the functions that show deprecation warnings and point to the new functions. - * Else we include the plugin's responsive images functions. +if ( ! function_exists( '_wp_upload_dir_baseurl' ) ) : +/** + * Caches and returns the base URL of the uploads directory. + * + * @since 3.0.0 + * @access private + * + * @return string The base URL, cached. + */ +function _wp_upload_dir_baseurl() { + static $baseurl = null; + + if ( ! $baseurl ) { + $uploads_dir = wp_upload_dir(); + $baseurl = $uploads_dir['baseurl']; + } + + return $baseurl; +} +endif; + +if ( ! function_exists( '_wp_get_image_size_from_meta' ) ) : +/** + * Get the image size as array from its meta data. + * + * Used for responsive images. + * + * @since 3.0.0 + * @access private + * + * @param string $size_name Image size. Accepts any valid image size name ('thumbnail', 'medium', etc.). + * @param array $image_meta The image meta data. + * @return array|bool Array of width and height values in pixels (in that order) + * or false if the size doesn't exist. + */ +function _wp_get_image_size_from_meta( $size_name, $image_meta ) { + if ( $size_name === 'full' ) { + return array( + absint( $image_meta['width'] ), + absint( $image_meta['height'] ), + ); + } elseif ( ! empty( $image_meta['sizes'][$size_name] ) ) { + return array( + absint( $image_meta['sizes'][$size_name]['width'] ), + absint( $image_meta['sizes'][$size_name]['height'] ), + ); + } + + return false; +} +endif; + +if ( ! function_exists( 'wp_get_attachment_image_srcset' ) ) : +/** + * Retrieves the value for an image attachment's 'srcset' attribute. + * + * @since 3.0.0 + * + * @param int $attachment_id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size name, or an array of + * width and height values in pixels (in that order). Default 'medium'. + * @param string $image_url Optional. The URL of the image. + * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. + * @return string|bool A string of sources with their descriptor and value, + * for use as value in a 'srcset' attribute or false. + */ +function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_url = null, $image_meta = null ) { + // Get the image meta data if it isn't passed as argument. + if ( ! is_array( $image_meta ) ) { + $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); + } + + // Bail early if image sizes info is not available. + if ( empty( $image_meta['sizes'] ) ) { + return false; + } + + $image_sizes = $image_meta['sizes']; + + // Add full size to the '$image_sizes' array. + $image_sizes['full'] = array( + 'width' => $image_meta['width'], + 'height' => $image_meta['height'], + 'file' => wp_basename( $image_meta['file'] ), + ); + + // Get the width and height of the image. + if ( is_array( $size ) ) { + $size_array = $size; + $image_width = absint( $size[0] ); + $image_height = absint( $size[1] ); + } elseif ( is_string( $size ) ) { + $size_array = _wp_get_image_size_from_meta( $size, $image_meta ); + $image_width = $size_array[0]; + $image_height = $size_array[1]; + } else { + return false; + } + + // Bail early if the image has no width. + if ( $image_width < 1 ) { + return false; + } + + // Get the image base URL and directory. + $image_baseurl = _wp_upload_dir_baseurl(); + $dirname = dirname( $image_meta['file'] ); + + if ( $dirname !== '.' ) { + $image_baseurl = path_join( $image_baseurl, $dirname ); + } + + // Calculate the image aspect ratio. + $image_ratio = $image_height / $image_width; + + // Get the image URL if it's not passed as argument. + if ( ! $image_url ) { + $image = wp_get_attachment_image_src( $attachment_id, $size ); + + if ( ! $image ) { + return false; + } + + $image_url = $image[0]; + } + + /* + * Images that have been edited in WordPress after being uploaded will + * contain a unique hash. Look for that hash and use it later to filter + * out images that are leftovers from previous versions. + */ + $image_edited = preg_match( '/-e[0-9]{13}/', $image_url, $image_edit_hash ); + + /** + * Filter the maximum image width to be included in a 'srcset' attribute. + * + * @since 3.0.0 + * + * @param int $max_width The maximum image width to be included in the 'srcset'. Default '1600'. + * @param array $size_array Array of width and height values in pixels (in that order). + */ + $max_srcset_image_width = apply_filters( 'max_srcset_image_width', 1600, $size_array ); + + // Array to hold URL candidates. + $sources = array(); + + /* + * Loop through available images. Only use images that are resized + * versions of the same edit. + */ + foreach ( $image_sizes as $image ) { + // Filter out images that are from previous edits. + if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) { + continue; + } + + // Filter out images that are wider than '$max_srcset_image_width'. + if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width ) { + continue; + } + + $candidate_url = $image['file']; + + // Calculate the new image ratio. + if ( $image['width'] ) { + $image_ratio_compare = $image['height'] / $image['width']; + } else { + $image_ratio_compare = 0; + } + + // If the new ratio differs by less than 0.01, use it. + if ( abs( $image_ratio - $image_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) { + // Add the URL, descriptor, and value to the sources array to be returned. + $sources[ $image['width'] ] = array( + 'url' => path_join( $image_baseurl, $candidate_url ), + 'value' => $image['width'], + 'descriptor' => 'w', + ); + } + } + + /** + * Filter the array used to create the 'srcset' value string. + * + * @since 3.0.0 + * + * @param array $sources An array of image URLs, values, and descriptors. + * @param int $attachment_id Image attachment ID. + * @param array|string $size Image size. Image size name, or an array of width and height + * values in pixels (in that order). + * @param string $image_url The URL of the image. + * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. + */ + $sources = apply_filters( 'wp_get_attachment_image_srcset', array_values( $sources ), $attachment_id, $size, $image_url, $image_meta ); + + // Only return a 'srcset' value if there is more than one source. + if ( count( $sources ) < 2 ) { + return false; + } + + // Create the 'srcset' value string. + $srcset = ''; + + foreach ( $sources as $source ) { + $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', '; + } + + return rtrim( $srcset, ', ' ); +} +endif; + +/** + * Returns an array of image sources for a 'srcset' attribute. + * + * @since 2.1.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_srcset()' + * + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default 'medium'. + * @return array|bool An array of 'srcset' values or false. + */ +function tevkori_get_srcset_array( $id, $size = 'medium' ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); + + $srcset = wp_get_attachment_image_srcset( $id, $size ); + + // Transform the 'srcset' value string to a pre-core style array. + $sources = explode( ', ', $srcset ); + $arr = array(); + + foreach ( $sources as $source ) { + $split = explode( ' ', $source ); + $width = rtrim( $split[1], "w" ); + $arr[ $width ] = $source; + } + + /** + * Filter the output of 'tevkori_get_srcset_array()'. + * + * @since 2.4.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_srcset' + * @see 'wp_get_attachment_image_srcset' + * + * @param array $arr An array of image sources. + * @param int $id Attachment ID for image. + * @param array|string $size Image size. Image size or an array of width and height + * values in pixels (in that order). + */ + return apply_filters( 'tevkori_srcset_array', $arr, $id, $size ); +} + +/** + * Returns the value for a 'srcset' attribute. + * + * @since 2.3.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_srcset()' + * + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default 'medium'. + * @return string|bool A 'srcset' value string or false. + */ +function tevkori_get_srcset( $id, $size = 'medium' ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); + + if ( has_filter( 'tevkori_srcset_array' ) ) { + $srcset_array = tevkori_get_srcset_array( $id, $size ); + + return implode( ', ', $srcset_array ); + } else { + return wp_get_attachment_image_srcset( $id, $size ); + } +} + +/** + * Returns a 'srcset' attribute. + * + * @since 2.1.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_srcset()' + * + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default 'medium'. + * @return string|bool A full 'srcset' string or false. + */ +function tevkori_get_srcset_string( $id, $size = 'medium' ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); + + if ( has_filter( 'tevkori_srcset_array' ) ) { + $srcset_value = tevkori_get_srcset( $id, $size ); + + return $srcset_value ? 'srcset="' . $srcset_value . '"' : false; + } else { + $srcset_value = wp_get_attachment_image_srcset( $id, $size ); + + return $srcset_value ? 'srcset="' . $srcset_value . '"' : false; + } +} + +if ( ! function_exists( 'wp_get_attachment_image_sizes' ) ) : +/** + * Retrieves the value for an image attachment's 'sizes' attribute. + * + * @since 3.0.0 + * + * @param array|string $size Image size. Accepts any valid image size name, or an array of + * width and height values in pixels (in that order). Default 'medium'. + * @param int $attachment_id Optional. Image attachment ID. Required if `$size` is an image size name + * and `$image_meta` is omited. Otherwise used to pass to the filter. + * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. + * @return string|bool A string of size values for use as value in a 'sizes' attribute or false. + */ +function wp_get_attachment_image_sizes( $size = 'medium', $attachment_id = 0, $image_meta = null ) { + $width = 0; + + if ( is_array( $size ) ) { + $width = absint( $size[0] ); + } elseif ( is_string( $size ) ) { + if ( ! $image_meta && $attachment_id ) { + $image_meta = wp_get_attachment_metadata( $attachment_id ); + } + if ( is_array( $image_meta ) ) { + $size_array = _wp_get_image_size_from_meta( $size, $image_meta ); + if ( $size_array ) { + $width = $size_array[0]; + } + } + } else { + return false; + } + + // Setup the default 'sizes' attribute. + $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $width ); + + /** + * Filter the output of 'wp_get_attachment_image_sizes()'. + * + * @since 3.0.0 + * + * @param string $sizes A source size value for use in a 'sizes' attribute. + * @param array|string $size Image size name, or an array of width and height + * values in pixels (in that order). + * @param int $attachment_id Image attachment ID of the original image, or 0. + * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()', + * or null. + */ + return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $size, $attachment_id, $image_meta ); +} +endif; + +/** + * Returns the value for a 'sizes' attribute. + * + * @since 2.2.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' + * @see 'wp_get_attachment_image_sizes()' + * + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default '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 = 'medium', $args = null ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); + + if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { + // Try to get the image width from '$args' first. + if ( is_array( $args ) && ! empty( $args['width'] ) ) { + $img_width = (int) $args['width']; + } elseif ( $img = image_get_intermediate_size( $id, $size ) ) { + list( $img_width, $img_height ) = image_constrain_size_for_editor( $img['width'], $img['height'], $size ); + } + + // Bail early if '$img_width' isn't set. + if ( ! $img_width ) { + return false; + } + + // Set the image width in pixels. + $img_width = $img_width . 'px'; + + // Set up our default values. + $defaults = array( + 'sizes' => array( + array( + 'size_value' => '100vw', + 'mq_value' => $img_width, + 'mq_name' => 'max-width' + ), + array( + 'size_value' => $img_width + ), + ) + ); + + $args = wp_parse_args( $args, $defaults ); + + /** + * Filter arguments used to create the 'sizes' attribute value. + * + * @since 2.4.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_sizes' + * @see 'wp_get_attachment_image_sizes' + * + * @param array $args An array of arguments used to create a 'sizes' attribute. + * @param int $id Post ID of the original image. + * @param array|string $size Image size. Image size or an array of width and height + * values in pixels (in that order). + */ + $args = apply_filters( 'tevkori_image_sizes_args', $args, $id, $size ); + + // If sizes is passed as a string, just use the string. + if ( is_string( $args['sizes'] ) ) { + $size_list = $args['sizes']; + + // Otherwise, breakdown the array and build a sizes string. + } elseif ( is_array( $args['sizes'] ) ) { + + $size_list = ''; + + foreach ( $args['sizes'] as $size ) { + + // Use 100vw as the size value unless something else is specified. + $size_value = ( $size['size_value'] ) ? $size['size_value'] : '100vw'; + + // If a media length is specified, build the media query. + if ( ! empty( $size['mq_value'] ) ) { + + $media_length = $size['mq_value']; + + // Use max-width as the media condition unless min-width is specified. + $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; + + // If a media length was set, create the media query. + $media_query = '(' . $media_condition . ": " . $media_length . ') '; + + } else { + + // If no media length was set, '$media_query' is blank. + $media_query = ''; + } + + // Add to the source size list string. + $size_list .= $media_query . $size_value . ', '; + } + + // Remove the trailing comma and space from the end of the string. + $size_list = substr( $size_list, 0, -2 ); + } + + // If '$size_list' is defined set the string, otherwise set false. + return ( $size_list ) ? $size_list : false; + } else { + return wp_get_attachment_image_sizes( $size, $id ); + } +} + +/** + * Returns a 'sizes' attribute. + * + * @since 2.2.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' + * @see 'wp_get_attachment_image_sizes()' + * + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default '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 = 'medium', $args = null ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); + + if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { + $sizes = tevkori_get_sizes( $id, $size, $arg ); + } else { + $sizes = wp_get_attachment_image_sizes( $size, $id ); + } + + return $sizes ? 'sizes="' . esc_attr( $sizes ) . '"' : false; +} + +if ( ! function_exists( 'wp_make_content_images_responsive' ) ) : +/** + * Filters 'img' elements in post content to add 'srcset' and 'sizes' attributes. + * + * @since 3.0.0 + * + * @see 'wp_image_add_srcset_and_sizes()' + * + * @param string $content The raw post content to be filtered. + * @return string Converted content with 'srcset' and 'sizes' attributes added to images. + */ + function wp_make_content_images_responsive( $content ) { + $images = get_media_embedded_in_content( $content, 'img' ); + + $selected_images = $attachment_ids = array(); + + foreach( $images as $image ) { + if ( false === strpos( $image, ' srcset="' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) && + ( $attachment_id = absint( $class_id[1] ) ) ) { + + /* + * If exactly the same image tag is used more than once, overwrite it. + * All identical tags will be replaced later with 'str_replace()'. + */ + $selected_images[ $image ] = $attachment_id; + // Overwrite the ID when the same image is included more than once. + $attachment_ids[ $attachment_id ] = true; + } + } + + if ( count( $attachment_ids ) > 1 ) { + /* + * Warm object cache for use with 'get_post_meta()'. + * + * To avoid making a database call for each image, a single query + * warms the object cache with the meta information for all images. + */ + update_meta_cache( 'post', array_keys( $attachment_ids ) ); + } + + foreach ( $selected_images as $image => $attachment_id ) { + $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); + $content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content ); + } + + return $content; +} +endif; + +if ( ! has_filter( 'the_content', 'wp_make_content_images_responsive' ) ) : +add_filter( 'the_content', 'wp_make_content_images_responsive', 5, 1 ); +endif; + +/** + * Filter to add 'srcset' and 'sizes' attributes to images in the post content. + * + * @since 2.5.0 + * @deprecated 3.0 Use 'wp_make_content_images_responsive()' + * @see 'wp_make_content_images_responsive()' + * + * @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 ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_make_content_images_responsive()' ); + return wp_make_content_images_responsive( $content ); +} + +if ( ! function_exists( 'wp_image_add_srcset_and_sizes' ) ) : +/** + * Adds 'srcset' and 'sizes' attributes to an existing 'img' element. + * + * @since 3.0.0 + * + * @see 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_sizes()' + * + * @param string $image An HTML 'img' element to be filtered. + * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. + * @param int $attachment_id Image attachment ID. + * @return string Converted 'img' element with 'srcset' and 'sizes' attributes added. */ -if ( function_exists( 'wp_get_attachment_image_srcset' ) ) { - require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-compat-shims.php' ); -} else { - require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-core-functions.php' ); + function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { + // Ensure the image meta exists. + if ( empty( $image_meta['sizes'] ) ) { + return $image; + } + + $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : ''; + list( $image_url ) = explode( '?', $src ); + + // Return early if we couldn't get the image source. + if ( ! $image_url ) { + return $image; + } + + // Bail early if an image has been inserted and later edited. + if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) && + strpos( wp_basename( $image_url ), $img_edit_hash[0] ) === false ) { + + return $image; + } + + $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? absint( $match_width[1] ) : 0; + $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? absint( $match_height[1] ) : 0; + + if ( ! $width || ! $height ) { + /* + * If attempts to parse the size value failed, attempt to use the image meta data to match + * the image file name from 'src' against the available sizes for an attachment. + */ + $image_filename = wp_basename( $image_url ); + + if ( $image_filename === wp_basename( $image_meta['file'] ) ) { + $width = absint( $image_meta['width'] ); + $height = absint( $image_meta['height'] ); + } else { + foreach( $image_meta['sizes'] as $image_size_data ) { + if ( $image_filename === $image_size_data['file'] ) { + $width = absint( $image_size_data['width'] ); + $height = absint( $image_size_data['height'] ); + break; + } + } + } + } + + // Return if we don't have a width or height. + if ( ! $width || ! $height ) { + return $image; + } + + $size_array = array( $width, $height ); + + // Get the 'srcset' and 'sizes' values. + $srcset = wp_get_attachment_image_srcset( $attachment_id, $size_array, $image_url, $image_meta ); + $sizes = wp_get_attachment_image_sizes( $size_array, $attachment_id, $image_meta ); + + if ( $srcset && $sizes ) { + // Format the 'srcset' and 'sizes' string and escape attributes. + $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes ) ); + + // Add 'srcset' and 'sizes' attributes to the image markup. + $image = preg_replace( '/]+?)[\/ ]*>/', '', $image ); + } + + return $image; + } +endif; + +/** + * Adds 'srcset' and 'sizes' attributes to image elements. + * + * @since 2.6.0 + * @deprecated 3.0 Use 'wp_image_add_srcset_and_sizes()' + * @see 'wp_image_add_srcset_and_sizes()' + * + * @param string $image An HTML 'img' element to be filtered. + * @return string Converted 'img' element with 'srcset' and 'sizes' added. + */ +function tevkori_img_add_srcset_and_sizes( $image ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_image_add_srcset_and_sizes()' ); + return wp_image_add_srcset_and_sizes( $image ); +} + +/** + * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. + * + * @see 'wp_get_attachment_image_attributes' + * @return array Attributes for image. + */ +function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { + // Set srcset and sizes if not already present and both were returned. + if ( empty( $attr['srcset'] ) ) { + $srcset = wp_get_attachment_image_srcset( $attachment->ID, $size ); + $sizes = wp_get_attachment_image_sizes( $size, $attachment->ID ); + + if ( $srcset && $sizes ) { + $attr['srcset'] = $srcset; + + if ( empty( $attr['sizes'] ) ) { + $attr['sizes'] = $sizes; + } + } + } + + return $attr; } +add_filter( 'wp_get_attachment_image_attributes', 'tevkori_filter_attachment_image_attributes', 0, 3 ); From 4c32f4cb95fa892377f5c10872cddaf293be1c0c Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Fri, 30 Oct 2015 09:35:31 +0100 Subject: [PATCH 25/61] Only add the attachment attribute filter if WP core isn't adding srcset and sizes --- wp-tevko-responsive-images.php | 52 ++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index baed6bc..8c93d48 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -46,6 +46,33 @@ function tevkori_get_picturefill() { } add_action( 'wp_enqueue_scripts', 'tevkori_get_picturefill' ); +if ( ! function_exists( 'wp_get_attachment_image_srcset' ) ) : +/** + * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. + * + * @see 'wp_get_attachment_image_attributes' + * @return array Attributes for image. + */ +function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { + // Set srcset and sizes if not already present and both were returned. + if ( empty( $attr['srcset'] ) ) { + $srcset = wp_get_attachment_image_srcset( $attachment->ID, $size ); + $sizes = wp_get_attachment_image_sizes( $size, $attachment->ID ); + + if ( $srcset && $sizes ) { + $attr['srcset'] = $srcset; + + if ( empty( $attr['sizes'] ) ) { + $attr['sizes'] = $sizes; + } + } + } + + return $attr; +} +add_filter( 'wp_get_attachment_image_attributes', 'tevkori_filter_attachment_image_attributes', 0, 3 ); +endif; + if ( ! function_exists( '_wp_upload_dir_baseurl' ) ) : /** * Caches and returns the base URL of the uploads directory. @@ -707,28 +734,3 @@ function tevkori_img_add_srcset_and_sizes( $image ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_image_add_srcset_and_sizes()' ); return wp_image_add_srcset_and_sizes( $image ); } - -/** - * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. - * - * @see 'wp_get_attachment_image_attributes' - * @return array Attributes for image. - */ -function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { - // Set srcset and sizes if not already present and both were returned. - if ( empty( $attr['srcset'] ) ) { - $srcset = wp_get_attachment_image_srcset( $attachment->ID, $size ); - $sizes = wp_get_attachment_image_sizes( $size, $attachment->ID ); - - if ( $srcset && $sizes ) { - $attr['srcset'] = $srcset; - - if ( empty( $attr['sizes'] ) ) { - $attr['sizes'] = $sizes; - } - } - } - - return $attr; -} -add_filter( 'wp_get_attachment_image_attributes', 'tevkori_filter_attachment_image_attributes', 0, 3 ); From 14b9925b56cbf277f91138a98f7eb08639925252 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Fri, 30 Oct 2015 09:47:50 +0100 Subject: [PATCH 26/61] Move deprecated functions to separate file --- wp-tevko-deprecated-functions.php | 265 +++++++++++++++++++++++++++++ wp-tevko-responsive-images.php | 267 +----------------------------- 2 files changed, 267 insertions(+), 265 deletions(-) create mode 100644 wp-tevko-deprecated-functions.php diff --git a/wp-tevko-deprecated-functions.php b/wp-tevko-deprecated-functions.php new file mode 100644 index 0000000..257d999 --- /dev/null +++ b/wp-tevko-deprecated-functions.php @@ -0,0 +1,265 @@ + array( + array( + 'size_value' => '100vw', + 'mq_value' => $img_width, + 'mq_name' => 'max-width' + ), + array( + 'size_value' => $img_width + ), + ) + ); + + $args = wp_parse_args( $args, $defaults ); + + /** + * Filter arguments used to create the 'sizes' attribute value. + * + * @since 2.4.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_sizes' + * @see 'wp_get_attachment_image_sizes' + * + * @param array $args An array of arguments used to create a 'sizes' attribute. + * @param int $id Post ID of the original image. + * @param array|string $size Image size. Image size or an array of width and height + * values in pixels (in that order). + */ + $args = apply_filters( 'tevkori_image_sizes_args', $args, $id, $size ); + + // If sizes is passed as a string, just use the string. + if ( is_string( $args['sizes'] ) ) { + $size_list = $args['sizes']; + + // Otherwise, breakdown the array and build a sizes string. + } elseif ( is_array( $args['sizes'] ) ) { + + $size_list = ''; + + foreach ( $args['sizes'] as $size ) { + + // Use 100vw as the size value unless something else is specified. + $size_value = ( $size['size_value'] ) ? $size['size_value'] : '100vw'; + + // If a media length is specified, build the media query. + if ( ! empty( $size['mq_value'] ) ) { + + $media_length = $size['mq_value']; + + // Use max-width as the media condition unless min-width is specified. + $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; + + // If a media length was set, create the media query. + $media_query = '(' . $media_condition . ": " . $media_length . ') '; + + } else { + + // If no media length was set, '$media_query' is blank. + $media_query = ''; + } + + // Add to the source size list string. + $size_list .= $media_query . $size_value . ', '; + } + + // Remove the trailing comma and space from the end of the string. + $size_list = substr( $size_list, 0, -2 ); + } + + // If '$size_list' is defined set the string, otherwise set false. + return ( $size_list ) ? $size_list : false; + } else { + return wp_get_attachment_image_sizes( $size, $id ); + } +} + +/** + * Returns a 'sizes' attribute. + * + * @since 2.2.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' + * @see 'wp_get_attachment_image_sizes()' + * + * @param int $id Image attachment ID. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default '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 = 'medium', $args = null ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); + + if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { + $sizes = tevkori_get_sizes( $id, $size, $arg ); + } else { + $sizes = wp_get_attachment_image_sizes( $size, $id ); + } + + return $sizes ? 'sizes="' . esc_attr( $sizes ) . '"' : false; +} + +/** + * Filter to add 'srcset' and 'sizes' attributes to images in the post content. + * + * @since 2.5.0 + * @deprecated 3.0 Use 'wp_make_content_images_responsive()' + * @see 'wp_make_content_images_responsive()' + * + * @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 ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_make_content_images_responsive()' ); + return wp_make_content_images_responsive( $content ); +} + +/** + * Adds 'srcset' and 'sizes' attributes to image elements. + * + * @since 2.6.0 + * @deprecated 3.0 Use 'wp_image_add_srcset_and_sizes()' + * @see 'wp_image_add_srcset_and_sizes()' + * + * @param string $image An HTML 'img' element to be filtered. + * @return string Converted 'img' element with 'srcset' and 'sizes' added. + */ +function tevkori_img_add_srcset_and_sizes( $image ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_image_add_srcset_and_sizes()' ); + return wp_image_add_srcset_and_sizes( $image ); +} diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 8c93d48..7aefc4f 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -19,6 +19,8 @@ defined( 'ABSPATH' ) or die( "No script kiddies please!" ); // List includes. +require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-deprecated-functions.php' ); + if ( class_exists( 'Imagick' ) ) { require_once( plugin_dir_path( __FILE__ ) . 'class-respimg.php' ); require_once( plugin_dir_path( __FILE__ ) . 'class-wp-image-editor-respimg.php' ); @@ -284,98 +286,6 @@ function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag } endif; -/** - * Returns an array of image sources for a 'srcset' attribute. - * - * @since 2.1.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' - * @see 'wp_get_attachment_image_srcset()' - * - * @param int $id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size, or an array of width and height - * values in pixels (in that order). Default 'medium'. - * @return array|bool An array of 'srcset' values or false. - */ -function tevkori_get_srcset_array( $id, $size = 'medium' ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); - - $srcset = wp_get_attachment_image_srcset( $id, $size ); - - // Transform the 'srcset' value string to a pre-core style array. - $sources = explode( ', ', $srcset ); - $arr = array(); - - foreach ( $sources as $source ) { - $split = explode( ' ', $source ); - $width = rtrim( $split[1], "w" ); - $arr[ $width ] = $source; - } - - /** - * Filter the output of 'tevkori_get_srcset_array()'. - * - * @since 2.4.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset' - * @see 'wp_get_attachment_image_srcset' - * - * @param array $arr An array of image sources. - * @param int $id Attachment ID for image. - * @param array|string $size Image size. Image size or an array of width and height - * values in pixels (in that order). - */ - return apply_filters( 'tevkori_srcset_array', $arr, $id, $size ); -} - -/** - * Returns the value for a 'srcset' attribute. - * - * @since 2.3.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' - * @see 'wp_get_attachment_image_srcset()' - * - * @param int $id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size, or an array of width and height - * values in pixels (in that order). Default 'medium'. - * @return string|bool A 'srcset' value string or false. - */ -function tevkori_get_srcset( $id, $size = 'medium' ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); - - if ( has_filter( 'tevkori_srcset_array' ) ) { - $srcset_array = tevkori_get_srcset_array( $id, $size ); - - return implode( ', ', $srcset_array ); - } else { - return wp_get_attachment_image_srcset( $id, $size ); - } -} - -/** - * Returns a 'srcset' attribute. - * - * @since 2.1.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' - * @see 'wp_get_attachment_image_srcset()' - * - * @param int $id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size, or an array of width and height - * values in pixels (in that order). Default 'medium'. - * @return string|bool A full 'srcset' string or false. - */ -function tevkori_get_srcset_string( $id, $size = 'medium' ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_srcset()' ); - - if ( has_filter( 'tevkori_srcset_array' ) ) { - $srcset_value = tevkori_get_srcset( $id, $size ); - - return $srcset_value ? 'srcset="' . $srcset_value . '"' : false; - } else { - $srcset_value = wp_get_attachment_image_srcset( $id, $size ); - - return $srcset_value ? 'srcset="' . $srcset_value . '"' : false; - } -} - if ( ! function_exists( 'wp_get_attachment_image_sizes' ) ) : /** * Retrieves the value for an image attachment's 'sizes' attribute. @@ -427,149 +337,6 @@ function wp_get_attachment_image_sizes( $size = 'medium', $attachment_id = 0, $i } endif; -/** - * Returns the value for a 'sizes' attribute. - * - * @since 2.2.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' - * @see 'wp_get_attachment_image_sizes()' - * - * @param int $id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size, or an array of width and height - * values in pixels (in that order). Default '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 = 'medium', $args = null ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); - - if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { - // Try to get the image width from '$args' first. - if ( is_array( $args ) && ! empty( $args['width'] ) ) { - $img_width = (int) $args['width']; - } elseif ( $img = image_get_intermediate_size( $id, $size ) ) { - list( $img_width, $img_height ) = image_constrain_size_for_editor( $img['width'], $img['height'], $size ); - } - - // Bail early if '$img_width' isn't set. - if ( ! $img_width ) { - return false; - } - - // Set the image width in pixels. - $img_width = $img_width . 'px'; - - // Set up our default values. - $defaults = array( - 'sizes' => array( - array( - 'size_value' => '100vw', - 'mq_value' => $img_width, - 'mq_name' => 'max-width' - ), - array( - 'size_value' => $img_width - ), - ) - ); - - $args = wp_parse_args( $args, $defaults ); - - /** - * Filter arguments used to create the 'sizes' attribute value. - * - * @since 2.4.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_sizes' - * @see 'wp_get_attachment_image_sizes' - * - * @param array $args An array of arguments used to create a 'sizes' attribute. - * @param int $id Post ID of the original image. - * @param array|string $size Image size. Image size or an array of width and height - * values in pixels (in that order). - */ - $args = apply_filters( 'tevkori_image_sizes_args', $args, $id, $size ); - - // If sizes is passed as a string, just use the string. - if ( is_string( $args['sizes'] ) ) { - $size_list = $args['sizes']; - - // Otherwise, breakdown the array and build a sizes string. - } elseif ( is_array( $args['sizes'] ) ) { - - $size_list = ''; - - foreach ( $args['sizes'] as $size ) { - - // Use 100vw as the size value unless something else is specified. - $size_value = ( $size['size_value'] ) ? $size['size_value'] : '100vw'; - - // If a media length is specified, build the media query. - if ( ! empty( $size['mq_value'] ) ) { - - $media_length = $size['mq_value']; - - // Use max-width as the media condition unless min-width is specified. - $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; - - // If a media length was set, create the media query. - $media_query = '(' . $media_condition . ": " . $media_length . ') '; - - } else { - - // If no media length was set, '$media_query' is blank. - $media_query = ''; - } - - // Add to the source size list string. - $size_list .= $media_query . $size_value . ', '; - } - - // Remove the trailing comma and space from the end of the string. - $size_list = substr( $size_list, 0, -2 ); - } - - // If '$size_list' is defined set the string, otherwise set false. - return ( $size_list ) ? $size_list : false; - } else { - return wp_get_attachment_image_sizes( $size, $id ); - } -} - -/** - * Returns a 'sizes' attribute. - * - * @since 2.2.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' - * @see 'wp_get_attachment_image_sizes()' - * - * @param int $id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size, or an array of width and height - * values in pixels (in that order). Default '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 = 'medium', $args = null ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); - - if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { - $sizes = tevkori_get_sizes( $id, $size, $arg ); - } else { - $sizes = wp_get_attachment_image_sizes( $size, $id ); - } - - return $sizes ? 'sizes="' . esc_attr( $sizes ) . '"' : false; -} - if ( ! function_exists( 'wp_make_content_images_responsive' ) ) : /** * Filters 'img' elements in post content to add 'srcset' and 'sizes' attributes. @@ -623,21 +390,6 @@ function wp_make_content_images_responsive( $content ) { add_filter( 'the_content', 'wp_make_content_images_responsive', 5, 1 ); endif; -/** - * Filter to add 'srcset' and 'sizes' attributes to images in the post content. - * - * @since 2.5.0 - * @deprecated 3.0 Use 'wp_make_content_images_responsive()' - * @see 'wp_make_content_images_responsive()' - * - * @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 ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_make_content_images_responsive()' ); - return wp_make_content_images_responsive( $content ); -} - if ( ! function_exists( 'wp_image_add_srcset_and_sizes' ) ) : /** * Adds 'srcset' and 'sizes' attributes to an existing 'img' element. @@ -719,18 +471,3 @@ function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { return $image; } endif; - -/** - * Adds 'srcset' and 'sizes' attributes to image elements. - * - * @since 2.6.0 - * @deprecated 3.0 Use 'wp_image_add_srcset_and_sizes()' - * @see 'wp_image_add_srcset_and_sizes()' - * - * @param string $image An HTML 'img' element to be filtered. - * @return string Converted 'img' element with 'srcset' and 'sizes' added. - */ -function tevkori_img_add_srcset_and_sizes( $image ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_image_add_srcset_and_sizes()' ); - return wp_image_add_srcset_and_sizes( $image ); -} From 19b08d0ecd708d199716994ce6d8d8bd4573b0ee Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Fri, 30 Oct 2015 18:51:35 +0100 Subject: [PATCH 27/61] Tell phpunit about expected deprecation warnings --- tests/test-suite.php | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/test-suite.php b/tests/test-suite.php index b756f86..6ee27cd 100644 --- a/tests/test-suite.php +++ b/tests/test-suite.php @@ -63,6 +63,9 @@ private function _test_img( $file = null ) { /* OUR TESTS */ + /** + * @expectedDeprecated tevkori_get_sizes + */ function test_tevkori_get_sizes() { // make an image $id = $this->_test_img(); @@ -87,6 +90,9 @@ function test_tevkori_get_sizes() { } } + /** + * @expectedDeprecated tevkori_get_sizes + */ function test_tevkori_get_sizes_with_args() { // make an image $id = $this->_test_img(); @@ -115,6 +121,9 @@ function test_tevkori_get_sizes_with_args() { $this->assertSame($expected, $sizes); } + /** + * @expectedDeprecated tevkori_get_sizes + */ function test_filter_tevkori_get_sizes_string() { // Add our test filter. add_filter( 'tevkori_image_sizes_args', array( $this, '_test_tevkori_image_sizes_args' ) ); @@ -137,6 +146,9 @@ function _test_tevkori_image_sizes_args( $args ) { return $args; } + /** + * @expectedDeprecated tevkori_get_srcset_array + */ function test_filter_tevkori_srcset_array() { // Add test filter add_filter( 'tevkori_srcset_array', array( $this, '_test_tevkori_srcset_array' ) ); @@ -167,6 +179,10 @@ function _test_tevkori_srcset_array( $array ) { return $array; } + /** + * @expectedDeprecated tevkori_get_sizes + * @expectedDeprecated tevkori_get_sizes_string + */ function test_tevkori_get_sizes_string() { // make an image $id = $this->_test_img(); @@ -179,6 +195,9 @@ function test_tevkori_get_sizes_string() { $this->assertSame( $expected, $sizes_string); } + /** + * @expectedDeprecated tevkori_get_srcset_array + */ function test_tevkori_get_srcset_array() { // make an image $id = $this->_test_img(); @@ -198,6 +217,9 @@ function test_tevkori_get_srcset_array() { $this->assertSame( $expected, $sizes ); } + /** + * @expectedDeprecated tevkori_get_srcset_array + */ function test_tevkori_get_srcset_array_random_size_name() { // make an image $id = $this->_test_img(); @@ -217,6 +239,9 @@ function test_tevkori_get_srcset_array_random_size_name() { $this->assertSame( $expected, $sizes ); } + /** + * @expectedDeprecated tevkori_get_srcset_array + */ 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' ); @@ -242,6 +267,10 @@ function test_tevkori_get_srcset_array_no_date_upoads() { update_option( 'uploads_use_yearmonth_folders', $uploads_use_yearmonth_folders ); } + /** + * @expectedDeprecated tevkori_get_srcset + * @expectedDeprecated tevkori_get_srcset_array + */ function test_tevkori_get_srcset_single_srcset() { // make an image $id = $this->_test_img(); @@ -256,6 +285,7 @@ function test_tevkori_get_srcset_single_srcset() { /** * Test for filtering out leftover sizes after an image is edited. * @group 155 + * @expectedDeprecated tevkori_get_srcset_array */ function test_tevkori_get_srcset_array_with_edits() { // Make an image. @@ -288,6 +318,9 @@ function test_tevkori_get_srcset_array_with_edits() { } } + /** + * @expectedDeprecated tevkori_get_srcset_array + */ function test_tevkori_get_srcset_array_false() { // make an image $id = $this->_test_img(); @@ -297,6 +330,9 @@ function test_tevkori_get_srcset_array_false() { $this->assertFalse( $sizes ); } + /** + * @expectedDeprecated tevkori_get_srcset_array + */ function test_tevkori_get_srcset_array_no_width() { // Filter image_downsize() output. add_filter( 'wp_generate_attachment_metadata', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) ); @@ -321,6 +357,9 @@ public function _test_tevkori_get_srcset_array_no_width_filter( $meta ) { return $meta; } + /** + * @expectedDeprecated tevkori_get_srcset_string + */ function test_tevkori_get_srcset_string() { // make an image $id = $this->_test_img(); @@ -395,6 +434,9 @@ function test_tevkori_filter_attachment_image_attributes_thumbnails() { /** * @group 170 + * @expectedDeprecated tevkori_get_srcset_string + * @expectedDeprecated tevkori_get_sizes_string + * @expectedDeprecated tevkori_filter_content_images */ function test_tevkori_filter_content_images() { // Make image. @@ -448,6 +490,7 @@ function test_tevkori_filter_content_images() { /** * @group 170 + * @expectedDeprecated tevkori_filter_content_images */ function test_tevkori_filter_content_images_with_preexisting_srcset() { // Make image. From 8bec8df24a24a4017aa9c3177565c6c107a4f6b1 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Fri, 30 Oct 2015 18:38:29 +0100 Subject: [PATCH 28/61] Corrections in keep same behaviour for deprecated functions --- wp-tevko-deprecated-functions.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/wp-tevko-deprecated-functions.php b/wp-tevko-deprecated-functions.php index 257d999..0cc7595 100644 --- a/wp-tevko-deprecated-functions.php +++ b/wp-tevko-deprecated-functions.php @@ -17,6 +17,10 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { $srcset = wp_get_attachment_image_srcset( $id, $size ); // Transform the 'srcset' value string to a pre-core style array. + if ( ! $srcset ) { + return false; + } + $sources = explode( ', ', $srcset ); $arr = array(); @@ -59,7 +63,7 @@ function tevkori_get_srcset( $id, $size = 'medium' ) { if ( has_filter( 'tevkori_srcset_array' ) ) { $srcset_array = tevkori_get_srcset_array( $id, $size ); - return implode( ', ', $srcset_array ); + return $scrset_array ? implode( ', ', $srcset_array ) : false; } else { return wp_get_attachment_image_srcset( $id, $size ); } @@ -112,7 +116,7 @@ function tevkori_get_srcset_string( $id, $size = 'medium' ) { function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); - if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { + if ( $args || has_filter( 'tevkori_image_sizes_args' ) ) { // Try to get the image width from '$args' first. if ( is_array( $args ) && ! empty( $args['width'] ) ) { $img_width = (int) $args['width']; @@ -225,8 +229,8 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { function tevkori_get_sizes_string( $id, $size = 'medium', $args = null ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_sizes()' ); - if ( $arg || has_filter( 'tevkori_image_sizes_args' ) ) { - $sizes = tevkori_get_sizes( $id, $size, $arg ); + if ( $args || has_filter( 'tevkori_image_sizes_args' ) ) { + $sizes = tevkori_get_sizes( $id, $size, $args ); } else { $sizes = wp_get_attachment_image_sizes( $size, $id ); } From 0cb82726b38c1ad841ce510f2e7cca2f79e29176 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Fri, 30 Oct 2015 19:15:18 +0100 Subject: [PATCH 29/61] Update new core functions --- wp-tevko-deprecated-functions.php | 17 ++- wp-tevko-responsive-images.php | 233 ++++++++++++++++-------------- 2 files changed, 133 insertions(+), 117 deletions(-) diff --git a/wp-tevko-deprecated-functions.php b/wp-tevko-deprecated-functions.php index 0cc7595..b438ac5 100644 --- a/wp-tevko-deprecated-functions.php +++ b/wp-tevko-deprecated-functions.php @@ -4,7 +4,8 @@ * * @since 2.1.0 * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' - * @see 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_sizes()' + * @see 'wp_calculate_image_srcset()' * * @param int $id Image attachment ID. * @param array|string $size Image size. Accepts any valid image size, or an array of width and height @@ -34,8 +35,8 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { * Filter the output of 'tevkori_get_srcset_array()'. * * @since 2.4.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset' - * @see 'wp_get_attachment_image_srcset' + * @deprecated 3.0 Use 'wp_calculate_image_srcset' + * @see 'wp_calculate_image_srcset' * * @param array $arr An array of image sources. * @param int $id Attachment ID for image. @@ -50,7 +51,8 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { * * @since 2.3.0 * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' - * @see 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_sizes()' + * @see 'wp_calculate_image_srcset()' * * @param int $id Image attachment ID. * @param array|string $size Image size. Accepts any valid image size, or an array of width and height @@ -74,7 +76,8 @@ function tevkori_get_srcset( $id, $size = 'medium' ) { * * @since 2.1.0 * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' - * @see 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_sizes()' + * @see 'wp_calculate_image_srcset()' * * @param int $id Image attachment ID. * @param array|string $size Image size. Accepts any valid image size, or an array of width and height @@ -204,7 +207,7 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { // If '$size_list' is defined set the string, otherwise set false. return ( $size_list ) ? $size_list : false; } else { - return wp_get_attachment_image_sizes( $size, $id ); + return wp_get_attachment_image_sizes( $size, $image_meta = null, $id ); } } @@ -232,7 +235,7 @@ function tevkori_get_sizes_string( $id, $size = 'medium', $args = null ) { if ( $args || has_filter( 'tevkori_image_sizes_args' ) ) { $sizes = tevkori_get_sizes( $id, $size, $args ); } else { - $sizes = wp_get_attachment_image_sizes( $size, $id ); + $sizes = wp_get_attachment_image_sizes( $size, $image_meta = null, $id ); } return $sizes ? 'sizes="' . esc_attr( $sizes ) . '"' : false; diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 7aefc4f..cb952ce 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -48,33 +48,6 @@ function tevkori_get_picturefill() { } add_action( 'wp_enqueue_scripts', 'tevkori_get_picturefill' ); -if ( ! function_exists( 'wp_get_attachment_image_srcset' ) ) : -/** - * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. - * - * @see 'wp_get_attachment_image_attributes' - * @return array Attributes for image. - */ -function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { - // Set srcset and sizes if not already present and both were returned. - if ( empty( $attr['srcset'] ) ) { - $srcset = wp_get_attachment_image_srcset( $attachment->ID, $size ); - $sizes = wp_get_attachment_image_sizes( $size, $attachment->ID ); - - if ( $srcset && $sizes ) { - $attr['srcset'] = $srcset; - - if ( empty( $attr['sizes'] ) ) { - $attr['sizes'] = $sizes; - } - } - } - - return $attr; -} -add_filter( 'wp_get_attachment_image_attributes', 'tevkori_filter_attachment_image_attributes', 0, 3 ); -endif; - if ( ! function_exists( '_wp_upload_dir_baseurl' ) ) : /** * Caches and returns the base URL of the uploads directory. @@ -128,32 +101,89 @@ function _wp_get_image_size_from_meta( $size_name, $image_meta ) { endif; if ( ! function_exists( 'wp_get_attachment_image_srcset' ) ) : +/** + * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. + * + * @see 'wp_get_attachment_image_attributes' + * @return array Attributes for image. + */ +function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { + // Set srcset and sizes if not already present and both were returned. + if ( empty( $attr['srcset'] ) ) { + $srcset = wp_get_attachment_image_srcset( $attachment->ID, $size ); + $sizes = wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment->ID ); + + if ( $srcset && $sizes ) { + $attr['srcset'] = $srcset; + + if ( empty( $attr['sizes'] ) ) { + $attr['sizes'] = $sizes; + } + } + } + + return $attr; +} +add_filter( 'wp_get_attachment_image_attributes', 'tevkori_filter_attachment_image_attributes', 0, 3 ); + /** * Retrieves the value for an image attachment's 'srcset' attribute. * * @since 3.0.0 * * @param int $attachment_id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size name, or an array of - * width and height values in pixels (in that order). Default 'medium'. - * @param string $image_url Optional. The URL of the image. + * @param array|string $size Image size. Accepts any valid image size, or an array of width and height + * values in pixels (in that order). Default 'medium'. * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. - * @return string|bool A string of sources with their descriptor and value, - * for use as value in a 'srcset' attribute or false. + * @return string|bool A 'srcset' value string or false. */ -function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_url = null, $image_meta = null ) { - // Get the image meta data if it isn't passed as argument. +function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null ) { + if ( ! $image = wp_get_attachment_image_src( $attachment_id, $size ) ) { + return false; + } + if ( ! is_array( $image_meta ) ) { $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); } - // Bail early if image sizes info is not available. + $image_url = $image[0]; + $size_array = array( + absint( $image[1] ), + absint( $image[2] ) + ); + + return wp_calculate_image_srcset( $image_url, $size_array, $image_meta, $attachment_id ); +} +endif; + +if ( ! function_exists( 'wp_calculate_image_srcset' ) ) : +/** + * A helper function to calculate the image sources to include in a 'srcset' attribute. + * + * @since 3.0.0 + * + * @param string $image_name The file name, path, URL, or partial path or URL, of the image being matched. + * @param array $size_array Array of width and height values in pixels (in that order). + * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. + * @param int $attachment_id Optional. The image attachment ID to pass to the filter. + * @return string|bool The 'srcset' attribute value. False on error or when only one source exists. + */ +function wp_calculate_image_srcset( $image_name, $size_array, $image_meta, $attachment_id = 0 ) { if ( empty( $image_meta['sizes'] ) ) { return false; } $image_sizes = $image_meta['sizes']; + // Get the width and height of the image. + $image_width = (int) $size_array[0]; + $image_height = (int) $size_array[1]; + + // Bail early if error/no width. + if ( $image_width < 1 ) { + return false; + } + // Add full size to the '$image_sizes' array. $image_sizes['full'] = array( 'width' => $image_meta['width'], @@ -161,27 +191,8 @@ function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag 'file' => wp_basename( $image_meta['file'] ), ); - // Get the width and height of the image. - if ( is_array( $size ) ) { - $size_array = $size; - $image_width = absint( $size[0] ); - $image_height = absint( $size[1] ); - } elseif ( is_string( $size ) ) { - $size_array = _wp_get_image_size_from_meta( $size, $image_meta ); - $image_width = $size_array[0]; - $image_height = $size_array[1]; - } else { - return false; - } - - // Bail early if the image has no width. - if ( $image_width < 1 ) { - return false; - } - - // Get the image base URL and directory. $image_baseurl = _wp_upload_dir_baseurl(); - $dirname = dirname( $image_meta['file'] ); + $dirname = dirname( $image_meta['file'] ); if ( $dirname !== '.' ) { $image_baseurl = path_join( $image_baseurl, $dirname ); @@ -190,28 +201,17 @@ function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag // Calculate the image aspect ratio. $image_ratio = $image_height / $image_width; - // Get the image URL if it's not passed as argument. - if ( ! $image_url ) { - $image = wp_get_attachment_image_src( $attachment_id, $size ); - - if ( ! $image ) { - return false; - } - - $image_url = $image[0]; - } - /* * Images that have been edited in WordPress after being uploaded will * contain a unique hash. Look for that hash and use it later to filter * out images that are leftovers from previous versions. */ - $image_edited = preg_match( '/-e[0-9]{13}/', $image_url, $image_edit_hash ); + $image_edited = preg_match( '/-e[0-9]{13}/', $image_name, $image_edit_hash ); /** * Filter the maximum image width to be included in a 'srcset' attribute. * - * @since 3.0.0 + * @since 4.4.0 * * @param int $max_width The maximum image width to be included in the 'srcset'. Default '1600'. * @param array $size_array Array of width and height values in pixels (in that order). @@ -226,6 +226,7 @@ function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag * versions of the same edit. */ foreach ( $image_sizes as $image ) { + // Filter out images that are from previous edits. if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) { continue; @@ -250,32 +251,39 @@ function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag // Add the URL, descriptor, and value to the sources array to be returned. $sources[ $image['width'] ] = array( 'url' => path_join( $image_baseurl, $candidate_url ), - 'value' => $image['width'], 'descriptor' => 'w', + 'value' => $image['width'], ); } } /** - * Filter the array used to create the 'srcset' value string. + * Filter the output of 'wp_calculate_image_srcset()'. * * @since 3.0.0 * - * @param array $sources An array of image URLs, values, and descriptors. - * @param int $attachment_id Image attachment ID. - * @param array|string $size Image size. Image size name, or an array of width and height - * values in pixels (in that order). - * @param string $image_url The URL of the image. - * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. + * @param array $sources An array of sources to include in the 'srcset'. Each source + * consists of an array containing the URL and the descriptor + * type and value (default: the image width): + * + * image width => array( + * 'url' => string, + * 'descriptor' => string ('w' or 'x'), + * 'value' => integer (width or pixel density) + * }, + * + * @param int $attachment_id Image attachment ID. + * @param array $size_array Array of width and height values in pixels (in that order). + * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. + */ - $sources = apply_filters( 'wp_get_attachment_image_srcset', array_values( $sources ), $attachment_id, $size, $image_url, $image_meta ); + $sources = apply_filters( 'wp_calculate_image_srcset', $sources, $attachment_id, $size_array, $image_meta ); // Only return a 'srcset' value if there is more than one source. if ( count( $sources ) < 2 ) { return false; } - // Create the 'srcset' value string. $srcset = ''; foreach ( $sources as $source ) { @@ -288,33 +296,38 @@ function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag if ( ! function_exists( 'wp_get_attachment_image_sizes' ) ) : /** - * Retrieves the value for an image attachment's 'sizes' attribute. + * Create 'sizes' attribute value for an image. * * @since 3.0.0 * - * @param array|string $size Image size. Accepts any valid image size name, or an array of - * width and height values in pixels (in that order). Default 'medium'. - * @param int $attachment_id Optional. Image attachment ID. Required if `$size` is an image size name - * and `$image_meta` is omited. Otherwise used to pass to the filter. + * @param array|string $size Image size. Accepts any valid image size name ('thumbnail', 'medium', etc.), + * or an array of width and height values in pixels (in that order). * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. - * @return string|bool A string of size values for use as value in a 'sizes' attribute or false. + * @param int $attachment_id Optional. Image attachment ID. Either `$image_meta` or `$attachment_id` is needed + * when using the image size name as argument for `$size`. + * @param string $image_url Optional. The URL to the image file. + * + * @return string|bool A valid source size value for use in a 'sizes' attribute or false. */ -function wp_get_attachment_image_sizes( $size = 'medium', $attachment_id = 0, $image_meta = null ) { +function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_id = 0, $image_url = null ) { $width = 0; if ( is_array( $size ) ) { $width = absint( $size[0] ); } elseif ( is_string( $size ) ) { if ( ! $image_meta && $attachment_id ) { - $image_meta = wp_get_attachment_metadata( $attachment_id ); + $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); } + if ( is_array( $image_meta ) ) { $size_array = _wp_get_image_size_from_meta( $size, $image_meta ); if ( $size_array ) { - $width = $size_array[0]; + $width = absint( $size_array[0] ); } } - } else { + } + + if ( ! $width ) { return false; } @@ -327,13 +340,13 @@ function wp_get_attachment_image_sizes( $size = 'medium', $attachment_id = 0, $i * @since 3.0.0 * * @param string $sizes A source size value for use in a 'sizes' attribute. - * @param array|string $size Image size name, or an array of width and height + * @param array|string $size Image size. Image size name, or an array of width and height * values in pixels (in that order). - * @param int $attachment_id Image attachment ID of the original image, or 0. - * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()', - * or null. + * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. + * @param int $attachment_id Image attachment ID of the original image. + * @param string $image_url Optional. The URL to the image file. */ - return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $size, $attachment_id, $image_meta ); + return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $size, $image_meta, $attachment_id, $image_url ); } endif; @@ -348,7 +361,7 @@ function wp_get_attachment_image_sizes( $size = 'medium', $attachment_id = 0, $i * @param string $content The raw post content to be filtered. * @return string Converted content with 'srcset' and 'sizes' attributes added to images. */ - function wp_make_content_images_responsive( $content ) { +function wp_make_content_images_responsive( $content ) { $images = get_media_embedded_in_content( $content, 'img' ); $selected_images = $attachment_ids = array(); @@ -404,61 +417,61 @@ function wp_make_content_images_responsive( $content ) { * @param int $attachment_id Image attachment ID. * @return string Converted 'img' element with 'srcset' and 'sizes' attributes added. */ - function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { +function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { // Ensure the image meta exists. if ( empty( $image_meta['sizes'] ) ) { return $image; } $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : ''; - list( $image_url ) = explode( '?', $src ); + list( $src ) = explode( '?', $src ); // Return early if we couldn't get the image source. - if ( ! $image_url ) { + if ( ! $src ) { return $image; } // Bail early if an image has been inserted and later edited. if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) && - strpos( wp_basename( $image_url ), $img_edit_hash[0] ) === false ) { + strpos( wp_basename( $src ), $img_edit_hash[0] ) === false ) { return $image; } - $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? absint( $match_width[1] ) : 0; - $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? absint( $match_height[1] ) : 0; + $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? (int) $match_width[1] : 0; + $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0; if ( ! $width || ! $height ) { /* * If attempts to parse the size value failed, attempt to use the image meta data to match * the image file name from 'src' against the available sizes for an attachment. */ - $image_filename = wp_basename( $image_url ); + $image_filename = wp_basename( $src ); if ( $image_filename === wp_basename( $image_meta['file'] ) ) { - $width = absint( $image_meta['width'] ); - $height = absint( $image_meta['height'] ); + $width = (int) $image_meta['width']; + $height = (int) $image_meta['height']; } else { foreach( $image_meta['sizes'] as $image_size_data ) { if ( $image_filename === $image_size_data['file'] ) { - $width = absint( $image_size_data['width'] ); - $height = absint( $image_size_data['height'] ); + $width = (int) $image_size_data['width']; + $height = (int) $image_size_data['height']; break; } } } } - // Return if we don't have a width or height. if ( ! $width || ! $height ) { return $image; } $size_array = array( $width, $height ); + $srcset = wp_calculate_image_srcset( $src, $size_array, $image_meta, $attachment_id ); - // Get the 'srcset' and 'sizes' values. - $srcset = wp_get_attachment_image_srcset( $attachment_id, $size_array, $image_url, $image_meta ); - $sizes = wp_get_attachment_image_sizes( $size_array, $attachment_id, $image_meta ); + if ( $srcset ) { + $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id, $src ); + } if ( $srcset && $sizes ) { // Format the 'srcset' and 'sizes' string and escape attributes. @@ -469,5 +482,5 @@ function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { } return $image; - } +} endif; From f255522a5c20283738da3dce75e6c563c07bfab4 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Mon, 2 Nov 2015 14:18:17 +0100 Subject: [PATCH 30/61] Correction of size name in unit test --- tests/test-suite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-suite.php b/tests/test-suite.php index 6ee27cd..9ebc9fe 100644 --- a/tests/test-suite.php +++ b/tests/test-suite.php @@ -363,7 +363,7 @@ public function _test_tevkori_get_srcset_array_no_width_filter( $meta ) { function test_tevkori_get_srcset_string() { // make an image $id = $this->_test_img(); - $sizes = tevkori_get_srcset_string( $id, 'full-size' ); + $sizes = tevkori_get_srcset_string( $id, 'full' ); $image = wp_get_attachment_metadata( $id ); $year_month = date('Y/m'); From fc61ccc8d19f8dc94dafff7e875c43993e6d3a98 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Mon, 2 Nov 2015 20:44:31 +0100 Subject: [PATCH 31/61] Make tevkori_get_sizes no longer constrain the image width --- wp-tevko-deprecated-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wp-tevko-deprecated-functions.php b/wp-tevko-deprecated-functions.php index b438ac5..e2dd9e5 100644 --- a/wp-tevko-deprecated-functions.php +++ b/wp-tevko-deprecated-functions.php @@ -124,7 +124,7 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { if ( is_array( $args ) && ! empty( $args['width'] ) ) { $img_width = (int) $args['width']; } elseif ( $img = image_get_intermediate_size( $id, $size ) ) { - list( $img_width, $img_height ) = image_constrain_size_for_editor( $img['width'], $img['height'], $size ); + $img_width = $img['width']; } // Bail early if '$img_width' isn't set. From 9e5705197df7a1ce6b67dc7bddc230ffcb1601a7 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Mon, 2 Nov 2015 20:45:43 +0100 Subject: [PATCH 32/61] Update sizes test to no longer expect all image widths to be constrained --- tests/test-suite.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/test-suite.php b/tests/test-suite.php index 9ebc9fe..c474b64 100644 --- a/tests/test-suite.php +++ b/tests/test-suite.php @@ -78,11 +78,6 @@ function test_tevkori_get_sizes() { foreach( $intermediates as $int ) { $width = get_option( $int . '_size_w' ); - // the sizes width gets constrained to $content_width by default - if ( $content_width > 0 ) { - $width = ( $width > $content_width ) ? $content_width : $width; - } - $expected = '(max-width: ' . $width . 'px) 100vw, ' . $width . 'px'; $sizes = tevkori_get_sizes( $id, $int ); From afdf5a4254359a506fefdde03403c8ce1c55ea2d Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Mon, 2 Nov 2015 17:23:02 +0100 Subject: [PATCH 33/61] Coding standards and inline docs corrections of test suite --- tests/test-suite.php | 141 ++++++++++++++++++++++--------------------- 1 file changed, 72 insertions(+), 69 deletions(-) diff --git a/tests/test-suite.php b/tests/test-suite.php index c474b64..b99027e 100644 --- a/tests/test-suite.php +++ b/tests/test-suite.php @@ -15,24 +15,24 @@ function tearDown() { private function _make_attachment( $upload, $parent_post_id = 0 ) { $type = ''; - if ( !empty($upload['type']) ) { + if ( ! empty($upload['type'] ) ) { $type = $upload['type']; } else { $mime = wp_check_filetype( $upload['file'] ); - if ($mime) + if ( $mime ) $type = $mime['type']; } $attachment = array( - 'post_title' => basename( $upload['file'] ), - 'post_content' => '', - 'post_type' => 'attachment', - 'post_parent' => $parent_post_id, + 'post_title' => basename( $upload['file'] ), + 'post_content' => '', + 'post_type' => 'attachment', + 'post_parent' => $parent_post_id, 'post_mime_type' => $type, - 'guid' => $upload[ 'url' ], + 'guid' => $upload[ 'url' ], ); - // Save the data + // Save the data. $id = wp_insert_attachment( $attachment, $upload[ 'file' ], $parent_post_id ); wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) ); @@ -41,22 +41,21 @@ private function _make_attachment( $upload, $parent_post_id = 0 ) { } /** - * Helper function to create an attachment from a file + * Helper function to create an attachment from a file. * * @uses _make_attachment * - * @param string Optional. A path to a file. Default: DIR_TESTDATA.'/images/canola.JPG'. - * @return int|bool An attachment ID or false. + * @param string Optional. A path to a file. Default: DIR_TESTDATA.'/images/canola.JPG'. + * @return int|bool An attachment ID or false. */ private function _test_img( $file = null ) { - $filename = $file ? $file : ( dirname(__FILE__) . '/data/test-large.png' ); - $contents = file_get_contents($filename); + $contents = file_get_contents( $filename ); + $upload = wp_upload_bits( basename( $filename ), null, $contents ); - $upload = wp_upload_bits(basename($filename), null, $contents); - $this->assertTrue( empty($upload['error']) ); + $this->assertTrue( empty( $upload['error'] ) ); - $id = $this->_make_attachment($upload); + $id = $this->_make_attachment( $upload ); return $id; } @@ -67,13 +66,13 @@ private function _test_img( $file = null ) { * @expectedDeprecated tevkori_get_sizes */ function test_tevkori_get_sizes() { - // make an image + // Make an image. $id = $this->_test_img(); global $content_width; - // test sizes against the default WP sizes - $intermediates = array('thumbnail', 'medium', 'large'); + // Test sizes against the default WP sizes. + $intermediates = array( 'thumbnail', 'medium', 'large' ); foreach( $intermediates as $int ) { $width = get_option( $int . '_size_w' ); @@ -81,7 +80,7 @@ function test_tevkori_get_sizes() { $expected = '(max-width: ' . $width . 'px) 100vw, ' . $width . 'px'; $sizes = tevkori_get_sizes( $id, $int ); - $this->assertSame($expected, $sizes); + $this->assertSame( $expected, $sizes ); } } @@ -89,23 +88,23 @@ function test_tevkori_get_sizes() { * @expectedDeprecated tevkori_get_sizes */ function test_tevkori_get_sizes_with_args() { - // make an image + // Make an image. $id = $this->_test_img(); $args = array( 'sizes' => array( array( - 'size_value' => '10em', - 'mq_value' => '60em', - 'mq_name' => 'min-width' + 'size_value' => '10em', + 'mq_value' => '60em', + 'mq_name' => 'min-width' ), array( - 'size_value' => '20em', - 'mq_value' => '30em', - 'mq_name' => 'min-width' + 'size_value' => '20em', + 'mq_value' => '30em', + 'mq_name' => 'min-width' ), array( - 'size_value' => 'calc(100vm - 30px)' + 'size_value' => 'calc(100vm - 30px)' ), ) ); @@ -113,7 +112,7 @@ function test_tevkori_get_sizes_with_args() { $expected = '(min-width: 60em) 10em, (min-width: 30em) 20em, calc(100vm - 30px)'; $sizes = tevkori_get_sizes( $id, 'medium', $args ); - $this->assertSame($expected, $sizes); + $this->assertSame( $expected, $sizes ); } /** @@ -125,10 +124,10 @@ function test_filter_tevkori_get_sizes_string() { // Set up our test. $id = $this->_test_img(); - $sizes = tevkori_get_sizes($id, 'medium'); + $sizes = tevkori_get_sizes( $id, 'medium' ); // Evaluate that the sizes returned is what we expected. - $this->assertSame( $sizes, '100vm'); + $this->assertSame( $sizes, '100vm' ); remove_filter( 'tevkori_image_sizes_args', array( $this, '_test_tevkori_image_sizes_args' ) ); } @@ -145,30 +144,30 @@ function _test_tevkori_image_sizes_args( $args ) { * @expectedDeprecated tevkori_get_srcset_array */ function test_filter_tevkori_srcset_array() { - // Add test filter + // Add test filter. add_filter( 'tevkori_srcset_array', array( $this, '_test_tevkori_srcset_array' ) ); // Set up our test. $id = $this->_test_img(); - $sizes = tevkori_get_srcset_array($id, 'medium'); + $sizes = tevkori_get_srcset_array( $id, 'medium' ); // Evaluate that the sizes returned is what we expected. foreach( $sizes as $width => $source ) { $this->assertTrue( $width <= 500 ); } - // Remove test filter + // Remove test filter. remove_filter( 'tevkori_srcset_array', array( $this, '_test_tevkori_srcset_array' ) ); } /** * A test filter for tevkori_get_srcset_array() that removes any sources - * that are larger that 500px wide. + * that are larger than 500px wide. */ function _test_tevkori_srcset_array( $array ) { foreach ( $array as $size => $file ) { if ( $size > 500 ) { - unset( $array[$size] ); + unset( $array[ $size ] ); } } return $array; @@ -179,25 +178,25 @@ function _test_tevkori_srcset_array( $array ) { * @expectedDeprecated tevkori_get_sizes_string */ function test_tevkori_get_sizes_string() { - // make an image + // Make an image. $id = $this->_test_img(); - $sizes = tevkori_get_sizes($id, 'medium'); + $sizes = tevkori_get_sizes( $id, 'medium' ); $sizes_string = tevkori_get_sizes_string( $id, 'medium' ); $expected = 'sizes="' . $sizes . '"'; - $this->assertSame( $expected, $sizes_string); + $this->assertSame( $expected, $sizes_string ); } /** * @expectedDeprecated tevkori_get_srcset_array */ function test_tevkori_get_srcset_array() { - // make an image + // Make an image. $id = $this->_test_img(); - $sizes = tevkori_get_srcset_array( $id, 'medium' ); + $sizes = tevkori_get_srcset_array( $id, 'medium' ); $year_month = date('Y/m'); $image = wp_get_attachment_metadata( $id ); @@ -216,10 +215,10 @@ function test_tevkori_get_srcset_array() { * @expectedDeprecated tevkori_get_srcset_array */ function test_tevkori_get_srcset_array_random_size_name() { - // make an image + // Make an image. $id = $this->_test_img(); - $sizes = tevkori_get_srcset_array( $id, 'foo' ); + $sizes = tevkori_get_srcset_array( $id, 'foo' ); $year_month = date('Y/m'); $image = wp_get_attachment_metadata( $id ); @@ -238,16 +237,15 @@ function test_tevkori_get_srcset_array_random_size_name() { * @expectedDeprecated tevkori_get_srcset_array */ function test_tevkori_get_srcset_array_no_date_upoads() { - // Save the current setting for uploads folders + // Save the current setting for uploads folders. $uploads_use_yearmonth_folders = get_option( 'uploads_use_yearmonth_folders' ); - // Disable date organized uploads + // Disable date organized uploads. update_option( 'uploads_use_yearmonth_folders', 0 ); - // make an image + // Make an image. $id = $this->_test_img(); $sizes = tevkori_get_srcset_array( $id, 'medium' ); - $image = wp_get_attachment_metadata( $id ); $expected = array( @@ -267,10 +265,12 @@ function test_tevkori_get_srcset_array_no_date_upoads() { * @expectedDeprecated tevkori_get_srcset_array */ function test_tevkori_get_srcset_single_srcset() { - // make an image + // Make an image. $id = $this->_test_img(); - // In our tests, thumbnails would only return a single srcset candidate, - // in which case we don't bother returning a srcset array. + /* + * In our tests, thumbnails would only return a single srcset candidate, + * in which case we don't bother returning a srcset array. + */ $sizes = tevkori_get_srcset( $id, 'thumbnail' ); $this->assertTrue( 1 === count( tevkori_get_srcset_array( $id, 'thumbnail' ) ) ); @@ -286,8 +286,10 @@ function test_tevkori_get_srcset_array_with_edits() { // Make an image. $id = $this->_test_img(); - // For this test we're going to mock metadata changes from an edit. - // Start by getting the attachment metadata. + /* + * For this test we're going to mock metadata changes from an edit. + * Start by getting the attachment metadata. + */ $meta = wp_get_attachment_metadata( $id ); // Mimick hash generation method used in wp_save_image(). @@ -317,11 +319,11 @@ function test_tevkori_get_srcset_array_with_edits() { * @expectedDeprecated tevkori_get_srcset_array */ function test_tevkori_get_srcset_array_false() { - // make an image + // Make an image. $id = $this->_test_img(); $sizes = tevkori_get_srcset_array( 99999, 'foo' ); - // For canola.jpg we should return + // For canola.jpg we should return. $this->assertFalse( $sizes ); } @@ -329,14 +331,15 @@ function test_tevkori_get_srcset_array_false() { * @expectedDeprecated tevkori_get_srcset_array */ function test_tevkori_get_srcset_array_no_width() { - // Filter image_downsize() output. + // Filter wp_generate_attachment_metadata() output. add_filter( 'wp_generate_attachment_metadata', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) ); - // Make our attachement. + // Make our attachment. $id = $this->_test_img(); + $srcset = tevkori_get_srcset_array( $id, 'medium' ); - // The srcset should be false + // The srcset should be false. $this->assertFalse( $srcset ); // Remove filter. @@ -344,7 +347,7 @@ function test_tevkori_get_srcset_array_no_width() { } /** - * Helper funtion to filter image_downsize and return zero values for width and height. + * Helper funtion to filter wp_generate_attachment_metadata and return zero values for width and height. */ public function _test_tevkori_get_srcset_array_no_width_filter( $meta ) { $meta['sizes']['medium']['width'] = 0; @@ -356,10 +359,10 @@ public function _test_tevkori_get_srcset_array_no_width_filter( $meta ) { * @expectedDeprecated tevkori_get_srcset_string */ function test_tevkori_get_srcset_string() { - // make an image + // Make an image. $id = $this->_test_img(); - $sizes = tevkori_get_srcset_string( $id, 'full' ); + $sizes = tevkori_get_srcset_string( $id, 'full' ); $image = wp_get_attachment_metadata( $id ); $year_month = date('Y/m'); @@ -377,13 +380,13 @@ function test_tevkori_get_srcset_string() { * @group 159 */ function test_tevkori_filter_attachment_image_attributes() { - // Make image. + // Make an image. $id = $this->_test_img(); // Get attachment post data. $attachment = get_post( $id ); $image = wp_get_attachment_image_src( $id, 'medium' ); - list($src, $width, $height) = $image; + list( $src, $width, $height ) = $image; // Create dummy attributes array. $attr = array( @@ -404,13 +407,13 @@ function test_tevkori_filter_attachment_image_attributes() { * @group 159 */ function test_tevkori_filter_attachment_image_attributes_thumbnails() { - // Make image. + // Make an image. $id = $this->_test_img(); // Get attachment post data. $attachment = get_post( $id ); $image = wp_get_attachment_image_src( $id, 'thumbnail' ); - list($src, $width, $height) = $image; + list( $src, $width, $height ) = $image; // Create dummy attributes array. $attr = array( @@ -434,7 +437,7 @@ function test_tevkori_filter_attachment_image_attributes_thumbnails() { * @expectedDeprecated tevkori_filter_content_images */ function test_tevkori_filter_content_images() { - // Make image. + // Make an image. $id = $this->_test_img(); $srcset = tevkori_get_srcset_string( $id, 'medium' ); @@ -445,9 +448,9 @@ function test_tevkori_filter_content_images() { $img_no_size = str_replace( 'size-', '', $img ); $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); + // Manually add srcset and sizes to the markup from get_image_tag(). + $respimg = preg_replace('|]+) />|', '', $img ); + $respimg_no_size = preg_replace('|]+) />|', '', $img_no_size ); $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:

@@ -488,7 +491,7 @@ function test_tevkori_filter_content_images() { * @expectedDeprecated tevkori_filter_content_images */ function test_tevkori_filter_content_images_with_preexisting_srcset() { - // Make image. + // Make an image. $id = $this->_test_img(); // Generate HTML and add a dummy srcset attribute. From 2f982ee97cb8257f0146a7f791c0d8d6265bccc1 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Tue, 3 Nov 2015 13:01:07 +0100 Subject: [PATCH 34/61] Update the no-width test --- tests/test-suite.php | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/tests/test-suite.php b/tests/test-suite.php index b99027e..9ba3ef6 100644 --- a/tests/test-suite.php +++ b/tests/test-suite.php @@ -331,28 +331,48 @@ function test_tevkori_get_srcset_array_false() { * @expectedDeprecated tevkori_get_srcset_array */ function test_tevkori_get_srcset_array_no_width() { - // Filter wp_generate_attachment_metadata() output. - add_filter( 'wp_generate_attachment_metadata', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) ); + // Filter wp_get_attachment_image_src() output. + add_filter( 'wp_get_attachment_image_src', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) ); // Make our attachment. $id = $this->_test_img(); - $srcset = tevkori_get_srcset_array( $id, 'medium' ); + /* + * 'tevkori_get_srcset_array()' calls `wp_get_attachment_image_srcset()` which uses + * `wp_get_attachment_image_src()` to get the image size. + * To manipulate the image size for this test we have to use the `wp_get_attachment_image_src` filter, + * but this was only introduced in WP 4.3. + * When testing against older WordPress versions we test 'wp_calculate_image_srcset()' instead. + */ + if ( has_filter( 'wp_get_attachment_image_src', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) ) ) { + $srcset = tevkori_get_srcset_array( $id, 'medium' ); + + // The srcset should be false. + $this->assertFalse( $srcset ); + } else { + // This function call is only because PHPUnit expects a deprecation warning. + $ignore = tevkori_get_srcset_array( $id, 'medium' ); + + $size_array = array( 0, 0 ); + $image_meta = wp_get_attachment_metadata( $id ); + $image_name = $image_meta['file']; + $srcset = wp_calculate_image_srcset( $image_name, $size_array, $image_meta ); - // The srcset should be false. - $this->assertFalse( $srcset ); + // The srcset should be false. + $this->assertFalse( $srcset ); + } // Remove filter. - remove_filter( 'wp_generate_attachment_metadata', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) ); + remove_filter( 'wp_get_attachment_image_src', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) ); } /** - * Helper funtion to filter wp_generate_attachment_metadata and return zero values for width and height. + * Helper funtion to filter wp_get_attachment_image_src and return zero values for width and height. */ - public function _test_tevkori_get_srcset_array_no_width_filter( $meta ) { - $meta['sizes']['medium']['width'] = 0; - $meta['sizes']['medium']['height'] = 0; - return $meta; + public function _test_tevkori_get_srcset_array_no_width_filter( $image ) { + $image[1] = 0; + $image[2] = 0; + return $image; } /** From 9b540e287ac2cb8f958b2e37bda0e2dc69aaf319 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Tue, 3 Nov 2015 15:20:39 +0100 Subject: [PATCH 35/61] Removed tevkori_img_add_srcset_and_sizes We don't do a 2.6.0 release so we don't need to deprecate this function. --- wp-tevko-deprecated-functions.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/wp-tevko-deprecated-functions.php b/wp-tevko-deprecated-functions.php index e2dd9e5..518ee5c 100644 --- a/wp-tevko-deprecated-functions.php +++ b/wp-tevko-deprecated-functions.php @@ -255,18 +255,3 @@ function tevkori_filter_content_images( $content ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_make_content_images_responsive()' ); return wp_make_content_images_responsive( $content ); } - -/** - * Adds 'srcset' and 'sizes' attributes to image elements. - * - * @since 2.6.0 - * @deprecated 3.0 Use 'wp_image_add_srcset_and_sizes()' - * @see 'wp_image_add_srcset_and_sizes()' - * - * @param string $image An HTML 'img' element to be filtered. - * @return string Converted 'img' element with 'srcset' and 'sizes' added. - */ -function tevkori_img_add_srcset_and_sizes( $image ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_image_add_srcset_and_sizes()' ); - return wp_image_add_srcset_and_sizes( $image ); -} From d10aad1d760581ad41920fefc2e622957c7ba889 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Tue, 3 Nov 2015 13:09:09 +0100 Subject: [PATCH 36/61] Add WordPress 4.3 to Travis --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 0029787..6306ea7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,8 @@ php: env: - WP_VERSION=latest WP_MULTISITE=0 - WP_VERSION=latest WP_MULTISITE=1 + - WP_VERSION=4.3 WP_MULTISITE=0 + - WP_VERSION=4.3 WP_MULTISITE=1 - WP_VERSION=4.2 WP_MULTISITE=0 - WP_VERSION=4.2 WP_MULTISITE=1 - WP_VERSION=4.1 WP_MULTISITE=0 From 994b876f07b2d47044737eac041529fd510c80c0 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 3 Nov 2015 07:14:54 -0600 Subject: [PATCH 37/61] Update install-wp-tests.sh and .travix.yml The old version of the install-wp-tests.sh script would only install the latest stable version. This update uses the latest template from WP-CLI, which includes support for testing against trunk. --- .travis.yml | 4 ++-- bin/install-wp-tests.sh | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6306ea7..bff1f9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,8 @@ php: - 7.0 env: - - WP_VERSION=latest WP_MULTISITE=0 - - WP_VERSION=latest WP_MULTISITE=1 + - WP_VERSION=trunk WP_MULTISITE=0 + - WP_VERSION=trunk WP_MULTISITE=1 - WP_VERSION=4.3 WP_MULTISITE=0 - WP_VERSION=4.3 WP_MULTISITE=1 - WP_VERSION=4.2 WP_MULTISITE=0 diff --git a/bin/install-wp-tests.sh b/bin/install-wp-tests.sh index 0aaf09f..5baa6cb 100755 --- a/bin/install-wp-tests.sh +++ b/bin/install-wp-tests.sh @@ -24,6 +24,8 @@ download() { if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then WP_TESTS_TAG="tags/$WP_VERSION" +elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + WP_TESTS_TAG="trunk" else # http serves a single offer, whereas https serves multiple. we only want one download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json @@ -46,15 +48,21 @@ install_wp() { mkdir -p $WP_CORE_DIR - if [ $WP_VERSION == 'latest' ]; then - local ARCHIVE_NAME='latest' + if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + mkdir -p /tmp/wordpress-nightly + download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip + unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/ + mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR else - local ARCHIVE_NAME="wordpress-$WP_VERSION" + if [ $WP_VERSION == 'latest' ]; then + local ARCHIVE_NAME='latest' + else + local ARCHIVE_NAME="wordpress-$WP_VERSION" + fi + download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz + tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR fi - download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR - download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php } From bb390f2c434500f3c463cca4359bb4e6656f8f7d Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 3 Nov 2015 08:28:20 -0600 Subject: [PATCH 38/61] Fix collision with _make_attachment() method in 4.4 This changes the name of our helper function, `_make_attachment()` to `create_upload_object` to avoid a name collision with a public method introduced to the `WP_UnitTestCase` class during the 4.4 cycle. I also mimicked the test performance improvements in core that uses a single upload for all the tests, where applicable so that we don't have the overhead of uploading an image during each test. Finally, this changes the main class name for our tests to `RICG_Responsive_Images_Tests`. --- tests/test-suite.php | 94 +++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 53 deletions(-) diff --git a/tests/test-suite.php b/tests/test-suite.php index 9ba3ef6..1f425eb 100644 --- a/tests/test-suite.php +++ b/tests/test-suite.php @@ -1,20 +1,25 @@ remove_added_uploads(); - parent::tearDown(); + protected static $large_id; + + protected static $test_file_name; + + public static function setUpBeforeClass() { + self::$test_file_name = dirname(__FILE__) . '/data/test-large.png'; + self::$large_id = self::create_upload_object( self::$test_file_name ); } - /** - * Helper function that creates an attachment in the DB. - * Copied from Tests_Post_Attachments Class in the WP Core test suite. - */ - private function _make_attachment( $upload, $parent_post_id = 0 ) { + public static function tearDownAfterClass() { + wp_delete_attachment( self::$large_id ); + } + public static function create_upload_object( $filename, $parent = 0 ) { + $contents = file_get_contents($filename); + $upload = wp_upload_bits(basename($filename), null, $contents); $type = ''; + if ( ! empty($upload['type'] ) ) { $type = $upload['type']; } else { @@ -27,36 +32,15 @@ private function _make_attachment( $upload, $parent_post_id = 0 ) { 'post_title' => basename( $upload['file'] ), 'post_content' => '', 'post_type' => 'attachment', - 'post_parent' => $parent_post_id, + 'post_parent' => $parent, 'post_mime_type' => $type, 'guid' => $upload[ 'url' ], ); // Save the data. - $id = wp_insert_attachment( $attachment, $upload[ 'file' ], $parent_post_id ); + $id = wp_insert_attachment( $attachment, $upload[ 'file' ], $parent ); wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) ); - return $this->ids[] = $id; - - } - - /** - * Helper function to create an attachment from a file. - * - * @uses _make_attachment - * - * @param string Optional. A path to a file. Default: DIR_TESTDATA.'/images/canola.JPG'. - * @return int|bool An attachment ID or false. - */ - private function _test_img( $file = null ) { - $filename = $file ? $file : ( dirname(__FILE__) . '/data/test-large.png' ); - $contents = file_get_contents( $filename ); - $upload = wp_upload_bits( basename( $filename ), null, $contents ); - - $this->assertTrue( empty( $upload['error'] ) ); - - $id = $this->_make_attachment( $upload ); - return $id; } @@ -67,7 +51,7 @@ private function _test_img( $file = null ) { */ function test_tevkori_get_sizes() { // Make an image. - $id = $this->_test_img(); + $id = self::$large_id; global $content_width; @@ -89,7 +73,7 @@ function test_tevkori_get_sizes() { */ function test_tevkori_get_sizes_with_args() { // Make an image. - $id = $this->_test_img(); + $id = self::$large_id; $args = array( 'sizes' => array( @@ -123,8 +107,8 @@ function test_filter_tevkori_get_sizes_string() { add_filter( 'tevkori_image_sizes_args', array( $this, '_test_tevkori_image_sizes_args' ) ); // Set up our test. - $id = $this->_test_img(); - $sizes = tevkori_get_sizes( $id, 'medium' ); + $id = self::$large_id; + $sizes = tevkori_get_sizes($id, 'medium'); // Evaluate that the sizes returned is what we expected. $this->assertSame( $sizes, '100vm' ); @@ -148,8 +132,8 @@ function test_filter_tevkori_srcset_array() { add_filter( 'tevkori_srcset_array', array( $this, '_test_tevkori_srcset_array' ) ); // Set up our test. - $id = $this->_test_img(); - $sizes = tevkori_get_srcset_array( $id, 'medium' ); + $id = self::$large_id; + $sizes = tevkori_get_srcset_array($id, 'medium'); // Evaluate that the sizes returned is what we expected. foreach( $sizes as $width => $source ) { @@ -179,7 +163,7 @@ function _test_tevkori_srcset_array( $array ) { */ function test_tevkori_get_sizes_string() { // Make an image. - $id = $this->_test_img(); + $id = self::$large_id; $sizes = tevkori_get_sizes( $id, 'medium' ); $sizes_string = tevkori_get_sizes_string( $id, 'medium' ); @@ -193,8 +177,9 @@ function test_tevkori_get_sizes_string() { * @expectedDeprecated tevkori_get_srcset_array */ function test_tevkori_get_srcset_array() { - // Make an image. - $id = $this->_test_img(); + // make an image + $id = self::$large_id; + $sizes = tevkori_get_srcset_array( $id, 'medium' ); $sizes = tevkori_get_srcset_array( $id, 'medium' ); $year_month = date('Y/m'); @@ -216,7 +201,8 @@ function test_tevkori_get_srcset_array() { */ function test_tevkori_get_srcset_array_random_size_name() { // Make an image. - $id = $this->_test_img(); + $id = self::$large_id; + $sizes = tevkori_get_srcset_array( $id, 'foo' ); $sizes = tevkori_get_srcset_array( $id, 'foo' ); $year_month = date('Y/m'); @@ -244,7 +230,7 @@ function test_tevkori_get_srcset_array_no_date_upoads() { update_option( 'uploads_use_yearmonth_folders', 0 ); // Make an image. - $id = $this->_test_img(); + $id = self::create_upload_object( self::$test_file_name ); $sizes = tevkori_get_srcset_array( $id, 'medium' ); $image = wp_get_attachment_metadata( $id ); @@ -266,7 +252,7 @@ function test_tevkori_get_srcset_array_no_date_upoads() { */ function test_tevkori_get_srcset_single_srcset() { // Make an image. - $id = $this->_test_img(); + $id = self::$large_id; /* * In our tests, thumbnails would only return a single srcset candidate, * in which case we don't bother returning a srcset array. @@ -284,7 +270,7 @@ function test_tevkori_get_srcset_single_srcset() { */ function test_tevkori_get_srcset_array_with_edits() { // Make an image. - $id = $this->_test_img(); + $id = self::$large_id; /* * For this test we're going to mock metadata changes from an edit. @@ -320,7 +306,7 @@ function test_tevkori_get_srcset_array_with_edits() { */ function test_tevkori_get_srcset_array_false() { // Make an image. - $id = $this->_test_img(); + $id = self::$large_id; $sizes = tevkori_get_srcset_array( 99999, 'foo' ); // For canola.jpg we should return. @@ -335,7 +321,8 @@ function test_tevkori_get_srcset_array_no_width() { add_filter( 'wp_get_attachment_image_src', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) ); // Make our attachment. - $id = $this->_test_img(); + $id = self::create_upload_object( self::$test_file_name ); + $srcset = tevkori_get_srcset_array( $id, 'medium' ); /* * 'tevkori_get_srcset_array()' calls `wp_get_attachment_image_srcset()` which uses @@ -380,7 +367,8 @@ public function _test_tevkori_get_srcset_array_no_width_filter( $image ) { */ function test_tevkori_get_srcset_string() { // Make an image. - $id = $this->_test_img(); + $id = self::$large_id; + $sizes = tevkori_get_srcset_string( $id, 'full-size' ); $sizes = tevkori_get_srcset_string( $id, 'full' ); $image = wp_get_attachment_metadata( $id ); @@ -401,7 +389,7 @@ function test_tevkori_get_srcset_string() { */ function test_tevkori_filter_attachment_image_attributes() { // Make an image. - $id = $this->_test_img(); + $id = self::$large_id; // Get attachment post data. $attachment = get_post( $id ); @@ -428,7 +416,7 @@ function test_tevkori_filter_attachment_image_attributes() { */ function test_tevkori_filter_attachment_image_attributes_thumbnails() { // Make an image. - $id = $this->_test_img(); + $id = self::$large_id; // Get attachment post data. $attachment = get_post( $id ); @@ -458,7 +446,7 @@ function test_tevkori_filter_attachment_image_attributes_thumbnails() { */ function test_tevkori_filter_content_images() { // Make an image. - $id = $this->_test_img(); + $id = self::$large_id; $srcset = tevkori_get_srcset_string( $id, 'medium' ); $sizes = tevkori_get_sizes_string( $id, 'medium' ); @@ -512,7 +500,7 @@ function test_tevkori_filter_content_images() { */ function test_tevkori_filter_content_images_with_preexisting_srcset() { // Make an image. - $id = $this->_test_img(); + $id = self::$large_id; // Generate HTML and add a dummy srcset attribute. $image_html = get_image_tag( $id, '', '', '', 'medium' ); From c2424e12c157f1055cf6bb898fbd4d2473d0ca06 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 3 Nov 2015 08:51:13 -0600 Subject: [PATCH 39/61] Update srcset tests to check for 'medium_large' The 'medium_large' size was added to core during the 4.4 cycle, which caused our expected `srcset` attributes to be off. This adds a whitelist for testing the default soft crops if they exist, which will make use of the 'meduim_large' size when applicable and still work when testing against versions of WP before the image size was added. --- tests/test-suite.php | 62 ++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/tests/test-suite.php b/tests/test-suite.php index 1f425eb..b378ad8 100644 --- a/tests/test-suite.php +++ b/tests/test-suite.php @@ -185,13 +185,15 @@ function test_tevkori_get_srcset_array() { $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' - ); + foreach( $image['sizes'] as $name => $size ) { + // Whitelist the sizes that should be included so we pick up 'medium_large' in 4.4. + if ( in_array( $name, array( 'medium', 'medium_large', 'large' ) ) ) { + $expected[$size['width']] = 'http://example.org/wp-content/uploads/' . $year_month = date('Y/m') . '/' . $size['file'] . ' ' . $size['width'] . 'w'; + } + } + + // Add the full size width at the end. + $expected[$image['width']] = 'http://example.org/wp-content/uploads/' . $image['file'] . ' ' . $image['width'] .'w'; $this->assertSame( $expected, $sizes ); } @@ -204,19 +206,7 @@ function test_tevkori_get_srcset_array_random_size_name() { $id = self::$large_id; $sizes = tevkori_get_srcset_array( $id, 'foo' ); - $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 ); + $this->assertFalse( $sizes ); } /** @@ -234,11 +224,15 @@ function test_tevkori_get_srcset_array_no_date_upoads() { $sizes = tevkori_get_srcset_array( $id, 'medium' ); $image = wp_get_attachment_metadata( $id ); - $expected = array( - $image['sizes']['medium']['width'] => 'http://example.org/wp-content/uploads/' . $image['sizes']['medium']['file'] . ' ' . $image['sizes']['medium']['width'] . 'w', - $image['sizes']['large']['width'] => 'http://example.org/wp-content/uploads/' . $image['sizes']['large']['file'] . ' ' . $image['sizes']['large']['width'] . 'w', - $image['width'] => 'http://example.org/wp-content/uploads/' . $image['file'] . ' ' . $image['width'] .'w' - ); + foreach( $image['sizes'] as $name => $size ) { + // Whitelist the sizes that should be included so we pick up 'medium_large' in 4.4. + if ( in_array( $name, array( 'medium', 'medium_large', 'large' ) ) ) { + $expected[$size['width']] = 'http://example.org/wp-content/uploads/' . $size['file'] . ' ' . $size['width'] . 'w'; + } + } + + // Add the full size width at the end. + $expected[$image['width']] = 'http://example.org/wp-content/uploads/' . $image['file'] . ' ' . $image['width'] .'w'; $this->assertSame( $expected, $sizes ); @@ -374,12 +368,18 @@ function test_tevkori_get_srcset_string() { $image = wp_get_attachment_metadata( $id ); $year_month = date('Y/m'); - $expected = 'srcset="'; - $expected .= 'http://example.org/wp-content/uploads/' . $year_month = date('Y/m') . '/' - . $image['sizes']['medium']['file'] . ' ' . $image['sizes']['medium']['width'] . 'w, '; - $expected .='http://example.org/wp-content/uploads/' . $year_month = date('Y/m') . '/' - . $image['sizes']['large']['file'] . ' ' . $image['sizes']['large']['width'] . 'w, '; - $expected .= 'http://example.org/wp-content/uploads/' . $image['file'] . ' ' . $image['width'] .'w"'; + $srcset = ''; + + foreach( $image['sizes'] as $name => $size ) { + // Whitelist the sizes that should be included so we pick up 'medium_large' in 4.4. + if ( in_array( $name, array( 'medium', 'medium_large', 'large' ) ) ) { + $srcset .= 'http://example.org/wp-content/uploads/' . $year_month = date('Y/m') . '/' . $size['file'] . ' ' . $size['width'] . 'w, '; + } + } + // Add the full size width at the end. + $srcset .= 'http://example.org/wp-content/uploads/' . $image['file'] . ' ' . $image['width'] .'w'; + + $expected = sprintf( 'srcset="%s"', $srcset ); $this->assertSame( $expected, $sizes ); } From 62adf1ac8ed701c93703051eeeeeb909ed2592d4 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 3 Nov 2015 09:19:55 -0600 Subject: [PATCH 40/61] Always load `tevkori_filter_attachment_image_attributes` If someone is calling `tevkori_filter_attachment_image_attributes` they should not get an undefined function error once they upgrade to WP 4.4. Instead of wrapping that function in a `function_exists` check, we do the check inside the function and return a deprecated notice and an unfiltered $attr array. --- wp-tevko-responsive-images.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index cb952ce..0bd1a1e 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -100,7 +100,7 @@ function _wp_get_image_size_from_meta( $size_name, $image_meta ) { } endif; -if ( ! function_exists( 'wp_get_attachment_image_srcset' ) ) : + /** * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. * @@ -108,6 +108,11 @@ function _wp_get_image_size_from_meta( $size_name, $image_meta ) { * @return array Attributes for image. */ function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { + if ( function_exists( 'wp_get_attachment_image_srcset' ) ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_attributes' ); + return $attr; + } + // Set srcset and sizes if not already present and both were returned. if ( empty( $attr['srcset'] ) ) { $srcset = wp_get_attachment_image_srcset( $attachment->ID, $size ); @@ -126,6 +131,7 @@ function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) } add_filter( 'wp_get_attachment_image_attributes', 'tevkori_filter_attachment_image_attributes', 0, 3 ); +if ( ! function_exists( 'wp_get_attachment_image_srcset' ) ) : /** * Retrieves the value for an image attachment's 'srcset' attribute. * From c3b66474af9af4896a6861b265ba7a15ec852d02 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 3 Nov 2015 09:24:36 -0600 Subject: [PATCH 41/61] Expect deprecated notices This adds expected deprecated notices for `tevkori_filter_attachment_image_attributes` --- tests/test-suite.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test-suite.php b/tests/test-suite.php index b378ad8..57b8b33 100644 --- a/tests/test-suite.php +++ b/tests/test-suite.php @@ -386,6 +386,7 @@ function test_tevkori_get_srcset_string() { /** * @group 159 + * @expectedDeprecated tevkori_filter_attachment_image_attributes */ function test_tevkori_filter_attachment_image_attributes() { // Make an image. @@ -413,6 +414,7 @@ function test_tevkori_filter_attachment_image_attributes() { /** * @group 159 + * @expectedDeprecated tevkori_filter_attachment_image_attributes */ function test_tevkori_filter_attachment_image_attributes_thumbnails() { // Make an image. From 5d6a45c143bbec562103baa3d98211b30040706a Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 3 Nov 2015 09:35:57 -0600 Subject: [PATCH 42/61] Expect `srcset` array when a random size name is used. If no size name is found, we fall back to the full size image, which results in a srcset array containing all soft-resized images. --- tests/test-suite.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/test-suite.php b/tests/test-suite.php index 57b8b33..87cfdf0 100644 --- a/tests/test-suite.php +++ b/tests/test-suite.php @@ -181,7 +181,6 @@ function test_tevkori_get_srcset_array() { $id = self::$large_id; $sizes = tevkori_get_srcset_array( $id, 'medium' ); - $sizes = tevkori_get_srcset_array( $id, 'medium' ); $year_month = date('Y/m'); $image = wp_get_attachment_metadata( $id ); @@ -206,7 +205,20 @@ function test_tevkori_get_srcset_array_random_size_name() { $id = self::$large_id; $sizes = tevkori_get_srcset_array( $id, 'foo' ); - $this->assertFalse( $sizes ); + $year_month = date('Y/m'); + $image = wp_get_attachment_metadata( $id ); + + foreach( $image['sizes'] as $name => $size ) { + // Whitelist the sizes that should be included so we pick up 'medium_large' in 4.4. + if ( in_array( $name, array( 'medium', 'medium_large', 'large' ) ) ) { + $expected[$size['width']] = 'http://example.org/wp-content/uploads/' . $year_month = date('Y/m') . '/' . $size['file'] . ' ' . $size['width'] . 'w'; + } + } + + // Add the full size width at the end. + $expected[$image['width']] = 'http://example.org/wp-content/uploads/' . $image['file'] . ' ' . $image['width'] .'w'; + + $this->assertSame( $expected, $sizes ); } /** From 025b2c3a537614b7568510186f359766b5574c92 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 3 Nov 2015 09:57:55 -0600 Subject: [PATCH 43/61] Update test filter for no width --- tests/test-suite.php | 42 +++++++++--------------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/tests/test-suite.php b/tests/test-suite.php index 87cfdf0..d186346 100644 --- a/tests/test-suite.php +++ b/tests/test-suite.php @@ -323,49 +323,25 @@ function test_tevkori_get_srcset_array_false() { * @expectedDeprecated tevkori_get_srcset_array */ function test_tevkori_get_srcset_array_no_width() { - // Filter wp_get_attachment_image_src() output. - add_filter( 'wp_get_attachment_image_src', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) ); + // Filter image_downsize() output. + add_filter( 'image_downsize', array( $this, '_filter_image_downsize' ), 10, 3 ); // Make our attachment. $id = self::create_upload_object( self::$test_file_name ); $srcset = tevkori_get_srcset_array( $id, 'medium' ); - /* - * 'tevkori_get_srcset_array()' calls `wp_get_attachment_image_srcset()` which uses - * `wp_get_attachment_image_src()` to get the image size. - * To manipulate the image size for this test we have to use the `wp_get_attachment_image_src` filter, - * but this was only introduced in WP 4.3. - * When testing against older WordPress versions we test 'wp_calculate_image_srcset()' instead. - */ - if ( has_filter( 'wp_get_attachment_image_src', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) ) ) { - $srcset = tevkori_get_srcset_array( $id, 'medium' ); - - // The srcset should be false. - $this->assertFalse( $srcset ); - } else { - // This function call is only because PHPUnit expects a deprecation warning. - $ignore = tevkori_get_srcset_array( $id, 'medium' ); - - $size_array = array( 0, 0 ); - $image_meta = wp_get_attachment_metadata( $id ); - $image_name = $image_meta['file']; - $srcset = wp_calculate_image_srcset( $image_name, $size_array, $image_meta ); - - // The srcset should be false. - $this->assertFalse( $srcset ); - } - + // The srcset should be false + $this->assertFalse( $srcset ); // Remove filter. - remove_filter( 'wp_get_attachment_image_src', array( $this, '_test_tevkori_get_srcset_array_no_width_filter' ) ); + remove_filter( 'image_downsize', array( $this, '_filter_image_downsize' ) ); } /** - * Helper funtion to filter wp_get_attachment_image_src and return zero values for width and height. + * Helper funtion to filter image_downsize and return zero values for width and height. */ - public function _test_tevkori_get_srcset_array_no_width_filter( $image ) { - $image[1] = 0; - $image[2] = 0; - return $image; + public function _filter_image_downsize( $out, $id, $size ) { + $img_url = wp_get_attachment_url($id); + return array( $img_url, 0, 0 ); } /** From f4c67235d3600dae1fcf1d901b6b20dc69c4b168 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Tue, 3 Nov 2015 10:20:29 -0600 Subject: [PATCH 44/61] Always run `tevkori_filter_attachment_image_attributes` --- 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 0bd1a1e..725cc63 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -108,10 +108,7 @@ function _wp_get_image_size_from_meta( $size_name, $image_meta ) { * @return array Attributes for image. */ function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { - if ( function_exists( 'wp_get_attachment_image_srcset' ) ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_attributes' ); - return $attr; - } + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_attributes' ); // Set srcset and sizes if not already present and both were returned. if ( empty( $attr['srcset'] ) ) { From 734586a65dc05685d1a8656022ca017e1912a17a Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Wed, 4 Nov 2015 10:20:21 -0600 Subject: [PATCH 45/61] Copy get_media_embedded_in_content() from WP 4.4 In core, we rely on `get_media_embedded_in_content()` to match images embedded in post content. However, in previous versions of WP, this function didn't support searching for images. This change provides consistency for any install making use of our included functions. --- wp-tevko-responsive-images.php | 43 +++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 725cc63..b638fd5 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -365,7 +365,7 @@ function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_i * @return string Converted content with 'srcset' and 'sizes' attributes added to images. */ function wp_make_content_images_responsive( $content ) { - $images = get_media_embedded_in_content( $content, 'img' ); + $images = tevkori_get_media_embedded_in_content( $content, 'img' ); $selected_images = $attachment_ids = array(); @@ -400,6 +400,47 @@ function wp_make_content_images_responsive( $content ) { return $content; } + +/** + * Check the content blob for an audio, video, object, embed, or iframe tags. + * This is a copy of `get_media_embedded_in_content()` in WP 4.4 in order to provide + * back compatibility to older versions of WordPress. + * + * @since 3.0.0 + * + * @param string $content A string which might contain media data. + * @param array $types An array of media types: 'audio', 'video', 'object', 'embed', or 'iframe'. + * @return array A list of found HTML media embeds. + */ +function tevkori_get_media_embedded_in_content( $content, $types = null ) { + $html = array(); + + /** + * Filter the embedded media types that are allowed to be returned from the content blob. + * + * @param array $allowed_media_types An array of allowed media types. Default media types are + * 'audio', 'video', 'object', 'embed', 'iframe', and 'img'. + */ + $allowed_media_types = apply_filters( 'media_embedded_in_content_allowed_types', array( 'audio', 'video', 'object', 'embed', 'iframe', 'img' ) ); + + if ( ! empty( $types ) ) { + if ( ! is_array( $types ) ) { + $types = array( $types ); + } + + $allowed_media_types = array_intersect( $allowed_media_types, $types ); + } + + $tags = implode( '|', $allowed_media_types ); + + if ( preg_match_all( '#<(?P' . $tags . ')[^<]*?(?:>[\s\S]*?<\/(?P=tag)>|\s*\/>)#', $content, $matches ) ) { + foreach ( $matches[0] as $match ) { + $html[] = $match; + } + } + + return $html; +} endif; if ( ! has_filter( 'the_content', 'wp_make_content_images_responsive' ) ) : From 5e2ff9c2fb8901145052d3f5cdeab6a9954592c6 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Wed, 4 Nov 2015 10:54:06 -0600 Subject: [PATCH 46/61] Move all our core functions to a separate file --- wp-tevko-core-responsive-functions.php | 453 ++++++++++++++++++++++++ wp-tevko-responsive-images.php | 464 +------------------------ 2 files changed, 462 insertions(+), 455 deletions(-) create mode 100644 wp-tevko-core-responsive-functions.php diff --git a/wp-tevko-core-responsive-functions.php b/wp-tevko-core-responsive-functions.php new file mode 100644 index 0000000..0d0a22e --- /dev/null +++ b/wp-tevko-core-responsive-functions.php @@ -0,0 +1,453 @@ + $image_meta['width'], + 'height' => $image_meta['height'], + 'file' => wp_basename( $image_meta['file'] ), + ); + + $image_baseurl = _wp_upload_dir_baseurl(); + $dirname = dirname( $image_meta['file'] ); + + if ( $dirname !== '.' ) { + $image_baseurl = path_join( $image_baseurl, $dirname ); + } + + // Calculate the image aspect ratio. + $image_ratio = $image_height / $image_width; + + /* + * Images that have been edited in WordPress after being uploaded will + * contain a unique hash. Look for that hash and use it later to filter + * out images that are leftovers from previous versions. + */ + $image_edited = preg_match( '/-e[0-9]{13}/', $image_name, $image_edit_hash ); + + /** + * Filter the maximum image width to be included in a 'srcset' attribute. + * + * @since 4.4.0 + * + * @param int $max_width The maximum image width to be included in the 'srcset'. Default '1600'. + * @param array $size_array Array of width and height values in pixels (in that order). + */ + $max_srcset_image_width = apply_filters( 'max_srcset_image_width', 1600, $size_array ); + + // Array to hold URL candidates. + $sources = array(); + + /* + * Loop through available images. Only use images that are resized + * versions of the same edit. + */ + foreach ( $image_sizes as $image ) { + + // Filter out images that are from previous edits. + if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) { + continue; + } + + // Filter out images that are wider than '$max_srcset_image_width'. + if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width ) { + continue; + } + + $candidate_url = $image['file']; + + // Calculate the new image ratio. + if ( $image['width'] ) { + $image_ratio_compare = $image['height'] / $image['width']; + } else { + $image_ratio_compare = 0; + } + + // If the new ratio differs by less than 0.01, use it. + if ( abs( $image_ratio - $image_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) { + // Add the URL, descriptor, and value to the sources array to be returned. + $sources[ $image['width'] ] = array( + 'url' => path_join( $image_baseurl, $candidate_url ), + 'descriptor' => 'w', + 'value' => $image['width'], + ); + } + } + + /** + * Filter the output of 'wp_calculate_image_srcset()'. + * + * @since 3.0.0 + * + * @param array $sources An array of sources to include in the 'srcset'. Each source + * consists of an array containing the URL and the descriptor + * type and value (default: the image width): + * + * image width => array( + * 'url' => string, + * 'descriptor' => string ('w' or 'x'), + * 'value' => integer (width or pixel density) + * }, + * + * @param int $attachment_id Image attachment ID. + * @param array $size_array Array of width and height values in pixels (in that order). + * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. + + */ + $sources = apply_filters( 'wp_calculate_image_srcset', $sources, $attachment_id, $size_array, $image_meta ); + + // Only return a 'srcset' value if there is more than one source. + if ( count( $sources ) < 2 ) { + return false; + } + + $srcset = ''; + + foreach ( $sources as $source ) { + $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', '; + } + + return rtrim( $srcset, ', ' ); +} +endif; + +if ( ! function_exists( 'wp_get_attachment_image_sizes' ) ) : +/** + * Create 'sizes' attribute value for an image. + * + * @since 3.0.0 + * + * @param array|string $size Image size. Accepts any valid image size name ('thumbnail', 'medium', etc.), + * or an array of width and height values in pixels (in that order). + * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. + * @param int $attachment_id Optional. Image attachment ID. Either `$image_meta` or `$attachment_id` is needed + * when using the image size name as argument for `$size`. + * @param string $image_url Optional. The URL to the image file. + * + * @return string|bool A valid source size value for use in a 'sizes' attribute or false. + */ +function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_id = 0, $image_url = null ) { + $width = 0; + + if ( is_array( $size ) ) { + $width = absint( $size[0] ); + } elseif ( is_string( $size ) ) { + if ( ! $image_meta && $attachment_id ) { + $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); + } + + if ( is_array( $image_meta ) ) { + $size_array = _wp_get_image_size_from_meta( $size, $image_meta ); + if ( $size_array ) { + $width = absint( $size_array[0] ); + } + } + } + + if ( ! $width ) { + return false; + } + + // Setup the default 'sizes' attribute. + $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $width ); + + /** + * Filter the output of 'wp_get_attachment_image_sizes()'. + * + * @since 3.0.0 + * + * @param string $sizes A source size value for use in a 'sizes' attribute. + * @param array|string $size Image size. Image size name, or an array of width and height + * values in pixels (in that order). + * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. + * @param int $attachment_id Image attachment ID of the original image. + * @param string $image_url Optional. The URL to the image file. + */ + return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $size, $image_meta, $attachment_id, $image_url ); +} +endif; + +if ( ! function_exists( 'wp_make_content_images_responsive' ) ) : +/** + * Filters 'img' elements in post content to add 'srcset' and 'sizes' attributes. + * + * @since 3.0.0 + * + * @see 'wp_image_add_srcset_and_sizes()' + * + * @param string $content The raw post content to be filtered. + * @return string Converted content with 'srcset' and 'sizes' attributes added to images. + */ +function wp_make_content_images_responsive( $content ) { + $images = tevkori_get_media_embedded_in_content( $content, 'img' ); + + $selected_images = $attachment_ids = array(); + + foreach( $images as $image ) { + if ( false === strpos( $image, ' srcset="' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) && + ( $attachment_id = absint( $class_id[1] ) ) ) { + + /* + * If exactly the same image tag is used more than once, overwrite it. + * All identical tags will be replaced later with 'str_replace()'. + */ + $selected_images[ $image ] = $attachment_id; + // Overwrite the ID when the same image is included more than once. + $attachment_ids[ $attachment_id ] = true; + } + } + + if ( count( $attachment_ids ) > 1 ) { + /* + * Warm object cache for use with 'get_post_meta()'. + * + * To avoid making a database call for each image, a single query + * warms the object cache with the meta information for all images. + */ + update_meta_cache( 'post', array_keys( $attachment_ids ) ); + } + + foreach ( $selected_images as $image => $attachment_id ) { + $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); + $content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content ); + } + + return $content; +} + +/** + * Check the content blob for an audio, video, object, embed, or iframe tags. + * This is a copy of `get_media_embedded_in_content()` in WP 4.4 in order to provide + * back compatibility to older versions of WordPress. + * + * @since 3.0.0 + * + * @param string $content A string which might contain media data. + * @param array $types An array of media types: 'audio', 'video', 'object', 'embed', or 'iframe'. + * @return array A list of found HTML media embeds. + */ +function tevkori_get_media_embedded_in_content( $content, $types = null ) { + $html = array(); + + /** + * Filter the embedded media types that are allowed to be returned from the content blob. + * + * @param array $allowed_media_types An array of allowed media types. Default media types are + * 'audio', 'video', 'object', 'embed', 'iframe', and 'img'. + */ + $allowed_media_types = apply_filters( 'media_embedded_in_content_allowed_types', array( 'audio', 'video', 'object', 'embed', 'iframe', 'img' ) ); + + if ( ! empty( $types ) ) { + if ( ! is_array( $types ) ) { + $types = array( $types ); + } + + $allowed_media_types = array_intersect( $allowed_media_types, $types ); + } + + $tags = implode( '|', $allowed_media_types ); + + if ( preg_match_all( '#<(?P' . $tags . ')[^<]*?(?:>[\s\S]*?<\/(?P=tag)>|\s*\/>)#', $content, $matches ) ) { + foreach ( $matches[0] as $match ) { + $html[] = $match; + } + } + + return $html; +} +endif; + +if ( ! has_filter( 'the_content', 'wp_make_content_images_responsive' ) ) : +add_filter( 'the_content', 'wp_make_content_images_responsive', 5, 1 ); +endif; + +if ( ! function_exists( 'wp_image_add_srcset_and_sizes' ) ) : +/** + * Adds 'srcset' and 'sizes' attributes to an existing 'img' element. + * + * @since 3.0.0 + * + * @see 'wp_get_attachment_image_srcset()' + * @see 'wp_get_attachment_image_sizes()' + * + * @param string $image An HTML 'img' element to be filtered. + * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. + * @param int $attachment_id Image attachment ID. + * @return string Converted 'img' element with 'srcset' and 'sizes' attributes added. + */ +function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { + // Ensure the image meta exists. + if ( empty( $image_meta['sizes'] ) ) { + return $image; + } + + $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : ''; + list( $src ) = explode( '?', $src ); + + // Return early if we couldn't get the image source. + if ( ! $src ) { + return $image; + } + + // Bail early if an image has been inserted and later edited. + if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) && + strpos( wp_basename( $src ), $img_edit_hash[0] ) === false ) { + + return $image; + } + + $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? (int) $match_width[1] : 0; + $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0; + + if ( ! $width || ! $height ) { + /* + * If attempts to parse the size value failed, attempt to use the image meta data to match + * the image file name from 'src' against the available sizes for an attachment. + */ + $image_filename = wp_basename( $src ); + + if ( $image_filename === wp_basename( $image_meta['file'] ) ) { + $width = (int) $image_meta['width']; + $height = (int) $image_meta['height']; + } else { + foreach( $image_meta['sizes'] as $image_size_data ) { + if ( $image_filename === $image_size_data['file'] ) { + $width = (int) $image_size_data['width']; + $height = (int) $image_size_data['height']; + break; + } + } + } + } + + if ( ! $width || ! $height ) { + return $image; + } + + $size_array = array( $width, $height ); + $srcset = wp_calculate_image_srcset( $src, $size_array, $image_meta, $attachment_id ); + + if ( $srcset ) { + $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id, $src ); + } + + if ( $srcset && $sizes ) { + // Format the 'srcset' and 'sizes' string and escape attributes. + $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes ) ); + + // Add 'srcset' and 'sizes' attributes to the image markup. + $image = preg_replace( '/]+?)[\/ ]*>/', '', $image ); + } + + return $image; +} +endif; diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index b638fd5..0a773fa 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -42,64 +42,13 @@ function tevkori_wp_image_editors( $editors ) { add_filter( 'wp_image_editors', 'tevkori_wp_image_editors' ); } -// Enqueue bundled version of the Picturefill library. -function tevkori_get_picturefill() { - wp_enqueue_script( 'picturefill', plugins_url( 'js/picturefill.min.js', __FILE__ ), array(), '3.0.1', true ); -} -add_action( 'wp_enqueue_scripts', 'tevkori_get_picturefill' ); - -if ( ! function_exists( '_wp_upload_dir_baseurl' ) ) : -/** - * Caches and returns the base URL of the uploads directory. - * - * @since 3.0.0 - * @access private - * - * @return string The base URL, cached. +/* + * Load copies of our core functions if the plugin is installed on a version of WordPress + * previous to 4.4, when the functions were added to core. */ -function _wp_upload_dir_baseurl() { - static $baseurl = null; - - if ( ! $baseurl ) { - $uploads_dir = wp_upload_dir(); - $baseurl = $uploads_dir['baseurl']; - } - - return $baseurl; -} -endif; - -if ( ! function_exists( '_wp_get_image_size_from_meta' ) ) : -/** - * Get the image size as array from its meta data. - * - * Used for responsive images. - * - * @since 3.0.0 - * @access private - * - * @param string $size_name Image size. Accepts any valid image size name ('thumbnail', 'medium', etc.). - * @param array $image_meta The image meta data. - * @return array|bool Array of width and height values in pixels (in that order) - * or false if the size doesn't exist. - */ -function _wp_get_image_size_from_meta( $size_name, $image_meta ) { - if ( $size_name === 'full' ) { - return array( - absint( $image_meta['width'] ), - absint( $image_meta['height'] ), - ); - } elseif ( ! empty( $image_meta['sizes'][$size_name] ) ) { - return array( - absint( $image_meta['sizes'][$size_name]['width'] ), - absint( $image_meta['sizes'][$size_name]['height'] ), - ); - } - - return false; +if ( ! function_exists( 'wp_get_attachment_image_srcset' ) ) { + require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-core-responsive-functions.php' ); } -endif; - /** * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. @@ -128,403 +77,8 @@ function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) } add_filter( 'wp_get_attachment_image_attributes', 'tevkori_filter_attachment_image_attributes', 0, 3 ); -if ( ! function_exists( 'wp_get_attachment_image_srcset' ) ) : -/** - * Retrieves the value for an image attachment's 'srcset' attribute. - * - * @since 3.0.0 - * - * @param int $attachment_id Image attachment ID. - * @param array|string $size Image size. Accepts any valid image size, or an array of width and height - * values in pixels (in that order). Default 'medium'. - * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. - * @return string|bool A 'srcset' value string or false. - */ -function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null ) { - if ( ! $image = wp_get_attachment_image_src( $attachment_id, $size ) ) { - return false; - } - - if ( ! is_array( $image_meta ) ) { - $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); - } - - $image_url = $image[0]; - $size_array = array( - absint( $image[1] ), - absint( $image[2] ) - ); - - return wp_calculate_image_srcset( $image_url, $size_array, $image_meta, $attachment_id ); -} -endif; - -if ( ! function_exists( 'wp_calculate_image_srcset' ) ) : -/** - * A helper function to calculate the image sources to include in a 'srcset' attribute. - * - * @since 3.0.0 - * - * @param string $image_name The file name, path, URL, or partial path or URL, of the image being matched. - * @param array $size_array Array of width and height values in pixels (in that order). - * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. - * @param int $attachment_id Optional. The image attachment ID to pass to the filter. - * @return string|bool The 'srcset' attribute value. False on error or when only one source exists. - */ -function wp_calculate_image_srcset( $image_name, $size_array, $image_meta, $attachment_id = 0 ) { - if ( empty( $image_meta['sizes'] ) ) { - return false; - } - - $image_sizes = $image_meta['sizes']; - - // Get the width and height of the image. - $image_width = (int) $size_array[0]; - $image_height = (int) $size_array[1]; - - // Bail early if error/no width. - if ( $image_width < 1 ) { - return false; - } - - // Add full size to the '$image_sizes' array. - $image_sizes['full'] = array( - 'width' => $image_meta['width'], - 'height' => $image_meta['height'], - 'file' => wp_basename( $image_meta['file'] ), - ); - - $image_baseurl = _wp_upload_dir_baseurl(); - $dirname = dirname( $image_meta['file'] ); - - if ( $dirname !== '.' ) { - $image_baseurl = path_join( $image_baseurl, $dirname ); - } - - // Calculate the image aspect ratio. - $image_ratio = $image_height / $image_width; - - /* - * Images that have been edited in WordPress after being uploaded will - * contain a unique hash. Look for that hash and use it later to filter - * out images that are leftovers from previous versions. - */ - $image_edited = preg_match( '/-e[0-9]{13}/', $image_name, $image_edit_hash ); - - /** - * Filter the maximum image width to be included in a 'srcset' attribute. - * - * @since 4.4.0 - * - * @param int $max_width The maximum image width to be included in the 'srcset'. Default '1600'. - * @param array $size_array Array of width and height values in pixels (in that order). - */ - $max_srcset_image_width = apply_filters( 'max_srcset_image_width', 1600, $size_array ); - - // Array to hold URL candidates. - $sources = array(); - - /* - * Loop through available images. Only use images that are resized - * versions of the same edit. - */ - foreach ( $image_sizes as $image ) { - - // Filter out images that are from previous edits. - if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) { - continue; - } - - // Filter out images that are wider than '$max_srcset_image_width'. - if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width ) { - continue; - } - - $candidate_url = $image['file']; - - // Calculate the new image ratio. - if ( $image['width'] ) { - $image_ratio_compare = $image['height'] / $image['width']; - } else { - $image_ratio_compare = 0; - } - - // If the new ratio differs by less than 0.01, use it. - if ( abs( $image_ratio - $image_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) { - // Add the URL, descriptor, and value to the sources array to be returned. - $sources[ $image['width'] ] = array( - 'url' => path_join( $image_baseurl, $candidate_url ), - 'descriptor' => 'w', - 'value' => $image['width'], - ); - } - } - - /** - * Filter the output of 'wp_calculate_image_srcset()'. - * - * @since 3.0.0 - * - * @param array $sources An array of sources to include in the 'srcset'. Each source - * consists of an array containing the URL and the descriptor - * type and value (default: the image width): - * - * image width => array( - * 'url' => string, - * 'descriptor' => string ('w' or 'x'), - * 'value' => integer (width or pixel density) - * }, - * - * @param int $attachment_id Image attachment ID. - * @param array $size_array Array of width and height values in pixels (in that order). - * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. - - */ - $sources = apply_filters( 'wp_calculate_image_srcset', $sources, $attachment_id, $size_array, $image_meta ); - - // Only return a 'srcset' value if there is more than one source. - if ( count( $sources ) < 2 ) { - return false; - } - - $srcset = ''; - - foreach ( $sources as $source ) { - $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', '; - } - - return rtrim( $srcset, ', ' ); -} -endif; - -if ( ! function_exists( 'wp_get_attachment_image_sizes' ) ) : -/** - * Create 'sizes' attribute value for an image. - * - * @since 3.0.0 - * - * @param array|string $size Image size. Accepts any valid image size name ('thumbnail', 'medium', etc.), - * or an array of width and height values in pixels (in that order). - * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. - * @param int $attachment_id Optional. Image attachment ID. Either `$image_meta` or `$attachment_id` is needed - * when using the image size name as argument for `$size`. - * @param string $image_url Optional. The URL to the image file. - * - * @return string|bool A valid source size value for use in a 'sizes' attribute or false. - */ -function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_id = 0, $image_url = null ) { - $width = 0; - - if ( is_array( $size ) ) { - $width = absint( $size[0] ); - } elseif ( is_string( $size ) ) { - if ( ! $image_meta && $attachment_id ) { - $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); - } - - if ( is_array( $image_meta ) ) { - $size_array = _wp_get_image_size_from_meta( $size, $image_meta ); - if ( $size_array ) { - $width = absint( $size_array[0] ); - } - } - } - - if ( ! $width ) { - return false; - } - - // Setup the default 'sizes' attribute. - $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $width ); - - /** - * Filter the output of 'wp_get_attachment_image_sizes()'. - * - * @since 3.0.0 - * - * @param string $sizes A source size value for use in a 'sizes' attribute. - * @param array|string $size Image size. Image size name, or an array of width and height - * values in pixels (in that order). - * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. - * @param int $attachment_id Image attachment ID of the original image. - * @param string $image_url Optional. The URL to the image file. - */ - return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $size, $image_meta, $attachment_id, $image_url ); -} -endif; - -if ( ! function_exists( 'wp_make_content_images_responsive' ) ) : -/** - * Filters 'img' elements in post content to add 'srcset' and 'sizes' attributes. - * - * @since 3.0.0 - * - * @see 'wp_image_add_srcset_and_sizes()' - * - * @param string $content The raw post content to be filtered. - * @return string Converted content with 'srcset' and 'sizes' attributes added to images. - */ -function wp_make_content_images_responsive( $content ) { - $images = tevkori_get_media_embedded_in_content( $content, 'img' ); - - $selected_images = $attachment_ids = array(); - - foreach( $images as $image ) { - if ( false === strpos( $image, ' srcset="' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) && - ( $attachment_id = absint( $class_id[1] ) ) ) { - - /* - * If exactly the same image tag is used more than once, overwrite it. - * All identical tags will be replaced later with 'str_replace()'. - */ - $selected_images[ $image ] = $attachment_id; - // Overwrite the ID when the same image is included more than once. - $attachment_ids[ $attachment_id ] = true; - } - } - - if ( count( $attachment_ids ) > 1 ) { - /* - * Warm object cache for use with 'get_post_meta()'. - * - * To avoid making a database call for each image, a single query - * warms the object cache with the meta information for all images. - */ - update_meta_cache( 'post', array_keys( $attachment_ids ) ); - } - - foreach ( $selected_images as $image => $attachment_id ) { - $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); - $content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content ); - } - - return $content; -} - -/** - * Check the content blob for an audio, video, object, embed, or iframe tags. - * This is a copy of `get_media_embedded_in_content()` in WP 4.4 in order to provide - * back compatibility to older versions of WordPress. - * - * @since 3.0.0 - * - * @param string $content A string which might contain media data. - * @param array $types An array of media types: 'audio', 'video', 'object', 'embed', or 'iframe'. - * @return array A list of found HTML media embeds. - */ -function tevkori_get_media_embedded_in_content( $content, $types = null ) { - $html = array(); - - /** - * Filter the embedded media types that are allowed to be returned from the content blob. - * - * @param array $allowed_media_types An array of allowed media types. Default media types are - * 'audio', 'video', 'object', 'embed', 'iframe', and 'img'. - */ - $allowed_media_types = apply_filters( 'media_embedded_in_content_allowed_types', array( 'audio', 'video', 'object', 'embed', 'iframe', 'img' ) ); - - if ( ! empty( $types ) ) { - if ( ! is_array( $types ) ) { - $types = array( $types ); - } - - $allowed_media_types = array_intersect( $allowed_media_types, $types ); - } - - $tags = implode( '|', $allowed_media_types ); - - if ( preg_match_all( '#<(?P' . $tags . ')[^<]*?(?:>[\s\S]*?<\/(?P=tag)>|\s*\/>)#', $content, $matches ) ) { - foreach ( $matches[0] as $match ) { - $html[] = $match; - } - } - - return $html; -} -endif; - -if ( ! has_filter( 'the_content', 'wp_make_content_images_responsive' ) ) : -add_filter( 'the_content', 'wp_make_content_images_responsive', 5, 1 ); -endif; - -if ( ! function_exists( 'wp_image_add_srcset_and_sizes' ) ) : -/** - * Adds 'srcset' and 'sizes' attributes to an existing 'img' element. - * - * @since 3.0.0 - * - * @see 'wp_get_attachment_image_srcset()' - * @see 'wp_get_attachment_image_sizes()' - * - * @param string $image An HTML 'img' element to be filtered. - * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. - * @param int $attachment_id Image attachment ID. - * @return string Converted 'img' element with 'srcset' and 'sizes' attributes added. - */ -function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { - // Ensure the image meta exists. - if ( empty( $image_meta['sizes'] ) ) { - return $image; - } - - $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : ''; - list( $src ) = explode( '?', $src ); - - // Return early if we couldn't get the image source. - if ( ! $src ) { - return $image; - } - - // Bail early if an image has been inserted and later edited. - if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) && - strpos( wp_basename( $src ), $img_edit_hash[0] ) === false ) { - - return $image; - } - - $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? (int) $match_width[1] : 0; - $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0; - - if ( ! $width || ! $height ) { - /* - * If attempts to parse the size value failed, attempt to use the image meta data to match - * the image file name from 'src' against the available sizes for an attachment. - */ - $image_filename = wp_basename( $src ); - - if ( $image_filename === wp_basename( $image_meta['file'] ) ) { - $width = (int) $image_meta['width']; - $height = (int) $image_meta['height']; - } else { - foreach( $image_meta['sizes'] as $image_size_data ) { - if ( $image_filename === $image_size_data['file'] ) { - $width = (int) $image_size_data['width']; - $height = (int) $image_size_data['height']; - break; - } - } - } - } - - if ( ! $width || ! $height ) { - return $image; - } - - $size_array = array( $width, $height ); - $srcset = wp_calculate_image_srcset( $src, $size_array, $image_meta, $attachment_id ); - - if ( $srcset ) { - $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id, $src ); - } - - if ( $srcset && $sizes ) { - // Format the 'srcset' and 'sizes' string and escape attributes. - $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes ) ); - - // Add 'srcset' and 'sizes' attributes to the image markup. - $image = preg_replace( '/]+?)[\/ ]*>/', '', $image ); - } - - return $image; +// Enqueue bundled version of the Picturefill library. +function tevkori_get_picturefill() { + wp_enqueue_script( 'picturefill', plugins_url( 'js/picturefill.min.js', __FILE__ ), array(), '3.0.1', true ); } -endif; +add_action( 'wp_enqueue_scripts', 'tevkori_get_picturefill' ); From ad717ce62525c6f0059af03a18122d16bc00b539 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Wed, 4 Nov 2015 20:16:41 +0100 Subject: [PATCH 47/61] Renamed core functions file --- ...core-responsive-functions.php => wp-tevko-core-functions.php | 0 wp-tevko-responsive-images.php | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename wp-tevko-core-responsive-functions.php => wp-tevko-core-functions.php (100%) diff --git a/wp-tevko-core-responsive-functions.php b/wp-tevko-core-functions.php similarity index 100% rename from wp-tevko-core-responsive-functions.php rename to wp-tevko-core-functions.php diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 0a773fa..637d912 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -47,7 +47,7 @@ function tevkori_wp_image_editors( $editors ) { * previous to 4.4, when the functions were added to core. */ if ( ! function_exists( 'wp_get_attachment_image_srcset' ) ) { - require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-core-responsive-functions.php' ); + require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-core-functions.php' ); } /** From 225c79069a7ac8f03c39e7185013113cca9666f1 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Wed, 4 Nov 2015 20:21:01 +0100 Subject: [PATCH 48/61] Removed function exists checks from new core functions The file is only included if wp_get_attachment_image_srcset() does not exists. That is sufficient. --- wp-tevko-core-functions.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/wp-tevko-core-functions.php b/wp-tevko-core-functions.php index 0d0a22e..4a0bb48 100644 --- a/wp-tevko-core-functions.php +++ b/wp-tevko-core-functions.php @@ -1,5 +1,4 @@ Date: Wed, 4 Nov 2015 20:44:36 +0100 Subject: [PATCH 49/61] Coding standards in php-respimg files --- class-respimg.php | 63 +++++++++++++++++-------------- class-wp-image-editor-respimg.php | 18 +++++---- 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/class-respimg.php b/class-respimg.php index d645a9c..2050a46 100644 --- a/class-respimg.php +++ b/class-respimg.php @@ -1,7 +1,7 @@ + * Hacked up version of php-respimg: https://github.com/nwtn/php-respimg * * @package wp-respimg * @version 0.0.1 @@ -35,9 +35,10 @@ class Respimg extends Imagick { * * @access public * - * @param integer $columns The number of columns in the output image. 0 = maintain aspect ratio based on $rows. - * @param integer $rows The number of rows in the output image. 0 = maintain aspect ratio based on $columns. - * @param bool $optim Whether you intend to perform optimization on the resulting image. Note that setting this to `true` doesn’t actually perform any optimization. + * @param integer $columns The number of columns in the output image. 0 = maintain aspect ratio based on $rows. + * @param integer $rows The number of rows in the output image. 0 = maintain aspect ratio based on $columns. + * @param bool $optim Whether you intend to perform optimization on the resulting image. + * Note that setting this to 'true' doesn't actually perform any optimization. */ public function smartResize( $columns, $rows, $optim = false ) { @@ -61,41 +62,41 @@ public function smartResize( $columns, $rows, $optim = false ) { if ( ! $optim ) { $this->stripImage(); } - } - /** * Changes the size of an image to the given dimensions and removes any associated profiles. * * `thumbnailImage` changes the size of an image to the given dimensions and - * removes any associated profiles. The goal is to produce small low cost + * removes any associated profiles. The goal is to produce small low cost * thumbnail images suited for display on the Web. * * With the original Imagick thumbnailImage implementation, there is no way to choose a * resampling filter. This class recreates Imagick’s C implementation and adds this * additional feature. * - * Note: has been filed for this issue. + * Note: https://github.com/mkoppanen/imagick/issues/90 has been filed for this issue. * * @access public * - * @param integer $columns The number of columns in the output image. 0 = maintain aspect ratio based on $rows. - * @param integer $rows The number of rows in the output image. 0 = maintain aspect ratio based on $columns. - * @param bool $bestfit Treat $columns and $rows as a bounding box in which to fit the image. - * @param bool $fill Fill in the bounding box with the background colour. - * @param integer $filter The resampling filter to use. Refer to the list of filter constants at . + * @param integer $columns The number of columns in the output image. 0 = maintain aspect ratio based on $rows. + * @param integer $rows The number of rows in the output image. 0 = maintain aspect ratio based on $columns. + * @param bool $bestfit Treat $columns and $rows as a bounding box in which to fit the image. + * @param bool $fill Fill in the bounding box with the background colour. + * @param integer $filter The resampling filter to use. Refer to the list of filter constants at . * - * @return bool Indicates whether the operation was performed successfully. + * @return bool Indicates whether the operation was performed successfully. */ public function thumbnailImage( $columns, $rows, $bestfit = false, $fill = false, $filter = Imagick::FILTER_TRIANGLE ) { - // sample factor; defined in original ImageMagick thumbnailImage function - // the scale to which the image should be resized using the `sample` function + /* + * Sample factor; defined in original ImageMagick thumbnailImage function + * the scale to which the image should be resized using the 'sample' function. + */ $SampleFactor = 5; - // filter whitelist + // Filter whitelist. $filters = array( Imagick::FILTER_POINT, Imagick::FILTER_BOX, @@ -114,23 +115,23 @@ public function thumbnailImage( $columns, $rows, $bestfit = false, $fill = false Imagick::FILTER_SINC ); - // Parse parameters given to function + // Parse parameters given to function. $columns = (double) $columns; $rows = (double) $rows; $bestfit = (bool) $bestfit; $fill = (bool) $fill; - // We can’t resize to (0,0) + // We can’t resize to (0,0). if ( $rows < 1 && $columns < 1 ) { return false; } - // Set a default filter if an acceptable one wasn’t passed + // Set a default filter if an acceptable one wasn’t passed. if ( ! in_array( $filter, $filters ) ) { $filter = Imagick::FILTER_TRIANGLE; } - // figure out the output width and height + // Figure out the output width and height. $width = (double) $this->getImageWidth(); $height = (double) $this->getImageHeight(); $new_width = $columns; @@ -144,8 +145,10 @@ public function thumbnailImage( $columns, $rows, $bestfit = false, $fill = false $new_width = round( $y_factor * $width ); } - // if bestfit is true, the new_width/new_height of the image will be different than - // the columns/rows parameters; those will define a bounding box in which the image will be fit + /* + * If bestfit is true, the new_width/new_height of the image will be different than + * the columns/rows parameters; those will define a bounding box in which the image will be fit. + */ if ( $bestfit && $x_factor > $y_factor ) { $x_factor = $y_factor; $new_width = round( $y_factor * $width ); @@ -160,8 +163,10 @@ public function thumbnailImage( $columns, $rows, $bestfit = false, $fill = false $new_height = 1; } - // if we’re resizing the image to more than about 1/3 it’s original size - // then just use the resize function + /* + * If we’re resizing the image to more than about 1/3 it’s original size + * then just use the resize function. + */ if ( ( $x_factor * $y_factor ) > 0.1 ) { $this->resizeImage( $new_width, $new_height, $filter, 1 ); @@ -215,8 +220,10 @@ public function thumbnailImage( $columns, $rows, $bestfit = false, $fill = false $this->setImageProperty( 'Thumb::Document::Pages', '' ); } - // In case user wants to fill use extent for it rather than creating a new canvas - // …fill out the bounding box + /* + * In case user wants to fill use extent for it rather than creating a new canvas + * fill out the bounding box. + */ if ( $bestfit && $fill && ( $new_width != $columns || $new_height != $rows ) ) { $extent_x = 0; $extent_y = 0; @@ -233,7 +240,5 @@ public function thumbnailImage( $columns, $rows, $bestfit = false, $fill = false } return true; - } - } diff --git a/class-wp-image-editor-respimg.php b/class-wp-image-editor-respimg.php index 123d98e..1e27be1 100644 --- a/class-wp-image-editor-respimg.php +++ b/class-wp-image-editor-respimg.php @@ -11,7 +11,7 @@ require_once( ABSPATH . WPINC . '/class-wp-image-editor-imagick.php' ); /** - * WordPress Image Editor Class for Image Manipulation through Imagick PHP Module with php-respimg + * WordPress Image Editor Class for Image Manipulation through Imagick PHP Module with php-respimg. * * @package wp-respimg * @uses WP_Image_Editor_Imagick Extends class @@ -34,8 +34,11 @@ public function load() { return new WP_Error( 'error_loading_image', __('File doesn’t exist?'), $this->file ); } - /** This filter is documented in wp-includes/class-wp-image-editor-imagick.php */ - // Even though Imagick uses less PHP memory than GD, set higher limit for users that have low PHP.ini limits + /* + * This filter is documented in wp-includes/class-wp-image-editor-imagick.php + * + * Even though Imagick uses less PHP memory than GD, set higher limit for users that have low PHP.ini limits. + */ @ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) ); try { @@ -44,7 +47,7 @@ public function load() { if ( ! $this->image->valid() ) { return new WP_Error( 'invalid_image', __('File is not an image.'), $this->file); } - // Select the first frame to handle animated images properly + // Select the first frame to handle animated images properly. if ( is_callable( array( $this->image, 'setIteratorIndex' ) ) ) { $this->image->setIteratorIndex(0); } @@ -200,8 +203,10 @@ public function crop( $src_x, $src_y, $src_w, $src_h, $dst_w = null, $dst_h = nu $this->image->setImagePage( $src_w, $src_h, 0, 0); if ( $dst_w || $dst_h ) { - // If destination width/height isn't specified, use same as - // width/height from source. + /* + * If destination width/height isn't specified, use same as + * width/height from source. + */ if ( ! $dst_w ) { $dst_w = $src_w; } @@ -222,5 +227,4 @@ public function crop( $src_x, $src_y, $src_w, $src_h, $dst_w = null, $dst_h = nu } return $this->update_size(); } - } From 87edb55bcc270874917a371caee8e58e79fb6c1b Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Wed, 4 Nov 2015 20:56:07 +0100 Subject: [PATCH 50/61] A bit more inline documentation in main plugin file --- wp-tevko-responsive-images.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 637d912..20cf2df 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -18,9 +18,10 @@ // Don't load the plugin directly. defined( 'ABSPATH' ) or die( "No script kiddies please!" ); -// List includes. -require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-deprecated-functions.php' ); - +/* + * Include the advanced image compression files. + * See readme.md for more information. + */ if ( class_exists( 'Imagick' ) ) { require_once( plugin_dir_path( __FILE__ ) . 'class-respimg.php' ); require_once( plugin_dir_path( __FILE__ ) . 'class-wp-image-editor-respimg.php' ); @@ -42,6 +43,9 @@ function tevkori_wp_image_editors( $editors ) { add_filter( 'wp_image_editors', 'tevkori_wp_image_editors' ); } +// Load the deprecated core functions. +require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-deprecated-functions.php' ); + /* * Load copies of our core functions if the plugin is installed on a version of WordPress * previous to 4.4, when the functions were added to core. @@ -53,13 +57,16 @@ function tevkori_wp_image_editors( $editors ) { /** * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. * + * @since 2.3.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_attributes' * @see 'wp_get_attachment_image_attributes' + * * @return array Attributes for image. */ function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_attributes' ); - // Set srcset and sizes if not already present and both were returned. + // Set 'srcset' and 'sizes' if not already present and both were returned. if ( empty( $attr['srcset'] ) ) { $srcset = wp_get_attachment_image_srcset( $attachment->ID, $size ); $sizes = wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment->ID ); From 5bae791e3e14c2f602d41d04c3f7c1e293bdb4fc Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Wed, 4 Nov 2015 20:30:57 +0100 Subject: [PATCH 51/61] Moved the post thumbnail filter code --- wp-tevko-core-functions.php | 3 +++ wp-tevko-deprecated-functions.php | 29 +++++++++++++++++++++++++++++ wp-tevko-responsive-images.php | 30 ------------------------------ 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/wp-tevko-core-functions.php b/wp-tevko-core-functions.php index 4a0bb48..7d25265 100644 --- a/wp-tevko-core-functions.php +++ b/wp-tevko-core-functions.php @@ -434,3 +434,6 @@ function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { return $image; } + +// Add the filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. +add_filter( 'wp_get_attachment_image_attributes', 'tevkori_filter_attachment_image_attributes', 0, 3 ); diff --git a/wp-tevko-deprecated-functions.php b/wp-tevko-deprecated-functions.php index 518ee5c..371c5ae 100644 --- a/wp-tevko-deprecated-functions.php +++ b/wp-tevko-deprecated-functions.php @@ -255,3 +255,32 @@ function tevkori_filter_content_images( $content ) { _deprecated_function( __FUNCTION__, '3.0.0', 'wp_make_content_images_responsive()' ); return wp_make_content_images_responsive( $content ); } + +/** + * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. + * + * @since 2.3.0 + * @deprecated 3.0 Use 'wp_get_attachment_image_attributes' + * @see 'wp_get_attachment_image_attributes' + * + * @return array Attributes for image. + */ +function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { + _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_attributes' ); + + // Set 'srcset' and 'sizes' if not already present and both were returned. + if ( empty( $attr['srcset'] ) ) { + $srcset = wp_get_attachment_image_srcset( $attachment->ID, $size ); + $sizes = wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment->ID ); + + if ( $srcset && $sizes ) { + $attr['srcset'] = $srcset; + + if ( empty( $attr['sizes'] ) ) { + $attr['sizes'] = $sizes; + } + } + } + + return $attr; +} diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index 20cf2df..eb4195b 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -54,36 +54,6 @@ function tevkori_wp_image_editors( $editors ) { require_once( plugin_dir_path( __FILE__ ) . 'wp-tevko-core-functions.php' ); } -/** - * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. - * - * @since 2.3.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_attributes' - * @see 'wp_get_attachment_image_attributes' - * - * @return array Attributes for image. - */ -function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_attributes' ); - - // Set 'srcset' and 'sizes' if not already present and both were returned. - if ( empty( $attr['srcset'] ) ) { - $srcset = wp_get_attachment_image_srcset( $attachment->ID, $size ); - $sizes = wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment->ID ); - - if ( $srcset && $sizes ) { - $attr['srcset'] = $srcset; - - if ( empty( $attr['sizes'] ) ) { - $attr['sizes'] = $sizes; - } - } - } - - return $attr; -} -add_filter( 'wp_get_attachment_image_attributes', 'tevkori_filter_attachment_image_attributes', 0, 3 ); - // Enqueue bundled version of the Picturefill library. function tevkori_get_picturefill() { wp_enqueue_script( 'picturefill', plugins_url( 'js/picturefill.min.js', __FILE__ ), array(), '3.0.1', true ); From abc0a27bdc657d78a7e160450e97f405caaa27df Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Wed, 4 Nov 2015 21:26:47 +0100 Subject: [PATCH 52/61] Use 3 digit version numbers in DocBlocks --- wp-tevko-deprecated-functions.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/wp-tevko-deprecated-functions.php b/wp-tevko-deprecated-functions.php index 371c5ae..8f02bd6 100644 --- a/wp-tevko-deprecated-functions.php +++ b/wp-tevko-deprecated-functions.php @@ -3,7 +3,7 @@ * Returns an array of image sources for a 'srcset' attribute. * * @since 2.1.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' + * @deprecated 3.0.0 Use 'wp_get_attachment_image_srcset()' * @see 'wp_get_attachment_image_sizes()' * @see 'wp_calculate_image_srcset()' * @@ -35,7 +35,7 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { * Filter the output of 'tevkori_get_srcset_array()'. * * @since 2.4.0 - * @deprecated 3.0 Use 'wp_calculate_image_srcset' + * @deprecated 3.0.0 Use 'wp_calculate_image_srcset' * @see 'wp_calculate_image_srcset' * * @param array $arr An array of image sources. @@ -50,7 +50,7 @@ function tevkori_get_srcset_array( $id, $size = 'medium' ) { * Returns the value for a 'srcset' attribute. * * @since 2.3.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' + * @deprecated 3.0.0 Use 'wp_get_attachment_image_srcset()' * @see 'wp_get_attachment_image_sizes()' * @see 'wp_calculate_image_srcset()' * @@ -75,7 +75,7 @@ function tevkori_get_srcset( $id, $size = 'medium' ) { * Returns a 'srcset' attribute. * * @since 2.1.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_srcset()' + * @deprecated 3.0.0 Use 'wp_get_attachment_image_srcset()' * @see 'wp_get_attachment_image_sizes()' * @see 'wp_calculate_image_srcset()' * @@ -102,7 +102,7 @@ function tevkori_get_srcset_string( $id, $size = 'medium' ) { * Returns the value for a 'sizes' attribute. * * @since 2.2.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' + * @deprecated 3.0.0 Use 'wp_get_attachment_image_sizes()' * @see 'wp_get_attachment_image_sizes()' * * @param int $id Image attachment ID. @@ -155,7 +155,7 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { * Filter arguments used to create the 'sizes' attribute value. * * @since 2.4.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_sizes' + * @deprecated 3.0.0 Use 'wp_get_attachment_image_sizes' * @see 'wp_get_attachment_image_sizes' * * @param array $args An array of arguments used to create a 'sizes' attribute. @@ -215,7 +215,7 @@ function tevkori_get_sizes( $id, $size = 'medium', $args = null ) { * Returns a 'sizes' attribute. * * @since 2.2.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_sizes()' + * @deprecated 3.0.0 Use 'wp_get_attachment_image_sizes()' * @see 'wp_get_attachment_image_sizes()' * * @param int $id Image attachment ID. @@ -245,7 +245,7 @@ function tevkori_get_sizes_string( $id, $size = 'medium', $args = null ) { * Filter to add 'srcset' and 'sizes' attributes to images in the post content. * * @since 2.5.0 - * @deprecated 3.0 Use 'wp_make_content_images_responsive()' + * @deprecated 3.0.0 Use 'wp_make_content_images_responsive()' * @see 'wp_make_content_images_responsive()' * * @param string $content The raw post content to be filtered. @@ -260,7 +260,7 @@ function tevkori_filter_content_images( $content ) { * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. * * @since 2.3.0 - * @deprecated 3.0 Use 'wp_get_attachment_image_attributes' + * @deprecated 3.0.0 Use 'wp_get_attachment_image_attributes' * @see 'wp_get_attachment_image_attributes' * * @return array Attributes for image. From c63ebb73c4906d1cec0e3759c4854321c85c47d9 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Wed, 4 Nov 2015 23:26:07 +0100 Subject: [PATCH 53/61] Update core functions See https://core.trac.wordpress.org/changeset/35498 --- wp-tevko-core-functions.php | 51 +++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/wp-tevko-core-functions.php b/wp-tevko-core-functions.php index 7d25265..5820136 100644 --- a/wp-tevko-core-functions.php +++ b/wp-tevko-core-functions.php @@ -8,14 +8,16 @@ * @return string The base URL, cached. */ function _wp_upload_dir_baseurl() { - static $baseurl = null; + static $baseurl = array(); - if ( ! $baseurl ) { + $blog_id = get_current_blog_id(); + + if ( empty( $baseurl[ $blog_id ] ) ) { $uploads_dir = wp_upload_dir(); - $baseurl = $uploads_dir['baseurl']; + $baseurl[ $blog_id ] = $uploads_dir['baseurl']; } - return $baseurl; + return $baseurl[ $blog_id ]; } /** @@ -67,13 +69,13 @@ function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); } - $image_url = $image[0]; + $image_src = $image[0]; $size_array = array( absint( $image[1] ), absint( $image[2] ) ); - return wp_calculate_image_srcset( $image_url, $size_array, $image_meta, $attachment_id ); + return wp_calculate_image_srcset( $image_src, $size_array, $image_meta, $attachment_id ); } /** @@ -81,13 +83,13 @@ function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag * * @since 3.0.0 * - * @param string $image_name The file name, path, URL, or partial path or URL, of the image being matched. + * @param string $image_name The 'src' of the image. * @param array $size_array Array of width and height values in pixels (in that order). * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Optional. The image attachment ID to pass to the filter. * @return string|bool The 'srcset' attribute value. False on error or when only one source exists. */ -function wp_calculate_image_srcset( $image_name, $size_array, $image_meta, $attachment_id = 0 ) { +function wp_calculate_image_srcset( $image_src, $size_array, $image_meta, $attachment_id = 0 ) { if ( empty( $image_meta['sizes'] ) ) { return false; } @@ -103,20 +105,27 @@ function wp_calculate_image_srcset( $image_name, $size_array, $image_meta, $atta return false; } + $image_basename = wp_basename( $image_meta['file'] ); + $image_baseurl = _wp_upload_dir_baseurl(); + // Add full size to the '$image_sizes' array. $image_sizes['full'] = array( 'width' => $image_meta['width'], 'height' => $image_meta['height'], - 'file' => wp_basename( $image_meta['file'] ), + 'file' => $image_basename, ); - $image_baseurl = _wp_upload_dir_baseurl(); - $dirname = dirname( $image_meta['file'] ); + // Uploads are (or have been) in year/month sub-directories. + if ( $image_basename !== $image_meta['file'] ) { + $dirname = dirname( $image_meta['file'] ); - if ( $dirname !== '.' ) { - $image_baseurl = path_join( $image_baseurl, $dirname ); + if ( $dirname !== '.' ) { + $image_baseurl = trailingslashit( $image_baseurl ) . $dirname; + } } + $image_baseurl = trailingslashit( $image_baseurl ); + // Calculate the image aspect ratio. $image_ratio = $image_height / $image_width; @@ -125,7 +134,7 @@ function wp_calculate_image_srcset( $image_name, $size_array, $image_meta, $atta * contain a unique hash. Look for that hash and use it later to filter * out images that are leftovers from previous versions. */ - $image_edited = preg_match( '/-e[0-9]{13}/', $image_name, $image_edit_hash ); + $image_edited = preg_match( '/-e[0-9]{13}/', wp_basename( $image_src ), $image_edit_hash ); /** * Filter the maximum image width to be included in a 'srcset' attribute. @@ -156,8 +165,6 @@ function wp_calculate_image_srcset( $image_name, $size_array, $image_meta, $atta continue; } - $candidate_url = $image['file']; - // Calculate the new image ratio. if ( $image['width'] ) { $image_ratio_compare = $image['height'] / $image['width']; @@ -166,10 +173,10 @@ function wp_calculate_image_srcset( $image_name, $size_array, $image_meta, $atta } // If the new ratio differs by less than 0.01, use it. - if ( abs( $image_ratio - $image_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) { + if ( abs( $image_ratio - $image_ratio_compare ) < 0.01 ) { // Add the URL, descriptor, and value to the sources array to be returned. $sources[ $image['width'] ] = array( - 'url' => path_join( $image_baseurl, $candidate_url ), + 'url' => $image_baseurl . $image['file'], 'descriptor' => 'w', 'value' => $image['width'], ); @@ -222,11 +229,11 @@ function wp_calculate_image_srcset( $image_name, $size_array, $image_meta, $atta * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Optional. Image attachment ID. Either `$image_meta` or `$attachment_id` is needed * when using the image size name as argument for `$size`. - * @param string $image_url Optional. The URL to the image file. + * @param string $image_src Optional. The URL to the image file. * * @return string|bool A valid source size value for use in a 'sizes' attribute or false. */ -function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_id = 0, $image_url = null ) { +function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_id = 0, $image_src = null ) { $width = 0; if ( is_array( $size ) ) { @@ -261,9 +268,9 @@ function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_i * values in pixels (in that order). * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Image attachment ID of the original image. - * @param string $image_url Optional. The URL to the image file. + * @param string $image_src Optional. The URL to the image file. */ - return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $size, $image_meta, $attachment_id, $image_url ); + return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $size, $image_meta, $attachment_id, $image_src ); } /** From 1f12f40ad5ab3933f019d9e4f364523424672688 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Wed, 4 Nov 2015 23:27:56 +0100 Subject: [PATCH 54/61] Don't add srcset attribute to full size GIFs --- wp-tevko-core-functions.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wp-tevko-core-functions.php b/wp-tevko-core-functions.php index 5820136..6a16230 100644 --- a/wp-tevko-core-functions.php +++ b/wp-tevko-core-functions.php @@ -105,6 +105,13 @@ function wp_calculate_image_srcset( $image_src, $size_array, $image_meta, $attac return false; } + // Don't add srcset attributes to (animated) gifs that are inserted at full size. + if ( isset( $image_sizes['thumbnail']['mime-type'] ) && 'image/gif' === $image_sizes['thumbnail']['mime-type'] && + false !== strpos( $image_src, $image_meta['file'] ) ) { + + return false; + } + $image_basename = wp_basename( $image_meta['file'] ); $image_baseurl = _wp_upload_dir_baseurl(); From 4fe849e709f8a1e983cc4703de42af961fbcc773 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Thu, 5 Nov 2015 00:20:16 +0100 Subject: [PATCH 55/61] Do not deprecate tevkori_filter_attachment_image_attributes We keep using this function for WP 4.3 and older and there is no alternative. Deprecating the function would show a warning when the filter is added. --- tests/test-suite.php | 2 -- wp-tevko-deprecated-functions.php | 3 --- 2 files changed, 5 deletions(-) diff --git a/tests/test-suite.php b/tests/test-suite.php index d186346..1a8f86b 100644 --- a/tests/test-suite.php +++ b/tests/test-suite.php @@ -374,7 +374,6 @@ function test_tevkori_get_srcset_string() { /** * @group 159 - * @expectedDeprecated tevkori_filter_attachment_image_attributes */ function test_tevkori_filter_attachment_image_attributes() { // Make an image. @@ -402,7 +401,6 @@ function test_tevkori_filter_attachment_image_attributes() { /** * @group 159 - * @expectedDeprecated tevkori_filter_attachment_image_attributes */ function test_tevkori_filter_attachment_image_attributes_thumbnails() { // Make an image. diff --git a/wp-tevko-deprecated-functions.php b/wp-tevko-deprecated-functions.php index 8f02bd6..c1de576 100644 --- a/wp-tevko-deprecated-functions.php +++ b/wp-tevko-deprecated-functions.php @@ -260,14 +260,11 @@ function tevkori_filter_content_images( $content ) { * Filter to add 'srcset' and 'sizes' attributes to post thumbnails and gallery images. * * @since 2.3.0 - * @deprecated 3.0.0 Use 'wp_get_attachment_image_attributes' * @see 'wp_get_attachment_image_attributes' * * @return array Attributes for image. */ function tevkori_filter_attachment_image_attributes( $attr, $attachment, $size ) { - _deprecated_function( __FUNCTION__, '3.0.0', 'wp_get_attachment_image_attributes' ); - // Set 'srcset' and 'sizes' if not already present and both were returned. if ( empty( $attr['srcset'] ) ) { $srcset = wp_get_attachment_image_srcset( $attachment->ID, $size ); From 44388cfeed2e72f6f5be9fd0bde91f2d50cdff46 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Thu, 5 Nov 2015 00:45:39 +0100 Subject: [PATCH 56/61] Moved add_filter below the function that it's adding --- wp-tevko-core-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wp-tevko-core-functions.php b/wp-tevko-core-functions.php index 6a16230..687cc72 100644 --- a/wp-tevko-core-functions.php +++ b/wp-tevko-core-functions.php @@ -326,6 +326,7 @@ function wp_make_content_images_responsive( $content ) { return $content; } +add_filter( 'the_content', 'wp_make_content_images_responsive', 5, 1 ); /** * Check the content blob for an audio, video, object, embed, or iframe tags. @@ -367,7 +368,6 @@ function tevkori_get_media_embedded_in_content( $content, $types = null ) { return $html; } -add_filter( 'the_content', 'wp_make_content_images_responsive', 5, 1 ); /** * Adds 'srcset' and 'sizes' attributes to an existing 'img' element. From 0163649d59a3876455fe816656016416c6f8c56d Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Thu, 5 Nov 2015 00:51:47 +0100 Subject: [PATCH 57/61] Replace data-sizes for backward compatibility --- wp-tevko-core-functions.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/wp-tevko-core-functions.php b/wp-tevko-core-functions.php index 687cc72..64b75da 100644 --- a/wp-tevko-core-functions.php +++ b/wp-tevko-core-functions.php @@ -362,6 +362,16 @@ function tevkori_get_media_embedded_in_content( $content, $types = null ) { if ( preg_match_all( '#<(?P' . $tags . ')[^<]*?(?:>[\s\S]*?<\/(?P=tag)>|\s*\/>)#', $content, $matches ) ) { foreach ( $matches[0] as $match ) { + + /* + * 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. + */ + $match = str_replace( ' data-sizes="', ' sizes="', $match ); + $html[] = $match; } } From a50efa0247aab777ab25f57d0452c69e43dcc069 Mon Sep 17 00:00:00 2001 From: Jasper de Groot Date: Thu, 5 Nov 2015 01:05:03 +0100 Subject: [PATCH 58/61] Update/cleanup changelog --- readme.md | 8 ++++---- readme.txt | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/readme.md b/readme.md index 4324040..6f1da20 100644 --- a/readme.md +++ b/readme.md @@ -146,12 +146,12 @@ We use a hook because if you attempt to dequeue a script before it's enqueued, w **3.0.0** -- Deprecates core functions that have been merged into WordPress core in 4.4. +- Deprecates all core functions that will be merged into WordPress core in 4.4. - Adds compatibility shims for sites using the plugin's internal functions and hooks. -- Turns display filter callback into a general utility function for adding srcset and sizes attributes image HTML. -- Upgrade to Picturefill 3.0.1 -- Avoids calling `image_downsize()` when calculating sizes attributes to speed things up. +- Adds a new display filter callback which can be use as general utility function for adding srcset and sizes attributes. - Fixes a bug when `wp_get_attachment_metadata()` failed to return an array. +- Update our tests to be compatible with WordPress 4.4 +- Upgrade to Picturefill 3.0.1 - Clean up inline docs. **2.5.2** diff --git a/readme.txt b/readme.txt index b3a6c0f..2211bcb 100644 --- a/readme.txt +++ b/readme.txt @@ -30,12 +30,12 @@ As of version 2.5.0, the plugin adds `srcset` and `sizes` attributes to images o == Changelog == = 3.0.0 = -* Deprecates core functions that have been merged into WordPress core in 4.4. +* Deprecates all core functions that will be merged into WordPress core in 4.4. * Adds compatibility shims for sites using the plugin's internal functions and hooks. -* Turns display filter callback into a general utility function for adding srcset and sizes attributes image HTML. -* Upgrade to Picturefill 3.0.1 -* Avoids calling `image_downsize()` when calculating sizes attributes to speed things up. +* Adds a new display filter callback which can be use as general utility function for adding srcset and sizes attributes. * Fixes a bug when `wp_get_attachment_metadata()` failed to return an array. +* Update our tests to be compatible with WordPress 4.4 +* Upgrade to Picturefill 3.0.1 * Clean up inline docs. = 2.5.2 = From f67e529520ff8effe3fb3a904affb9fe250ecb9a Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Wed, 4 Nov 2015 19:29:28 -0600 Subject: [PATCH 59/61] Revert "Replace data-sizes for backward compatibility" This reverts commit 0163649d59a3876455fe816656016416c6f8c56d. --- wp-tevko-core-functions.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/wp-tevko-core-functions.php b/wp-tevko-core-functions.php index 64b75da..687cc72 100644 --- a/wp-tevko-core-functions.php +++ b/wp-tevko-core-functions.php @@ -362,16 +362,6 @@ function tevkori_get_media_embedded_in_content( $content, $types = null ) { if ( preg_match_all( '#<(?P' . $tags . ')[^<]*?(?:>[\s\S]*?<\/(?P=tag)>|\s*\/>)#', $content, $matches ) ) { foreach ( $matches[0] as $match ) { - - /* - * 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. - */ - $match = str_replace( ' data-sizes="', ' sizes="', $match ); - $html[] = $match; } } From dcb6262a52082a5ca4641423afe4a528e19c0cd1 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Wed, 4 Nov 2015 19:29:49 -0600 Subject: [PATCH 60/61] Add back compatability shim for data-sizes at all times. This comes after reverting 0163649 since we have to transform data-sizes attributes no matter which version of WP is installed. Since this filter uses a simple `str_replace()` instead of a preg_match, it's probably cleaner to add a separate filter than trying to piggyback on our `wp_make_content_images_responsive()` filter, and the performance should be similar either way. --- wp-tevko-responsive-images.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/wp-tevko-responsive-images.php b/wp-tevko-responsive-images.php index eb4195b..993c56e 100644 --- a/wp-tevko-responsive-images.php +++ b/wp-tevko-responsive-images.php @@ -59,3 +59,20 @@ function tevkori_get_picturefill() { wp_enqueue_script( 'picturefill', plugins_url( 'js/picturefill.min.js', __FILE__ ), array(), '3.0.1', true ); } add_action( 'wp_enqueue_scripts', 'tevkori_get_picturefill' ); + +/** + * Back compatability shim for 'data-sizes' attributes in content. + * + * 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. + * + * @since 3.0.0 + * + * @param string $content The content to filter; + * @return string The filtered content with `data-sizes` repaced by `sizes` attributes. + */ +function tevkori_replace_data_sizes( $content ) { + return str_replace( ' data-sizes="', ' sizes="', $content ); +} +add_filter( 'the_content', 'tevkori_replace_data_sizes' ); From c38194aef79e20fdf338b2b1d24d468d399ff6c9 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Wed, 4 Nov 2015 20:12:35 -0600 Subject: [PATCH 61/61] Update functions reference in the readme.md file --- readme.md | 96 ++++++++++++++++++++----------------------------------- 1 file changed, 35 insertions(+), 61 deletions(-) diff --git a/readme.md b/readme.md index 6f1da20..732cd46 100644 --- a/readme.md +++ b/readme.md @@ -38,97 +38,71 @@ add_action( 'after_setup_theme', 'custom_theme_setup' ); --- +### Function Reference -#### tevkori_get_sizes( $id, $size, $args ) +#### wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_id = 0, $image_src = null ) -Returns a valid source size value for use in a 'sizes' attribute. The parameters include the ID of the image, the default size of the image, and an array or string containing of size information. The ID parameter is required. [Link](https://github.com/ResponsiveImagesCG/wp-tevko-responsive-images/blob/master/wp-tevko-responsive-images.php#L28) +Create 'sizes' attribute value for an image. -***Usage Example*** +**Return:** (string|bool) A valid source size value for use in a 'sizes' attribute or false. -``` - -``` -By default, the sizes attribute will be declared as 100% of the viewport width when the viewport width is smaller than the width of the image, or to the width of the image itself when the viewport is larger than the image. In other words, this: - -`(max-width: {{image-width}}) 100vw, {{image-width}}` +##### Parameters -You can override those defaults by passing your own size values as set of arrays to the `$args` parameter. +**$size** (array|string) +Image size. Accepts any valid image size name ('thumbnail', 'medium', etc.), or an array of width and height values in pixels (in that order). -*Example:* +**$image_meta** (array) (Optional) The image meta data as returned by 'wp_get_attachment_metadata()'. -``` -$args = array( - 'sizes' => array( - array( - 'size_value' => '10em', - 'mq_value' => '60em', - 'mq_name' => 'min-width' - ), - array( - 'size_value' => '20em', - 'mq_value' => '30em', - 'mq_name' => 'min-width' - ), - array( - 'size_value' => 'calc(100vm - 30px)' - ), - ) -); - -$sizes = tevkori_get_sizes( $id, 'medium', $args ); -``` +**$attachment_id** (int) +(Optional) Image attachment ID. Either `$image_meta` or `$attachment_id` is needed when using the image size name as argument for `$size`. -Which would output a sizes value of: -`(min-width: 60em) 10em, (min-width: 30em) 20em, calc(100vm - 30px)` +**$image_src** (string) +(Optional) The URL to the image file. ---- +##### Usage Example -#### tevkori_get_sizes_string( $id, $size, $args) +``` + +``` -Returns A full 'sizes' attribute. The parameters include the ID of the image, the default size of the image, and an array or string containing of size information. The ID parameter is required. +By default, the sizes attribute will be declared as 100% of the viewport width when the viewport width is smaller than the width of the image, or to the width of the image itself when the viewport is larger than the image. In other words, this: -***Usage Example*** +`(max-width: {{image-width}}) 100vw, {{image-width}}` -``` - > -``` +You can override those defaults by adding a filter to `wp_get_attachment_image_sizes`. --- -#### tevkori_get_srcset_array( $id, $size ) -Returns an array of image source candidates for use in a 'srcset' attribute. The parameters include the ID of the image, the default size of the image, and An array of of srcset values. The ID parameter is required. [Link](https://github.com/ResponsiveImagesCG/wp-tevko-responsive-images/blob/master/wp-tevko-responsive-images.php#L132) +#### wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null ) -***Usage Example*** +Retrieves the value for an image attachment's 'srcset' attribute. -``` -$sources = tevkori_get_srcset_array( 11, 'medium' ); +**Return:** (string|bool) A 'srcset' value string or false. -// Optionally remove a specific source from the srcset list. -foreach( $sources as $key => $source ) { - if ( strpos( $source, '300w' ) ) { - unset( $s[$key] ); - } -} +##### Parameters - -``` +**$attachment_id** (int) +Image attachment ID. ---- +**$size** (array|string) +Image size. Accepts any valid image size, or an array of width and height values in pixels (in that order). Default 'medium'. -#### tevkori_get_srcset_string( $id, $size ) +**$image_meta** (array) +(Optional) The image meta data as returned by 'wp_get_attachment_metadata()'. -Returns A full 'srcset' attribute. The parameters include the ID of the image and its default size. The ID parameter is required. [Link](https://github.com/ResponsiveImagesCG/wp-tevko-responsive-images/blob/master/wp-tevko-responsive-images.php#L196) -***Usage Example*** +##### Usage Example ``` - > + ``` -**Dependencies** +--- + +### Dependencies -The only external dependency included in this plugin is [Picturefill](http://scottjehl.github.io/picturefill/) - v2.3.0. If you would like to remove Picturefill (see notes about [browser support](http://scottjehl.github.io/picturefill/#support)), add the following to your functions.php file: +The only external dependency included in this plugin is [Picturefill](http://scottjehl.github.io/picturefill/) - v3.0.1. If you would like to remove Picturefill (see notes about [browser support](http://scottjehl.github.io/picturefill/#support)), add the following to your functions.php file: function mytheme_dequeue_scripts() { wp_dequeue_script('picturefill');