2008-02-21 07:00:15 +01:00
< ? php
2008-09-01 07:45:41 +02:00
/**
* WordPress API for media display .
*
* @ package WordPress
*/
2008-02-21 07:00:15 +01:00
2008-09-01 07:45:41 +02:00
/**
* Scale down the default size of an image .
*
* This is so that the image is a better fit for the editor and theme .
*
* The $size parameter accepts either an array or a string . The supported string
* values are 'thumb' or 'thumbnail' for the given thumbnail size or defaults at
* 128 width and 96 height in pixels . Also supported for the string value is
* 'medium' and 'full' . The 'full' isn ' t actually supported , but any value other
* than the supported will result in the content_width size or 500 if that is
* not set .
*
2011-09-30 00:57:43 +02:00
* Finally , there is a filter named 'editor_max_image_size' , that will be called
2008-09-01 07:45:41 +02:00
* on the calculated array for width and height , respectively . The second
* parameter will be the value that was in the $size parameter . The returned
* type for the hook is an array with the width as the first element and the
* height as the second element .
*
* @ since 2.5 . 0
* @ uses wp_constrain_dimensions () This function passes the widths and the heights .
*
* @ param int $width Width of the image
* @ param int $height Height of the image
* @ param string | array $size Size of what the result image should be .
* @ return array Width and height of what the result image should resize to .
*/
2008-02-21 07:00:15 +01:00
function image_constrain_size_for_editor ( $width , $height , $size = 'medium' ) {
2009-12-08 22:08:19 +01:00
global $content_width , $_wp_additional_image_sizes ;
2008-03-02 21:17:30 +01:00
2008-03-12 09:10:00 +01:00
if ( is_array ( $size ) ) {
$max_width = $size [ 0 ];
$max_height = $size [ 1 ];
}
elseif ( $size == 'thumb' || $size == 'thumbnail' ) {
2008-02-21 07:00:15 +01:00
$max_width = intval ( get_option ( 'thumbnail_size_w' ));
$max_height = intval ( get_option ( 'thumbnail_size_h' ));
// last chance thumbnail size defaults
if ( ! $max_width && ! $max_height ) {
$max_width = 128 ;
$max_height = 96 ;
}
}
elseif ( $size == 'medium' ) {
$max_width = intval ( get_option ( 'medium_size_w' ));
$max_height = intval ( get_option ( 'medium_size_h' ));
// if no width is set, default to the theme content width if available
}
2008-08-11 05:54:26 +02:00
elseif ( $size == 'large' ) {
2011-12-14 00:45:31 +01:00
// We're inserting a large size image into the editor. If it's a really
2008-09-18 08:14:46 +02:00
// big image we'll scale it down to fit reasonably within the editor
2011-12-14 00:45:31 +01:00
// itself, and within the theme's content width if it's known. The user
2008-09-18 08:14:46 +02:00
// can resize it in the editor if they wish.
2008-08-11 05:54:26 +02:00
$max_width = intval ( get_option ( 'large_size_w' ));
$max_height = intval ( get_option ( 'large_size_h' ));
if ( intval ( $content_width ) > 0 )
$max_width = min ( intval ( $content_width ), $max_width );
2009-12-08 22:08:19 +01:00
} elseif ( isset ( $_wp_additional_image_sizes ) && count ( $_wp_additional_image_sizes ) && in_array ( $size , array_keys ( $_wp_additional_image_sizes ) ) ) {
$max_width = intval ( $_wp_additional_image_sizes [ $size ][ 'width' ] );
$max_height = intval ( $_wp_additional_image_sizes [ $size ][ 'height' ] );
2010-02-14 07:34:47 +01:00
if ( intval ( $content_width ) > 0 && is_admin () ) // Only in admin. Assume that theme authors know what they're doing.
$max_width = min ( intval ( $content_width ), $max_width );
2008-08-11 05:54:26 +02:00
}
// $size == 'full' has no constraint
else {
$max_width = $width ;
$max_height = $height ;
2008-02-21 07:00:15 +01:00
}
list ( $max_width , $max_height ) = apply_filters ( 'editor_max_image_size' , array ( $max_width , $max_height ), $size );
2008-12-09 19:03:31 +01:00
2008-02-21 07:00:15 +01:00
return wp_constrain_dimensions ( $width , $height , $max_width , $max_height );
}
2008-09-01 07:45:41 +02:00
/**
* Retrieve width and height attributes using given width and height values .
*
* Both attributes are required in the sense that both parameters must have a
* value , but are optional in that if you set them to false or null , then they
* will not be added to the returned string .
*
* You can set the value using a string , but it will only take numeric values .
* If you wish to put 'px' after the numbers , then it will be stripped out of
* the return .
*
* @ since 2.5 . 0
*
* @ param int | string $width Optional . Width attribute value .
* @ param int | string $height Optional . Height attribute value .
* @ return string HTML attributes for width and , or height .
*/
2008-02-21 07:00:15 +01:00
function image_hwstring ( $width , $height ) {
$out = '' ;
if ( $width )
$out .= 'width="' . intval ( $width ) . '" ' ;
if ( $height )
$out .= 'height="' . intval ( $height ) . '" ' ;
return $out ;
}
2008-09-01 07:45:41 +02:00
/**
* Scale an image to fit a particular size ( such as 'thumb' or 'medium' ) .
*
* Array with image url , width , height , and whether is intermediate size , in
* that order is returned on success is returned . $is_intermediate is true if
* $url is a resized image , false if it is the original .
*
* The URL might be the original image , or it might be a resized version . This
* function won ' t create a new resized copy , it will just return an already
* resized one if it exists .
*
2008-09-18 08:14:46 +02:00
* A plugin may use the 'image_downsize' filter to hook into and offer image
* resizing services for images . The hook must return an array with the same
* elements that are returned in the function . The first element being the URL
* to the new image that was resized .
*
2008-09-01 07:45:41 +02:00
* @ since 2.5 . 0
* @ uses apply_filters () Calls 'image_downsize' on $id and $size to provide
2008-09-18 08:14:46 +02:00
* resize services .
2008-09-01 07:45:41 +02:00
*
* @ param int $id Attachment ID for image .
2011-03-23 19:46:38 +01:00
* @ param array | string $size Optional , default is 'medium' . Size of image , either array or string .
2008-09-01 07:45:41 +02:00
* @ return bool | array False on failure , array on success .
*/
2008-02-21 07:00:15 +01:00
function image_downsize ( $id , $size = 'medium' ) {
2008-03-02 21:17:30 +01:00
2008-03-10 22:31:33 +01:00
if ( ! wp_attachment_is_image ( $id ) )
return false ;
2008-02-21 07:00:15 +01:00
$img_url = wp_get_attachment_url ( $id );
$meta = wp_get_attachment_metadata ( $id );
$width = $height = 0 ;
2008-08-11 05:54:26 +02:00
$is_intermediate = false ;
2010-11-02 18:19:55 +01:00
$img_url_basename = wp_basename ( $img_url );
2008-03-02 21:17:30 +01:00
2008-02-21 07:00:15 +01:00
// plugins can use this to provide resize services
if ( $out = apply_filters ( 'image_downsize' , false , $id , $size ) )
return $out ;
2008-03-02 21:17:30 +01:00
2008-03-03 05:17:37 +01:00
// try for a new style intermediate size
if ( $intermediate = image_get_intermediate_size ( $id , $size ) ) {
2010-11-02 18:19:55 +01:00
$img_url = str_replace ( $img_url_basename , $intermediate [ 'file' ], $img_url );
2008-03-03 05:17:37 +01:00
$width = $intermediate [ 'width' ];
$height = $intermediate [ 'height' ];
2008-08-11 05:54:26 +02:00
$is_intermediate = true ;
2008-03-03 05:17:37 +01:00
}
elseif ( $size == 'thumbnail' ) {
// fall back to the old thumbnail
2008-07-04 18:15:29 +02:00
if ( ( $thumb_file = wp_get_attachment_thumb_file ( $id )) && $info = getimagesize ( $thumb_file ) ) {
2010-11-02 18:19:55 +01:00
$img_url = str_replace ( $img_url_basename , wp_basename ( $thumb_file ), $img_url );
2008-03-03 05:17:37 +01:00
$width = $info [ 0 ];
$height = $info [ 1 ];
2008-08-11 05:54:26 +02:00
$is_intermediate = true ;
2008-02-21 07:00:15 +01:00
}
}
2008-03-12 09:10:00 +01:00
if ( ! $width && ! $height && isset ( $meta [ 'width' ], $meta [ 'height' ]) ) {
2008-08-11 05:54:26 +02:00
// any other type: use the real image
$width = $meta [ 'width' ];
$height = $meta [ 'height' ];
2008-02-21 07:00:15 +01:00
}
2008-12-09 19:03:31 +01:00
2008-08-11 05:54:26 +02:00
if ( $img_url ) {
// we have the actual image size, but might need to further constrain it if content_width is narrower
list ( $width , $height ) = image_constrain_size_for_editor ( $width , $height , $size );
2008-03-02 21:17:30 +01:00
2008-08-11 05:54:26 +02:00
return array ( $img_url , $width , $height , $is_intermediate );
}
2008-03-13 00:15:31 +01:00
return false ;
2008-03-02 21:17:30 +01:00
2008-02-21 07:00:15 +01:00
}
2009-12-08 22:08:19 +01:00
/**
* Registers a new image size
2011-09-30 00:57:43 +02:00
*
* @ since 2.9 . 0
2009-12-08 22:08:19 +01:00
*/
2010-10-27 02:33:29 +02:00
function add_image_size ( $name , $width = 0 , $height = 0 , $crop = false ) {
2009-12-08 22:08:19 +01:00
global $_wp_additional_image_sizes ;
2010-10-27 02:33:29 +02:00
$_wp_additional_image_sizes [ $name ] = array ( 'width' => absint ( $width ), 'height' => absint ( $height ), 'crop' => ( bool ) $crop );
2009-12-08 22:08:19 +01:00
}
/**
2009-12-10 07:14:36 +01:00
* Registers an image size for the post thumbnail
2011-09-30 00:57:43 +02:00
*
* @ since 2.9 . 0
2009-12-08 22:08:19 +01:00
*/
2010-10-27 02:33:29 +02:00
function set_post_thumbnail_size ( $width = 0 , $height = 0 , $crop = false ) {
2009-12-10 07:14:36 +01:00
add_image_size ( 'post-thumbnail' , $width , $height , $crop );
2009-12-08 22:08:19 +01:00
}
2008-05-31 21:12:55 +02:00
/**
* An < img src /> tag for an image attachment , scaling it down if requested .
*
2008-09-18 08:14:46 +02:00
* The filter 'get_image_tag_class' allows for changing the class name for the
* image without having to use regular expressions on the HTML content . The
* parameters are : what WordPress will use for the class , the Attachment ID ,
* image align value , and the size the image should be .
*
* The second filter 'get_image_tag' has the HTML content , which can then be
* further manipulated by a plugin to change all attribute values and even HTML
* content .
2008-05-31 21:12:55 +02:00
*
2008-09-01 07:45:41 +02:00
* @ since 2.5 . 0
*
2008-05-31 21:12:55 +02:00
* @ uses apply_filters () The 'get_image_tag_class' filter is the IMG element
* class attribute .
* @ uses apply_filters () The 'get_image_tag' filter is the full IMG element with
* all attributes .
*
* @ param int $id Attachment ID .
* @ param string $alt Image Description for the alt attribute .
* @ param string $title Image Description for the title attribute .
* @ param string $align Part of the class name for aligning the image .
* @ param string $size Optional . Default is 'medium' .
* @ return string HTML IMG element for given image attachment
*/
2008-03-22 00:21:27 +01:00
function get_image_tag ( $id , $alt , $title , $align , $size = 'medium' ) {
2008-02-21 07:00:15 +01:00
list ( $img_src , $width , $height ) = image_downsize ( $id , $size );
$hwstring = image_hwstring ( $width , $height );
2009-05-05 21:43:53 +02:00
$class = 'align' . esc_attr ( $align ) . ' size-' . esc_attr ( $size ) . ' wp-image-' . $id ;
2008-05-31 21:12:55 +02:00
$class = apply_filters ( 'get_image_tag_class' , $class , $id , $align , $size );
2009-05-05 21:43:53 +02:00
$html = '<img src="' . esc_attr ( $img_src ) . '" alt="' . esc_attr ( $alt ) . '" title="' . esc_attr ( $title ) . '" ' . $hwstring . 'class="' . $class . '" />' ;
2008-02-21 07:00:15 +01:00
2008-04-25 19:58:38 +02:00
$html = apply_filters ( 'get_image_tag' , $html , $id , $alt , $title , $align , $size );
2008-02-21 07:00:15 +01:00
return $html ;
}
2010-03-28 05:39:00 +02:00
/**
* Load an image from a string , if PHP supports it .
*
* @ since 2.1 . 0
*
* @ param string $file Filename of the image to load .
* @ return resource The resulting image resource on success , Error string on failure .
*/
function wp_load_image ( $file ) {
if ( is_numeric ( $file ) )
$file = get_attached_file ( $file );
if ( ! file_exists ( $file ) )
return sprintf ( __ ( 'File “%s” doesn’t exist?' ), $file );
if ( ! function_exists ( 'imagecreatefromstring' ) )
return __ ( 'The GD image library is not installed.' );
// Set artificially high because GD uses uncompressed images in memory
2011-04-28 18:25:36 +02:00
@ ini_set ( 'memory_limit' , apply_filters ( 'image_memory_limit' , WP_MAX_MEMORY_LIMIT ) );
2010-03-28 05:39:00 +02:00
$image = imagecreatefromstring ( file_get_contents ( $file ) );
if ( ! is_resource ( $image ) )
return sprintf ( __ ( 'File “%s” is not an image.' ), $file );
return $image ;
}
2008-09-18 08:14:46 +02:00
/**
2011-09-05 21:08:15 +02:00
* Calculates the new dimensions for a downsampled image .
2008-09-18 08:14:46 +02:00
*
2010-01-25 19:50:01 +01:00
* If either width or height are empty , no constraint is applied on
2008-09-18 08:14:46 +02:00
* that dimension .
*
* @ since 2.5 . 0
*
* @ param int $current_width Current width of the image .
* @ param int $current_height Current height of the image .
* @ param int $max_width Optional . Maximum wanted width .
* @ param int $max_height Optional . Maximum wanted height .
* @ return array First item is the width , the second item is the height .
*/
2008-02-26 19:46:03 +01:00
function wp_constrain_dimensions ( $current_width , $current_height , $max_width = 0 , $max_height = 0 ) {
if ( ! $max_width and ! $max_height )
return array ( $current_width , $current_height );
2008-03-02 21:17:30 +01:00
2008-02-26 19:46:03 +01:00
$width_ratio = $height_ratio = 1.0 ;
2010-05-27 22:41:36 +02:00
$did_width = $did_height = false ;
2008-03-02 21:17:30 +01:00
2010-05-27 22:37:42 +02:00
if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) {
2008-02-26 19:46:03 +01:00
$width_ratio = $max_width / $current_width ;
2010-05-27 22:37:42 +02:00
$did_width = true ;
}
2008-03-02 21:17:30 +01:00
2010-05-27 22:37:42 +02:00
if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height ) {
2008-02-26 19:46:03 +01:00
$height_ratio = $max_height / $current_height ;
2010-05-27 22:37:42 +02:00
$did_height = true ;
}
2008-03-02 21:17:30 +01:00
2010-05-27 22:37:42 +02:00
// Calculate the larger/smaller ratios
$smaller_ratio = min ( $width_ratio , $height_ratio );
$larger_ratio = max ( $width_ratio , $height_ratio );
if ( intval ( $current_width * $larger_ratio ) > $max_width || intval ( $current_height * $larger_ratio ) > $max_height )
// The larger ratio is too big. It would result in an overflow.
$ratio = $smaller_ratio ;
else
// The larger ratio fits, and is likely to be a more "snug" fit.
$ratio = $larger_ratio ;
$w = intval ( $current_width * $ratio );
$h = intval ( $current_height * $ratio );
// Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short
2011-09-05 21:08:15 +02:00
// 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.
2010-05-27 22:37:42 +02:00
// Thus we look for dimensions that are one pixel shy of the max value and bump them up
2010-05-27 22:41:36 +02:00
if ( $did_width && $w == $max_width - 1 )
2010-05-27 22:37:42 +02:00
$w = $max_width ; // Round it up
2010-05-27 22:41:36 +02:00
if ( $did_height && $h == $max_height - 1 )
2010-05-27 22:37:42 +02:00
$h = $max_height ; // Round it up
return array ( $w , $h );
2008-02-26 19:46:03 +01:00
}
2008-09-18 08:14:46 +02:00
/**
* Retrieve calculated resized dimensions for use in imagecopyresampled () .
*
* Calculate dimensions and coordinates for a resized image that fits within a
* specified width and height . If $crop is true , the largest matching central
* portion of the image will be cropped out and resized to the required size .
*
* @ since 2.5 . 0
*
* @ param int $orig_w Original width .
* @ param int $orig_h Original height .
* @ param int $dest_w New width .
* @ param int $dest_h New height .
* @ param bool $crop Optional , default is false . Whether to crop image or resize .
2011-09-30 00:57:43 +02:00
* @ return bool | array False on failure . Returned array matches parameters for imagecopyresampled () PHP function .
2008-09-18 08:14:46 +02:00
*/
2009-11-26 07:58:21 +01:00
function image_resize_dimensions ( $orig_w , $orig_h , $dest_w , $dest_h , $crop = false ) {
2008-03-02 21:17:30 +01:00
2008-02-26 19:46:03 +01:00
if ( $orig_w <= 0 || $orig_h <= 0 )
return false ;
// at least one of dest_w or dest_h must be specific
if ( $dest_w <= 0 && $dest_h <= 0 )
return false ;
2008-03-02 21:17:30 +01:00
2008-02-26 19:46:03 +01:00
if ( $crop ) {
// crop the largest possible portion of the original image that we can size to $dest_w x $dest_h
$aspect_ratio = $orig_w / $orig_h ;
$new_w = min ( $dest_w , $orig_w );
$new_h = min ( $dest_h , $orig_h );
2009-11-26 07:58:21 +01:00
if ( ! $new_w ) {
2008-02-26 19:46:03 +01:00
$new_w = intval ( $new_h * $aspect_ratio );
}
2009-11-26 07:58:21 +01:00
if ( ! $new_h ) {
2008-02-26 19:46:03 +01:00
$new_h = intval ( $new_w / $aspect_ratio );
}
$size_ratio = max ( $new_w / $orig_w , $new_h / $orig_h );
2008-03-02 21:17:30 +01:00
2009-11-26 07:58:21 +01:00
$crop_w = round ( $new_w / $size_ratio );
$crop_h = round ( $new_h / $size_ratio );
2008-02-26 19:46:03 +01:00
2009-11-26 07:58:21 +01:00
$s_x = floor ( ( $orig_w - $crop_w ) / 2 );
$s_y = floor ( ( $orig_h - $crop_h ) / 2 );
} else {
2008-02-26 19:46:03 +01:00
// don't crop, just resize using $dest_w x $dest_h as a maximum bounding box
$crop_w = $orig_w ;
$crop_h = $orig_h ;
2008-03-02 21:17:30 +01:00
2008-02-26 19:46:03 +01:00
$s_x = 0 ;
$s_y = 0 ;
2008-03-02 21:17:30 +01:00
2008-02-26 19:46:03 +01:00
list ( $new_w , $new_h ) = wp_constrain_dimensions ( $orig_w , $orig_h , $dest_w , $dest_h );
}
2008-03-02 21:17:30 +01:00
2008-02-26 19:46:03 +01:00
// if the resulting image would be the same size or larger we don't want to resize it
2009-11-26 07:58:21 +01:00
if ( $new_w >= $orig_w && $new_h >= $orig_h )
2008-02-26 19:46:03 +01:00
return false ;
// the return array matches the parameters to imagecopyresampled()
// int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h
2009-12-12 09:06:24 +01:00
return array ( 0 , 0 , ( int ) $s_x , ( int ) $s_y , ( int ) $new_w , ( int ) $new_h , ( int ) $crop_w , ( int ) $crop_h );
2008-02-26 19:46:03 +01:00
}
2008-09-01 07:45:41 +02:00
/**
* Scale down an image to fit a particular size and save a new copy of the image .
*
2008-09-18 08:14:46 +02:00
* The PNG transparency will be preserved using the function , as well as the
* image type . If the file going in is PNG , then the resized image is going to
* be PNG . The only supported image types are PNG , GIF , and JPEG .
*
* Some functionality requires API to exist , so some PHP version may lose out
* support . This is not the fault of WordPress ( where functionality is
* downgraded , not actual defects ), but of your PHP version .
*
* @ since 2.5 . 0
*
* @ param string $file Image file path .
* @ param int $max_w Maximum width to resize to .
* @ param int $max_h Maximum height to resize to .
* @ param bool $crop Optional . Whether to crop image or resize .
2011-09-30 00:57:43 +02:00
* @ param string $suffix Optional . File suffix .
2008-09-18 08:14:46 +02:00
* @ param string $dest_path Optional . New image file path .
* @ param int $jpeg_quality Optional , default is 90. Image quality percentage .
2010-04-16 15:53:22 +02:00
* @ return mixed WP_Error on failure . String with new destination path .
2008-09-01 07:45:41 +02:00
*/
2009-07-27 20:32:30 +02:00
function image_resize ( $file , $max_w , $max_h , $crop = false , $suffix = null , $dest_path = null , $jpeg_quality = 90 ) {
2008-02-26 19:46:03 +01:00
$image = wp_load_image ( $file );
if ( ! is_resource ( $image ) )
2009-12-23 19:39:31 +01:00
return new WP_Error ( 'error_loading_image' , $image , $file );
2008-02-26 19:46:03 +01:00
2009-07-27 20:32:30 +02:00
$size = @ getimagesize ( $file );
if ( ! $size )
return new WP_Error ( 'invalid_image' , __ ( 'Could not read image size' ), $file );
list ( $orig_w , $orig_h , $orig_type ) = $size ;
2008-02-26 19:46:03 +01:00
$dims = image_resize_dimensions ( $orig_w , $orig_h , $max_w , $max_h , $crop );
2009-07-27 20:32:30 +02:00
if ( ! $dims )
2010-04-16 15:53:22 +02:00
return new WP_Error ( 'error_getting_dimensions' , __ ( 'Could not calculate resized image dimensions' ) );
2008-02-26 19:46:03 +01:00
list ( $dst_x , $dst_y , $src_x , $src_y , $dst_w , $dst_h , $src_w , $src_h ) = $dims ;
2008-03-02 21:17:30 +01:00
2009-09-11 00:07:33 +02:00
$newimage = wp_imagecreatetruecolor ( $dst_w , $dst_h );
2008-02-26 19:46:03 +01:00
imagecopyresampled ( $newimage , $image , $dst_x , $dst_y , $src_x , $src_y , $dst_w , $dst_h , $src_w , $src_h );
2009-09-14 16:03:32 +02:00
2009-07-22 05:02:44 +02:00
// convert from full colors to index colors, like original PNG.
2010-03-28 04:57:09 +02:00
if ( IMAGETYPE_PNG == $orig_type && function_exists ( 'imageistruecolor' ) && ! imageistruecolor ( $image ) )
2009-07-22 05:02:44 +02:00
imagetruecolortopalette ( $newimage , false , imagecolorstotal ( $image ) );
2008-02-26 19:46:03 +01:00
// we don't need the original in memory anymore
imagedestroy ( $image );
// $suffix will be appended to the destination filename, just before the extension
if ( ! $suffix )
$suffix = " { $dst_w } x { $dst_h } " ;
$info = pathinfo ( $file );
$dir = $info [ 'dirname' ];
$ext = $info [ 'extension' ];
2010-11-02 18:19:55 +01:00
$name = wp_basename ( $file , " . $ext " );
2008-02-26 19:46:03 +01:00
if ( ! is_null ( $dest_path ) and $_dest_path = realpath ( $dest_path ) )
$dir = $_dest_path ;
$destfilename = " { $dir } / { $name } - { $suffix } . { $ext } " ;
2009-07-27 20:32:30 +02:00
if ( IMAGETYPE_GIF == $orig_type ) {
if ( ! imagegif ( $newimage , $destfilename ) )
2008-02-26 19:46:03 +01:00
return new WP_Error ( 'resize_path_invalid' , __ ( 'Resize path invalid' ));
2009-07-27 20:32:30 +02:00
} elseif ( IMAGETYPE_PNG == $orig_type ) {
2009-09-04 04:36:34 +02:00
if ( ! imagepng ( $newimage , $destfilename ) )
2008-02-26 19:46:03 +01:00
return new WP_Error ( 'resize_path_invalid' , __ ( 'Resize path invalid' ));
2009-07-27 20:32:30 +02:00
} else {
2008-02-26 19:46:03 +01:00
// all other formats are converted to jpg
$destfilename = " { $dir } / { $name } - { $suffix } .jpg " ;
2009-09-14 16:03:32 +02:00
if ( ! imagejpeg ( $newimage , $destfilename , apply_filters ( 'jpeg_quality' , $jpeg_quality , 'image_resize' ) ) )
2008-02-26 19:46:03 +01:00
return new WP_Error ( 'resize_path_invalid' , __ ( 'Resize path invalid' ));
}
imagedestroy ( $newimage );
// Set correct file permissions
$stat = stat ( dirname ( $destfilename ));
$perms = $stat [ 'mode' ] & 0000666 ; //same permissions as parent folder, strip off the executable bits
@ chmod ( $destfilename , $perms );
return $destfilename ;
}
2008-09-18 08:14:46 +02:00
/**
* Resize an image to make a thumbnail or intermediate size .
*
* The returned array has the file size , the image width , and image height . The
* filter 'image_make_intermediate_size' can be used to hook in and change the
* values of the returned array . The only parameter is the resized file path .
*
* @ since 2.5 . 0
*
* @ param string $file File path .
* @ param int $width Image width .
* @ param int $height Image height .
* @ param bool $crop Optional , default is false . Whether to crop image to specified height and width or resize .
* @ return bool | array False , if no image was created . Metadata array on success .
*/
2008-03-03 05:17:37 +01:00
function image_make_intermediate_size ( $file , $width , $height , $crop = false ) {
if ( $width || $height ) {
$resized_file = image_resize ( $file , $width , $height , $crop );
2008-03-04 05:23:35 +01:00
if ( ! is_wp_error ( $resized_file ) && $resized_file && $info = getimagesize ( $resized_file ) ) {
2008-04-16 23:59:23 +02:00
$resized_file = apply_filters ( 'image_make_intermediate_size' , $resized_file );
2008-03-03 05:17:37 +01:00
return array (
2010-11-02 18:19:55 +01:00
'file' => wp_basename ( $resized_file ),
2008-03-03 05:17:37 +01:00
'width' => $info [ 0 ],
'height' => $info [ 1 ],
);
}
}
return false ;
}
2008-09-18 08:14:46 +02:00
/**
* Retrieve the image ' s intermediate size ( resized ) path , width , and height .
*
* The $size parameter can be an array with the width and height respectively .
* If the size matches the 'sizes' metadata array for width and height , then it
* will be used . If there is no direct match , then the nearest image size larger
* than the specified size will be used . If nothing is found , then the function
* will break out and return false .
2008-12-09 19:03:31 +01:00
*
2008-09-18 08:14:46 +02:00
* The metadata 'sizes' is used for compatible sizes that can be used for the
* parameter $size value .
*
* The url path will be given , when the $size parameter is a string .
*
2010-05-27 07:03:46 +02:00
* If you are passing an array for the $size , you should consider using
* add_image_size () so that a cropped version is generated . It ' s much more
* efficient than having to find the closest - sized image and then having the
* browser scale down the image .
*
2008-09-18 08:14:46 +02:00
* @ since 2.5 . 0
2010-05-27 07:03:46 +02:00
* @ see add_image_size ()
2008-09-18 08:14:46 +02:00
*
* @ param int $post_id Attachment ID for image .
* @ param array | string $size Optional , default is 'thumbnail' . Size of image , either array or string .
* @ return bool | array False on failure or array of file path , width , and height on success .
*/
2008-03-03 05:17:37 +01:00
function image_get_intermediate_size ( $post_id , $size = 'thumbnail' ) {
2008-07-06 18:40:15 +02:00
if ( ! is_array ( $imagedata = wp_get_attachment_metadata ( $post_id ) ) )
2008-03-03 05:17:37 +01:00
return false ;
2008-03-12 09:10:00 +01:00
// get the best one for a specified set of dimensions
if ( is_array ( $size ) && ! empty ( $imagedata [ 'sizes' ]) ) {
foreach ( $imagedata [ 'sizes' ] as $_size => $data ) {
// already cropped to width or height; so use this size
if ( ( $data [ 'width' ] == $size [ 0 ] && $data [ 'height' ] <= $size [ 1 ] ) || ( $data [ 'height' ] == $size [ 1 ] && $data [ 'width' ] <= $size [ 0 ] ) ) {
$file = $data [ 'file' ];
list ( $width , $height ) = image_constrain_size_for_editor ( $data [ 'width' ], $data [ 'height' ], $size );
return compact ( 'file' , 'width' , 'height' );
}
// add to lookup table: area => size
$areas [ $data [ 'width' ] * $data [ 'height' ]] = $_size ;
}
if ( ! $size || ! empty ( $areas ) ) {
// find for the smallest image not smaller than the desired size
ksort ( $areas );
foreach ( $areas as $_size ) {
$data = $imagedata [ 'sizes' ][ $_size ];
if ( $data [ 'width' ] >= $size [ 0 ] || $data [ 'height' ] >= $size [ 1 ] ) {
2010-02-14 09:21:07 +01:00
// Skip images with unexpectedly divergent aspect ratios (crops)
// First, we calculate what size the original image would be if constrained to a box the size of the current image in the loop
$maybe_cropped = image_resize_dimensions ( $imagedata [ 'width' ], $imagedata [ 'height' ], $data [ 'width' ], $data [ 'height' ], false );
2010-05-27 22:37:42 +02:00
// 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
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' ] ) ) )
2010-02-14 09:21:07 +01:00
continue ;
// If we're still here, then we're going to use this size
2008-03-12 09:10:00 +01:00
$file = $data [ 'file' ];
list ( $width , $height ) = image_constrain_size_for_editor ( $data [ 'width' ], $data [ 'height' ], $size );
return compact ( 'file' , 'width' , 'height' );
}
}
}
}
if ( is_array ( $size ) || empty ( $size ) || empty ( $imagedata [ 'sizes' ][ $size ]) )
2008-03-03 05:17:37 +01:00
return false ;
2008-08-09 07:36:14 +02:00
2008-03-13 00:15:31 +01:00
$data = $imagedata [ 'sizes' ][ $size ];
// include the full filesystem path of the intermediate file
if ( empty ( $data [ 'path' ]) && ! empty ( $data [ 'file' ]) ) {
$file_url = wp_get_attachment_url ( $post_id );
$data [ 'path' ] = path_join ( dirname ( $imagedata [ 'file' ]), $data [ 'file' ] );
$data [ 'url' ] = path_join ( dirname ( $file_url ), $data [ 'file' ] );
}
return $data ;
2008-03-03 05:17:37 +01:00
}
2010-01-08 09:51:12 +01:00
/**
* Get the available image sizes
2010-03-26 20:13:36 +01:00
* @ since 3.0 . 0
2010-01-08 09:51:12 +01:00
* @ return array Returns a filtered array of image size strings
*/
function get_intermediate_image_sizes () {
global $_wp_additional_image_sizes ;
$image_sizes = array ( 'thumbnail' , 'medium' , 'large' ); // Standard sizes
if ( isset ( $_wp_additional_image_sizes ) && count ( $_wp_additional_image_sizes ) )
$image_sizes = array_merge ( $image_sizes , array_keys ( $_wp_additional_image_sizes ) );
return apply_filters ( 'intermediate_image_sizes' , $image_sizes );
}
2008-09-18 08:14:46 +02:00
/**
* Retrieve an image to represent an attachment .
*
* A mime icon for files , thumbnail or intermediate size for images .
*
* @ since 2.5 . 0
*
* @ param int $attachment_id Image attachment ID .
* @ param string $size Optional , default is 'thumbnail' .
* @ param bool $icon Optional , default is false . Whether it is an icon .
* @ return bool | array Returns an array ( url , width , height ), or false , if no image is available .
*/
2008-03-12 09:10:00 +01:00
function wp_get_attachment_image_src ( $attachment_id , $size = 'thumbnail' , $icon = false ) {
2008-08-09 07:36:14 +02:00
2008-03-04 05:21:37 +01:00
// get a thumbnail or intermediate image if there is one
2008-03-10 22:31:33 +01:00
if ( $image = image_downsize ( $attachment_id , $size ) )
return $image ;
2009-06-06 17:02:55 +02:00
$src = false ;
2008-03-12 09:10:00 +01:00
if ( $icon && $src = wp_mime_type_icon ( $attachment_id ) ) {
2008-11-14 19:32:10 +01:00
$icon_dir = apply_filters ( 'icon_dir' , ABSPATH . WPINC . '/images/crystal' );
2010-11-02 18:19:55 +01:00
$src_file = $icon_dir . '/' . wp_basename ( $src );
2008-03-04 05:21:37 +01:00
@ list ( $width , $height ) = getimagesize ( $src_file );
}
if ( $src && $width && $height )
return array ( $src , $width , $height );
return false ;
}
2008-09-18 08:14:46 +02:00
/**
2009-03-08 06:42:17 +01:00
* Get an HTML img element representing an image attachment
2008-09-18 08:14:46 +02:00
*
2010-05-27 07:03:46 +02:00
* While $size will accept an array , it is better to register a size with
* add_image_size () so that a cropped version is generated . It ' s much more
* efficient than having to find the closest - sized image and then having the
* browser scale down the image .
*
* @ see add_image_size ()
2009-03-08 06:42:17 +01:00
* @ uses apply_filters () Calls 'wp_get_attachment_image_attributes' hook on attributes array
* @ uses wp_get_attachment_image_src () Gets attachment file URL and dimensions
2008-09-18 08:14:46 +02:00
* @ since 2.5 . 0
*
* @ param int $attachment_id Image attachment ID .
* @ param string $size Optional , default is 'thumbnail' .
* @ param bool $icon Optional , default is false . Whether it is an icon .
* @ return string HTML img element or empty string on failure .
*/
2009-10-15 14:31:48 +02:00
function wp_get_attachment_image ( $attachment_id , $size = 'thumbnail' , $icon = false , $attr = '' ) {
2008-03-04 05:21:37 +01:00
$html = '' ;
2008-03-12 09:10:00 +01:00
$image = wp_get_attachment_image_src ( $attachment_id , $size , $icon );
2008-03-04 05:21:37 +01:00
if ( $image ) {
list ( $src , $width , $height ) = $image ;
2008-11-26 03:27:37 +01:00
$hwstring = image_hwstring ( $width , $height );
2008-03-12 09:10:00 +01:00
if ( is_array ( $size ) )
$size = join ( 'x' , $size );
2009-03-08 06:42:17 +01:00
$attachment =& get_post ( $attachment_id );
2009-10-15 14:31:48 +02:00
$default_attr = array (
2009-03-08 06:42:17 +01:00
'src' => $src ,
'class' => " attachment- $size " ,
2010-04-18 10:52:18 +02:00
'alt' => trim ( strip_tags ( get_post_meta ( $attachment_id , '_wp_attachment_image_alt' , true ) )), // Use Alt field first
2009-03-08 06:42:17 +01:00
'title' => trim ( strip_tags ( $attachment -> post_title )),
2009-10-15 14:31:48 +02:00
);
2010-04-18 10:52:18 +02:00
if ( empty ( $default_attr [ 'alt' ]) )
$default_attr [ 'alt' ] = trim ( strip_tags ( $attachment -> post_excerpt )); // If not, Use the Caption
if ( empty ( $default_attr [ 'alt' ]) )
$default_attr [ 'alt' ] = trim ( strip_tags ( $attachment -> post_title )); // Finally, use the title
2009-10-15 14:31:48 +02:00
$attr = wp_parse_args ( $attr , $default_attr );
2009-03-08 06:42:17 +01:00
$attr = apply_filters ( 'wp_get_attachment_image_attributes' , $attr , $attachment );
2009-05-05 21:43:53 +02:00
$attr = array_map ( 'esc_attr' , $attr );
2009-03-08 06:42:17 +01:00
$html = rtrim ( " <img $hwstring " );
foreach ( $attr as $name => $value ) {
$html .= " $name = " . '"' . $value . '"' ;
}
$html .= ' />' ;
2008-03-04 05:21:37 +01:00
}
2008-08-09 07:36:14 +02:00
2008-03-04 05:21:37 +01:00
return $html ;
}
2008-03-03 05:17:37 +01:00
2009-10-15 16:27:04 +02:00
/**
2011-09-30 00:57:43 +02:00
* Adds a 'wp-post-image' class to post thumbnails
2009-12-10 07:14:36 +01:00
* Uses the begin_fetch_post_thumbnail_html and end_fetch_post_thumbnail_html action hooks to
2011-09-30 00:57:43 +02:00
* dynamically add / remove itself so as to only filter post thumbnails
2009-10-15 22:26:21 +02:00
*
2009-10-15 16:27:04 +02:00
* @ since 2.9 . 0
* @ param array $attr Attributes including src , class , alt , title
* @ return array
*/
2009-12-10 07:14:36 +01:00
function _wp_post_thumbnail_class_filter ( $attr ) {
2009-10-15 16:27:04 +02:00
$attr [ 'class' ] .= ' wp-post-image' ;
return $attr ;
}
/**
2009-12-10 07:14:36 +01:00
* Adds _wp_post_thumbnail_class_filter to the wp_get_attachment_image_attributes filter
2009-10-15 22:26:21 +02:00
*
2009-10-15 16:27:04 +02:00
* @ since 2.9 . 0
*/
2009-12-10 07:14:36 +01:00
function _wp_post_thumbnail_class_filter_add ( $attr ) {
add_filter ( 'wp_get_attachment_image_attributes' , '_wp_post_thumbnail_class_filter' );
2009-10-15 16:27:04 +02:00
}
/**
2009-12-10 07:14:36 +01:00
* Removes _wp_post_thumbnail_class_filter from the wp_get_attachment_image_attributes filter
2009-10-15 22:26:21 +02:00
*
2009-10-15 16:27:04 +02:00
* @ since 2.9 . 0
*/
2009-12-10 07:14:36 +01:00
function _wp_post_thumbnail_class_filter_remove ( $attr ) {
remove_filter ( 'wp_get_attachment_image_attributes' , '_wp_post_thumbnail_class_filter' );
2009-10-15 16:27:04 +02:00
}
2008-07-09 01:37:56 +02:00
add_shortcode ( 'wp_caption' , 'img_caption_shortcode' );
2008-07-11 17:59:14 +02:00
add_shortcode ( 'caption' , 'img_caption_shortcode' );
2008-07-02 20:41:11 +02:00
2008-09-18 08:14:46 +02:00
/**
* The Caption shortcode .
*
* Allows a plugin to replace the content that would otherwise be returned . The
* filter is 'img_caption_shortcode' and passes an empty string , the attr
* parameter and the content parameter values .
*
* The supported attributes for the shortcode are 'id' , 'align' , 'width' , and
* 'caption' .
*
* @ since 2.6 . 0
*
* @ param array $attr Attributes attributed to the shortcode .
* @ param string $content Optional . Shortcode content .
* @ return string
*/
2008-07-09 01:37:56 +02:00
function img_caption_shortcode ( $attr , $content = null ) {
2008-07-11 17:59:14 +02:00
2008-07-02 20:41:11 +02:00
// Allow plugins/themes to override the default caption template.
2008-07-09 01:37:56 +02:00
$output = apply_filters ( 'img_caption_shortcode' , '' , $attr , $content );
2008-07-02 20:41:11 +02:00
if ( $output != '' )
return $output ;
extract ( shortcode_atts ( array (
'id' => '' ,
'align' => 'alignnone' ,
'width' => '' ,
'caption' => ''
), $attr ));
2008-08-09 07:36:14 +02:00
2008-07-02 20:41:11 +02:00
if ( 1 > ( int ) $width || empty ( $caption ) )
return $content ;
2008-08-09 07:36:14 +02:00
2009-08-18 18:05:07 +02:00
if ( $id ) $id = 'id="' . esc_attr ( $id ) . '" ' ;
2008-08-09 07:36:14 +02:00
2009-08-18 18:05:07 +02:00
return '<div ' . $id . 'class="wp-caption ' . esc_attr ( $align ) . '" style="width: ' . ( 10 + ( int ) $width ) . 'px">'
2009-02-04 18:07:26 +01:00
. do_shortcode ( $content ) . '<p class="wp-caption-text">' . $caption . '</p></div>' ;
2008-07-02 20:41:11 +02:00
}
2008-04-25 02:43:44 +02:00
add_shortcode ( 'gallery' , 'gallery_shortcode' );
2008-03-06 20:48:54 +01:00
2008-09-18 08:14:46 +02:00
/**
* The Gallery shortcode .
*
* This implements the functionality of the Gallery Shortcode for displaying
* WordPress images on a post .
*
* @ since 2.5 . 0
*
2011-09-30 00:57:43 +02:00
* @ param array $attr Attributes of the shortcode .
2008-09-18 08:14:46 +02:00
* @ return string HTML content to display gallery .
*/
2008-03-06 20:48:54 +01:00
function gallery_shortcode ( $attr ) {
2011-08-25 21:35:22 +02:00
global $post ;
2009-05-25 01:47:49 +02:00
2009-05-15 10:52:04 +02:00
static $instance = 0 ;
$instance ++ ;
2008-03-06 20:48:54 +01:00
// Allow plugins/themes to override the default gallery template.
$output = apply_filters ( 'post_gallery' , '' , $attr );
if ( $output != '' )
return $output ;
2008-04-03 05:05:49 +02:00
// We're trusting author input, so let's at least make sure it looks like a valid orderby statement
if ( isset ( $attr [ 'orderby' ] ) ) {
$attr [ 'orderby' ] = sanitize_sql_orderby ( $attr [ 'orderby' ] );
if ( ! $attr [ 'orderby' ] )
unset ( $attr [ 'orderby' ] );
}
2008-03-24 03:57:19 +01:00
extract ( shortcode_atts ( array (
2008-05-05 17:46:32 +02:00
'order' => 'ASC' ,
'orderby' => 'menu_order ID' ,
2008-03-24 03:57:19 +01:00
'id' => $post -> ID ,
'itemtag' => 'dl' ,
'icontag' => 'dt' ,
'captiontag' => 'dd' ,
'columns' => 3 ,
2009-08-04 09:32:18 +02:00
'size' => 'thumbnail' ,
'include' => '' ,
'exclude' => ''
2008-03-24 03:57:19 +01:00
), $attr ));
$id = intval ( $id );
2009-08-04 09:32:18 +02:00
if ( 'RAND' == $order )
$orderby = 'none' ;
if ( ! empty ( $include ) ) {
2009-08-05 07:56:00 +02:00
$include = preg_replace ( '/[^0-9,]+/' , '' , $include );
2009-08-04 09:32:18 +02:00
$_attachments = get_posts ( array ( 'include' => $include , 'post_status' => 'inherit' , 'post_type' => 'attachment' , 'post_mime_type' => 'image' , 'order' => $order , 'orderby' => $orderby ) );
$attachments = array ();
foreach ( $_attachments as $key => $val ) {
$attachments [ $val -> ID ] = $_attachments [ $key ];
}
} elseif ( ! empty ( $exclude ) ) {
2009-08-05 07:56:00 +02:00
$exclude = preg_replace ( '/[^0-9,]+/' , '' , $exclude );
2009-08-04 09:32:18 +02:00
$attachments = get_children ( array ( 'post_parent' => $id , 'exclude' => $exclude , 'post_status' => 'inherit' , 'post_type' => 'attachment' , 'post_mime_type' => 'image' , 'order' => $order , 'orderby' => $orderby ) );
} else {
$attachments = get_children ( array ( 'post_parent' => $id , 'post_status' => 'inherit' , 'post_type' => 'attachment' , 'post_mime_type' => 'image' , 'order' => $order , 'orderby' => $orderby ) );
}
2008-03-06 20:48:54 +01:00
if ( empty ( $attachments ) )
return '' ;
2008-03-14 20:23:56 +01:00
if ( is_feed () ) {
$output = " \n " ;
2009-05-15 10:52:04 +02:00
foreach ( $attachments as $att_id => $attachment )
$output .= wp_get_attachment_link ( $att_id , $size , true ) . " \n " ;
2008-03-14 20:23:56 +01:00
return $output ;
}
2008-03-24 03:57:19 +01:00
$itemtag = tag_escape ( $itemtag );
$captiontag = tag_escape ( $captiontag );
$columns = intval ( $columns );
2008-03-26 04:34:55 +01:00
$itemwidth = $columns > 0 ? floor ( 100 / $columns ) : 100 ;
2010-05-03 07:49:19 +02:00
$float = is_rtl () ? 'right' : 'left' ;
2010-01-15 23:11:12 +01:00
2009-05-15 10:52:04 +02:00
$selector = " gallery- { $instance } " ;
2008-08-09 07:36:14 +02:00
2010-12-10 20:15:37 +01:00
$gallery_style = $gallery_div = '' ;
if ( apply_filters ( 'use_default_gallery_style' , true ) )
$gallery_style = "
2008-03-06 20:48:54 +01:00
< style type = 'text/css' >
2009-05-15 10:52:04 +02:00
#{$selector} {
2008-03-06 20:48:54 +01:00
margin : auto ;
}
2009-05-15 10:52:04 +02:00
#{$selector} .gallery-item {
2009-12-08 13:45:32 +01:00
float : { $float };
2008-03-06 20:48:54 +01:00
margin - top : 10 px ;
text - align : center ;
2010-12-10 20:15:37 +01:00
width : { $itemwidth } % ;
}
2009-05-15 10:52:04 +02:00
#{$selector} img {
2008-03-06 20:48:54 +01:00
border : 2 px solid #cfcfcf;
}
2009-05-15 10:52:04 +02:00
#{$selector} .gallery-caption {
2008-03-24 03:57:19 +01:00
margin - left : 0 ;
}
2008-03-06 20:48:54 +01:00
</ style >
2010-12-10 20:15:37 +01:00
<!-- see gallery_shortcode () in wp - includes / media . php --> " ;
$size_class = sanitize_html_class ( $size );
$gallery_div = " <div id=' $selector ' class='gallery galleryid- { $id } gallery-columns- { $columns } gallery-size- { $size_class } '> " ;
$output = apply_filters ( 'gallery_style' , $gallery_style . " \n \t \t " . $gallery_div );
2008-03-06 20:48:54 +01:00
2008-10-22 20:45:09 +02:00
$i = 0 ;
2008-03-06 20:48:54 +01:00
foreach ( $attachments as $id => $attachment ) {
2008-11-26 03:27:37 +01:00
$link = isset ( $attr [ 'link' ]) && 'file' == $attr [ 'link' ] ? wp_get_attachment_link ( $id , $size , false , false ) : wp_get_attachment_link ( $id , $size , true , false );
2008-11-23 07:37:15 +01:00
2008-03-24 03:57:19 +01:00
$output .= " < { $itemtag } class='gallery-item'> " ;
2008-03-06 20:48:54 +01:00
$output .= "
2008-03-24 03:57:19 +01:00
< { $icontag } class = 'gallery-icon' >
2008-03-06 20:48:54 +01:00
$link
2008-03-24 03:57:19 +01:00
</ { $icontag } > " ;
if ( $captiontag && trim ( $attachment -> post_excerpt ) ) {
$output .= "
2010-12-10 20:05:50 +01:00
< { $captiontag } class = 'wp-caption-text gallery-caption' >
2009-05-15 01:15:28 +02:00
" . wptexturize( $attachment->post_excerpt ) . "
2008-03-24 03:57:19 +01:00
</ { $captiontag } > " ;
}
$output .= " </ { $itemtag } > " ;
if ( $columns > 0 && ++ $i % $columns == 0 )
2008-03-06 20:48:54 +01:00
$output .= '<br style="clear: both" />' ;
}
$output .= "
2008-03-30 18:41:43 +02:00
< br style = 'clear: both;' />
2008-03-06 20:48:54 +01:00
</ div > \n " ;
return $output ;
}
2008-09-01 07:45:41 +02:00
/**
* Display previous image link that has the same post parent .
*
* @ since 2.5 . 0
2009-02-04 16:12:24 +01:00
* @ param string $size Optional , default is 'thumbnail' . Size of image , either array or string . 0 or 'none' will default to post_title or $text ;
* @ param string $text Optional , default is false . If included , link will reflect $text variable .
* @ return string HTML content .
2008-09-01 07:45:41 +02:00
*/
2009-02-04 16:12:24 +01:00
function previous_image_link ( $size = 'thumbnail' , $text = false ) {
adjacent_image_link ( true , $size , $text );
2008-03-11 01:09:14 +01:00
}
2008-09-01 07:45:41 +02:00
/**
* Display next image link that has the same post parent .
*
* @ since 2.5 . 0
2009-02-04 16:12:24 +01:00
* @ param string $size Optional , default is 'thumbnail' . Size of image , either array or string . 0 or 'none' will default to post_title or $text ;
* @ param string $text Optional , default is false . If included , link will reflect $text variable .
* @ return string HTML content .
2008-09-01 07:45:41 +02:00
*/
2009-02-04 16:12:24 +01:00
function next_image_link ( $size = 'thumbnail' , $text = false ) {
adjacent_image_link ( false , $size , $text );
2008-03-11 01:09:14 +01:00
}
2008-09-01 07:45:41 +02:00
/**
* Display next or previous image link that has the same post parent .
*
* Retrieves the current attachment object from the $post global .
*
* @ since 2.5 . 0
*
2011-09-30 00:57:43 +02:00
* @ param bool $prev Optional . Default is true to display previous link , false for next .
2008-09-01 07:45:41 +02:00
*/
2009-02-04 16:12:24 +01:00
function adjacent_image_link ( $prev = true , $size = 'thumbnail' , $text = false ) {
2008-03-11 01:09:14 +01:00
global $post ;
$post = get_post ( $post );
2008-05-05 17:46:32 +02:00
$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' ) ));
2008-03-11 01:09:14 +01:00
foreach ( $attachments as $k => $attachment )
if ( $attachment -> ID == $post -> ID )
break ;
$k = $prev ? $k - 1 : $k + 1 ;
if ( isset ( $attachments [ $k ]) )
2009-02-04 16:12:24 +01:00
echo wp_get_attachment_link ( $attachments [ $k ] -> ID , $size , true , false , $text );
2008-03-11 01:09:14 +01:00
}
2008-09-18 08:14:46 +02:00
/**
* Retrieve taxonomies attached to the attachment .
*
* @ since 2.5 . 0
*
* @ param int | array | object $attachment Attachment ID , Attachment data array , or Attachment data object .
* @ return array Empty array on failure . List of taxonomies on success .
*/
2008-03-26 07:37:19 +01:00
function get_attachment_taxonomies ( $attachment ) {
if ( is_int ( $attachment ) )
$attachment = get_post ( $attachment );
else if ( is_array ( $attachment ) )
$attachment = ( object ) $attachment ;
if ( ! is_object ( $attachment ) )
return array ();
$filename = basename ( $attachment -> guid );
$objects = array ( 'attachment' );
if ( false !== strpos ( $filename , '.' ) )
$objects [] = 'attachment:' . substr ( $filename , strrpos ( $filename , '.' ) + 1 );
if ( ! empty ( $attachment -> post_mime_type ) ) {
$objects [] = 'attachment:' . $attachment -> post_mime_type ;
if ( false !== strpos ( $attachment -> post_mime_type , '/' ) )
foreach ( explode ( '/' , $attachment -> post_mime_type ) as $token )
if ( ! empty ( $token ) )
$objects [] = " attachment: $token " ;
}
$taxonomies = array ();
foreach ( $objects as $object )
if ( $taxes = get_object_taxonomies ( $object ) )
$taxonomies = array_merge ( $taxonomies , $taxes );
return array_unique ( $taxonomies );
}
2009-09-11 00:07:33 +02:00
/**
* Check if the installed version of GD supports particular image type
*
* @ since 2.9 . 0
*
2010-09-07 13:21:11 +02:00
* @ param string $mime_type
2009-09-11 00:07:33 +02:00
* @ return bool
*/
function gd_edit_image_support ( $mime_type ) {
if ( function_exists ( 'imagetypes' ) ) {
switch ( $mime_type ) {
case 'image/jpeg' :
return ( imagetypes () & IMG_JPG ) != 0 ;
case 'image/png' :
return ( imagetypes () & IMG_PNG ) != 0 ;
case 'image/gif' :
return ( imagetypes () & IMG_GIF ) != 0 ;
}
} else {
switch ( $mime_type ) {
case 'image/jpeg' :
return function_exists ( 'imagecreatefromjpeg' );
case 'image/png' :
return function_exists ( 'imagecreatefrompng' );
case 'image/gif' :
return function_exists ( 'imagecreatefromgif' );
2009-09-14 16:03:32 +02:00
}
2009-09-11 00:07:33 +02:00
}
return false ;
}
/**
* Create new GD image resource with transparency support
*
* @ since 2.9 . 0
*
2010-09-07 13:21:11 +02:00
* @ param int $width Image width
* @ param int $height Image height
2009-09-11 00:07:33 +02:00
* @ return image resource
*/
function wp_imagecreatetruecolor ( $width , $height ) {
$img = imagecreatetruecolor ( $width , $height );
if ( is_resource ( $img ) && function_exists ( 'imagealphablending' ) && function_exists ( 'imagesavealpha' ) ) {
imagealphablending ( $img , false );
imagesavealpha ( $img , true );
}
return $img ;
}
2009-10-13 19:04:22 +02:00
/**
* API for easily embedding rich media such as videos and images into content .
*
* @ package WordPress
* @ subpackage Embed
* @ since 2.9 . 0
*/
class WP_Embed {
var $handlers = array ();
var $post_ID ;
var $usecache = true ;
var $linkifunknown = true ;
/**
2011-04-11 20:57:34 +02:00
* Constructor
2009-10-13 19:04:22 +02:00
*/
function __construct () {
// Hack to get the [embed] shortcode to run before wpautop()
add_filter ( 'the_content' , array ( & $this , 'run_shortcode' ), 8 );
2010-04-08 04:16:21 +02:00
// Shortcode placeholder for strip_shortcodes()
add_shortcode ( 'embed' , '__return_false' );
2009-10-13 19:04:22 +02:00
// Attempts to embed all URLs in a post
if ( get_option ( 'embed_autourls' ) )
add_filter ( 'the_content' , array ( & $this , 'autoembed' ), 8 );
2009-11-06 15:22:23 +01:00
// After a post is saved, invalidate the oEmbed cache
add_action ( 'save_post' , array ( & $this , 'delete_oembed_caches' ) );
2009-10-13 19:04:22 +02:00
// After a post is saved, cache oEmbed items via AJAX
2009-11-02 15:41:35 +01:00
add_action ( 'edit_form_advanced' , array ( & $this , 'maybe_run_ajax_cache' ) );
2009-10-13 19:04:22 +02:00
}
/**
* Process the [ embed ] shortcode .
*
* Since the [ embed ] shortcode needs to be run earlier than other shortcodes ,
* this function removes all existing shortcodes , registers the [ embed ] shortcode ,
* calls { @ link do_shortcode ()}, and then re - registers the old shortcodes .
*
* @ uses $shortcode_tags
* @ uses remove_all_shortcodes ()
* @ uses add_shortcode ()
* @ uses do_shortcode ()
*
* @ param string $content Content to parse
* @ return string Content with shortcode parsed
*/
function run_shortcode ( $content ) {
global $shortcode_tags ;
2010-07-27 20:02:45 +02:00
// Back up current registered shortcodes and clear them all out
2009-10-13 19:04:22 +02:00
$orig_shortcode_tags = $shortcode_tags ;
remove_all_shortcodes ();
add_shortcode ( 'embed' , array ( & $this , 'shortcode' ) );
// Do the shortcode (only the [embed] one is registered)
$content = do_shortcode ( $content );
// Put the original shortcodes back
$shortcode_tags = $orig_shortcode_tags ;
return $content ;
}
/**
2011-09-30 00:57:43 +02:00
* If a post / page was saved , then output JavaScript to make
2009-10-13 19:04:22 +02:00
* an AJAX request that will call WP_Embed :: cache_oembed () .
*/
function maybe_run_ajax_cache () {
global $post_ID ;
if ( empty ( $post_ID ) || empty ( $_GET [ 'message' ]) || 1 != $_GET [ 'message' ] )
return ;
?>
< script type = " text/javascript " >
/* <![CDATA[ */
jQuery ( document ) . ready ( function ( $ ){
2012-02-08 17:12:11 +01:00
$ . get ( " <?php echo admin_url( 'admin-ajax.php?action=oembed-cache&post=' . $post_ID , 'relative' ); ?> " );
2009-10-13 19:04:22 +02:00
});
/* ]]> */
</ script >
< ? php
}
/**
* Register an embed handler . Do not use this function directly , use { @ link wp_embed_register_handler ()} instead .
* This function should probably also only be used for sites that do not support oEmbed .
*
* @ param string $id An internal ID / name for the handler . Needs to be unique .
* @ param string $regex The regex that will be used to see if this handler should be used for a URL .
* @ param callback $callback The callback function that will be called if the regex is matched .
* @ param int $priority Optional . Used to specify the order in which the registered handlers will be tested ( default : 10 ) . Lower numbers correspond with earlier testing , and handlers with the same priority are tested in the order in which they were added to the action .
*/
function register_handler ( $id , $regex , $callback , $priority = 10 ) {
$this -> handlers [ $priority ][ $id ] = array (
'regex' => $regex ,
'callback' => $callback ,
);
}
/**
* Unregister a previously registered embed handler . Do not use this function directly , use { @ link wp_embed_unregister_handler ()} instead .
*
* @ param string $id The handler ID that should be removed .
* @ param int $priority Optional . The priority of the handler to be removed ( default : 10 ) .
*/
function unregister_handler ( $id , $priority = 10 ) {
if ( isset ( $this -> handlers [ $priority ][ $id ]) )
unset ( $this -> handlers [ $priority ][ $id ]);
}
/**
* The { @ link do_shortcode ()} callback function .
*
* Attempts to convert a URL into embed HTML . Starts by checking the URL against the regex of the registered embed handlers .
* If none of the regex matches and it ' s enabled , then the URL will be given to the { @ link WP_oEmbed } class .
*
* @ uses wp_oembed_get ()
* @ uses wp_parse_args ()
* @ uses wp_embed_defaults ()
* @ uses WP_Embed :: maybe_make_link ()
* @ uses get_option ()
* @ uses current_user_can ()
* @ uses wp_cache_get ()
* @ uses wp_cache_set ()
* @ uses get_post_meta ()
* @ uses update_post_meta ()
*
* @ param array $attr Shortcode attributes .
2011-09-05 21:08:15 +02:00
* @ param string $url The URL attempting to be embedded .
2009-10-13 19:04:22 +02:00
* @ return string The embed HTML on success , otherwise the original URL .
*/
function shortcode ( $attr , $url = '' ) {
2009-12-06 18:40:36 +01:00
global $post ;
2009-10-13 19:04:22 +02:00
if ( empty ( $url ) )
return '' ;
$rawattr = $attr ;
$attr = wp_parse_args ( $attr , wp_embed_defaults () );
2010-12-05 03:23:17 +01:00
// kses converts & into & and we need to undo this
// See http://core.trac.wordpress.org/ticket/11311
$url = str_replace ( '&' , '&' , $url );
2009-10-13 19:04:22 +02:00
// Look for known internal handlers
ksort ( $this -> handlers );
foreach ( $this -> handlers as $priority => $handlers ) {
foreach ( $handlers as $id => $handler ) {
if ( preg_match ( $handler [ 'regex' ], $url , $matches ) && is_callable ( $handler [ 'callback' ] ) ) {
if ( false !== $return = call_user_func ( $handler [ 'callback' ], $matches , $attr , $url , $rawattr ) )
2009-11-06 15:22:23 +01:00
return apply_filters ( 'embed_handler_html' , $return , $url , $attr );
2009-10-13 19:04:22 +02:00
}
}
}
$post_ID = ( ! empty ( $post -> ID ) ) ? $post -> ID : null ;
if ( ! empty ( $this -> post_ID ) ) // Potentially set by WP_Embed::cache_oembed()
$post_ID = $this -> post_ID ;
// Unknown URL format. Let oEmbed have a go.
2009-11-02 15:41:35 +01:00
if ( $post_ID ) {
2009-10-13 19:04:22 +02:00
// Check for a cached result (stored in the post meta)
2009-12-06 18:40:36 +01:00
$cachekey = '_oembed_' . md5 ( $url . serialize ( $attr ) );
2009-10-13 19:04:22 +02:00
if ( $this -> usecache ) {
2009-12-06 18:40:36 +01:00
$cache = get_post_meta ( $post_ID , $cachekey , true );
2009-10-13 19:04:22 +02:00
// Failures are cached
if ( '{{unknown}}' === $cache )
return $this -> maybe_make_link ( $url );
if ( ! empty ( $cache ) )
2010-12-06 04:38:27 +01:00
return apply_filters ( 'embed_oembed_html' , $cache , $url , $attr , $post_ID );
2009-10-13 19:04:22 +02:00
}
// Use oEmbed to get the HTML
2010-03-19 22:15:00 +01:00
$attr [ 'discover' ] = ( apply_filters ( 'embed_oembed_discover' , false ) && author_can ( $post_ID , 'unfiltered_html' ) );
2009-10-13 19:04:22 +02:00
$html = wp_oembed_get ( $url , $attr );
// Cache the result
$cache = ( $html ) ? $html : '{{unknown}}' ;
2009-12-06 18:40:36 +01:00
update_post_meta ( $post_ID , $cachekey , $cache );
2009-10-13 19:04:22 +02:00
// If there was a result, return it
if ( $html )
2010-12-06 04:38:27 +01:00
return apply_filters ( 'embed_oembed_html' , $html , $url , $attr , $post_ID );
2009-10-13 19:04:22 +02:00
}
// Still unknown
return $this -> maybe_make_link ( $url );
}
2009-11-06 15:22:23 +01:00
/**
* Delete all oEmbed caches .
*
* @ param int $post_ID Post ID to delete the caches for .
*/
function delete_oembed_caches ( $post_ID ) {
$post_metas = get_post_custom_keys ( $post_ID );
if ( empty ( $post_metas ) )
return ;
2009-12-06 18:40:36 +01:00
foreach ( $post_metas as $post_meta_key ) {
2009-11-06 15:22:23 +01:00
if ( '_oembed_' == substr ( $post_meta_key , 0 , 8 ) )
delete_post_meta ( $post_ID , $post_meta_key );
}
}
2009-10-13 19:04:22 +02:00
/**
* Triggers a caching of all oEmbed results .
*
* @ param int $post_ID Post ID to do the caching for .
*/
function cache_oembed ( $post_ID ) {
$post = get_post ( $post_ID );
if ( empty ( $post -> ID ) || ! in_array ( $post -> post_type , apply_filters ( 'embed_cache_oembed_types' , array ( 'post' , 'page' ) ) ) )
return ;
// Trigger a caching
if ( ! empty ( $post -> post_content ) ) {
$this -> post_ID = $post -> ID ;
$this -> usecache = false ;
$content = $this -> run_shortcode ( $post -> post_content );
if ( get_option ( 'embed_autourls' ) )
$this -> autoembed ( $content );
$this -> usecache = true ;
}
}
/**
* Passes any unlinked URLs that are on their own line to { @ link WP_Embed :: shortcode ()} for potential embedding .
*
* @ uses WP_Embed :: autoembed_callback ()
*
* @ param string $content The content to be searched .
* @ return string Potentially modified $content .
*/
function autoembed ( $content ) {
return preg_replace_callback ( '|^\s*(https?://[^\s"]+)\s*$|im' , array ( & $this , 'autoembed_callback' ), $content );
}
/**
* Callback function for { @ link WP_Embed :: autoembed ()} .
*
* @ uses WP_Embed :: shortcode ()
*
* @ param array $match A regex match array .
* @ return string The embed HTML on success , otherwise the original URL .
*/
function autoembed_callback ( $match ) {
$oldval = $this -> linkifunknown ;
$this -> linkifunknown = false ;
$return = $this -> shortcode ( array (), $match [ 1 ] );
$this -> linkifunknown = $oldval ;
return " \n $return\n " ;
}
/**
* Conditionally makes a hyperlink based on an internal class variable .
*
* @ param string $url URL to potentially be linked .
* @ return string Linked URL or the original URL .
*/
function maybe_make_link ( $url ) {
2009-11-06 15:22:23 +01:00
$output = ( $this -> linkifunknown ) ? '<a href="' . esc_attr ( $url ) . '">' . esc_html ( $url ) . '</a>' : $url ;
return apply_filters ( 'embed_maybe_make_link' , $output , $url );
2009-10-13 19:04:22 +02:00
}
}
2011-08-11 06:45:14 +02:00
$GLOBALS [ 'wp_embed' ] = new WP_Embed ();
2009-10-13 19:04:22 +02:00
/**
* Register an embed handler . This function should probably only be used for sites that do not support oEmbed .
*
2009-10-14 00:36:24 +02:00
* @ since 2.9 . 0
2009-10-13 19:04:22 +02:00
* @ see WP_Embed :: register_handler ()
*/
function wp_embed_register_handler ( $id , $regex , $callback , $priority = 10 ) {
global $wp_embed ;
$wp_embed -> register_handler ( $id , $regex , $callback , $priority );
}
/**
* Unregister a previously registered embed handler .
*
2009-10-14 00:36:24 +02:00
* @ since 2.9 . 0
2009-10-13 19:04:22 +02:00
* @ see WP_Embed :: unregister_handler ()
*/
function wp_embed_unregister_handler ( $id , $priority = 10 ) {
global $wp_embed ;
$wp_embed -> unregister_handler ( $id , $priority );
}
/**
* Create default array of embed parameters .
*
2009-10-14 00:36:24 +02:00
* @ since 2.9 . 0
*
2009-10-13 19:04:22 +02:00
* @ return array Default embed parameters .
*/
function wp_embed_defaults () {
if ( ! empty ( $GLOBALS [ 'content_width' ]) )
$theme_width = ( int ) $GLOBALS [ 'content_width' ];
$width = get_option ( 'embed_size_w' );
2010-01-27 15:38:48 +01:00
if ( empty ( $width ) && ! empty ( $theme_width ) )
2009-10-13 19:04:22 +02:00
$width = $theme_width ;
2010-01-27 15:38:48 +01:00
if ( empty ( $width ) )
2009-10-13 19:04:22 +02:00
$width = 500 ;
2010-01-27 15:38:48 +01:00
$height = get_option ( 'embed_size_h' );
if ( empty ( $height ) )
$height = 700 ;
2009-10-13 19:04:22 +02:00
return apply_filters ( 'embed_defaults' , array (
2010-01-27 15:38:48 +01:00
'width' => $width ,
'height' => $height ,
2009-10-13 19:04:22 +02:00
) );
}
/**
* Based on a supplied width / height example , return the biggest possible dimensions based on the max width / height .
*
2009-10-14 00:36:24 +02:00
* @ since 2.9 . 0
2009-10-13 19:04:22 +02:00
* @ uses wp_constrain_dimensions () This function passes the widths and the heights .
*
* @ param int $example_width The width of an example embed .
* @ param int $example_height The height of an example embed .
* @ param int $max_width The maximum allowed width .
* @ param int $max_height The maximum allowed height .
* @ return array The maximum possible width and height based on the example ratio .
*/
function wp_expand_dimensions ( $example_width , $example_height , $max_width , $max_height ) {
$example_width = ( int ) $example_width ;
$example_height = ( int ) $example_height ;
$max_width = ( int ) $max_width ;
$max_height = ( int ) $max_height ;
return wp_constrain_dimensions ( $example_width * 1000000 , $example_height * 1000000 , $max_width , $max_height );
}
/**
* Attempts to fetch the embed HTML for a provided URL using oEmbed .
*
2009-10-14 00:36:24 +02:00
* @ since 2.9 . 0
2009-10-13 19:04:22 +02:00
* @ see WP_oEmbed
*
* @ uses _wp_oembed_get_object ()
* @ uses WP_oEmbed :: get_html ()
*
2011-09-05 21:08:15 +02:00
* @ param string $url The URL that should be embedded .
2011-09-30 00:57:43 +02:00
* @ param array $args Additional arguments and parameters .
2009-10-13 19:04:22 +02:00
* @ return string The original URL on failure or the embed HTML on success .
*/
function wp_oembed_get ( $url , $args = '' ) {
2010-04-18 11:51:19 +02:00
require_once ( ABSPATH . WPINC . '/class-oembed.php' );
2009-10-13 19:04:22 +02:00
$oembed = _wp_oembed_get_object ();
return $oembed -> get_html ( $url , $args );
}
2009-10-14 00:36:24 +02:00
/**
* Adds a URL format and oEmbed provider URL pair .
*
* @ since 2.9 . 0
* @ see WP_oEmbed
*
* @ uses _wp_oembed_get_object ()
*
2009-10-23 21:33:24 +02:00
* @ param string $format The format of URL that this provider can handle . You can use asterisks as wildcards .
2009-10-14 00:36:24 +02:00
* @ param string $provider The URL to the oEmbed provider .
2010-02-24 21:13:23 +01:00
* @ param boolean $regex Whether the $format parameter is in a regex format .
2009-10-14 00:36:24 +02:00
*/
2009-10-23 21:33:24 +02:00
function wp_oembed_add_provider ( $format , $provider , $regex = false ) {
2010-04-18 11:51:19 +02:00
require_once ( ABSPATH . WPINC . '/class-oembed.php' );
2009-10-14 00:36:24 +02:00
$oembed = _wp_oembed_get_object ();
2009-10-23 21:33:24 +02:00
$oembed -> providers [ $format ] = array ( $provider , $regex );
2011-04-28 19:03:23 +02:00
}
/**
* Determines if default embed handlers should be loaded .
*
* Checks to make sure that the embeds library hasn ' t already been loaded . If
* it hasn ' t , then it will load the embeds library .
*
* @ since 2.9 . 0
*/
function wp_maybe_load_embeds () {
if ( ! apply_filters ( 'load_default_embeds' , true ) )
return ;
wp_embed_register_handler ( 'googlevideo' , '#http://video\.google\.([A-Za-z.]{2,5})/videoplay\?docid=([\d-]+)(.*?)#i' , 'wp_embed_handler_googlevideo' );
}
/**
* The Google Video embed handler callback . Google Video does not support oEmbed .
*
* @ see WP_Embed :: register_handler ()
* @ see WP_Embed :: shortcode ()
*
* @ param array $matches The regex matches from the provided regex when calling { @ link wp_embed_register_handler ()} .
* @ param array $attr Embed attributes .
* @ param string $url The original URL that was matched by the regex .
* @ param array $rawattr The original unmodified attributes .
* @ return string The embed HTML .
*/
function wp_embed_handler_googlevideo ( $matches , $attr , $url , $rawattr ) {
// If the user supplied a fixed width AND height, use it
if ( ! empty ( $rawattr [ 'width' ]) && ! empty ( $rawattr [ 'height' ]) ) {
$width = ( int ) $rawattr [ 'width' ];
$height = ( int ) $rawattr [ 'height' ];
} else {
list ( $width , $height ) = wp_expand_dimensions ( 425 , 344 , $attr [ 'width' ], $attr [ 'height' ] );
}
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 );
}