[ Index ] |
WordPress Cross Reference |
[Summary view] [Print] [Text view]
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%%;" class="wp-video">%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 add_action( 'customize_controls_print_footer_scripts', 'wp_print_media_templates' ); 1946 1947 do_action( 'wp_enqueue_media' ); 1948 } 1949 1950 /** 1951 * Retrieve media attached to the passed post 1952 * 1953 * @since 3.6.0 1954 * 1955 * @param string $type (Mime) type of media desired 1956 * @param mixed $post Post ID or object 1957 * @return array Found attachments 1958 */ 1959 function get_attached_media( $type, $post = 0 ) { 1960 if ( ! $post = get_post( $post ) ) 1961 return array(); 1962 1963 $args = array( 1964 'post_parent' => $post->ID, 1965 'post_type' => 'attachment', 1966 'post_mime_type' => $type, 1967 'posts_per_page' => -1, 1968 'orderby' => 'menu_order', 1969 'order' => 'ASC', 1970 ); 1971 1972 $args = apply_filters( 'get_attached_media_args', $args, $type, $post ); 1973 1974 $children = get_children( $args ); 1975 1976 return (array) apply_filters( 'get_attached_media', $children, $type, $post ); 1977 } 1978 1979 /** 1980 * Check the content blob for an <audio>, <video> <object>, <embed>, or <iframe> 1981 * 1982 * @since 3.6.0 1983 * 1984 * @param string $content A string which might contain media data. 1985 * @param array $types array of media types: 'audio', 'video', 'object', 'embed', or 'iframe' 1986 * @return array A list of found HTML media embeds 1987 */ 1988 function get_media_embedded_in_content( $content, $types = null ) { 1989 $html = array(); 1990 $allowed_media_types = array( 'audio', 'video', 'object', 'embed', 'iframe' ); 1991 if ( ! empty( $types ) ) { 1992 if ( ! is_array( $types ) ) 1993 $types = array( $types ); 1994 $allowed_media_types = array_intersect( $allowed_media_types, $types ); 1995 } 1996 1997 foreach ( $allowed_media_types as $tag ) { 1998 if ( preg_match( '#' . get_tag_regex( $tag ) . '#', $content, $matches ) ) { 1999 $html[] = $matches[0]; 2000 } 2001 } 2002 2003 return $html; 2004 } 2005 2006 /** 2007 * Retrieve galleries from the passed post's content 2008 * 2009 * @since 3.6.0 2010 * 2011 * @param mixed $post Optional. Post ID or object. 2012 * @param boolean $html Whether to return HTML or data in the array 2013 * @return array A list of arrays, each containing gallery data and srcs parsed 2014 * from the expanded shortcode 2015 */ 2016 function get_post_galleries( $post, $html = true ) { 2017 if ( ! $post = get_post( $post ) ) 2018 return array(); 2019 2020 if ( ! has_shortcode( $post->post_content, 'gallery' ) ) 2021 return array(); 2022 2023 $galleries = array(); 2024 if ( preg_match_all( '/' . get_shortcode_regex() . '/s', $post->post_content, $matches, PREG_SET_ORDER ) ) { 2025 foreach ( $matches as $shortcode ) { 2026 if ( 'gallery' === $shortcode[2] ) { 2027 $srcs = array(); 2028 $count = 1; 2029 2030 $gallery = do_shortcode_tag( $shortcode ); 2031 if ( $html ) { 2032 $galleries[] = $gallery; 2033 } else { 2034 preg_match_all( '#src=([\'"])(.+?)\1#is', $gallery, $src, PREG_SET_ORDER ); 2035 if ( ! empty( $src ) ) { 2036 foreach ( $src as $s ) 2037 $srcs[] = $s[2]; 2038 } 2039 2040 $data = shortcode_parse_atts( $shortcode[3] ); 2041 $data['src'] = array_values( array_unique( $srcs ) ); 2042 $galleries[] = $data; 2043 } 2044 } 2045 } 2046 } 2047 2048 return apply_filters( 'get_post_galleries', $galleries, $post ); 2049 } 2050 2051 /** 2052 * Check a specified post's content for gallery and, if present, return the first 2053 * 2054 * @since 3.6.0 2055 * 2056 * @param mixed $post Optional. Post ID or object. 2057 * @param boolean $html Whether to return HTML or data 2058 * @return string|array Gallery data and srcs parsed from the expanded shortcode 2059 */ 2060 function get_post_gallery( $post = 0, $html = true ) { 2061 $galleries = get_post_galleries( $post, $html ); 2062 $gallery = reset( $galleries ); 2063 2064 return apply_filters( 'get_post_gallery', $gallery, $post, $galleries ); 2065 } 2066 2067 /** 2068 * Retrieve the image srcs from galleries from a post's content, if present 2069 * 2070 * @since 3.6.0 2071 * 2072 * @param mixed $post Optional. Post ID or object. 2073 * @return array A list of lists, each containing image srcs parsed 2074 * from an expanded shortcode 2075 */ 2076 function get_post_galleries_images( $post = 0 ) { 2077 $galleries = get_post_galleries( $post, false ); 2078 return wp_list_pluck( $galleries, 'src' ); 2079 } 2080 2081 /** 2082 * Check a post's content for galleries and return the image srcs for the first found gallery 2083 * 2084 * @since 3.6.0 2085 * 2086 * @param mixed $post Optional. Post ID or object. 2087 * @return array A list of a gallery's image srcs in order 2088 */ 2089 function get_post_gallery_images( $post = 0 ) { 2090 $gallery = get_post_gallery( $post, false ); 2091 return empty( $gallery['src'] ) ? array() : $gallery['src']; 2092 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 25 01:41:18 2014 | WordPress honlapkészítés: online1.hu |