Changeset 34855 for trunk/src/wp-includes/media.php
- Timestamp:
- 10/06/2015 04:58:21 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/media.php
r34851 r34855 778 778 $attr = wp_parse_args($attr, $default_attr); 779 779 780 // Generate srcset and sizes if not already present. 781 if ( empty( $attr['srcset'] ) && $srcset = wp_get_attachment_image_srcset( $attachment_id, $size ) ) { 782 $attr['srcset'] = $srcset; 783 $sizes_args = array( 784 'height' => $height, 785 'width' => $width, 786 ); 787 $attr['sizes'] = wp_get_attachment_image_sizes( $attachment_id, $size, $sizes_args ); 788 } 789 780 790 /** 781 791 * Filter the list of attachment image attributes. … … 813 823 $image = wp_get_attachment_image_src( $attachment_id, $size, $icon ); 814 824 return isset( $image['0'] ) ? $image['0'] : false; 825 } 826 827 /** 828 * Retrieves an array of URLs and pixel widths representing sizes of an image. 829 * 830 * The purpose is to populate a source set when creating responsive image markup. 831 * 832 * @since 4.4.0 833 * 834 * @param int $attachment_id Image attachment ID. 835 * @param string $size Optional. Name of image size. Default 'medium'. 836 * @return array|bool $images { 837 * Array image candidate values containing a URL, descriptor type, and 838 * descriptor value. False if none exist. 839 * 840 * @type array $values { 841 * @type string $url An image URL. 842 * @type string $descriptor A width or density descriptor used in a srcset. 843 * @type int $value The descriptor value representing a width or 844 * or pixel density. 845 * } 846 * } 847 * 848 */ 849 function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium' ) { 850 // Get the intermediate size. 851 $image = image_get_intermediate_size( $attachment_id, $size ); 852 853 // Get the post meta. 854 $img_meta = wp_get_attachment_metadata( $attachment_id ); 855 if ( ! is_array( $img_meta ) ) { 856 return false; 857 } 858 859 // Extract the height and width from the intermediate or the full size. 860 $img_width = ( $image ) ? $image['width'] : $img_meta['width']; 861 $img_height = ( $image ) ? $image['height'] : $img_meta['height']; 862 863 // Bail early if the width isn't greater that zero. 864 if ( ! $img_width > 0 ) { 865 return false; 866 } 867 868 // Use the URL from the intermediate size or build the url from the metadata. 869 if ( ! empty( $image['url'] ) ) { 870 $img_url = $image['url']; 871 } else { 872 $uploads_dir = wp_upload_dir(); 873 $img_file = ( $image ) ? path_join( dirname( $img_meta['file'] ) , $image['file'] ) : $img_meta['file']; 874 $img_url = $uploads_dir['baseurl'] . '/' . $img_file; 875 } 876 877 $img_sizes = $img_meta['sizes']; 878 879 // Add full size to the img_sizes array. 880 $img_sizes['full'] = array( 881 'width' => $img_meta['width'], 882 'height' => $img_meta['height'], 883 'file' => wp_basename( $img_meta['file'] ) 884 ); 885 886 // Calculate the image aspect ratio. 887 $img_ratio = $img_height / $img_width; 888 889 /* 890 * Images that have been edited in WordPress after being uploaded will 891 * contain a unique hash. Look for that hash and use it later to filter 892 * out images that are leftovers from previous versions. 893 */ 894 $img_edited = preg_match( '/-e[0-9]{13}/', $img_url, $img_edit_hash ); 895 896 /* 897 * Set up arrays to hold url candidates and matched image sources so 898 * we can avoid duplicates without looping through the full sources array 899 */ 900 $candidates = $sources = array(); 901 902 /* 903 * Loop through available images and only use images that are resized 904 * versions of the same rendition. 905 */ 906 foreach ( $img_sizes as $img ) { 907 908 // Filter out images that are leftovers from previous renditions. 909 if ( $img_edited && ! strpos( $img['file'], $img_edit_hash[0] ) ) { 910 continue; 911 } 912 913 $candidate_url = path_join( dirname( $img_url ), $img['file'] ); 914 915 // Calculate the new image ratio. 916 $img_ratio_compare = $img['height'] / $img['width']; 917 918 // If the new ratio differs by less than 0.01, use it. 919 if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 && ! in_array( $candidate_url, $candidates ) ) { 920 // Add the URL to our list of candidates. 921 $candidates[] = $candidate_url; 922 923 // Add the url, descriptor, and value to the sources array to be returned. 924 $sources[] = array( 925 'url' => $candidate_url, 926 'descriptor' => 'w', 927 'value' => $img['width'], 928 ); 929 } 930 } 931 932 /** 933 * Filter the output of wp_get_attachment_image_srcset_array(). 934 * 935 * @since 4.4.0 936 * 937 * @param array $sources An array of image urls and widths. 938 * @param int $attachment_id Attachment ID for image. 939 * @param array|string $size Size of image, either array or string. 940 */ 941 return apply_filters( 'wp_get_attachment_image_srcset_array', $sources, $attachment_id, $size ); 942 } 943 944 /** 945 * Retrieves the value for an image attachment's 'srcset' attribute. 946 * 947 * @since 4.4.0 948 * 949 * @param int $attachment_id Image attachment ID. 950 * @param string $size Optional. Name of image size. Default 'medium'. 951 * @return string|bool A 'srcset' value string or false. 952 */ 953 function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium' ) { 954 $srcset_array = wp_get_attachment_image_srcset_array( $attachment_id, $size ); 955 956 // Only return a srcset value if there is more than one source. 957 if ( count( $srcset_array ) <= 1 ) { 958 return false; 959 } 960 961 $srcset = ''; 962 foreach ( $srcset_array as $source ) { 963 $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', '; 964 } 965 966 /** 967 * Filter the output of wp_get_attachment_image_srcset(). 968 * 969 * @since 4.4.0 970 * 971 * @param string $srcset A source set formated for a `srcset` attribute. 972 * @param int $attachment_id Attachment ID for image. 973 * @param array|string $size Size of image, either array or string. 974 */ 975 return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size ); 976 } 977 978 /** 979 * Retrieves a source size attribute for an image from an array of values. 980 * 981 * @since 4.4.0 982 * 983 * @param int $attachment_id Image attachment ID. 984 * @param string $size Optional. Name of image size. Default value: 'medium'. 985 * @param array $args { 986 * Optional. Arguments to retrieve attachments. 987 * 988 * @type array|string $sizes An array or string containing of size information. 989 * @type int $width A single width value used in the default `sizes` string. 990 * } 991 * @return string|bool A valid source size value for use in a 'sizes' attribute or false. 992 */ 993 function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $args = null ) { 994 995 // Try to get the image width from $args before calling image_downsize(). 996 if ( is_array( $args ) && ! empty( $args['width'] ) ) { 997 $img_width = (int) $args['width']; 998 } elseif ( $img = image_get_intermediate_size( $attachment_id, $size ) ) { 999 list( $img_width, $img_height ) = image_constrain_size_for_editor( $img['width'], $img['height'], $size ); 1000 } 1001 1002 // Bail early if $image_width isn't set. 1003 if ( ! $img_width ) { 1004 return false; 1005 } 1006 1007 // Set the image width in pixels. 1008 $img_width = $img_width . 'px'; 1009 1010 // Set up our default values. 1011 $defaults = array( 1012 'sizes' => array( 1013 array( 1014 'size_value' => '100vw', 1015 'mq_value' => $img_width, 1016 'mq_name' => 'max-width' 1017 ), 1018 array( 1019 'size_value' => $img_width 1020 ), 1021 ) 1022 ); 1023 1024 $args = wp_parse_args( $args, $defaults ); 1025 1026 /** 1027 * Filter arguments used to create 'sizes' attribute. 1028 * 1029 * @since 4.4.0 1030 * 1031 * @param array $args An array of arguments used to create a 'sizes' attribute. 1032 * @param int $attachment_id Post ID of the original image. 1033 * @param string $size Name of the image size being used. 1034 */ 1035 $args = apply_filters( 'wp_image_sizes_args', $args, $attachment_id, $size ); 1036 1037 // If sizes is passed as a string, just use the string. 1038 if ( is_string( $args['sizes'] ) ) { 1039 $size_list = $args['sizes']; 1040 1041 // Otherwise, breakdown the array and build a sizes string. 1042 } elseif ( is_array( $args['sizes'] ) ) { 1043 1044 $size_list = ''; 1045 1046 foreach ( $args['sizes'] as $size ) { 1047 1048 // Use 100vw as the size value unless something else is specified. 1049 $size_value = ( $size['size_value'] ) ? $size['size_value'] : '100vw'; 1050 1051 // If a media length is specified, build the media query. 1052 if ( ! empty( $size['mq_value'] ) ) { 1053 1054 $media_length = $size['mq_value']; 1055 1056 // Use max-width as the media condition unless min-width is specified. 1057 $media_condition = ( ! empty( $size['mq_name'] ) ) ? $size['mq_name'] : 'max-width'; 1058 1059 // If a media_length was set, create the media query. 1060 $media_query = '(' . $media_condition . ": " . $media_length . ') '; 1061 1062 } else { 1063 // If no media length was set, $media_query is blank. 1064 $media_query = ''; 1065 } 1066 1067 // Add to the source size list string. 1068 $size_list .= $media_query . $size_value . ', '; 1069 } 1070 1071 // Remove the trailing comma and space from the end of the string. 1072 $size_list = substr( $size_list, 0, -2 ); 1073 } 1074 1075 // Return the sizes value as $size_list or false. 1076 return ( $size_list ) ? $size_list : false; 1077 } 1078 1079 /** 1080 * Filters 'img' elements in post content to add 'srcset' and 'sizes' attributes. 1081 * 1082 * @since 4.4.0 1083 * 1084 * @see wp_img_add_srcset_and_sizes() 1085 * 1086 * @param string $content The raw post content to be filtered. 1087 * @return string Converted content with 'srcset' and 'sizes' attributes added to images. 1088 */ 1089 function wp_make_content_images_responsive( $content ) { 1090 $images = get_media_embedded_in_content( $content, 'img' ); 1091 1092 $attachment_ids = array(); 1093 1094 foreach( $images as $image ) { 1095 if ( preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) ) { 1096 $attachment_id = (int) $class_id[1]; 1097 if ( $attachment_id ) { 1098 $attachment_ids[] = $attachment_id; 1099 } 1100 } 1101 } 1102 1103 if ( 0 < count( $attachment_ids ) ) { 1104 /* 1105 * Warm object caches for use with wp_get_attachment_metadata. 1106 * 1107 * To avoid making a database call for each image, a single query 1108 * warms the object cache with the meta information for all images. 1109 */ 1110 _prime_post_caches( $attachment_ids, false, true ); 1111 } 1112 1113 foreach( $images as $image ) { 1114 $content = str_replace( $image, wp_img_add_srcset_and_sizes( $image ), $content ); 1115 } 1116 1117 return $content; 1118 } 1119 1120 /** 1121 * Adds 'srcset' and 'sizes' attributes to an existing 'img' element. 1122 * 1123 * @since 4.4.0 1124 * 1125 * @see wp_get_attachment_image_srcset() 1126 * @see wp_get_attachment_image_sizes() 1127 * 1128 * @param string $image An HTML 'img' element to be filtered. 1129 * @return string Converted 'img' element with `srcset` and `sizes` attributes added. 1130 */ 1131 function wp_img_add_srcset_and_sizes( $image ) { 1132 // Return early if a 'srcset' attribute already exists. 1133 if ( false !== strpos( $image, ' srcset="' ) ) { 1134 return $image; 1135 } 1136 1137 // Parse id, size, width, and height from the `img` element. 1138 $id = preg_match( '/wp-image-([0-9]+)/i', $image, $match_id ) ? (int) $match_id[1] : false; 1139 $size = preg_match( '/size-([^\s|"]+)/i', $image, $match_size ) ? $match_size[1] : false; 1140 $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? (int) $match_width[1] : false; 1141 $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : false; 1142 1143 if ( $id && false === $size ) { 1144 $size = array( $width, $height ); 1145 } 1146 1147 /* 1148 * If attempts to parse the size value failed, attempt to use the image 1149 * metadata to match the 'src' against the available sizes for an attachment. 1150 */ 1151 if ( ! $size && ! empty( $id ) && is_array( $meta = wp_get_attachment_metadata( $id ) ) ) { 1152 // Parse the image src value from the img element. 1153 $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : false; 1154 1155 // Return early if the src value is empty. 1156 if ( ! $src ) { 1157 return $image; 1158 } 1159 1160 /* 1161 * First, see if the file is the full size image. If not, loop through 1162 * the intermediate sizes until we find a file that matches. 1163 */ 1164 $image_filename = wp_basename( $src ); 1165 1166 if ( $image_filename === basename( $meta['file'] ) ) { 1167 $size = 'full'; 1168 } else { 1169 foreach( $meta['sizes'] as $image_size => $image_size_data ) { 1170 if ( $image_filename === $image_size_data['file'] ) { 1171 $size = $image_size; 1172 break; 1173 } 1174 } 1175 } 1176 1177 } 1178 1179 // If ID and size, try for 'srcset' and 'sizes' and update the markup. 1180 if ( $id && $size && $srcset = wp_get_attachment_image_srcset( $id, $size ) ) { 1181 1182 /* 1183 * Pass the 'height' and 'width' to 'wp_get_attachment_image_sizes()' to avoid 1184 * recalculating the image size. 1185 */ 1186 $args = array( 1187 'height' => $height, 1188 'width' => $width, 1189 ); 1190 1191 $sizes = wp_get_attachment_image_sizes( $id, $size, $args ); 1192 1193 // Format the srcset and sizes string and escape attributes. 1194 $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes) ); 1195 1196 // Add srcset and sizes attributes to the image markup. 1197 $image = preg_replace( '/<img ([^>]+)[\s?][\/?]>/', '<img $1' . $srcset_and_sizes . ' />', $image ); 1198 } 1199 1200 return $image; 815 1201 } 816 1202 … … 2987 3373 * 2988 3374 * @since 4.2.0 3375 * @since 4.4.0 Added 'img' to the allowed types. 2989 3376 * 2990 3377 * @param array $allowed_media_types An array of allowed media types. Default media types are 2991 * 'audio', 'video', 'object', 'embed', and 'iframe'.2992 */ 2993 $allowed_media_types = apply_filters( 'media_embedded_in_content_allowed_types', array( 'audio', 'video', 'object', 'embed', 'iframe' ) );3378 * 'audio', 'video', 'object', 'embed', 'iframe', and 'img'. 3379 */ 3380 $allowed_media_types = apply_filters( 'media_embedded_in_content_allowed_types', array( 'audio', 'video', 'object', 'embed', 'iframe', 'img' ) ); 2994 3381 2995 3382 if ( ! empty( $types ) ) {
Note: See TracChangeset
for help on using the changeset viewer.