|
1 <?php |
|
2 /** |
|
3 * WordPress API for media display. |
|
4 * |
|
5 * @package WordPress |
|
6 * @subpackage Media |
|
7 */ |
|
8 |
|
9 /** |
|
10 * Scale down the default size of an image. |
|
11 * |
|
12 * This is so that the image is a better fit for the editor and theme. |
|
13 * |
|
14 * The $size parameter accepts either an array or a string. The supported string |
|
15 * values are 'thumb' or 'thumbnail' for the given thumbnail size or defaults at |
|
16 * 128 width and 96 height in pixels. Also supported for the string value is |
|
17 * 'medium' and 'full'. The 'full' isn't actually supported, but any value other |
|
18 * than the supported will result in the content_width size or 500 if that is |
|
19 * not set. |
|
20 * |
|
21 * Finally, there is a filter named 'editor_max_image_size', that will be called |
|
22 * on the calculated array for width and height, respectively. The second |
|
23 * parameter will be the value that was in the $size parameter. The returned |
|
24 * type for the hook is an array with the width as the first element and the |
|
25 * height as the second element. |
|
26 * |
|
27 * @since 2.5.0 |
|
28 * @uses wp_constrain_dimensions() This function passes the widths and the heights. |
|
29 * |
|
30 * @param int $width Width of the image |
|
31 * @param int $height Height of the image |
|
32 * @param string|array $size Size of what the result image should be. |
|
33 * @param context Could be 'display' (like in a theme) or 'edit' (like inserting into an editor) |
|
34 * @return array Width and height of what the result image should resize to. |
|
35 */ |
|
36 function image_constrain_size_for_editor($width, $height, $size = 'medium', $context = null ) { |
|
37 global $content_width, $_wp_additional_image_sizes; |
|
38 |
|
39 if ( ! $context ) |
|
40 $context = is_admin() ? 'edit' : 'display'; |
|
41 |
|
42 if ( is_array($size) ) { |
|
43 $max_width = $size[0]; |
|
44 $max_height = $size[1]; |
|
45 } |
|
46 elseif ( $size == 'thumb' || $size == 'thumbnail' ) { |
|
47 $max_width = intval(get_option('thumbnail_size_w')); |
|
48 $max_height = intval(get_option('thumbnail_size_h')); |
|
49 // last chance thumbnail size defaults |
|
50 if ( !$max_width && !$max_height ) { |
|
51 $max_width = 128; |
|
52 $max_height = 96; |
|
53 } |
|
54 } |
|
55 elseif ( $size == 'medium' ) { |
|
56 $max_width = intval(get_option('medium_size_w')); |
|
57 $max_height = intval(get_option('medium_size_h')); |
|
58 // if no width is set, default to the theme content width if available |
|
59 } |
|
60 elseif ( $size == 'large' ) { |
|
61 // We're inserting a large size image into the editor. If it's a really |
|
62 // big image we'll scale it down to fit reasonably within the editor |
|
63 // itself, and within the theme's content width if it's known. The user |
|
64 // can resize it in the editor if they wish. |
|
65 $max_width = intval(get_option('large_size_w')); |
|
66 $max_height = intval(get_option('large_size_h')); |
|
67 if ( intval($content_width) > 0 ) |
|
68 $max_width = min( intval($content_width), $max_width ); |
|
69 } elseif ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ) ) ) { |
|
70 $max_width = intval( $_wp_additional_image_sizes[$size]['width'] ); |
|
71 $max_height = intval( $_wp_additional_image_sizes[$size]['height'] ); |
|
72 if ( intval($content_width) > 0 && 'edit' == $context ) // Only in admin. Assume that theme authors know what they're doing. |
|
73 $max_width = min( intval($content_width), $max_width ); |
|
74 } |
|
75 // $size == 'full' has no constraint |
|
76 else { |
|
77 $max_width = $width; |
|
78 $max_height = $height; |
|
79 } |
|
80 |
|
81 list( $max_width, $max_height ) = apply_filters( 'editor_max_image_size', array( $max_width, $max_height ), $size, $context ); |
|
82 |
|
83 return wp_constrain_dimensions( $width, $height, $max_width, $max_height ); |
|
84 } |
|
85 |
|
86 /** |
|
87 * Retrieve width and height attributes using given width and height values. |
|
88 * |
|
89 * Both attributes are required in the sense that both parameters must have a |
|
90 * value, but are optional in that if you set them to false or null, then they |
|
91 * will not be added to the returned string. |
|
92 * |
|
93 * You can set the value using a string, but it will only take numeric values. |
|
94 * If you wish to put 'px' after the numbers, then it will be stripped out of |
|
95 * the return. |
|
96 * |
|
97 * @since 2.5.0 |
|
98 * |
|
99 * @param int|string $width Optional. Width attribute value. |
|
100 * @param int|string $height Optional. Height attribute value. |
|
101 * @return string HTML attributes for width and, or height. |
|
102 */ |
|
103 function image_hwstring($width, $height) { |
|
104 $out = ''; |
|
105 if ($width) |
|
106 $out .= 'width="'.intval($width).'" '; |
|
107 if ($height) |
|
108 $out .= 'height="'.intval($height).'" '; |
|
109 return $out; |
|
110 } |
|
111 |
|
112 /** |
|
113 * Scale an image to fit a particular size (such as 'thumb' or 'medium'). |
|
114 * |
|
115 * Array with image url, width, height, and whether is intermediate size, in |
|
116 * that order is returned on success is returned. $is_intermediate is true if |
|
117 * $url is a resized image, false if it is the original. |
|
118 * |
|
119 * The URL might be the original image, or it might be a resized version. This |
|
120 * function won't create a new resized copy, it will just return an already |
|
121 * resized one if it exists. |
|
122 * |
|
123 * A plugin may use the 'image_downsize' filter to hook into and offer image |
|
124 * resizing services for images. The hook must return an array with the same |
|
125 * elements that are returned in the function. The first element being the URL |
|
126 * to the new image that was resized. |
|
127 * |
|
128 * @since 2.5.0 |
|
129 * @uses apply_filters() Calls 'image_downsize' on $id and $size to provide |
|
130 * resize services. |
|
131 * |
|
132 * @param int $id Attachment ID for image. |
|
133 * @param array|string $size Optional, default is 'medium'. Size of image, either array or string. |
|
134 * @return bool|array False on failure, array on success. |
|
135 */ |
|
136 function image_downsize($id, $size = 'medium') { |
|
137 |
|
138 if ( !wp_attachment_is_image($id) ) |
|
139 return false; |
|
140 |
|
141 // plugins can use this to provide resize services |
|
142 if ( $out = apply_filters( 'image_downsize', false, $id, $size ) ) |
|
143 return $out; |
|
144 |
|
145 $img_url = wp_get_attachment_url($id); |
|
146 $meta = wp_get_attachment_metadata($id); |
|
147 $width = $height = 0; |
|
148 $is_intermediate = false; |
|
149 $img_url_basename = wp_basename($img_url); |
|
150 |
|
151 // try for a new style intermediate size |
|
152 if ( $intermediate = image_get_intermediate_size($id, $size) ) { |
|
153 $img_url = str_replace($img_url_basename, $intermediate['file'], $img_url); |
|
154 $width = $intermediate['width']; |
|
155 $height = $intermediate['height']; |
|
156 $is_intermediate = true; |
|
157 } |
|
158 elseif ( $size == 'thumbnail' ) { |
|
159 // fall back to the old thumbnail |
|
160 if ( ($thumb_file = wp_get_attachment_thumb_file($id)) && $info = getimagesize($thumb_file) ) { |
|
161 $img_url = str_replace($img_url_basename, wp_basename($thumb_file), $img_url); |
|
162 $width = $info[0]; |
|
163 $height = $info[1]; |
|
164 $is_intermediate = true; |
|
165 } |
|
166 } |
|
167 if ( !$width && !$height && isset( $meta['width'], $meta['height'] ) ) { |
|
168 // any other type: use the real image |
|
169 $width = $meta['width']; |
|
170 $height = $meta['height']; |
|
171 } |
|
172 |
|
173 if ( $img_url) { |
|
174 // we have the actual image size, but might need to further constrain it if content_width is narrower |
|
175 list( $width, $height ) = image_constrain_size_for_editor( $width, $height, $size ); |
|
176 |
|
177 return array( $img_url, $width, $height, $is_intermediate ); |
|
178 } |
|
179 return false; |
|
180 |
|
181 } |
|
182 |
|
183 /** |
|
184 * Registers a new image size |
|
185 * |
|
186 * @since 2.9.0 |
|
187 */ |
|
188 function add_image_size( $name, $width = 0, $height = 0, $crop = false ) { |
|
189 global $_wp_additional_image_sizes; |
|
190 $_wp_additional_image_sizes[$name] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => (bool) $crop ); |
|
191 } |
|
192 |
|
193 /** |
|
194 * Registers an image size for the post thumbnail |
|
195 * |
|
196 * @since 2.9.0 |
|
197 */ |
|
198 function set_post_thumbnail_size( $width = 0, $height = 0, $crop = false ) { |
|
199 add_image_size( 'post-thumbnail', $width, $height, $crop ); |
|
200 } |
|
201 |
|
202 /** |
|
203 * An <img src /> tag for an image attachment, scaling it down if requested. |
|
204 * |
|
205 * The filter 'get_image_tag_class' allows for changing the class name for the |
|
206 * image without having to use regular expressions on the HTML content. The |
|
207 * parameters are: what WordPress will use for the class, the Attachment ID, |
|
208 * image align value, and the size the image should be. |
|
209 * |
|
210 * The second filter 'get_image_tag' has the HTML content, which can then be |
|
211 * further manipulated by a plugin to change all attribute values and even HTML |
|
212 * content. |
|
213 * |
|
214 * @since 2.5.0 |
|
215 * |
|
216 * @uses apply_filters() The 'get_image_tag_class' filter is the IMG element |
|
217 * class attribute. |
|
218 * @uses apply_filters() The 'get_image_tag' filter is the full IMG element with |
|
219 * all attributes. |
|
220 * |
|
221 * @param int $id Attachment ID. |
|
222 * @param string $alt Image Description for the alt attribute. |
|
223 * @param string $title Image Description for the title attribute. |
|
224 * @param string $align Part of the class name for aligning the image. |
|
225 * @param string $size Optional. Default is 'medium'. |
|
226 * @return string HTML IMG element for given image attachment |
|
227 */ |
|
228 function get_image_tag($id, $alt, $title, $align, $size='medium') { |
|
229 |
|
230 list( $img_src, $width, $height ) = image_downsize($id, $size); |
|
231 $hwstring = image_hwstring($width, $height); |
|
232 |
|
233 $title = $title ? 'title="' . esc_attr( $title ) . '" ' : ''; |
|
234 |
|
235 $class = 'align' . esc_attr($align) .' size-' . esc_attr($size) . ' wp-image-' . $id; |
|
236 $class = apply_filters('get_image_tag_class', $class, $id, $align, $size); |
|
237 |
|
238 $html = '<img src="' . esc_attr($img_src) . '" alt="' . esc_attr($alt) . '" ' . $title . $hwstring . 'class="' . $class . '" />'; |
|
239 |
|
240 $html = apply_filters( 'get_image_tag', $html, $id, $alt, $title, $align, $size ); |
|
241 |
|
242 return $html; |
|
243 } |
|
244 |
|
245 /** |
|
246 * Calculates the new dimensions for a downsampled image. |
|
247 * |
|
248 * If either width or height are empty, no constraint is applied on |
|
249 * that dimension. |
|
250 * |
|
251 * @since 2.5.0 |
|
252 * |
|
253 * @param int $current_width Current width of the image. |
|
254 * @param int $current_height Current height of the image. |
|
255 * @param int $max_width Optional. Maximum wanted width. |
|
256 * @param int $max_height Optional. Maximum wanted height. |
|
257 * @return array First item is the width, the second item is the height. |
|
258 */ |
|
259 function wp_constrain_dimensions( $current_width, $current_height, $max_width=0, $max_height=0 ) { |
|
260 if ( !$max_width and !$max_height ) |
|
261 return array( $current_width, $current_height ); |
|
262 |
|
263 $width_ratio = $height_ratio = 1.0; |
|
264 $did_width = $did_height = false; |
|
265 |
|
266 if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) { |
|
267 $width_ratio = $max_width / $current_width; |
|
268 $did_width = true; |
|
269 } |
|
270 |
|
271 if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height ) { |
|
272 $height_ratio = $max_height / $current_height; |
|
273 $did_height = true; |
|
274 } |
|
275 |
|
276 // Calculate the larger/smaller ratios |
|
277 $smaller_ratio = min( $width_ratio, $height_ratio ); |
|
278 $larger_ratio = max( $width_ratio, $height_ratio ); |
|
279 |
|
280 if ( intval( $current_width * $larger_ratio ) > $max_width || intval( $current_height * $larger_ratio ) > $max_height ) |
|
281 // The larger ratio is too big. It would result in an overflow. |
|
282 $ratio = $smaller_ratio; |
|
283 else |
|
284 // The larger ratio fits, and is likely to be a more "snug" fit. |
|
285 $ratio = $larger_ratio; |
|
286 |
|
287 // Very small dimensions may result in 0, 1 should be the minimum. |
|
288 $w = max ( 1, intval( $current_width * $ratio ) ); |
|
289 $h = max ( 1, intval( $current_height * $ratio ) ); |
|
290 |
|
291 // Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short |
|
292 // We also have issues with recursive calls resulting in an ever-changing result. Constraining to the result of a constraint should yield the original result. |
|
293 // Thus we look for dimensions that are one pixel shy of the max value and bump them up |
|
294 if ( $did_width && $w == $max_width - 1 ) |
|
295 $w = $max_width; // Round it up |
|
296 if ( $did_height && $h == $max_height - 1 ) |
|
297 $h = $max_height; // Round it up |
|
298 |
|
299 return array( $w, $h ); |
|
300 } |
|
301 |
|
302 /** |
|
303 * Retrieve calculated resized dimensions for use in WP_Image_Editor. |
|
304 * |
|
305 * Calculate dimensions and coordinates for a resized image that fits within a |
|
306 * specified width and height. If $crop is true, the largest matching central |
|
307 * portion of the image will be cropped out and resized to the required size. |
|
308 * |
|
309 * @since 2.5.0 |
|
310 * @uses apply_filters() Calls 'image_resize_dimensions' on $orig_w, $orig_h, $dest_w, $dest_h and |
|
311 * $crop to provide custom resize dimensions. |
|
312 * |
|
313 * @param int $orig_w Original width. |
|
314 * @param int $orig_h Original height. |
|
315 * @param int $dest_w New width. |
|
316 * @param int $dest_h New height. |
|
317 * @param bool $crop Optional, default is false. Whether to crop image or resize. |
|
318 * @return bool|array False on failure. Returned array matches parameters for imagecopyresampled() PHP function. |
|
319 */ |
|
320 function image_resize_dimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop = false) { |
|
321 |
|
322 if ($orig_w <= 0 || $orig_h <= 0) |
|
323 return false; |
|
324 // at least one of dest_w or dest_h must be specific |
|
325 if ($dest_w <= 0 && $dest_h <= 0) |
|
326 return false; |
|
327 |
|
328 // plugins can use this to provide custom resize dimensions |
|
329 $output = apply_filters( 'image_resize_dimensions', null, $orig_w, $orig_h, $dest_w, $dest_h, $crop ); |
|
330 if ( null !== $output ) |
|
331 return $output; |
|
332 |
|
333 if ( $crop ) { |
|
334 // crop the largest possible portion of the original image that we can size to $dest_w x $dest_h |
|
335 $aspect_ratio = $orig_w / $orig_h; |
|
336 $new_w = min($dest_w, $orig_w); |
|
337 $new_h = min($dest_h, $orig_h); |
|
338 |
|
339 if ( !$new_w ) { |
|
340 $new_w = intval($new_h * $aspect_ratio); |
|
341 } |
|
342 |
|
343 if ( !$new_h ) { |
|
344 $new_h = intval($new_w / $aspect_ratio); |
|
345 } |
|
346 |
|
347 $size_ratio = max($new_w / $orig_w, $new_h / $orig_h); |
|
348 |
|
349 $crop_w = round($new_w / $size_ratio); |
|
350 $crop_h = round($new_h / $size_ratio); |
|
351 |
|
352 $s_x = floor( ($orig_w - $crop_w) / 2 ); |
|
353 $s_y = floor( ($orig_h - $crop_h) / 2 ); |
|
354 } else { |
|
355 // don't crop, just resize using $dest_w x $dest_h as a maximum bounding box |
|
356 $crop_w = $orig_w; |
|
357 $crop_h = $orig_h; |
|
358 |
|
359 $s_x = 0; |
|
360 $s_y = 0; |
|
361 |
|
362 list( $new_w, $new_h ) = wp_constrain_dimensions( $orig_w, $orig_h, $dest_w, $dest_h ); |
|
363 } |
|
364 |
|
365 // if the resulting image would be the same size or larger we don't want to resize it |
|
366 if ( $new_w >= $orig_w && $new_h >= $orig_h ) |
|
367 return false; |
|
368 |
|
369 // the return array matches the parameters to imagecopyresampled() |
|
370 // int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h |
|
371 return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h ); |
|
372 |
|
373 } |
|
374 |
|
375 /** |
|
376 * Resize an image to make a thumbnail or intermediate size. |
|
377 * |
|
378 * The returned array has the file size, the image width, and image height. The |
|
379 * filter 'image_make_intermediate_size' can be used to hook in and change the |
|
380 * values of the returned array. The only parameter is the resized file path. |
|
381 * |
|
382 * @since 2.5.0 |
|
383 * |
|
384 * @param string $file File path. |
|
385 * @param int $width Image width. |
|
386 * @param int $height Image height. |
|
387 * @param bool $crop Optional, default is false. Whether to crop image to specified height and width or resize. |
|
388 * @return bool|array False, if no image was created. Metadata array on success. |
|
389 */ |
|
390 function image_make_intermediate_size( $file, $width, $height, $crop = false ) { |
|
391 if ( $width || $height ) { |
|
392 $editor = wp_get_image_editor( $file ); |
|
393 |
|
394 if ( is_wp_error( $editor ) || is_wp_error( $editor->resize( $width, $height, $crop ) ) ) |
|
395 return false; |
|
396 |
|
397 $resized_file = $editor->save(); |
|
398 |
|
399 if ( ! is_wp_error( $resized_file ) && $resized_file ) { |
|
400 unset( $resized_file['path'] ); |
|
401 return $resized_file; |
|
402 } |
|
403 } |
|
404 return false; |
|
405 } |
|
406 |
|
407 /** |
|
408 * Retrieve the image's intermediate size (resized) path, width, and height. |
|
409 * |
|
410 * The $size parameter can be an array with the width and height respectively. |
|
411 * If the size matches the 'sizes' metadata array for width and height, then it |
|
412 * will be used. If there is no direct match, then the nearest image size larger |
|
413 * than the specified size will be used. If nothing is found, then the function |
|
414 * will break out and return false. |
|
415 * |
|
416 * The metadata 'sizes' is used for compatible sizes that can be used for the |
|
417 * parameter $size value. |
|
418 * |
|
419 * The url path will be given, when the $size parameter is a string. |
|
420 * |
|
421 * If you are passing an array for the $size, you should consider using |
|
422 * add_image_size() so that a cropped version is generated. It's much more |
|
423 * efficient than having to find the closest-sized image and then having the |
|
424 * browser scale down the image. |
|
425 * |
|
426 * @since 2.5.0 |
|
427 * @see add_image_size() |
|
428 * |
|
429 * @param int $post_id Attachment ID for image. |
|
430 * @param array|string $size Optional, default is 'thumbnail'. Size of image, either array or string. |
|
431 * @return bool|array False on failure or array of file path, width, and height on success. |
|
432 */ |
|
433 function image_get_intermediate_size($post_id, $size='thumbnail') { |
|
434 if ( !is_array( $imagedata = wp_get_attachment_metadata( $post_id ) ) ) |
|
435 return false; |
|
436 |
|
437 // get the best one for a specified set of dimensions |
|
438 if ( is_array($size) && !empty($imagedata['sizes']) ) { |
|
439 foreach ( $imagedata['sizes'] as $_size => $data ) { |
|
440 // already cropped to width or height; so use this size |
|
441 if ( ( $data['width'] == $size[0] && $data['height'] <= $size[1] ) || ( $data['height'] == $size[1] && $data['width'] <= $size[0] ) ) { |
|
442 $file = $data['file']; |
|
443 list($width, $height) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); |
|
444 return compact( 'file', 'width', 'height' ); |
|
445 } |
|
446 // add to lookup table: area => size |
|
447 $areas[$data['width'] * $data['height']] = $_size; |
|
448 } |
|
449 if ( !$size || !empty($areas) ) { |
|
450 // find for the smallest image not smaller than the desired size |
|
451 ksort($areas); |
|
452 foreach ( $areas as $_size ) { |
|
453 $data = $imagedata['sizes'][$_size]; |
|
454 if ( $data['width'] >= $size[0] || $data['height'] >= $size[1] ) { |
|
455 // Skip images with unexpectedly divergent aspect ratios (crops) |
|
456 // First, we calculate what size the original image would be if constrained to a box the size of the current image in the loop |
|
457 $maybe_cropped = image_resize_dimensions($imagedata['width'], $imagedata['height'], $data['width'], $data['height'], false ); |
|
458 // If the size doesn't match within one pixel, then it is of a different aspect ratio, so we skip it, unless it's the thumbnail size |
|
459 if ( 'thumbnail' != $_size && ( !$maybe_cropped || ( $maybe_cropped[4] != $data['width'] && $maybe_cropped[4] + 1 != $data['width'] ) || ( $maybe_cropped[5] != $data['height'] && $maybe_cropped[5] + 1 != $data['height'] ) ) ) |
|
460 continue; |
|
461 // If we're still here, then we're going to use this size |
|
462 $file = $data['file']; |
|
463 list($width, $height) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); |
|
464 return compact( 'file', 'width', 'height' ); |
|
465 } |
|
466 } |
|
467 } |
|
468 } |
|
469 |
|
470 if ( is_array($size) || empty($size) || empty($imagedata['sizes'][$size]) ) |
|
471 return false; |
|
472 |
|
473 $data = $imagedata['sizes'][$size]; |
|
474 // include the full filesystem path of the intermediate file |
|
475 if ( empty($data['path']) && !empty($data['file']) ) { |
|
476 $file_url = wp_get_attachment_url($post_id); |
|
477 $data['path'] = path_join( dirname($imagedata['file']), $data['file'] ); |
|
478 $data['url'] = path_join( dirname($file_url), $data['file'] ); |
|
479 } |
|
480 return $data; |
|
481 } |
|
482 |
|
483 /** |
|
484 * Get the available image sizes |
|
485 * @since 3.0.0 |
|
486 * @return array Returns a filtered array of image size strings |
|
487 */ |
|
488 function get_intermediate_image_sizes() { |
|
489 global $_wp_additional_image_sizes; |
|
490 $image_sizes = array('thumbnail', 'medium', 'large'); // Standard sizes |
|
491 if ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) ) |
|
492 $image_sizes = array_merge( $image_sizes, array_keys( $_wp_additional_image_sizes ) ); |
|
493 |
|
494 return apply_filters( 'intermediate_image_sizes', $image_sizes ); |
|
495 } |
|
496 |
|
497 /** |
|
498 * Retrieve an image to represent an attachment. |
|
499 * |
|
500 * A mime icon for files, thumbnail or intermediate size for images. |
|
501 * |
|
502 * @since 2.5.0 |
|
503 * |
|
504 * @param int $attachment_id Image attachment ID. |
|
505 * @param string $size Optional, default is 'thumbnail'. |
|
506 * @param bool $icon Optional, default is false. Whether it is an icon. |
|
507 * @return bool|array Returns an array (url, width, height), or false, if no image is available. |
|
508 */ |
|
509 function wp_get_attachment_image_src($attachment_id, $size='thumbnail', $icon = false) { |
|
510 |
|
511 // get a thumbnail or intermediate image if there is one |
|
512 if ( $image = image_downsize($attachment_id, $size) ) |
|
513 return $image; |
|
514 |
|
515 $src = false; |
|
516 |
|
517 if ( $icon && $src = wp_mime_type_icon($attachment_id) ) { |
|
518 $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/crystal' ); |
|
519 $src_file = $icon_dir . '/' . wp_basename($src); |
|
520 @list($width, $height) = getimagesize($src_file); |
|
521 } |
|
522 if ( $src && $width && $height ) |
|
523 return array( $src, $width, $height ); |
|
524 return false; |
|
525 } |
|
526 |
|
527 /** |
|
528 * Get an HTML img element representing an image attachment |
|
529 * |
|
530 * While $size will accept an array, it is better to register a size with |
|
531 * add_image_size() so that a cropped version is generated. It's much more |
|
532 * efficient than having to find the closest-sized image and then having the |
|
533 * browser scale down the image. |
|
534 * |
|
535 * @see add_image_size() |
|
536 * @uses apply_filters() Calls 'wp_get_attachment_image_attributes' hook on attributes array |
|
537 * @uses wp_get_attachment_image_src() Gets attachment file URL and dimensions |
|
538 * @since 2.5.0 |
|
539 * |
|
540 * @param int $attachment_id Image attachment ID. |
|
541 * @param string $size Optional, default is 'thumbnail'. |
|
542 * @param bool $icon Optional, default is false. Whether it is an icon. |
|
543 * @param mixed $attr Optional, attributes for the image markup. |
|
544 * @return string HTML img element or empty string on failure. |
|
545 */ |
|
546 function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = false, $attr = '') { |
|
547 |
|
548 $html = ''; |
|
549 $image = wp_get_attachment_image_src($attachment_id, $size, $icon); |
|
550 if ( $image ) { |
|
551 list($src, $width, $height) = $image; |
|
552 $hwstring = image_hwstring($width, $height); |
|
553 if ( is_array($size) ) |
|
554 $size = join('x', $size); |
|
555 $attachment = get_post($attachment_id); |
|
556 $default_attr = array( |
|
557 'src' => $src, |
|
558 'class' => "attachment-$size", |
|
559 'alt' => trim(strip_tags( get_post_meta($attachment_id, '_wp_attachment_image_alt', true) )), // Use Alt field first |
|
560 ); |
|
561 if ( empty($default_attr['alt']) ) |
|
562 $default_attr['alt'] = trim(strip_tags( $attachment->post_excerpt )); // If not, Use the Caption |
|
563 if ( empty($default_attr['alt']) ) |
|
564 $default_attr['alt'] = trim(strip_tags( $attachment->post_title )); // Finally, use the title |
|
565 |
|
566 $attr = wp_parse_args($attr, $default_attr); |
|
567 $attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment ); |
|
568 $attr = array_map( 'esc_attr', $attr ); |
|
569 $html = rtrim("<img $hwstring"); |
|
570 foreach ( $attr as $name => $value ) { |
|
571 $html .= " $name=" . '"' . $value . '"'; |
|
572 } |
|
573 $html .= ' />'; |
|
574 } |
|
575 |
|
576 return $html; |
|
577 } |
|
578 |
|
579 /** |
|
580 * Adds a 'wp-post-image' class to post thumbnails |
|
581 * Uses the begin_fetch_post_thumbnail_html and end_fetch_post_thumbnail_html action hooks to |
|
582 * dynamically add/remove itself so as to only filter post thumbnails |
|
583 * |
|
584 * @since 2.9.0 |
|
585 * @param array $attr Attributes including src, class, alt, title |
|
586 * @return array |
|
587 */ |
|
588 function _wp_post_thumbnail_class_filter( $attr ) { |
|
589 $attr['class'] .= ' wp-post-image'; |
|
590 return $attr; |
|
591 } |
|
592 |
|
593 /** |
|
594 * Adds _wp_post_thumbnail_class_filter to the wp_get_attachment_image_attributes filter |
|
595 * |
|
596 * @since 2.9.0 |
|
597 */ |
|
598 function _wp_post_thumbnail_class_filter_add( $attr ) { |
|
599 add_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' ); |
|
600 } |
|
601 |
|
602 /** |
|
603 * Removes _wp_post_thumbnail_class_filter from the wp_get_attachment_image_attributes filter |
|
604 * |
|
605 * @since 2.9.0 |
|
606 */ |
|
607 function _wp_post_thumbnail_class_filter_remove( $attr ) { |
|
608 remove_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' ); |
|
609 } |
|
610 |
|
611 add_shortcode('wp_caption', 'img_caption_shortcode'); |
|
612 add_shortcode('caption', 'img_caption_shortcode'); |
|
613 |
|
614 /** |
|
615 * The Caption shortcode. |
|
616 * |
|
617 * Allows a plugin to replace the content that would otherwise be returned. The |
|
618 * filter is 'img_caption_shortcode' and passes an empty string, the attr |
|
619 * parameter and the content parameter values. |
|
620 * |
|
621 * The supported attributes for the shortcode are 'id', 'align', 'width', and |
|
622 * 'caption'. |
|
623 * |
|
624 * @since 2.6.0 |
|
625 * |
|
626 * @param array $attr Attributes attributed to the shortcode. |
|
627 * @param string $content Optional. Shortcode content. |
|
628 * @return string |
|
629 */ |
|
630 function img_caption_shortcode($attr, $content = null) { |
|
631 // New-style shortcode with the caption inside the shortcode with the link and image tags. |
|
632 if ( ! isset( $attr['caption'] ) ) { |
|
633 if ( preg_match( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is', $content, $matches ) ) { |
|
634 $content = $matches[1]; |
|
635 $attr['caption'] = trim( $matches[2] ); |
|
636 } |
|
637 } |
|
638 |
|
639 // Allow plugins/themes to override the default caption template. |
|
640 $output = apply_filters('img_caption_shortcode', '', $attr, $content); |
|
641 if ( $output != '' ) |
|
642 return $output; |
|
643 |
|
644 $atts = shortcode_atts( array( |
|
645 'id' => '', |
|
646 'align' => 'alignnone', |
|
647 'width' => '', |
|
648 'caption' => '' |
|
649 ), $attr, 'caption' ); |
|
650 |
|
651 $atts['width'] = (int) $atts['width']; |
|
652 if ( $atts['width'] < 1 || empty( $atts['caption'] ) ) |
|
653 return $content; |
|
654 |
|
655 if ( ! empty( $atts['id'] ) ) |
|
656 $atts['id'] = 'id="' . esc_attr( $atts['id'] ) . '" '; |
|
657 |
|
658 $caption_width = 10 + $atts['width']; |
|
659 |
|
660 /** |
|
661 * Filter the width of an image's caption. |
|
662 * |
|
663 * By default, the caption is 10 pixels greater than the width of the image, |
|
664 * to prevent post content from running up against a floated image. |
|
665 * |
|
666 * @since 3.7.0 |
|
667 * |
|
668 * @param int $caption_width Width in pixels. To remove this inline style, return zero. |
|
669 * @param array $atts { |
|
670 * The attributes of the caption shortcode. |
|
671 * |
|
672 * @type string 'id' The ID of the div element for the caption. |
|
673 * @type string 'align' The class name that aligns the caption. Default 'alignnone'. |
|
674 * @type int 'width' The width of the image being captioned. |
|
675 * @type string 'caption' The image's caption. |
|
676 * } |
|
677 * @param string $content The image element, possibly wrapped in a hyperlink. |
|
678 */ |
|
679 $caption_width = apply_filters( 'img_caption_shortcode_width', $caption_width, $atts, $content ); |
|
680 |
|
681 $style = ''; |
|
682 if ( $caption_width ) |
|
683 $style = 'style="width: ' . (int) $caption_width . 'px" '; |
|
684 |
|
685 return '<div ' . $atts['id'] . $style . 'class="wp-caption ' . esc_attr( $atts['align'] ) . '">' |
|
686 . do_shortcode( $content ) . '<p class="wp-caption-text">' . $atts['caption'] . '</p></div>'; |
|
687 } |
|
688 |
|
689 add_shortcode('gallery', 'gallery_shortcode'); |
|
690 |
|
691 /** |
|
692 * The Gallery shortcode. |
|
693 * |
|
694 * This implements the functionality of the Gallery Shortcode for displaying |
|
695 * WordPress images on a post. |
|
696 * |
|
697 * @since 2.5.0 |
|
698 * |
|
699 * @param array $attr Attributes of the shortcode. |
|
700 * @return string HTML content to display gallery. |
|
701 */ |
|
702 function gallery_shortcode($attr) { |
|
703 $post = get_post(); |
|
704 |
|
705 static $instance = 0; |
|
706 $instance++; |
|
707 |
|
708 if ( ! empty( $attr['ids'] ) ) { |
|
709 // 'ids' is explicitly ordered, unless you specify otherwise. |
|
710 if ( empty( $attr['orderby'] ) ) |
|
711 $attr['orderby'] = 'post__in'; |
|
712 $attr['include'] = $attr['ids']; |
|
713 } |
|
714 |
|
715 // Allow plugins/themes to override the default gallery template. |
|
716 $output = apply_filters('post_gallery', '', $attr); |
|
717 if ( $output != '' ) |
|
718 return $output; |
|
719 |
|
720 // We're trusting author input, so let's at least make sure it looks like a valid orderby statement |
|
721 if ( isset( $attr['orderby'] ) ) { |
|
722 $attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] ); |
|
723 if ( !$attr['orderby'] ) |
|
724 unset( $attr['orderby'] ); |
|
725 } |
|
726 |
|
727 extract(shortcode_atts(array( |
|
728 'order' => 'ASC', |
|
729 'orderby' => 'menu_order ID', |
|
730 'id' => $post ? $post->ID : 0, |
|
731 'itemtag' => 'dl', |
|
732 'icontag' => 'dt', |
|
733 'captiontag' => 'dd', |
|
734 'columns' => 3, |
|
735 'size' => 'thumbnail', |
|
736 'include' => '', |
|
737 'exclude' => '', |
|
738 'link' => '' |
|
739 ), $attr, 'gallery')); |
|
740 |
|
741 $id = intval($id); |
|
742 if ( 'RAND' == $order ) |
|
743 $orderby = 'none'; |
|
744 |
|
745 if ( !empty($include) ) { |
|
746 $_attachments = get_posts( array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); |
|
747 |
|
748 $attachments = array(); |
|
749 foreach ( $_attachments as $key => $val ) { |
|
750 $attachments[$val->ID] = $_attachments[$key]; |
|
751 } |
|
752 } elseif ( !empty($exclude) ) { |
|
753 $attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); |
|
754 } else { |
|
755 $attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); |
|
756 } |
|
757 |
|
758 if ( empty($attachments) ) |
|
759 return ''; |
|
760 |
|
761 if ( is_feed() ) { |
|
762 $output = "\n"; |
|
763 foreach ( $attachments as $att_id => $attachment ) |
|
764 $output .= wp_get_attachment_link($att_id, $size, true) . "\n"; |
|
765 return $output; |
|
766 } |
|
767 |
|
768 $itemtag = tag_escape($itemtag); |
|
769 $captiontag = tag_escape($captiontag); |
|
770 $icontag = tag_escape($icontag); |
|
771 $valid_tags = wp_kses_allowed_html( 'post' ); |
|
772 if ( ! isset( $valid_tags[ $itemtag ] ) ) |
|
773 $itemtag = 'dl'; |
|
774 if ( ! isset( $valid_tags[ $captiontag ] ) ) |
|
775 $captiontag = 'dd'; |
|
776 if ( ! isset( $valid_tags[ $icontag ] ) ) |
|
777 $icontag = 'dt'; |
|
778 |
|
779 $columns = intval($columns); |
|
780 $itemwidth = $columns > 0 ? floor(100/$columns) : 100; |
|
781 $float = is_rtl() ? 'right' : 'left'; |
|
782 |
|
783 $selector = "gallery-{$instance}"; |
|
784 |
|
785 $gallery_style = $gallery_div = ''; |
|
786 if ( apply_filters( 'use_default_gallery_style', true ) ) |
|
787 $gallery_style = " |
|
788 <style type='text/css'> |
|
789 #{$selector} { |
|
790 margin: auto; |
|
791 } |
|
792 #{$selector} .gallery-item { |
|
793 float: {$float}; |
|
794 margin-top: 10px; |
|
795 text-align: center; |
|
796 width: {$itemwidth}%; |
|
797 } |
|
798 #{$selector} img { |
|
799 border: 2px solid #cfcfcf; |
|
800 } |
|
801 #{$selector} .gallery-caption { |
|
802 margin-left: 0; |
|
803 } |
|
804 /* see gallery_shortcode() in wp-includes/media.php */ |
|
805 </style>"; |
|
806 $size_class = sanitize_html_class( $size ); |
|
807 $gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>"; |
|
808 $output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div ); |
|
809 |
|
810 $i = 0; |
|
811 foreach ( $attachments as $id => $attachment ) { |
|
812 if ( ! empty( $link ) && 'file' === $link ) |
|
813 $image_output = wp_get_attachment_link( $id, $size, false, false ); |
|
814 elseif ( ! empty( $link ) && 'none' === $link ) |
|
815 $image_output = wp_get_attachment_image( $id, $size, false ); |
|
816 else |
|
817 $image_output = wp_get_attachment_link( $id, $size, true, false ); |
|
818 |
|
819 $image_meta = wp_get_attachment_metadata( $id ); |
|
820 |
|
821 $orientation = ''; |
|
822 if ( isset( $image_meta['height'], $image_meta['width'] ) ) |
|
823 $orientation = ( $image_meta['height'] > $image_meta['width'] ) ? 'portrait' : 'landscape'; |
|
824 |
|
825 $output .= "<{$itemtag} class='gallery-item'>"; |
|
826 $output .= " |
|
827 <{$icontag} class='gallery-icon {$orientation}'> |
|
828 $image_output |
|
829 </{$icontag}>"; |
|
830 if ( $captiontag && trim($attachment->post_excerpt) ) { |
|
831 $output .= " |
|
832 <{$captiontag} class='wp-caption-text gallery-caption'> |
|
833 " . wptexturize($attachment->post_excerpt) . " |
|
834 </{$captiontag}>"; |
|
835 } |
|
836 $output .= "</{$itemtag}>"; |
|
837 if ( $columns > 0 && ++$i % $columns == 0 ) |
|
838 $output .= '<br style="clear: both" />'; |
|
839 } |
|
840 |
|
841 $output .= " |
|
842 <br style='clear: both;' /> |
|
843 </div>\n"; |
|
844 |
|
845 return $output; |
|
846 } |
|
847 |
|
848 /** |
|
849 * Provide a No-JS Flash fallback as a last resort for audio / video |
|
850 * |
|
851 * @since 3.6.0 |
|
852 * |
|
853 * @param string $url |
|
854 * @return string Fallback HTML |
|
855 */ |
|
856 function wp_mediaelement_fallback( $url ) { |
|
857 return apply_filters( 'wp_mediaelement_fallback', sprintf( '<a href="%1$s">%1$s</a>', esc_url( $url ) ), $url ); |
|
858 } |
|
859 |
|
860 /** |
|
861 * Return a filtered list of WP-supported audio formats |
|
862 * |
|
863 * @since 3.6.0 |
|
864 * @return array |
|
865 */ |
|
866 function wp_get_audio_extensions() { |
|
867 return apply_filters( 'wp_audio_extensions', array( 'mp3', 'ogg', 'wma', 'm4a', 'wav' ) ); |
|
868 } |
|
869 |
|
870 /** |
|
871 * The Audio shortcode. |
|
872 * |
|
873 * This implements the functionality of the Audio Shortcode for displaying |
|
874 * WordPress mp3s in a post. |
|
875 * |
|
876 * @since 3.6.0 |
|
877 * |
|
878 * @param array $attr Attributes of the shortcode. |
|
879 * @param string $content Optional. Shortcode content. |
|
880 * @return string HTML content to display audio. |
|
881 */ |
|
882 function wp_audio_shortcode( $attr, $content = '' ) { |
|
883 $post_id = get_post() ? get_the_ID() : 0; |
|
884 |
|
885 static $instances = 0; |
|
886 $instances++; |
|
887 |
|
888 /** |
|
889 * Override the default audio shortcode. |
|
890 * |
|
891 * @since 3.7.0 |
|
892 * |
|
893 * @param null Empty variable to be replaced with shortcode markup. |
|
894 * @param array $attr Attributes of the shortcode. |
|
895 * @param string $content Shortcode content. |
|
896 * @param int $instances Unique numeric ID of this audio shortcode instance. |
|
897 */ |
|
898 $html = apply_filters( 'wp_audio_shortcode_override', '', $attr, $content, $instances ); |
|
899 if ( '' !== $html ) |
|
900 return $html; |
|
901 |
|
902 $audio = null; |
|
903 |
|
904 $default_types = wp_get_audio_extensions(); |
|
905 $defaults_atts = array( |
|
906 'src' => '', |
|
907 'loop' => '', |
|
908 'autoplay' => '', |
|
909 'preload' => 'none' |
|
910 ); |
|
911 foreach ( $default_types as $type ) |
|
912 $defaults_atts[$type] = ''; |
|
913 |
|
914 $atts = shortcode_atts( $defaults_atts, $attr, 'audio' ); |
|
915 extract( $atts ); |
|
916 |
|
917 $primary = false; |
|
918 if ( ! empty( $src ) ) { |
|
919 $type = wp_check_filetype( $src, wp_get_mime_types() ); |
|
920 if ( ! in_array( strtolower( $type['ext'] ), $default_types ) ) |
|
921 return sprintf( '<a class="wp-embedded-audio" href="%s">%s</a>', esc_url( $src ), esc_html( $src ) ); |
|
922 $primary = true; |
|
923 array_unshift( $default_types, 'src' ); |
|
924 } else { |
|
925 foreach ( $default_types as $ext ) { |
|
926 if ( ! empty( $$ext ) ) { |
|
927 $type = wp_check_filetype( $$ext, wp_get_mime_types() ); |
|
928 if ( strtolower( $type['ext'] ) === $ext ) |
|
929 $primary = true; |
|
930 } |
|
931 } |
|
932 } |
|
933 |
|
934 if ( ! $primary ) { |
|
935 $audios = get_attached_media( 'audio', $post_id ); |
|
936 if ( empty( $audios ) ) |
|
937 return; |
|
938 |
|
939 $audio = reset( $audios ); |
|
940 $src = wp_get_attachment_url( $audio->ID ); |
|
941 if ( empty( $src ) ) |
|
942 return; |
|
943 |
|
944 array_unshift( $default_types, 'src' ); |
|
945 } |
|
946 |
|
947 $library = apply_filters( 'wp_audio_shortcode_library', 'mediaelement' ); |
|
948 if ( 'mediaelement' === $library && did_action( 'init' ) ) { |
|
949 wp_enqueue_style( 'wp-mediaelement' ); |
|
950 wp_enqueue_script( 'wp-mediaelement' ); |
|
951 } |
|
952 |
|
953 $atts = array( |
|
954 'class' => apply_filters( 'wp_audio_shortcode_class', 'wp-audio-shortcode' ), |
|
955 'id' => sprintf( 'audio-%d-%d', $post_id, $instances ), |
|
956 'loop' => $loop, |
|
957 'autoplay' => $autoplay, |
|
958 'preload' => $preload, |
|
959 'style' => 'width: 100%', |
|
960 ); |
|
961 |
|
962 // These ones should just be omitted altogether if they are blank |
|
963 foreach ( array( 'loop', 'autoplay', 'preload' ) as $a ) { |
|
964 if ( empty( $atts[$a] ) ) |
|
965 unset( $atts[$a] ); |
|
966 } |
|
967 |
|
968 $attr_strings = array(); |
|
969 foreach ( $atts as $k => $v ) { |
|
970 $attr_strings[] = $k . '="' . esc_attr( $v ) . '"'; |
|
971 } |
|
972 |
|
973 $html = ''; |
|
974 if ( 'mediaelement' === $library && 1 === $instances ) |
|
975 $html .= "<!--[if lt IE 9]><script>document.createElement('audio');</script><![endif]-->\n"; |
|
976 $html .= sprintf( '<audio %s controls="controls">', join( ' ', $attr_strings ) ); |
|
977 |
|
978 $fileurl = ''; |
|
979 $source = '<source type="%s" src="%s" />'; |
|
980 foreach ( $default_types as $fallback ) { |
|
981 if ( ! empty( $$fallback ) ) { |
|
982 if ( empty( $fileurl ) ) |
|
983 $fileurl = $$fallback; |
|
984 $type = wp_check_filetype( $$fallback, wp_get_mime_types() ); |
|
985 $html .= sprintf( $source, $type['type'], esc_url( $$fallback ) ); |
|
986 } |
|
987 } |
|
988 |
|
989 if ( 'mediaelement' === $library ) |
|
990 $html .= wp_mediaelement_fallback( $fileurl ); |
|
991 $html .= '</audio>'; |
|
992 |
|
993 return apply_filters( 'wp_audio_shortcode', $html, $atts, $audio, $post_id, $library ); |
|
994 } |
|
995 add_shortcode( 'audio', 'wp_audio_shortcode' ); |
|
996 |
|
997 /** |
|
998 * Return a filtered list of WP-supported video formats |
|
999 * |
|
1000 * @since 3.6.0 |
|
1001 * @return array |
|
1002 */ |
|
1003 function wp_get_video_extensions() { |
|
1004 return apply_filters( 'wp_video_extensions', array( 'mp4', 'm4v', 'webm', 'ogv', 'wmv', 'flv' ) ); |
|
1005 } |
|
1006 |
|
1007 /** |
|
1008 * The Video shortcode. |
|
1009 * |
|
1010 * This implements the functionality of the Video Shortcode for displaying |
|
1011 * WordPress mp4s in a post. |
|
1012 * |
|
1013 * @since 3.6.0 |
|
1014 * |
|
1015 * @param array $attr Attributes of the shortcode. |
|
1016 * @param string $content Optional. Shortcode content. |
|
1017 * @return string HTML content to display video. |
|
1018 */ |
|
1019 function wp_video_shortcode( $attr, $content = '' ) { |
|
1020 global $content_width; |
|
1021 $post_id = get_post() ? get_the_ID() : 0; |
|
1022 |
|
1023 static $instances = 0; |
|
1024 $instances++; |
|
1025 |
|
1026 /** |
|
1027 * Override the default video shortcode. |
|
1028 * |
|
1029 * @since 3.7.0 |
|
1030 * |
|
1031 * @param null Empty variable to be replaced with shortcode markup. |
|
1032 * @param array $attr Attributes of the shortcode. |
|
1033 * @param string $content Shortcode content. |
|
1034 * @param int $instances Unique numeric ID of this video shortcode instance. |
|
1035 */ |
|
1036 $html = apply_filters( 'wp_video_shortcode_override', '', $attr, $content, $instances ); |
|
1037 if ( '' !== $html ) |
|
1038 return $html; |
|
1039 |
|
1040 $video = null; |
|
1041 |
|
1042 $default_types = wp_get_video_extensions(); |
|
1043 $defaults_atts = array( |
|
1044 'src' => '', |
|
1045 'poster' => '', |
|
1046 'loop' => '', |
|
1047 'autoplay' => '', |
|
1048 'preload' => 'metadata', |
|
1049 'height' => 360, |
|
1050 'width' => empty( $content_width ) ? 640 : $content_width, |
|
1051 ); |
|
1052 |
|
1053 foreach ( $default_types as $type ) |
|
1054 $defaults_atts[$type] = ''; |
|
1055 |
|
1056 $atts = shortcode_atts( $defaults_atts, $attr, 'video' ); |
|
1057 extract( $atts ); |
|
1058 |
|
1059 $w = $width; |
|
1060 $h = $height; |
|
1061 if ( is_admin() && $width > 600 ) |
|
1062 $w = 600; |
|
1063 elseif ( ! is_admin() && $w > $defaults_atts['width'] ) |
|
1064 $w = $defaults_atts['width']; |
|
1065 |
|
1066 if ( $w < $width ) |
|
1067 $height = round( ( $h * $w ) / $width ); |
|
1068 |
|
1069 $width = $w; |
|
1070 |
|
1071 $primary = false; |
|
1072 if ( ! empty( $src ) ) { |
|
1073 $type = wp_check_filetype( $src, wp_get_mime_types() ); |
|
1074 if ( ! in_array( strtolower( $type['ext'] ), $default_types ) ) |
|
1075 return sprintf( '<a class="wp-embedded-video" href="%s">%s</a>', esc_url( $src ), esc_html( $src ) ); |
|
1076 $primary = true; |
|
1077 array_unshift( $default_types, 'src' ); |
|
1078 } else { |
|
1079 foreach ( $default_types as $ext ) { |
|
1080 if ( ! empty( $$ext ) ) { |
|
1081 $type = wp_check_filetype( $$ext, wp_get_mime_types() ); |
|
1082 if ( strtolower( $type['ext'] ) === $ext ) |
|
1083 $primary = true; |
|
1084 } |
|
1085 } |
|
1086 } |
|
1087 |
|
1088 if ( ! $primary ) { |
|
1089 $videos = get_attached_media( 'video', $post_id ); |
|
1090 if ( empty( $videos ) ) |
|
1091 return; |
|
1092 |
|
1093 $video = reset( $videos ); |
|
1094 $src = wp_get_attachment_url( $video->ID ); |
|
1095 if ( empty( $src ) ) |
|
1096 return; |
|
1097 |
|
1098 array_unshift( $default_types, 'src' ); |
|
1099 } |
|
1100 |
|
1101 $library = apply_filters( 'wp_video_shortcode_library', 'mediaelement' ); |
|
1102 if ( 'mediaelement' === $library && did_action( 'init' ) ) { |
|
1103 wp_enqueue_style( 'wp-mediaelement' ); |
|
1104 wp_enqueue_script( 'wp-mediaelement' ); |
|
1105 } |
|
1106 |
|
1107 $atts = array( |
|
1108 'class' => apply_filters( 'wp_video_shortcode_class', 'wp-video-shortcode' ), |
|
1109 'id' => sprintf( 'video-%d-%d', $post_id, $instances ), |
|
1110 'width' => absint( $width ), |
|
1111 'height' => absint( $height ), |
|
1112 'poster' => esc_url( $poster ), |
|
1113 'loop' => $loop, |
|
1114 'autoplay' => $autoplay, |
|
1115 'preload' => $preload, |
|
1116 ); |
|
1117 |
|
1118 // These ones should just be omitted altogether if they are blank |
|
1119 foreach ( array( 'poster', 'loop', 'autoplay', 'preload' ) as $a ) { |
|
1120 if ( empty( $atts[$a] ) ) |
|
1121 unset( $atts[$a] ); |
|
1122 } |
|
1123 |
|
1124 $attr_strings = array(); |
|
1125 foreach ( $atts as $k => $v ) { |
|
1126 $attr_strings[] = $k . '="' . esc_attr( $v ) . '"'; |
|
1127 } |
|
1128 |
|
1129 $html = ''; |
|
1130 if ( 'mediaelement' === $library && 1 === $instances ) |
|
1131 $html .= "<!--[if lt IE 9]><script>document.createElement('video');</script><![endif]-->\n"; |
|
1132 $html .= sprintf( '<video %s controls="controls">', join( ' ', $attr_strings ) ); |
|
1133 |
|
1134 $fileurl = ''; |
|
1135 $source = '<source type="%s" src="%s" />'; |
|
1136 foreach ( $default_types as $fallback ) { |
|
1137 if ( ! empty( $$fallback ) ) { |
|
1138 if ( empty( $fileurl ) ) |
|
1139 $fileurl = $$fallback; |
|
1140 $type = wp_check_filetype( $$fallback, wp_get_mime_types() ); |
|
1141 // m4v sometimes shows up as video/mpeg which collides with mp4 |
|
1142 if ( 'm4v' === $type['ext'] ) |
|
1143 $type['type'] = 'video/m4v'; |
|
1144 $html .= sprintf( $source, $type['type'], esc_url( $$fallback ) ); |
|
1145 } |
|
1146 } |
|
1147 if ( 'mediaelement' === $library ) |
|
1148 $html .= wp_mediaelement_fallback( $fileurl ); |
|
1149 $html .= '</video>'; |
|
1150 |
|
1151 $html = sprintf( '<div style="width: %dpx; max-width: 100%%;">%s</div>', $width, $html ); |
|
1152 return apply_filters( 'wp_video_shortcode', $html, $atts, $video, $post_id, $library ); |
|
1153 } |
|
1154 add_shortcode( 'video', 'wp_video_shortcode' ); |
|
1155 |
|
1156 /** |
|
1157 * Display previous image link that has the same post parent. |
|
1158 * |
|
1159 * @since 2.5.0 |
|
1160 * @param string $size Optional, default is 'thumbnail'. Size of image, either array or string. 0 or 'none' will default to post_title or $text; |
|
1161 * @param string $text Optional, default is false. If included, link will reflect $text variable. |
|
1162 * @return string HTML content. |
|
1163 */ |
|
1164 function previous_image_link($size = 'thumbnail', $text = false) { |
|
1165 adjacent_image_link(true, $size, $text); |
|
1166 } |
|
1167 |
|
1168 /** |
|
1169 * Display next image link that has the same post parent. |
|
1170 * |
|
1171 * @since 2.5.0 |
|
1172 * @param string $size Optional, default is 'thumbnail'. Size of image, either array or string. 0 or 'none' will default to post_title or $text; |
|
1173 * @param string $text Optional, default is false. If included, link will reflect $text variable. |
|
1174 * @return string HTML content. |
|
1175 */ |
|
1176 function next_image_link($size = 'thumbnail', $text = false) { |
|
1177 adjacent_image_link(false, $size, $text); |
|
1178 } |
|
1179 |
|
1180 /** |
|
1181 * Display next or previous image link that has the same post parent. |
|
1182 * |
|
1183 * Retrieves the current attachment object from the $post global. |
|
1184 * |
|
1185 * @since 2.5.0 |
|
1186 * |
|
1187 * @param bool $prev Optional. Default is true to display previous link, false for next. |
|
1188 */ |
|
1189 function adjacent_image_link($prev = true, $size = 'thumbnail', $text = false) { |
|
1190 $post = get_post(); |
|
1191 $attachments = array_values( get_children( array( 'post_parent' => $post->post_parent, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order ID' ) ) ); |
|
1192 |
|
1193 foreach ( $attachments as $k => $attachment ) |
|
1194 if ( $attachment->ID == $post->ID ) |
|
1195 break; |
|
1196 |
|
1197 $k = $prev ? $k - 1 : $k + 1; |
|
1198 |
|
1199 $output = $attachment_id = null; |
|
1200 if ( isset( $attachments[ $k ] ) ) { |
|
1201 $attachment_id = $attachments[ $k ]->ID; |
|
1202 $output = wp_get_attachment_link( $attachment_id, $size, true, false, $text ); |
|
1203 } |
|
1204 |
|
1205 $adjacent = $prev ? 'previous' : 'next'; |
|
1206 echo apply_filters( "{$adjacent}_image_link", $output, $attachment_id, $size, $text ); |
|
1207 } |
|
1208 |
|
1209 /** |
|
1210 * Retrieve taxonomies attached to the attachment. |
|
1211 * |
|
1212 * @since 2.5.0 |
|
1213 * |
|
1214 * @param int|array|object $attachment Attachment ID, Attachment data array, or Attachment data object. |
|
1215 * @return array Empty array on failure. List of taxonomies on success. |
|
1216 */ |
|
1217 function get_attachment_taxonomies($attachment) { |
|
1218 if ( is_int( $attachment ) ) |
|
1219 $attachment = get_post($attachment); |
|
1220 else if ( is_array($attachment) ) |
|
1221 $attachment = (object) $attachment; |
|
1222 |
|
1223 if ( ! is_object($attachment) ) |
|
1224 return array(); |
|
1225 |
|
1226 $filename = basename($attachment->guid); |
|
1227 |
|
1228 $objects = array('attachment'); |
|
1229 |
|
1230 if ( false !== strpos($filename, '.') ) |
|
1231 $objects[] = 'attachment:' . substr($filename, strrpos($filename, '.') + 1); |
|
1232 if ( !empty($attachment->post_mime_type) ) { |
|
1233 $objects[] = 'attachment:' . $attachment->post_mime_type; |
|
1234 if ( false !== strpos($attachment->post_mime_type, '/') ) |
|
1235 foreach ( explode('/', $attachment->post_mime_type) as $token ) |
|
1236 if ( !empty($token) ) |
|
1237 $objects[] = "attachment:$token"; |
|
1238 } |
|
1239 |
|
1240 $taxonomies = array(); |
|
1241 foreach ( $objects as $object ) |
|
1242 if ( $taxes = get_object_taxonomies($object) ) |
|
1243 $taxonomies = array_merge($taxonomies, $taxes); |
|
1244 |
|
1245 return array_unique($taxonomies); |
|
1246 } |
|
1247 |
|
1248 /** |
|
1249 * Return all of the taxonomy names that are registered for attachments. |
|
1250 * |
|
1251 * Handles mime-type-specific taxonomies such as attachment:image and attachment:video. |
|
1252 * |
|
1253 * @since 3.5.0 |
|
1254 * @see get_attachment_taxonomies() |
|
1255 * @uses get_taxonomies() |
|
1256 * |
|
1257 * @param string $output The type of output to return, either taxonomy 'names' or 'objects'. 'names' is the default. |
|
1258 * @return array The names of all taxonomy of $object_type. |
|
1259 */ |
|
1260 function get_taxonomies_for_attachments( $output = 'names' ) { |
|
1261 $taxonomies = array(); |
|
1262 foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy ) { |
|
1263 foreach ( $taxonomy->object_type as $object_type ) { |
|
1264 if ( 'attachment' == $object_type || 0 === strpos( $object_type, 'attachment:' ) ) { |
|
1265 if ( 'names' == $output ) |
|
1266 $taxonomies[] = $taxonomy->name; |
|
1267 else |
|
1268 $taxonomies[ $taxonomy->name ] = $taxonomy; |
|
1269 break; |
|
1270 } |
|
1271 } |
|
1272 } |
|
1273 |
|
1274 return $taxonomies; |
|
1275 } |
|
1276 |
|
1277 /** |
|
1278 * Create new GD image resource with transparency support |
|
1279 * @TODO: Deprecate if possible. |
|
1280 * |
|
1281 * @since 2.9.0 |
|
1282 * |
|
1283 * @param int $width Image width |
|
1284 * @param int $height Image height |
|
1285 * @return image resource |
|
1286 */ |
|
1287 function wp_imagecreatetruecolor($width, $height) { |
|
1288 $img = imagecreatetruecolor($width, $height); |
|
1289 if ( is_resource($img) && function_exists('imagealphablending') && function_exists('imagesavealpha') ) { |
|
1290 imagealphablending($img, false); |
|
1291 imagesavealpha($img, true); |
|
1292 } |
|
1293 return $img; |
|
1294 } |
|
1295 |
|
1296 /** |
|
1297 * Register an embed handler. This function should probably only be used for sites that do not support oEmbed. |
|
1298 * |
|
1299 * @since 2.9.0 |
|
1300 * @see WP_Embed::register_handler() |
|
1301 */ |
|
1302 function wp_embed_register_handler( $id, $regex, $callback, $priority = 10 ) { |
|
1303 global $wp_embed; |
|
1304 $wp_embed->register_handler( $id, $regex, $callback, $priority ); |
|
1305 } |
|
1306 |
|
1307 /** |
|
1308 * Unregister a previously registered embed handler. |
|
1309 * |
|
1310 * @since 2.9.0 |
|
1311 * @see WP_Embed::unregister_handler() |
|
1312 */ |
|
1313 function wp_embed_unregister_handler( $id, $priority = 10 ) { |
|
1314 global $wp_embed; |
|
1315 $wp_embed->unregister_handler( $id, $priority ); |
|
1316 } |
|
1317 |
|
1318 /** |
|
1319 * Create default array of embed parameters. |
|
1320 * |
|
1321 * The width defaults to the content width as specified by the theme. If the |
|
1322 * theme does not specify a content width, then 500px is used. |
|
1323 * |
|
1324 * The default height is 1.5 times the width, or 1000px, whichever is smaller. |
|
1325 * |
|
1326 * The 'embed_defaults' filter can be used to adjust either of these values. |
|
1327 * |
|
1328 * @since 2.9.0 |
|
1329 * |
|
1330 * @return array Default embed parameters. |
|
1331 */ |
|
1332 function wp_embed_defaults() { |
|
1333 if ( ! empty( $GLOBALS['content_width'] ) ) |
|
1334 $width = (int) $GLOBALS['content_width']; |
|
1335 |
|
1336 if ( empty( $width ) ) |
|
1337 $width = 500; |
|
1338 |
|
1339 $height = min( ceil( $width * 1.5 ), 1000 ); |
|
1340 |
|
1341 return apply_filters( 'embed_defaults', compact( 'width', 'height' ) ); |
|
1342 } |
|
1343 |
|
1344 /** |
|
1345 * Based on a supplied width/height example, return the biggest possible dimensions based on the max width/height. |
|
1346 * |
|
1347 * @since 2.9.0 |
|
1348 * @uses wp_constrain_dimensions() This function passes the widths and the heights. |
|
1349 * |
|
1350 * @param int $example_width The width of an example embed. |
|
1351 * @param int $example_height The height of an example embed. |
|
1352 * @param int $max_width The maximum allowed width. |
|
1353 * @param int $max_height The maximum allowed height. |
|
1354 * @return array The maximum possible width and height based on the example ratio. |
|
1355 */ |
|
1356 function wp_expand_dimensions( $example_width, $example_height, $max_width, $max_height ) { |
|
1357 $example_width = (int) $example_width; |
|
1358 $example_height = (int) $example_height; |
|
1359 $max_width = (int) $max_width; |
|
1360 $max_height = (int) $max_height; |
|
1361 |
|
1362 return wp_constrain_dimensions( $example_width * 1000000, $example_height * 1000000, $max_width, $max_height ); |
|
1363 } |
|
1364 |
|
1365 /** |
|
1366 * Attempts to fetch the embed HTML for a provided URL using oEmbed. |
|
1367 * |
|
1368 * @since 2.9.0 |
|
1369 * @see WP_oEmbed |
|
1370 * |
|
1371 * @uses _wp_oembed_get_object() |
|
1372 * @uses WP_oEmbed::get_html() |
|
1373 * |
|
1374 * @param string $url The URL that should be embedded. |
|
1375 * @param array $args Additional arguments and parameters. |
|
1376 * @return bool|string False on failure or the embed HTML on success. |
|
1377 */ |
|
1378 function wp_oembed_get( $url, $args = '' ) { |
|
1379 require_once( ABSPATH . WPINC . '/class-oembed.php' ); |
|
1380 $oembed = _wp_oembed_get_object(); |
|
1381 return $oembed->get_html( $url, $args ); |
|
1382 } |
|
1383 |
|
1384 /** |
|
1385 * Adds a URL format and oEmbed provider URL pair. |
|
1386 * |
|
1387 * @since 2.9.0 |
|
1388 * @see WP_oEmbed |
|
1389 * |
|
1390 * @uses _wp_oembed_get_object() |
|
1391 * |
|
1392 * @param string $format The format of URL that this provider can handle. You can use asterisks as wildcards. |
|
1393 * @param string $provider The URL to the oEmbed provider. |
|
1394 * @param boolean $regex Whether the $format parameter is in a regex format. |
|
1395 */ |
|
1396 function wp_oembed_add_provider( $format, $provider, $regex = false ) { |
|
1397 require_once( ABSPATH . WPINC . '/class-oembed.php' ); |
|
1398 $oembed = _wp_oembed_get_object(); |
|
1399 $oembed->providers[$format] = array( $provider, $regex ); |
|
1400 } |
|
1401 |
|
1402 /** |
|
1403 * Removes an oEmbed provider. |
|
1404 * |
|
1405 * @since 3.5.0 |
|
1406 * @see WP_oEmbed |
|
1407 * |
|
1408 * @uses _wp_oembed_get_object() |
|
1409 * |
|
1410 * @param string $format The URL format for the oEmbed provider to remove. |
|
1411 */ |
|
1412 function wp_oembed_remove_provider( $format ) { |
|
1413 require_once( ABSPATH . WPINC . '/class-oembed.php' ); |
|
1414 |
|
1415 $oembed = _wp_oembed_get_object(); |
|
1416 |
|
1417 if ( isset( $oembed->providers[ $format ] ) ) { |
|
1418 unset( $oembed->providers[ $format ] ); |
|
1419 return true; |
|
1420 } |
|
1421 |
|
1422 return false; |
|
1423 } |
|
1424 |
|
1425 /** |
|
1426 * Determines if default embed handlers should be loaded. |
|
1427 * |
|
1428 * Checks to make sure that the embeds library hasn't already been loaded. If |
|
1429 * it hasn't, then it will load the embeds library. |
|
1430 * |
|
1431 * @since 2.9.0 |
|
1432 */ |
|
1433 function wp_maybe_load_embeds() { |
|
1434 if ( ! apply_filters( 'load_default_embeds', true ) ) |
|
1435 return; |
|
1436 wp_embed_register_handler( 'googlevideo', '#http://video\.google\.([A-Za-z.]{2,5})/videoplay\?docid=([\d-]+)(.*?)#i', 'wp_embed_handler_googlevideo' ); |
|
1437 wp_embed_register_handler( 'audio', '#^https?://.+?\.(' . join( '|', wp_get_audio_extensions() ) . ')$#i', apply_filters( 'wp_audio_embed_handler', 'wp_embed_handler_audio' ), 9999 ); |
|
1438 wp_embed_register_handler( 'video', '#^https?://.+?\.(' . join( '|', wp_get_video_extensions() ) . ')$#i', apply_filters( 'wp_video_embed_handler', 'wp_embed_handler_video' ), 9999 ); |
|
1439 } |
|
1440 |
|
1441 /** |
|
1442 * The Google Video embed handler callback. Google Video does not support oEmbed. |
|
1443 * |
|
1444 * @see WP_Embed::register_handler() |
|
1445 * @see WP_Embed::shortcode() |
|
1446 * |
|
1447 * @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}. |
|
1448 * @param array $attr Embed attributes. |
|
1449 * @param string $url The original URL that was matched by the regex. |
|
1450 * @param array $rawattr The original unmodified attributes. |
|
1451 * @return string The embed HTML. |
|
1452 */ |
|
1453 function wp_embed_handler_googlevideo( $matches, $attr, $url, $rawattr ) { |
|
1454 // If the user supplied a fixed width AND height, use it |
|
1455 if ( !empty($rawattr['width']) && !empty($rawattr['height']) ) { |
|
1456 $width = (int) $rawattr['width']; |
|
1457 $height = (int) $rawattr['height']; |
|
1458 } else { |
|
1459 list( $width, $height ) = wp_expand_dimensions( 425, 344, $attr['width'], $attr['height'] ); |
|
1460 } |
|
1461 |
|
1462 return apply_filters( 'embed_googlevideo', '<embed type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docid=' . esc_attr($matches[2]) . '&hl=en&fs=true" style="width:' . esc_attr($width) . 'px;height:' . esc_attr($height) . 'px" allowFullScreen="true" allowScriptAccess="always" />', $matches, $attr, $url, $rawattr ); |
|
1463 } |
|
1464 |
|
1465 /** |
|
1466 * Audio embed handler callback. |
|
1467 * |
|
1468 * @since 3.6.0 |
|
1469 * |
|
1470 * @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}. |
|
1471 * @param array $attr Embed attributes. |
|
1472 * @param string $url The original URL that was matched by the regex. |
|
1473 * @param array $rawattr The original unmodified attributes. |
|
1474 * @return string The embed HTML. |
|
1475 */ |
|
1476 function wp_embed_handler_audio( $matches, $attr, $url, $rawattr ) { |
|
1477 $audio = sprintf( '[audio src="%s" /]', esc_url( $url ) ); |
|
1478 return apply_filters( 'wp_embed_handler_audio', $audio, $attr, $url, $rawattr ); |
|
1479 } |
|
1480 |
|
1481 /** |
|
1482 * Video embed handler callback. |
|
1483 * |
|
1484 * @since 3.6.0 |
|
1485 * |
|
1486 * @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}. |
|
1487 * @param array $attr Embed attributes. |
|
1488 * @param string $url The original URL that was matched by the regex. |
|
1489 * @param array $rawattr The original unmodified attributes. |
|
1490 * @return string The embed HTML. |
|
1491 */ |
|
1492 function wp_embed_handler_video( $matches, $attr, $url, $rawattr ) { |
|
1493 $dimensions = ''; |
|
1494 if ( ! empty( $rawattr['width'] ) && ! empty( $rawattr['height'] ) ) { |
|
1495 $dimensions .= sprintf( 'width="%d" ', (int) $rawattr['width'] ); |
|
1496 $dimensions .= sprintf( 'height="%d" ', (int) $rawattr['height'] ); |
|
1497 } |
|
1498 $video = sprintf( '[video %s src="%s" /]', $dimensions, esc_url( $url ) ); |
|
1499 return apply_filters( 'wp_embed_handler_video', $video, $attr, $url, $rawattr ); |
|
1500 } |
|
1501 |
|
1502 /** |
|
1503 * Converts a shorthand byte value to an integer byte value. |
|
1504 * |
|
1505 * @since 2.3.0 |
|
1506 * |
|
1507 * @param string $size A shorthand byte value. |
|
1508 * @return int An integer byte value. |
|
1509 */ |
|
1510 function wp_convert_hr_to_bytes( $size ) { |
|
1511 $size = strtolower( $size ); |
|
1512 $bytes = (int) $size; |
|
1513 if ( strpos( $size, 'k' ) !== false ) |
|
1514 $bytes = intval( $size ) * 1024; |
|
1515 elseif ( strpos( $size, 'm' ) !== false ) |
|
1516 $bytes = intval($size) * 1024 * 1024; |
|
1517 elseif ( strpos( $size, 'g' ) !== false ) |
|
1518 $bytes = intval( $size ) * 1024 * 1024 * 1024; |
|
1519 return $bytes; |
|
1520 } |
|
1521 |
|
1522 /** |
|
1523 * Determine the maximum upload size allowed in php.ini. |
|
1524 * |
|
1525 * @since 2.5.0 |
|
1526 * |
|
1527 * @return int Allowed upload size. |
|
1528 */ |
|
1529 function wp_max_upload_size() { |
|
1530 $u_bytes = wp_convert_hr_to_bytes( ini_get( 'upload_max_filesize' ) ); |
|
1531 $p_bytes = wp_convert_hr_to_bytes( ini_get( 'post_max_size' ) ); |
|
1532 $bytes = apply_filters( 'upload_size_limit', min( $u_bytes, $p_bytes ), $u_bytes, $p_bytes ); |
|
1533 return $bytes; |
|
1534 } |
|
1535 |
|
1536 /** |
|
1537 * Returns a WP_Image_Editor instance and loads file into it. |
|
1538 * |
|
1539 * @since 3.5.0 |
|
1540 * @access public |
|
1541 * |
|
1542 * @param string $path Path to file to load |
|
1543 * @param array $args Additional data. Accepts { 'mime_type'=>string, 'methods'=>{string, string, ...} } |
|
1544 * @return WP_Image_Editor|WP_Error |
|
1545 */ |
|
1546 function wp_get_image_editor( $path, $args = array() ) { |
|
1547 $args['path'] = $path; |
|
1548 |
|
1549 if ( ! isset( $args['mime_type'] ) ) { |
|
1550 $file_info = wp_check_filetype( $args['path'] ); |
|
1551 |
|
1552 // If $file_info['type'] is false, then we let the editor attempt to |
|
1553 // figure out the file type, rather than forcing a failure based on extension. |
|
1554 if ( isset( $file_info ) && $file_info['type'] ) |
|
1555 $args['mime_type'] = $file_info['type']; |
|
1556 } |
|
1557 |
|
1558 $implementation = _wp_image_editor_choose( $args ); |
|
1559 |
|
1560 if ( $implementation ) { |
|
1561 $editor = new $implementation( $path ); |
|
1562 $loaded = $editor->load(); |
|
1563 |
|
1564 if ( is_wp_error( $loaded ) ) |
|
1565 return $loaded; |
|
1566 |
|
1567 return $editor; |
|
1568 } |
|
1569 |
|
1570 return new WP_Error( 'image_no_editor', __('No editor could be selected.') ); |
|
1571 } |
|
1572 |
|
1573 /** |
|
1574 * Tests whether there is an editor that supports a given mime type or methods. |
|
1575 * |
|
1576 * @since 3.5.0 |
|
1577 * @access public |
|
1578 * |
|
1579 * @param string|array $args Array of requirements. Accepts { 'mime_type'=>string, 'methods'=>{string, string, ...} } |
|
1580 * @return boolean true if an eligible editor is found; false otherwise |
|
1581 */ |
|
1582 function wp_image_editor_supports( $args = array() ) { |
|
1583 return (bool) _wp_image_editor_choose( $args ); |
|
1584 } |
|
1585 |
|
1586 /** |
|
1587 * Tests which editors are capable of supporting the request. |
|
1588 * |
|
1589 * @since 3.5.0 |
|
1590 * @access private |
|
1591 * |
|
1592 * @param array $args Additional data. Accepts { 'mime_type'=>string, 'methods'=>{string, string, ...} } |
|
1593 * @return string|bool Class name for the first editor that claims to support the request. False if no editor claims to support the request. |
|
1594 */ |
|
1595 function _wp_image_editor_choose( $args = array() ) { |
|
1596 require_once ABSPATH . WPINC . '/class-wp-image-editor.php'; |
|
1597 require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php'; |
|
1598 require_once ABSPATH . WPINC . '/class-wp-image-editor-imagick.php'; |
|
1599 |
|
1600 $implementations = apply_filters( 'wp_image_editors', |
|
1601 array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) ); |
|
1602 |
|
1603 foreach ( $implementations as $implementation ) { |
|
1604 if ( ! call_user_func( array( $implementation, 'test' ), $args ) ) |
|
1605 continue; |
|
1606 |
|
1607 if ( isset( $args['mime_type'] ) && |
|
1608 ! call_user_func( |
|
1609 array( $implementation, 'supports_mime_type' ), |
|
1610 $args['mime_type'] ) ) { |
|
1611 continue; |
|
1612 } |
|
1613 |
|
1614 if ( isset( $args['methods'] ) && |
|
1615 array_diff( $args['methods'], get_class_methods( $implementation ) ) ) { |
|
1616 continue; |
|
1617 } |
|
1618 |
|
1619 return $implementation; |
|
1620 } |
|
1621 |
|
1622 return false; |
|
1623 } |
|
1624 |
|
1625 /** |
|
1626 * Prints default plupload arguments. |
|
1627 * |
|
1628 * @since 3.4.0 |
|
1629 */ |
|
1630 function wp_plupload_default_settings() { |
|
1631 global $wp_scripts; |
|
1632 |
|
1633 $data = $wp_scripts->get_data( 'wp-plupload', 'data' ); |
|
1634 if ( $data && false !== strpos( $data, '_wpPluploadSettings' ) ) |
|
1635 return; |
|
1636 |
|
1637 $max_upload_size = wp_max_upload_size(); |
|
1638 |
|
1639 $defaults = array( |
|
1640 'runtimes' => 'html5,silverlight,flash,html4', |
|
1641 'file_data_name' => 'async-upload', // key passed to $_FILE. |
|
1642 'multiple_queues' => true, |
|
1643 'max_file_size' => $max_upload_size . 'b', |
|
1644 'url' => admin_url( 'async-upload.php', 'relative' ), |
|
1645 'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ), |
|
1646 'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ), |
|
1647 'filters' => array( array( 'title' => __( 'Allowed Files' ), 'extensions' => '*') ), |
|
1648 'multipart' => true, |
|
1649 'urlstream_upload' => true, |
|
1650 ); |
|
1651 |
|
1652 // Multi-file uploading doesn't currently work in iOS Safari, |
|
1653 // single-file allows the built-in camera to be used as source for images |
|
1654 if ( wp_is_mobile() ) |
|
1655 $defaults['multi_selection'] = false; |
|
1656 |
|
1657 $defaults = apply_filters( 'plupload_default_settings', $defaults ); |
|
1658 |
|
1659 $params = array( |
|
1660 'action' => 'upload-attachment', |
|
1661 ); |
|
1662 |
|
1663 $params = apply_filters( 'plupload_default_params', $params ); |
|
1664 $params['_wpnonce'] = wp_create_nonce( 'media-form' ); |
|
1665 $defaults['multipart_params'] = $params; |
|
1666 |
|
1667 $settings = array( |
|
1668 'defaults' => $defaults, |
|
1669 'browser' => array( |
|
1670 'mobile' => wp_is_mobile(), |
|
1671 'supported' => _device_can_upload(), |
|
1672 ), |
|
1673 'limitExceeded' => is_multisite() && ! is_upload_space_available() |
|
1674 ); |
|
1675 |
|
1676 $script = 'var _wpPluploadSettings = ' . json_encode( $settings ) . ';'; |
|
1677 |
|
1678 if ( $data ) |
|
1679 $script = "$data\n$script"; |
|
1680 |
|
1681 $wp_scripts->add_data( 'wp-plupload', 'data', $script ); |
|
1682 } |
|
1683 add_action( 'customize_controls_enqueue_scripts', 'wp_plupload_default_settings' ); |
|
1684 |
|
1685 /** |
|
1686 * Prepares an attachment post object for JS, where it is expected |
|
1687 * to be JSON-encoded and fit into an Attachment model. |
|
1688 * |
|
1689 * @since 3.5.0 |
|
1690 * |
|
1691 * @param mixed $attachment Attachment ID or object. |
|
1692 * @return array Array of attachment details. |
|
1693 */ |
|
1694 function wp_prepare_attachment_for_js( $attachment ) { |
|
1695 if ( ! $attachment = get_post( $attachment ) ) |
|
1696 return; |
|
1697 |
|
1698 if ( 'attachment' != $attachment->post_type ) |
|
1699 return; |
|
1700 |
|
1701 $meta = wp_get_attachment_metadata( $attachment->ID ); |
|
1702 if ( false !== strpos( $attachment->post_mime_type, '/' ) ) |
|
1703 list( $type, $subtype ) = explode( '/', $attachment->post_mime_type ); |
|
1704 else |
|
1705 list( $type, $subtype ) = array( $attachment->post_mime_type, '' ); |
|
1706 |
|
1707 $attachment_url = wp_get_attachment_url( $attachment->ID ); |
|
1708 |
|
1709 $response = array( |
|
1710 'id' => $attachment->ID, |
|
1711 'title' => $attachment->post_title, |
|
1712 'filename' => wp_basename( $attachment->guid ), |
|
1713 'url' => $attachment_url, |
|
1714 'link' => get_attachment_link( $attachment->ID ), |
|
1715 'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ), |
|
1716 'author' => $attachment->post_author, |
|
1717 'description' => $attachment->post_content, |
|
1718 'caption' => $attachment->post_excerpt, |
|
1719 'name' => $attachment->post_name, |
|
1720 'status' => $attachment->post_status, |
|
1721 'uploadedTo' => $attachment->post_parent, |
|
1722 'date' => strtotime( $attachment->post_date_gmt ) * 1000, |
|
1723 'modified' => strtotime( $attachment->post_modified_gmt ) * 1000, |
|
1724 'menuOrder' => $attachment->menu_order, |
|
1725 'mime' => $attachment->post_mime_type, |
|
1726 'type' => $type, |
|
1727 'subtype' => $subtype, |
|
1728 'icon' => wp_mime_type_icon( $attachment->ID ), |
|
1729 'dateFormatted' => mysql2date( get_option('date_format'), $attachment->post_date ), |
|
1730 'nonces' => array( |
|
1731 'update' => false, |
|
1732 'delete' => false, |
|
1733 ), |
|
1734 'editLink' => false, |
|
1735 ); |
|
1736 |
|
1737 if ( current_user_can( 'edit_post', $attachment->ID ) ) { |
|
1738 $response['nonces']['update'] = wp_create_nonce( 'update-post_' . $attachment->ID ); |
|
1739 $response['editLink'] = get_edit_post_link( $attachment->ID, 'raw' ); |
|
1740 } |
|
1741 |
|
1742 if ( current_user_can( 'delete_post', $attachment->ID ) ) |
|
1743 $response['nonces']['delete'] = wp_create_nonce( 'delete-post_' . $attachment->ID ); |
|
1744 |
|
1745 if ( $meta && 'image' === $type ) { |
|
1746 $sizes = array(); |
|
1747 /** This filter is documented in wp-admin/includes/media.php */ |
|
1748 $possible_sizes = apply_filters( 'image_size_names_choose', array( |
|
1749 'thumbnail' => __('Thumbnail'), |
|
1750 'medium' => __('Medium'), |
|
1751 'large' => __('Large'), |
|
1752 'full' => __('Full Size'), |
|
1753 ) ); |
|
1754 unset( $possible_sizes['full'] ); |
|
1755 |
|
1756 // Loop through all potential sizes that may be chosen. Try to do this with some efficiency. |
|
1757 // First: run the image_downsize filter. If it returns something, we can use its data. |
|
1758 // If the filter does not return something, then image_downsize() is just an expensive |
|
1759 // way to check the image metadata, which we do second. |
|
1760 foreach ( $possible_sizes as $size => $label ) { |
|
1761 if ( $downsize = apply_filters( 'image_downsize', false, $attachment->ID, $size ) ) { |
|
1762 if ( ! $downsize[3] ) |
|
1763 continue; |
|
1764 $sizes[ $size ] = array( |
|
1765 'height' => $downsize[2], |
|
1766 'width' => $downsize[1], |
|
1767 'url' => $downsize[0], |
|
1768 'orientation' => $downsize[2] > $downsize[1] ? 'portrait' : 'landscape', |
|
1769 ); |
|
1770 } elseif ( isset( $meta['sizes'][ $size ] ) ) { |
|
1771 if ( ! isset( $base_url ) ) |
|
1772 $base_url = str_replace( wp_basename( $attachment_url ), '', $attachment_url ); |
|
1773 |
|
1774 // Nothing from the filter, so consult image metadata if we have it. |
|
1775 $size_meta = $meta['sizes'][ $size ]; |
|
1776 |
|
1777 // We have the actual image size, but might need to further constrain it if content_width is narrower. |
|
1778 // Thumbnail, medium, and full sizes are also checked against the site's height/width options. |
|
1779 list( $width, $height ) = image_constrain_size_for_editor( $size_meta['width'], $size_meta['height'], $size, 'edit' ); |
|
1780 |
|
1781 $sizes[ $size ] = array( |
|
1782 'height' => $height, |
|
1783 'width' => $width, |
|
1784 'url' => $base_url . $size_meta['file'], |
|
1785 'orientation' => $height > $width ? 'portrait' : 'landscape', |
|
1786 ); |
|
1787 } |
|
1788 } |
|
1789 |
|
1790 $sizes['full'] = array( 'url' => $attachment_url ); |
|
1791 |
|
1792 if ( isset( $meta['height'], $meta['width'] ) ) { |
|
1793 $sizes['full']['height'] = $meta['height']; |
|
1794 $sizes['full']['width'] = $meta['width']; |
|
1795 $sizes['full']['orientation'] = $meta['height'] > $meta['width'] ? 'portrait' : 'landscape'; |
|
1796 } |
|
1797 |
|
1798 $response = array_merge( $response, array( 'sizes' => $sizes ), $sizes['full'] ); |
|
1799 } elseif ( $meta && 'video' === $type ) { |
|
1800 if ( isset( $meta['width'] ) ) |
|
1801 $response['width'] = (int) $meta['width']; |
|
1802 if ( isset( $meta['height'] ) ) |
|
1803 $response['height'] = (int) $meta['height']; |
|
1804 } |
|
1805 |
|
1806 if ( $meta && ( 'audio' === $type || 'video' === $type ) ) { |
|
1807 if ( isset( $meta['length_formatted'] ) ) |
|
1808 $response['fileLength'] = $meta['length_formatted']; |
|
1809 } |
|
1810 |
|
1811 if ( function_exists('get_compat_media_markup') ) |
|
1812 $response['compat'] = get_compat_media_markup( $attachment->ID, array( 'in_modal' => true ) ); |
|
1813 |
|
1814 return apply_filters( 'wp_prepare_attachment_for_js', $response, $attachment, $meta ); |
|
1815 } |
|
1816 |
|
1817 /** |
|
1818 * Enqueues all scripts, styles, settings, and templates necessary to use |
|
1819 * all media JS APIs. |
|
1820 * |
|
1821 * @since 3.5.0 |
|
1822 */ |
|
1823 function wp_enqueue_media( $args = array() ) { |
|
1824 |
|
1825 // Enqueue me just once per page, please. |
|
1826 if ( did_action( 'wp_enqueue_media' ) ) |
|
1827 return; |
|
1828 |
|
1829 $defaults = array( |
|
1830 'post' => null, |
|
1831 ); |
|
1832 $args = wp_parse_args( $args, $defaults ); |
|
1833 |
|
1834 // We're going to pass the old thickbox media tabs to `media_upload_tabs` |
|
1835 // to ensure plugins will work. We will then unset those tabs. |
|
1836 $tabs = array( |
|
1837 // handler action suffix => tab label |
|
1838 'type' => '', |
|
1839 'type_url' => '', |
|
1840 'gallery' => '', |
|
1841 'library' => '', |
|
1842 ); |
|
1843 |
|
1844 $tabs = apply_filters( 'media_upload_tabs', $tabs ); |
|
1845 unset( $tabs['type'], $tabs['type_url'], $tabs['gallery'], $tabs['library'] ); |
|
1846 |
|
1847 $props = array( |
|
1848 'link' => get_option( 'image_default_link_type' ), // db default is 'file' |
|
1849 'align' => get_option( 'image_default_align' ), // empty default |
|
1850 'size' => get_option( 'image_default_size' ), // empty default |
|
1851 ); |
|
1852 |
|
1853 $settings = array( |
|
1854 'tabs' => $tabs, |
|
1855 'tabUrl' => add_query_arg( array( 'chromeless' => true ), admin_url('media-upload.php') ), |
|
1856 'mimeTypes' => wp_list_pluck( get_post_mime_types(), 0 ), |
|
1857 'captions' => ! apply_filters( 'disable_captions', '' ), |
|
1858 'nonce' => array( |
|
1859 'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ), |
|
1860 ), |
|
1861 'post' => array( |
|
1862 'id' => 0, |
|
1863 ), |
|
1864 'defaultProps' => $props, |
|
1865 'embedExts' => array_merge( wp_get_audio_extensions(), wp_get_video_extensions() ), |
|
1866 ); |
|
1867 |
|
1868 $post = null; |
|
1869 if ( isset( $args['post'] ) ) { |
|
1870 $post = get_post( $args['post'] ); |
|
1871 $settings['post'] = array( |
|
1872 'id' => $post->ID, |
|
1873 'nonce' => wp_create_nonce( 'update-post_' . $post->ID ), |
|
1874 ); |
|
1875 |
|
1876 if ( current_theme_supports( 'post-thumbnails', $post->post_type ) && post_type_supports( $post->post_type, 'thumbnail' ) ) { |
|
1877 $featured_image_id = get_post_meta( $post->ID, '_thumbnail_id', true ); |
|
1878 $settings['post']['featuredImageId'] = $featured_image_id ? $featured_image_id : -1; |
|
1879 } |
|
1880 } |
|
1881 |
|
1882 $hier = $post && is_post_type_hierarchical( $post->post_type ); |
|
1883 |
|
1884 $strings = array( |
|
1885 // Generic |
|
1886 'url' => __( 'URL' ), |
|
1887 'addMedia' => __( 'Add Media' ), |
|
1888 'search' => __( 'Search' ), |
|
1889 'select' => __( 'Select' ), |
|
1890 'cancel' => __( 'Cancel' ), |
|
1891 /* translators: This is a would-be plural string used in the media manager. |
|
1892 If there is not a word you can use in your language to avoid issues with the |
|
1893 lack of plural support here, turn it into "selected: %d" then translate it. |
|
1894 */ |
|
1895 'selected' => __( '%d selected' ), |
|
1896 'dragInfo' => __( 'Drag and drop to reorder images.' ), |
|
1897 |
|
1898 // Upload |
|
1899 'uploadFilesTitle' => __( 'Upload Files' ), |
|
1900 'uploadImagesTitle' => __( 'Upload Images' ), |
|
1901 |
|
1902 // Library |
|
1903 'mediaLibraryTitle' => __( 'Media Library' ), |
|
1904 'insertMediaTitle' => __( 'Insert Media' ), |
|
1905 'createNewGallery' => __( 'Create a new gallery' ), |
|
1906 'returnToLibrary' => __( '← Return to library' ), |
|
1907 'allMediaItems' => __( 'All media items' ), |
|
1908 'noItemsFound' => __( 'No items found.' ), |
|
1909 'insertIntoPost' => $hier ? __( 'Insert into page' ) : __( 'Insert into post' ), |
|
1910 'uploadedToThisPost' => $hier ? __( 'Uploaded to this page' ) : __( 'Uploaded to this post' ), |
|
1911 'warnDelete' => __( "You are about to permanently delete this item.\n 'Cancel' to stop, 'OK' to delete." ), |
|
1912 |
|
1913 // From URL |
|
1914 'insertFromUrlTitle' => __( 'Insert from URL' ), |
|
1915 |
|
1916 // Featured Images |
|
1917 'setFeaturedImageTitle' => __( 'Set Featured Image' ), |
|
1918 'setFeaturedImage' => __( 'Set featured image' ), |
|
1919 |
|
1920 // Gallery |
|
1921 'createGalleryTitle' => __( 'Create Gallery' ), |
|
1922 'editGalleryTitle' => __( 'Edit Gallery' ), |
|
1923 'cancelGalleryTitle' => __( '← Cancel Gallery' ), |
|
1924 'insertGallery' => __( 'Insert gallery' ), |
|
1925 'updateGallery' => __( 'Update gallery' ), |
|
1926 'addToGallery' => __( 'Add to gallery' ), |
|
1927 'addToGalleryTitle' => __( 'Add to Gallery' ), |
|
1928 'reverseOrder' => __( 'Reverse order' ), |
|
1929 ); |
|
1930 |
|
1931 $settings = apply_filters( 'media_view_settings', $settings, $post ); |
|
1932 $strings = apply_filters( 'media_view_strings', $strings, $post ); |
|
1933 |
|
1934 $strings['settings'] = $settings; |
|
1935 |
|
1936 wp_localize_script( 'media-views', '_wpMediaViewsL10n', $strings ); |
|
1937 |
|
1938 wp_enqueue_script( 'media-editor' ); |
|
1939 wp_enqueue_style( 'media-views' ); |
|
1940 wp_plupload_default_settings(); |
|
1941 |
|
1942 require_once ABSPATH . WPINC . '/media-template.php'; |
|
1943 add_action( 'admin_footer', 'wp_print_media_templates' ); |
|
1944 add_action( 'wp_footer', 'wp_print_media_templates' ); |
|
1945 |
|
1946 do_action( 'wp_enqueue_media' ); |
|
1947 } |
|
1948 |
|
1949 /** |
|
1950 * Retrieve media attached to the passed post |
|
1951 * |
|
1952 * @since 3.6.0 |
|
1953 * |
|
1954 * @param string $type (Mime) type of media desired |
|
1955 * @param mixed $post Post ID or object |
|
1956 * @return array Found attachments |
|
1957 */ |
|
1958 function get_attached_media( $type, $post = 0 ) { |
|
1959 if ( ! $post = get_post( $post ) ) |
|
1960 return array(); |
|
1961 |
|
1962 $args = array( |
|
1963 'post_parent' => $post->ID, |
|
1964 'post_type' => 'attachment', |
|
1965 'post_mime_type' => $type, |
|
1966 'posts_per_page' => -1, |
|
1967 'orderby' => 'menu_order', |
|
1968 'order' => 'ASC', |
|
1969 ); |
|
1970 |
|
1971 $args = apply_filters( 'get_attached_media_args', $args, $type, $post ); |
|
1972 |
|
1973 $children = get_children( $args ); |
|
1974 |
|
1975 return (array) apply_filters( 'get_attached_media', $children, $type, $post ); |
|
1976 } |
|
1977 |
|
1978 /** |
|
1979 * Check the content blob for an <audio>, <video> <object>, <embed>, or <iframe> |
|
1980 * |
|
1981 * @since 3.6.0 |
|
1982 * |
|
1983 * @param string $content A string which might contain media data. |
|
1984 * @param array $types array of media types: 'audio', 'video', 'object', 'embed', or 'iframe' |
|
1985 * @return array A list of found HTML media embeds |
|
1986 */ |
|
1987 function get_media_embedded_in_content( $content, $types = null ) { |
|
1988 $html = array(); |
|
1989 $allowed_media_types = array( 'audio', 'video', 'object', 'embed', 'iframe' ); |
|
1990 if ( ! empty( $types ) ) { |
|
1991 if ( ! is_array( $types ) ) |
|
1992 $types = array( $types ); |
|
1993 $allowed_media_types = array_intersect( $allowed_media_types, $types ); |
|
1994 } |
|
1995 |
|
1996 foreach ( $allowed_media_types as $tag ) { |
|
1997 if ( preg_match( '#' . get_tag_regex( $tag ) . '#', $content, $matches ) ) { |
|
1998 $html[] = $matches[0]; |
|
1999 } |
|
2000 } |
|
2001 |
|
2002 return $html; |
|
2003 } |
|
2004 |
|
2005 /** |
|
2006 * Retrieve galleries from the passed post's content |
|
2007 * |
|
2008 * @since 3.6.0 |
|
2009 * |
|
2010 * @param mixed $post Optional. Post ID or object. |
|
2011 * @param boolean $html Whether to return HTML or data in the array |
|
2012 * @return array A list of arrays, each containing gallery data and srcs parsed |
|
2013 * from the expanded shortcode |
|
2014 */ |
|
2015 function get_post_galleries( $post, $html = true ) { |
|
2016 if ( ! $post = get_post( $post ) ) |
|
2017 return array(); |
|
2018 |
|
2019 if ( ! has_shortcode( $post->post_content, 'gallery' ) ) |
|
2020 return array(); |
|
2021 |
|
2022 $galleries = array(); |
|
2023 if ( preg_match_all( '/' . get_shortcode_regex() . '/s', $post->post_content, $matches, PREG_SET_ORDER ) ) { |
|
2024 foreach ( $matches as $shortcode ) { |
|
2025 if ( 'gallery' === $shortcode[2] ) { |
|
2026 $srcs = array(); |
|
2027 $count = 1; |
|
2028 |
|
2029 $gallery = do_shortcode_tag( $shortcode ); |
|
2030 if ( $html ) { |
|
2031 $galleries[] = $gallery; |
|
2032 } else { |
|
2033 preg_match_all( '#src=([\'"])(.+?)\1#is', $gallery, $src, PREG_SET_ORDER ); |
|
2034 if ( ! empty( $src ) ) { |
|
2035 foreach ( $src as $s ) |
|
2036 $srcs[] = $s[2]; |
|
2037 } |
|
2038 |
|
2039 $data = shortcode_parse_atts( $shortcode[3] ); |
|
2040 $data['src'] = array_values( array_unique( $srcs ) ); |
|
2041 $galleries[] = $data; |
|
2042 } |
|
2043 } |
|
2044 } |
|
2045 } |
|
2046 |
|
2047 return apply_filters( 'get_post_galleries', $galleries, $post ); |
|
2048 } |
|
2049 |
|
2050 /** |
|
2051 * Check a specified post's content for gallery and, if present, return the first |
|
2052 * |
|
2053 * @since 3.6.0 |
|
2054 * |
|
2055 * @param mixed $post Optional. Post ID or object. |
|
2056 * @param boolean $html Whether to return HTML or data |
|
2057 * @return string|array Gallery data and srcs parsed from the expanded shortcode |
|
2058 */ |
|
2059 function get_post_gallery( $post = 0, $html = true ) { |
|
2060 $galleries = get_post_galleries( $post, $html ); |
|
2061 $gallery = reset( $galleries ); |
|
2062 |
|
2063 return apply_filters( 'get_post_gallery', $gallery, $post, $galleries ); |
|
2064 } |
|
2065 |
|
2066 /** |
|
2067 * Retrieve the image srcs from galleries from a post's content, if present |
|
2068 * |
|
2069 * @since 3.6.0 |
|
2070 * |
|
2071 * @param mixed $post Optional. Post ID or object. |
|
2072 * @return array A list of lists, each containing image srcs parsed |
|
2073 * from an expanded shortcode |
|
2074 */ |
|
2075 function get_post_galleries_images( $post = 0 ) { |
|
2076 $galleries = get_post_galleries( $post, false ); |
|
2077 return wp_list_pluck( $galleries, 'src' ); |
|
2078 } |
|
2079 |
|
2080 /** |
|
2081 * Check a post's content for galleries and return the image srcs for the first found gallery |
|
2082 * |
|
2083 * @since 3.6.0 |
|
2084 * |
|
2085 * @param mixed $post Optional. Post ID or object. |
|
2086 * @return array A list of a gallery's image srcs in order |
|
2087 */ |
|
2088 function get_post_gallery_images( $post = 0 ) { |
|
2089 $gallery = get_post_gallery( $post, false ); |
|
2090 return empty( $gallery['src'] ) ? array() : $gallery['src']; |
|
2091 } |