web/wp-includes/media.php
changeset 194 32102edaa81b
parent 136 bde1974c263b
child 204 09a1c134465b
equal deleted inserted replaced
193:2f6f6f7551ca 194:32102edaa81b
    15  * 128 width and 96 height in pixels. Also supported for the string value is
    15  * 128 width and 96 height in pixels. Also supported for the string value is
    16  * 'medium' and 'full'. The 'full' isn't actually supported, but any value other
    16  * 'medium' and 'full'. The 'full' isn't actually supported, but any value other
    17  * than the supported will result in the content_width size or 500 if that is
    17  * than the supported will result in the content_width size or 500 if that is
    18  * not set.
    18  * not set.
    19  *
    19  *
    20  * Finally, there is a filter named, 'editor_max_image_size' that will be called
    20  * Finally, there is a filter named 'editor_max_image_size', that will be called
    21  * on the calculated array for width and height, respectively. The second
    21  * on the calculated array for width and height, respectively. The second
    22  * parameter will be the value that was in the $size parameter. The returned
    22  * parameter will be the value that was in the $size parameter. The returned
    23  * type for the hook is an array with the width as the first element and the
    23  * type for the hook is an array with the width as the first element and the
    24  * height as the second element.
    24  * height as the second element.
    25  *
    25  *
    51 		$max_width = intval(get_option('medium_size_w'));
    51 		$max_width = intval(get_option('medium_size_w'));
    52 		$max_height = intval(get_option('medium_size_h'));
    52 		$max_height = intval(get_option('medium_size_h'));
    53 		// if no width is set, default to the theme content width if available
    53 		// if no width is set, default to the theme content width if available
    54 	}
    54 	}
    55 	elseif ( $size == 'large' ) {
    55 	elseif ( $size == 'large' ) {
    56 		// we're inserting a large size image into the editor.  if it's a really
    56 		// We're inserting a large size image into the editor. If it's a really
    57 		// big image we'll scale it down to fit reasonably within the editor
    57 		// big image we'll scale it down to fit reasonably within the editor
    58 		// itself, and within the theme's content width if it's known.  the user
    58 		// itself, and within the theme's content width if it's known. The user
    59 		// can resize it in the editor if they wish.
    59 		// can resize it in the editor if they wish.
    60 		$max_width = intval(get_option('large_size_w'));
    60 		$max_width = intval(get_option('large_size_w'));
    61 		$max_height = intval(get_option('large_size_h'));
    61 		$max_height = intval(get_option('large_size_h'));
    62 		if ( intval($content_width) > 0 )
    62 		if ( intval($content_width) > 0 )
    63 			$max_width = min( intval($content_width), $max_width );
    63 			$max_width = min( intval($content_width), $max_width );
    64 	} elseif ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ) ) ) {
    64 	} elseif ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ) ) ) {
    65 		$max_width = intval( $_wp_additional_image_sizes[$size]['width'] );
    65 		$max_width = intval( $_wp_additional_image_sizes[$size]['width'] );
    66 		$max_height = intval( $_wp_additional_image_sizes[$size]['height'] );
    66 		$max_height = intval( $_wp_additional_image_sizes[$size]['height'] );
    67 		if ( intval($content_width) > 0 )
    67 		if ( intval($content_width) > 0 && is_admin() ) // Only in admin. Assume that theme authors know what they're doing.
    68 			$max_width = min( intval($content_width), $max_width );
    68 			$max_width = min( intval($content_width), $max_width );
    69 	}
    69 	}
    70 	// $size == 'full' has no constraint
    70 	// $size == 'full' has no constraint
    71 	else {
    71 	else {
    72 		$max_width = $width;
    72 		$max_width = $width;
   123  * @since 2.5.0
   123  * @since 2.5.0
   124  * @uses apply_filters() Calls 'image_downsize' on $id and $size to provide
   124  * @uses apply_filters() Calls 'image_downsize' on $id and $size to provide
   125  *		resize services.
   125  *		resize services.
   126  *
   126  *
   127  * @param int $id Attachment ID for image.
   127  * @param int $id Attachment ID for image.
   128  * @param string $size Optional, default is 'medium'. Size of image, can be 'thumbnail'.
   128  * @param array|string $size Optional, default is 'medium'. Size of image, either array or string.
   129  * @return bool|array False on failure, array on success.
   129  * @return bool|array False on failure, array on success.
   130  */
   130  */
   131 function image_downsize($id, $size = 'medium') {
   131 function image_downsize($id, $size = 'medium') {
   132 
   132 
   133 	if ( !wp_attachment_is_image($id) )
   133 	if ( !wp_attachment_is_image($id) )
   135 
   135 
   136 	$img_url = wp_get_attachment_url($id);
   136 	$img_url = wp_get_attachment_url($id);
   137 	$meta = wp_get_attachment_metadata($id);
   137 	$meta = wp_get_attachment_metadata($id);
   138 	$width = $height = 0;
   138 	$width = $height = 0;
   139 	$is_intermediate = false;
   139 	$is_intermediate = false;
       
   140 	$img_url_basename = wp_basename($img_url);
   140 
   141 
   141 	// plugins can use this to provide resize services
   142 	// plugins can use this to provide resize services
   142 	if ( $out = apply_filters('image_downsize', false, $id, $size) )
   143 	if ( $out = apply_filters('image_downsize', false, $id, $size) )
   143 		return $out;
   144 		return $out;
   144 
   145 
   145 	// try for a new style intermediate size
   146 	// try for a new style intermediate size
   146 	if ( $intermediate = image_get_intermediate_size($id, $size) ) {
   147 	if ( $intermediate = image_get_intermediate_size($id, $size) ) {
   147 		$img_url = str_replace(basename($img_url), $intermediate['file'], $img_url);
   148 		$img_url = str_replace($img_url_basename, $intermediate['file'], $img_url);
   148 		$width = $intermediate['width'];
   149 		$width = $intermediate['width'];
   149 		$height = $intermediate['height'];
   150 		$height = $intermediate['height'];
   150 		$is_intermediate = true;
   151 		$is_intermediate = true;
   151 	}
   152 	}
   152 	elseif ( $size == 'thumbnail' ) {
   153 	elseif ( $size == 'thumbnail' ) {
   153 		// fall back to the old thumbnail
   154 		// fall back to the old thumbnail
   154 		if ( ($thumb_file = wp_get_attachment_thumb_file($id)) && $info = getimagesize($thumb_file) ) {
   155 		if ( ($thumb_file = wp_get_attachment_thumb_file($id)) && $info = getimagesize($thumb_file) ) {
   155 			$img_url = str_replace(basename($img_url), basename($thumb_file), $img_url);
   156 			$img_url = str_replace($img_url_basename, wp_basename($thumb_file), $img_url);
   156 			$width = $info[0];
   157 			$width = $info[0];
   157 			$height = $info[1];
   158 			$height = $info[1];
   158 			$is_intermediate = true;
   159 			$is_intermediate = true;
   159 		}
   160 		}
   160 	}
   161 	}
   174 
   175 
   175 }
   176 }
   176 
   177 
   177 /**
   178 /**
   178  * Registers a new image size
   179  * Registers a new image size
   179  */
   180  *
   180 function add_image_size( $name, $width = 0, $height = 0, $crop = FALSE ) {
   181  * @since 2.9.0
       
   182  */
       
   183 function add_image_size( $name, $width = 0, $height = 0, $crop = false ) {
   181 	global $_wp_additional_image_sizes;
   184 	global $_wp_additional_image_sizes;
   182 	$_wp_additional_image_sizes[$name] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => !!$crop );
   185 	$_wp_additional_image_sizes[$name] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => (bool) $crop );
   183 }
   186 }
   184 
   187 
   185 /**
   188 /**
   186  * Registers an image size for the post thumbnail
   189  * Registers an image size for the post thumbnail
   187  */
   190  *
   188 function set_post_thumbnail_size( $width = 0, $height = 0, $crop = FALSE ) {
   191  * @since 2.9.0
       
   192  */
       
   193 function set_post_thumbnail_size( $width = 0, $height = 0, $crop = false ) {
   189 	add_image_size( 'post-thumbnail', $width, $height, $crop );
   194 	add_image_size( 'post-thumbnail', $width, $height, $crop );
   190 }
   195 }
   191 
   196 
   192 /**
   197 /**
   193  * An <img src /> tag for an image attachment, scaling it down if requested.
   198  * An <img src /> tag for an image attachment, scaling it down if requested.
   229 
   234 
   230 	return $html;
   235 	return $html;
   231 }
   236 }
   232 
   237 
   233 /**
   238 /**
   234  * Calculates the new dimentions for a downsampled image.
   239  * Load an image from a string, if PHP supports it.
   235  *
   240  *
   236  * Same as {@link wp_shrink_dimensions()}, except the max parameters are
   241  * @since 2.1.0
   237  * optional. If either width or height are empty, no constraint is applied on
   242  *
       
   243  * @param string $file Filename of the image to load.
       
   244  * @return resource The resulting image resource on success, Error string on failure.
       
   245  */
       
   246 function wp_load_image( $file ) {
       
   247 	if ( is_numeric( $file ) )
       
   248 		$file = get_attached_file( $file );
       
   249 
       
   250 	if ( ! file_exists( $file ) )
       
   251 		return sprintf(__('File &#8220;%s&#8221; doesn&#8217;t exist?'), $file);
       
   252 
       
   253 	if ( ! function_exists('imagecreatefromstring') )
       
   254 		return __('The GD image library is not installed.');
       
   255 
       
   256 	// Set artificially high because GD uses uncompressed images in memory
       
   257 	@ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) );
       
   258 	$image = imagecreatefromstring( file_get_contents( $file ) );
       
   259 
       
   260 	if ( !is_resource( $image ) )
       
   261 		return sprintf(__('File &#8220;%s&#8221; is not an image.'), $file);
       
   262 
       
   263 	return $image;
       
   264 }
       
   265 
       
   266 /**
       
   267  * Calculates the new dimensions for a downsampled image.
       
   268  *
       
   269  * If either width or height are empty, no constraint is applied on
   238  * that dimension.
   270  * that dimension.
   239  *
   271  *
   240  * @since 2.5.0
   272  * @since 2.5.0
   241  *
   273  *
   242  * @param int $current_width Current width of the image.
   274  * @param int $current_width Current width of the image.
   248 function wp_constrain_dimensions( $current_width, $current_height, $max_width=0, $max_height=0 ) {
   280 function wp_constrain_dimensions( $current_width, $current_height, $max_width=0, $max_height=0 ) {
   249 	if ( !$max_width and !$max_height )
   281 	if ( !$max_width and !$max_height )
   250 		return array( $current_width, $current_height );
   282 		return array( $current_width, $current_height );
   251 
   283 
   252 	$width_ratio = $height_ratio = 1.0;
   284 	$width_ratio = $height_ratio = 1.0;
   253 
   285 	$did_width = $did_height = false;
   254 	if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width )
   286 
       
   287 	if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) {
   255 		$width_ratio = $max_width / $current_width;
   288 		$width_ratio = $max_width / $current_width;
   256 
   289 		$did_width = true;
   257 	if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height )
   290 	}
       
   291 
       
   292 	if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height ) {
   258 		$height_ratio = $max_height / $current_height;
   293 		$height_ratio = $max_height / $current_height;
   259 
   294 		$did_height = true;
   260 	// the smaller ratio is the one we need to fit it to the constraining box
   295 	}
   261 	$ratio = min( $width_ratio, $height_ratio );
   296 
   262 
   297 	// Calculate the larger/smaller ratios
   263 	return array( intval($current_width * $ratio), intval($current_height * $ratio) );
   298 	$smaller_ratio = min( $width_ratio, $height_ratio );
       
   299 	$larger_ratio  = max( $width_ratio, $height_ratio );
       
   300 
       
   301 	if ( intval( $current_width * $larger_ratio ) > $max_width || intval( $current_height * $larger_ratio ) > $max_height )
       
   302  		// The larger ratio is too big. It would result in an overflow.
       
   303 		$ratio = $smaller_ratio;
       
   304 	else
       
   305 		// The larger ratio fits, and is likely to be a more "snug" fit.
       
   306 		$ratio = $larger_ratio;
       
   307 
       
   308 	$w = intval( $current_width  * $ratio );
       
   309 	$h = intval( $current_height * $ratio );
       
   310 
       
   311 	// Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short
       
   312 	// 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.
       
   313 	// Thus we look for dimensions that are one pixel shy of the max value and bump them up
       
   314 	if ( $did_width && $w == $max_width - 1 )
       
   315 		$w = $max_width; // Round it up
       
   316 	if ( $did_height && $h == $max_height - 1 )
       
   317 		$h = $max_height; // Round it up
       
   318 
       
   319 	return array( $w, $h );
   264 }
   320 }
   265 
   321 
   266 /**
   322 /**
   267  * Retrieve calculated resized dimensions for use in imagecopyresampled().
   323  * Retrieve calculated resized dimensions for use in imagecopyresampled().
   268  *
   324  *
   269  * Calculate dimensions and coordinates for a resized image that fits within a
   325  * Calculate dimensions and coordinates for a resized image that fits within a
   270  * specified width and height. If $crop is true, the largest matching central
   326  * specified width and height. If $crop is true, the largest matching central
   271  * portion of the image will be cropped out and resized to the required size.
   327  * portion of the image will be cropped out and resized to the required size.
   272  *
   328  *
   273  * @since 2.5.0
   329  * @since 2.5.0
       
   330  * @uses apply_filters() Calls 'image_resize_dimensions' on $orig_w, $orig_h, $dest_w, $dest_h and
       
   331  *		$crop to provide custom resize dimensions.
   274  *
   332  *
   275  * @param int $orig_w Original width.
   333  * @param int $orig_w Original width.
   276  * @param int $orig_h Original height.
   334  * @param int $orig_h Original height.
   277  * @param int $dest_w New width.
   335  * @param int $dest_w New width.
   278  * @param int $dest_h New height.
   336  * @param int $dest_h New height.
   279  * @param bool $crop Optional, default is false. Whether to crop image or resize.
   337  * @param bool $crop Optional, default is false. Whether to crop image or resize.
   280  * @return bool|array False, on failure. Returned array matches parameters for imagecopyresampled() PHP function.
   338  * @return bool|array False on failure. Returned array matches parameters for imagecopyresampled() PHP function.
   281  */
   339  */
   282 function image_resize_dimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop = false) {
   340 function image_resize_dimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop = false) {
   283 
   341 
   284 	if ($orig_w <= 0 || $orig_h <= 0)
   342 	if ($orig_w <= 0 || $orig_h <= 0)
   285 		return false;
   343 		return false;
   286 	// at least one of dest_w or dest_h must be specific
   344 	// at least one of dest_w or dest_h must be specific
   287 	if ($dest_w <= 0 && $dest_h <= 0)
   345 	if ($dest_w <= 0 && $dest_h <= 0)
   288 		return false;
   346 		return false;
       
   347 
       
   348 	// plugins can use this to provide custom resize dimensions
       
   349 	$output = apply_filters( 'image_resize_dimensions', null, $orig_w, $orig_h, $dest_w, $dest_h, $crop );
       
   350 	if ( null !== $output )
       
   351 		return $output;
   289 
   352 
   290 	if ( $crop ) {
   353 	if ( $crop ) {
   291 		// crop the largest possible portion of the original image that we can size to $dest_w x $dest_h
   354 		// crop the largest possible portion of the original image that we can size to $dest_w x $dest_h
   292 		$aspect_ratio = $orig_w / $orig_h;
   355 		$aspect_ratio = $orig_w / $orig_h;
   293 		$new_w = min($dest_w, $orig_w);
   356 		$new_w = min($dest_w, $orig_w);
   344  *
   407  *
   345  * @param string $file Image file path.
   408  * @param string $file Image file path.
   346  * @param int $max_w Maximum width to resize to.
   409  * @param int $max_w Maximum width to resize to.
   347  * @param int $max_h Maximum height to resize to.
   410  * @param int $max_h Maximum height to resize to.
   348  * @param bool $crop Optional. Whether to crop image or resize.
   411  * @param bool $crop Optional. Whether to crop image or resize.
   349  * @param string $suffix Optional. File Suffix.
   412  * @param string $suffix Optional. File suffix.
   350  * @param string $dest_path Optional. New image file path.
   413  * @param string $dest_path Optional. New image file path.
   351  * @param int $jpeg_quality Optional, default is 90. Image quality percentage.
   414  * @param int $jpeg_quality Optional, default is 90. Image quality percentage.
   352  * @return mixed WP_Error on failure. String with new destination path. Array of dimensions from {@link image_resize_dimensions()}
   415  * @return mixed WP_Error on failure. String with new destination path.
   353  */
   416  */
   354 function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
   417 function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
   355 
   418 
   356 	$image = wp_load_image( $file );
   419 	$image = wp_load_image( $file );
   357 	if ( !is_resource( $image ) )
   420 	if ( !is_resource( $image ) )
   358 		return new WP_Error('error_loading_image', $image);
   421 		return new WP_Error( 'error_loading_image', $image, $file );
   359 
   422 
   360 	$size = @getimagesize( $file );
   423 	$size = @getimagesize( $file );
   361 	if ( !$size )
   424 	if ( !$size )
   362 		return new WP_Error('invalid_image', __('Could not read image size'), $file);
   425 		return new WP_Error('invalid_image', __('Could not read image size'), $file);
   363 	list($orig_w, $orig_h, $orig_type) = $size;
   426 	list($orig_w, $orig_h, $orig_type) = $size;
   364 
   427 
   365 	$dims = image_resize_dimensions($orig_w, $orig_h, $max_w, $max_h, $crop);
   428 	$dims = image_resize_dimensions($orig_w, $orig_h, $max_w, $max_h, $crop);
   366 	if ( !$dims )
   429 	if ( !$dims )
   367 		return $dims;
   430 		return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') );
   368 	list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims;
   431 	list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims;
   369 
   432 
   370 	$newimage = wp_imagecreatetruecolor( $dst_w, $dst_h );
   433 	$newimage = wp_imagecreatetruecolor( $dst_w, $dst_h );
   371 
   434 
   372 	imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
   435 	imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
   373 
   436 
   374 	// convert from full colors to index colors, like original PNG.
   437 	// convert from full colors to index colors, like original PNG.
   375 	if ( IMAGETYPE_PNG == $orig_type && !imageistruecolor( $image ) )
   438 	if ( IMAGETYPE_PNG == $orig_type && function_exists('imageistruecolor') && !imageistruecolor( $image ) )
   376 		imagetruecolortopalette( $newimage, false, imagecolorstotal( $image ) );
   439 		imagetruecolortopalette( $newimage, false, imagecolorstotal( $image ) );
   377 
   440 
   378 	// we don't need the original in memory anymore
   441 	// we don't need the original in memory anymore
   379 	imagedestroy( $image );
   442 	imagedestroy( $image );
   380 
   443 
   383 		$suffix = "{$dst_w}x{$dst_h}";
   446 		$suffix = "{$dst_w}x{$dst_h}";
   384 
   447 
   385 	$info = pathinfo($file);
   448 	$info = pathinfo($file);
   386 	$dir = $info['dirname'];
   449 	$dir = $info['dirname'];
   387 	$ext = $info['extension'];
   450 	$ext = $info['extension'];
   388 	$name = basename($file, ".{$ext}");
   451 	$name = wp_basename($file, ".$ext");
       
   452 
   389 	if ( !is_null($dest_path) and $_dest_path = realpath($dest_path) )
   453 	if ( !is_null($dest_path) and $_dest_path = realpath($dest_path) )
   390 		$dir = $_dest_path;
   454 		$dir = $_dest_path;
   391 	$destfilename = "{$dir}/{$name}-{$suffix}.{$ext}";
   455 	$destfilename = "{$dir}/{$name}-{$suffix}.{$ext}";
   392 
   456 
   393 	if ( IMAGETYPE_GIF == $orig_type ) {
   457 	if ( IMAGETYPE_GIF == $orig_type ) {
   396 	} elseif ( IMAGETYPE_PNG == $orig_type ) {
   460 	} elseif ( IMAGETYPE_PNG == $orig_type ) {
   397 		if ( !imagepng( $newimage, $destfilename ) )
   461 		if ( !imagepng( $newimage, $destfilename ) )
   398 			return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
   462 			return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
   399 	} else {
   463 	} else {
   400 		// all other formats are converted to jpg
   464 		// all other formats are converted to jpg
   401 		$destfilename = "{$dir}/{$name}-{$suffix}.jpg";
   465 		if ( 'jpg' != $ext && 'jpeg' != $ext )
       
   466 			$destfilename = "{$dir}/{$name}-{$suffix}.jpg";
   402 		if ( !imagejpeg( $newimage, $destfilename, apply_filters( 'jpeg_quality', $jpeg_quality, 'image_resize' ) ) )
   467 		if ( !imagejpeg( $newimage, $destfilename, apply_filters( 'jpeg_quality', $jpeg_quality, 'image_resize' ) ) )
   403 			return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
   468 			return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
   404 	}
   469 	}
   405 
   470 
   406 	imagedestroy( $newimage );
   471 	imagedestroy( $newimage );
   432 	if ( $width || $height ) {
   497 	if ( $width || $height ) {
   433 		$resized_file = image_resize($file, $width, $height, $crop);
   498 		$resized_file = image_resize($file, $width, $height, $crop);
   434 		if ( !is_wp_error($resized_file) && $resized_file && $info = getimagesize($resized_file) ) {
   499 		if ( !is_wp_error($resized_file) && $resized_file && $info = getimagesize($resized_file) ) {
   435 			$resized_file = apply_filters('image_make_intermediate_size', $resized_file);
   500 			$resized_file = apply_filters('image_make_intermediate_size', $resized_file);
   436 			return array(
   501 			return array(
   437 				'file' => basename( $resized_file ),
   502 				'file' => wp_basename( $resized_file ),
   438 				'width' => $info[0],
   503 				'width' => $info[0],
   439 				'height' => $info[1],
   504 				'height' => $info[1],
   440 			);
   505 			);
   441 		}
   506 		}
   442 	}
   507 	}
   455  * The metadata 'sizes' is used for compatible sizes that can be used for the
   520  * The metadata 'sizes' is used for compatible sizes that can be used for the
   456  * parameter $size value.
   521  * parameter $size value.
   457  *
   522  *
   458  * The url path will be given, when the $size parameter is a string.
   523  * The url path will be given, when the $size parameter is a string.
   459  *
   524  *
       
   525  * If you are passing an array for the $size, you should consider using
       
   526  * add_image_size() so that a cropped version is generated. It's much more
       
   527  * efficient than having to find the closest-sized image and then having the
       
   528  * browser scale down the image.
       
   529  *
   460  * @since 2.5.0
   530  * @since 2.5.0
       
   531  * @see add_image_size()
   461  *
   532  *
   462  * @param int $post_id Attachment ID for image.
   533  * @param int $post_id Attachment ID for image.
   463  * @param array|string $size Optional, default is 'thumbnail'. Size of image, either array or string.
   534  * @param array|string $size Optional, default is 'thumbnail'. Size of image, either array or string.
   464  * @return bool|array False on failure or array of file path, width, and height on success.
   535  * @return bool|array False on failure or array of file path, width, and height on success.
   465  */
   536  */
   483 			// find for the smallest image not smaller than the desired size
   554 			// find for the smallest image not smaller than the desired size
   484 			ksort($areas);
   555 			ksort($areas);
   485 			foreach ( $areas as $_size ) {
   556 			foreach ( $areas as $_size ) {
   486 				$data = $imagedata['sizes'][$_size];
   557 				$data = $imagedata['sizes'][$_size];
   487 				if ( $data['width'] >= $size[0] || $data['height'] >= $size[1] ) {
   558 				if ( $data['width'] >= $size[0] || $data['height'] >= $size[1] ) {
       
   559 					// Skip images with unexpectedly divergent aspect ratios (crops)
       
   560 					// First, we calculate what size the original image would be if constrained to a box the size of the current image in the loop
       
   561 					$maybe_cropped = image_resize_dimensions($imagedata['width'], $imagedata['height'], $data['width'], $data['height'], false );
       
   562 					// 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
       
   563 					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'] ) ) )
       
   564 						continue;
       
   565 					// If we're still here, then we're going to use this size
   488 					$file = $data['file'];
   566 					$file = $data['file'];
   489 					list($width, $height) = image_constrain_size_for_editor( $data['width'], $data['height'], $size );
   567 					list($width, $height) = image_constrain_size_for_editor( $data['width'], $data['height'], $size );
   490 					return compact( 'file', 'width', 'height' );
   568 					return compact( 'file', 'width', 'height' );
   491 				}
   569 				}
   492 			}
   570 			}
   505 	}
   583 	}
   506 	return $data;
   584 	return $data;
   507 }
   585 }
   508 
   586 
   509 /**
   587 /**
       
   588  * Get the available image sizes
       
   589  * @since 3.0.0
       
   590  * @return array Returns a filtered array of image size strings
       
   591  */
       
   592 function get_intermediate_image_sizes() {
       
   593 	global $_wp_additional_image_sizes;
       
   594 	$image_sizes = array('thumbnail', 'medium', 'large'); // Standard sizes
       
   595 	if ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) )
       
   596 		$image_sizes = array_merge( $image_sizes, array_keys( $_wp_additional_image_sizes ) );
       
   597 
       
   598 	return apply_filters( 'intermediate_image_sizes', $image_sizes );
       
   599 }
       
   600 
       
   601 /**
   510  * Retrieve an image to represent an attachment.
   602  * Retrieve an image to represent an attachment.
   511  *
   603  *
   512  * A mime icon for files, thumbnail or intermediate size for images.
   604  * A mime icon for files, thumbnail or intermediate size for images.
   513  *
   605  *
   514  * @since 2.5.0
   606  * @since 2.5.0
   526 
   618 
   527 	$src = false;
   619 	$src = false;
   528 
   620 
   529 	if ( $icon && $src = wp_mime_type_icon($attachment_id) ) {
   621 	if ( $icon && $src = wp_mime_type_icon($attachment_id) ) {
   530 		$icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/crystal' );
   622 		$icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/crystal' );
   531 		$src_file = $icon_dir . '/' . basename($src);
   623 		$src_file = $icon_dir . '/' . wp_basename($src);
   532 		@list($width, $height) = getimagesize($src_file);
   624 		@list($width, $height) = getimagesize($src_file);
   533 	}
   625 	}
   534 	if ( $src && $width && $height )
   626 	if ( $src && $width && $height )
   535 		return array( $src, $width, $height );
   627 		return array( $src, $width, $height );
   536 	return false;
   628 	return false;
   537 }
   629 }
   538 
   630 
   539 /**
   631 /**
   540  * Get an HTML img element representing an image attachment
   632  * Get an HTML img element representing an image attachment
   541  *
   633  *
       
   634  * While $size will accept an array, it is better to register a size with
       
   635  * add_image_size() so that a cropped version is generated. It's much more
       
   636  * efficient than having to find the closest-sized image and then having the
       
   637  * browser scale down the image.
       
   638  *
       
   639  * @see add_image_size()
   542  * @uses apply_filters() Calls 'wp_get_attachment_image_attributes' hook on attributes array
   640  * @uses apply_filters() Calls 'wp_get_attachment_image_attributes' hook on attributes array
   543  * @uses wp_get_attachment_image_src() Gets attachment file URL and dimensions
   641  * @uses wp_get_attachment_image_src() Gets attachment file URL and dimensions
   544  * @since 2.5.0
   642  * @since 2.5.0
   545  *
   643  *
   546  * @param int $attachment_id Image attachment ID.
   644  * @param int $attachment_id Image attachment ID.
   559 			$size = join('x', $size);
   657 			$size = join('x', $size);
   560 		$attachment =& get_post($attachment_id);
   658 		$attachment =& get_post($attachment_id);
   561 		$default_attr = array(
   659 		$default_attr = array(
   562 			'src'	=> $src,
   660 			'src'	=> $src,
   563 			'class'	=> "attachment-$size",
   661 			'class'	=> "attachment-$size",
   564 			'alt'	=> trim(strip_tags( $attachment->post_excerpt )),
   662 			'alt'	=> trim(strip_tags( get_post_meta($attachment_id, '_wp_attachment_image_alt', true) )), // Use Alt field first
   565 			'title'	=> trim(strip_tags( $attachment->post_title )),
   663 			'title'	=> trim(strip_tags( $attachment->post_title )),
   566 		);
   664 		);
       
   665 		if ( empty($default_attr['alt']) )
       
   666 			$default_attr['alt'] = trim(strip_tags( $attachment->post_excerpt )); // If not, Use the Caption
       
   667 		if ( empty($default_attr['alt']) )
       
   668 			$default_attr['alt'] = trim(strip_tags( $attachment->post_title )); // Finally, use the title
       
   669 
   567 		$attr = wp_parse_args($attr, $default_attr);
   670 		$attr = wp_parse_args($attr, $default_attr);
   568 		$attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment );
   671 		$attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment );
   569 		$attr = array_map( 'esc_attr', $attr );
   672 		$attr = array_map( 'esc_attr', $attr );
   570 		$html = rtrim("<img $hwstring");
   673 		$html = rtrim("<img $hwstring");
   571 		foreach ( $attr as $name => $value ) {
   674 		foreach ( $attr as $name => $value ) {
   576 
   679 
   577 	return $html;
   680 	return $html;
   578 }
   681 }
   579 
   682 
   580 /**
   683 /**
   581  * Adds a 'wp-post-image' class to post thumbnail thumbnails
   684  * Adds a 'wp-post-image' class to post thumbnails
   582  * Uses the begin_fetch_post_thumbnail_html and end_fetch_post_thumbnail_html action hooks to
   685  * Uses the begin_fetch_post_thumbnail_html and end_fetch_post_thumbnail_html action hooks to
   583  * dynamically add/remove itself so as to only filter post thumbnail thumbnails
   686  * dynamically add/remove itself so as to only filter post thumbnails
   584  *
   687  *
   585  * @author Mark Jaquith
       
   586  * @since 2.9.0
   688  * @since 2.9.0
   587  * @param array $attr Attributes including src, class, alt, title
   689  * @param array $attr Attributes including src, class, alt, title
   588  * @return array
   690  * @return array
   589  */
   691  */
   590 function _wp_post_thumbnail_class_filter( $attr ) {
   692 function _wp_post_thumbnail_class_filter( $attr ) {
   593 }
   695 }
   594 
   696 
   595 /**
   697 /**
   596  * Adds _wp_post_thumbnail_class_filter to the wp_get_attachment_image_attributes filter
   698  * Adds _wp_post_thumbnail_class_filter to the wp_get_attachment_image_attributes filter
   597  *
   699  *
   598  * @author Mark Jaquith
       
   599  * @since 2.9.0
   700  * @since 2.9.0
   600  */
   701  */
   601 function _wp_post_thumbnail_class_filter_add( $attr ) {
   702 function _wp_post_thumbnail_class_filter_add( $attr ) {
   602 	add_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' );
   703 	add_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' );
   603 }
   704 }
   604 
   705 
   605 /**
   706 /**
   606  * Removes _wp_post_thumbnail_class_filter from the wp_get_attachment_image_attributes filter
   707  * Removes _wp_post_thumbnail_class_filter from the wp_get_attachment_image_attributes filter
   607  *
   708  *
   608  * @author Mark Jaquith
       
   609  * @since 2.9.0
   709  * @since 2.9.0
   610  */
   710  */
   611 function _wp_post_thumbnail_class_filter_remove( $attr ) {
   711 function _wp_post_thumbnail_class_filter_remove( $attr ) {
   612 	remove_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' );
   712 	remove_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' );
   613 }
   713 }
   630  * @param array $attr Attributes attributed to the shortcode.
   730  * @param array $attr Attributes attributed to the shortcode.
   631  * @param string $content Optional. Shortcode content.
   731  * @param string $content Optional. Shortcode content.
   632  * @return string
   732  * @return string
   633  */
   733  */
   634 function img_caption_shortcode($attr, $content = null) {
   734 function img_caption_shortcode($attr, $content = null) {
       
   735 	// New-style shortcode with the caption inside the shortcode with the link and image tags.
       
   736 	if ( ! isset( $attr['caption'] ) ) {
       
   737 		if ( preg_match( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is', $content, $matches ) ) {
       
   738 			$content = $matches[1];
       
   739 			$attr['caption'] = trim( $matches[2] );
       
   740 		}
       
   741 	}
   635 
   742 
   636 	// Allow plugins/themes to override the default caption template.
   743 	// Allow plugins/themes to override the default caption template.
   637 	$output = apply_filters('img_caption_shortcode', '', $attr, $content);
   744 	$output = apply_filters('img_caption_shortcode', '', $attr, $content);
   638 	if ( $output != '' )
   745 	if ( $output != '' )
   639 		return $output;
   746 		return $output;
   662  * This implements the functionality of the Gallery Shortcode for displaying
   769  * This implements the functionality of the Gallery Shortcode for displaying
   663  * WordPress images on a post.
   770  * WordPress images on a post.
   664  *
   771  *
   665  * @since 2.5.0
   772  * @since 2.5.0
   666  *
   773  *
   667  * @param array $attr Attributes attributed to the shortcode.
   774  * @param array $attr Attributes of the shortcode.
   668  * @return string HTML content to display gallery.
   775  * @return string HTML content to display gallery.
   669  */
   776  */
   670 function gallery_shortcode($attr) {
   777 function gallery_shortcode($attr) {
   671 	global $post, $wp_locale;
   778 	global $post;
   672 
   779 
   673 	static $instance = 0;
   780 	static $instance = 0;
   674 	$instance++;
   781 	$instance++;
   675 
   782 
   676 	// Allow plugins/themes to override the default gallery template.
   783 	// Allow plugins/themes to override the default gallery template.
   729 
   836 
   730 	$itemtag = tag_escape($itemtag);
   837 	$itemtag = tag_escape($itemtag);
   731 	$captiontag = tag_escape($captiontag);
   838 	$captiontag = tag_escape($captiontag);
   732 	$columns = intval($columns);
   839 	$columns = intval($columns);
   733 	$itemwidth = $columns > 0 ? floor(100/$columns) : 100;
   840 	$itemwidth = $columns > 0 ? floor(100/$columns) : 100;
   734 	$float = $wp_locale->text_direction == 'rtl' ? 'right' : 'left'; 
   841 	$float = is_rtl() ? 'right' : 'left';
   735 	
   842 
   736 	$selector = "gallery-{$instance}";
   843 	$selector = "gallery-{$instance}";
   737 
   844 
   738 	$output = apply_filters('gallery_style', "
   845 	$gallery_style = $gallery_div = '';
       
   846 	if ( apply_filters( 'use_default_gallery_style', true ) )
       
   847 		$gallery_style = "
   739 		<style type='text/css'>
   848 		<style type='text/css'>
   740 			#{$selector} {
   849 			#{$selector} {
   741 				margin: auto;
   850 				margin: auto;
   742 			}
   851 			}
   743 			#{$selector} .gallery-item {
   852 			#{$selector} .gallery-item {
   744 				float: {$float};
   853 				float: {$float};
   745 				margin-top: 10px;
   854 				margin-top: 10px;
   746 				text-align: center;
   855 				text-align: center;
   747 				width: {$itemwidth}%;			}
   856 				width: {$itemwidth}%;
       
   857 			}
   748 			#{$selector} img {
   858 			#{$selector} img {
   749 				border: 2px solid #cfcfcf;
   859 				border: 2px solid #cfcfcf;
   750 			}
   860 			}
   751 			#{$selector} .gallery-caption {
   861 			#{$selector} .gallery-caption {
   752 				margin-left: 0;
   862 				margin-left: 0;
   753 			}
   863 			}
   754 		</style>
   864 		</style>
   755 		<!-- see gallery_shortcode() in wp-includes/media.php -->
   865 		<!-- see gallery_shortcode() in wp-includes/media.php -->";
   756 		<div id='$selector' class='gallery galleryid-{$id}'>");
   866 	$size_class = sanitize_html_class( $size );
       
   867 	$gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>";
       
   868 	$output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div );
   757 
   869 
   758 	$i = 0;
   870 	$i = 0;
   759 	foreach ( $attachments as $id => $attachment ) {
   871 	foreach ( $attachments as $id => $attachment ) {
   760 		$link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false);
   872 		$link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false);
   761 
   873 
   764 			<{$icontag} class='gallery-icon'>
   876 			<{$icontag} class='gallery-icon'>
   765 				$link
   877 				$link
   766 			</{$icontag}>";
   878 			</{$icontag}>";
   767 		if ( $captiontag && trim($attachment->post_excerpt) ) {
   879 		if ( $captiontag && trim($attachment->post_excerpt) ) {
   768 			$output .= "
   880 			$output .= "
   769 				<{$captiontag} class='gallery-caption'>
   881 				<{$captiontag} class='wp-caption-text gallery-caption'>
   770 				" . wptexturize($attachment->post_excerpt) . "
   882 				" . wptexturize($attachment->post_excerpt) . "
   771 				</{$captiontag}>";
   883 				</{$captiontag}>";
   772 		}
   884 		}
   773 		$output .= "</{$itemtag}>";
   885 		$output .= "</{$itemtag}>";
   774 		if ( $columns > 0 && ++$i % $columns == 0 )
   886 		if ( $columns > 0 && ++$i % $columns == 0 )
   811  *
   923  *
   812  * Retrieves the current attachment object from the $post global.
   924  * Retrieves the current attachment object from the $post global.
   813  *
   925  *
   814  * @since 2.5.0
   926  * @since 2.5.0
   815  *
   927  *
   816  * @param bool $prev Optional. Default is true to display previous link, true for next.
   928  * @param bool $prev Optional. Default is true to display previous link, false for next.
   817  */
   929  */
   818 function adjacent_image_link($prev = true, $size = 'thumbnail', $text = false) {
   930 function adjacent_image_link($prev = true, $size = 'thumbnail', $text = false) {
   819 	global $post;
   931 	global $post;
   820 	$post = get_post($post);
   932 	$post = get_post($post);
   821 	$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') ));
   933 	$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') ));
   872 /**
   984 /**
   873  * Check if the installed version of GD supports particular image type
   985  * Check if the installed version of GD supports particular image type
   874  *
   986  *
   875  * @since 2.9.0
   987  * @since 2.9.0
   876  *
   988  *
   877  * @param $mime_type string
   989  * @param string $mime_type
   878  * @return bool
   990  * @return bool
   879  */
   991  */
   880 function gd_edit_image_support($mime_type) {
   992 function gd_edit_image_support($mime_type) {
   881 	if ( function_exists('imagetypes') ) {
   993 	if ( function_exists('imagetypes') ) {
   882 		switch( $mime_type ) {
   994 		switch( $mime_type ) {
   903 /**
  1015 /**
   904  * Create new GD image resource with transparency support
  1016  * Create new GD image resource with transparency support
   905  *
  1017  *
   906  * @since 2.9.0
  1018  * @since 2.9.0
   907  *
  1019  *
   908  * @param $width
  1020  * @param int $width Image width
   909  * @param $height
  1021  * @param int $height Image height
   910  * @return image resource
  1022  * @return image resource
   911  */
  1023  */
   912 function wp_imagecreatetruecolor($width, $height) {
  1024 function wp_imagecreatetruecolor($width, $height) {
   913 	$img = imagecreatetruecolor($width, $height);
  1025 	$img = imagecreatetruecolor($width, $height);
   914 	if ( is_resource($img) && function_exists('imagealphablending') && function_exists('imagesavealpha') ) {
  1026 	if ( is_resource($img) && function_exists('imagealphablending') && function_exists('imagesavealpha') ) {
   930 	var $post_ID;
  1042 	var $post_ID;
   931 	var $usecache = true;
  1043 	var $usecache = true;
   932 	var $linkifunknown = true;
  1044 	var $linkifunknown = true;
   933 
  1045 
   934 	/**
  1046 	/**
   935 	 * PHP4 constructor
  1047 	 * Constructor
   936 	 */
       
   937 	function WP_Embed() {
       
   938 		return $this->__construct();
       
   939 	}
       
   940 
       
   941 	/**
       
   942 	 * PHP5 constructor
       
   943 	 */
  1048 	 */
   944 	function __construct() {
  1049 	function __construct() {
   945 		// Hack to get the [embed] shortcode to run before wpautop()
  1050 		// Hack to get the [embed] shortcode to run before wpautop()
   946 		add_filter( 'the_content', array(&$this, 'run_shortcode'), 8 );
  1051 		add_filter( 'the_content', array(&$this, 'run_shortcode'), 8 );
       
  1052 
       
  1053 		// Shortcode placeholder for strip_shortcodes()
       
  1054 		add_shortcode( 'embed', '__return_false' );
   947 
  1055 
   948 		// Attempts to embed all URLs in a post
  1056 		// Attempts to embed all URLs in a post
   949 		if ( get_option('embed_autourls') )
  1057 		if ( get_option('embed_autourls') )
   950 			add_filter( 'the_content', array(&$this, 'autoembed'), 8 );
  1058 			add_filter( 'the_content', array(&$this, 'autoembed'), 8 );
   951 
  1059 
   972 	 * @return string Content with shortcode parsed
  1080 	 * @return string Content with shortcode parsed
   973 	 */
  1081 	 */
   974 	function run_shortcode( $content ) {
  1082 	function run_shortcode( $content ) {
   975 		global $shortcode_tags;
  1083 		global $shortcode_tags;
   976 
  1084 
   977 		// Backup current registered shortcodes and clear them all out
  1085 		// Back up current registered shortcodes and clear them all out
   978 		$orig_shortcode_tags = $shortcode_tags;
  1086 		$orig_shortcode_tags = $shortcode_tags;
   979 		remove_all_shortcodes();
  1087 		remove_all_shortcodes();
   980 
  1088 
   981 		add_shortcode( 'embed', array(&$this, 'shortcode') );
  1089 		add_shortcode( 'embed', array(&$this, 'shortcode') );
   982 
  1090 
   988 
  1096 
   989 		return $content;
  1097 		return $content;
   990 	}
  1098 	}
   991 
  1099 
   992 	/**
  1100 	/**
   993 	 * If a post/page was saved, then output Javascript to make
  1101 	 * If a post/page was saved, then output JavaScript to make
   994 	 * an AJAX request that will call WP_Embed::cache_oembed().
  1102 	 * an AJAX request that will call WP_Embed::cache_oembed().
   995 	 */
  1103 	 */
   996 	function maybe_run_ajax_cache() {
  1104 	function maybe_run_ajax_cache() {
   997 		global $post_ID;
  1105 		global $post_ID;
   998 
  1106 
  1001 
  1109 
  1002 ?>
  1110 ?>
  1003 <script type="text/javascript">
  1111 <script type="text/javascript">
  1004 /* <![CDATA[ */
  1112 /* <![CDATA[ */
  1005 	jQuery(document).ready(function($){
  1113 	jQuery(document).ready(function($){
  1006 		$.get("<?php echo admin_url( 'admin-ajax.php?action=oembed-cache&post=' . $post_ID ); ?>");
  1114 		$.get("<?php echo admin_url( 'admin-ajax.php?action=oembed-cache&post=' . $post_ID, 'relative' ); ?>");
  1007 	});
  1115 	});
  1008 /* ]]> */
  1116 /* ]]> */
  1009 </script>
  1117 </script>
  1010 <?php
  1118 <?php
  1011 	}
  1119 	}
  1053 	 * @uses wp_cache_set()
  1161 	 * @uses wp_cache_set()
  1054 	 * @uses get_post_meta()
  1162 	 * @uses get_post_meta()
  1055 	 * @uses update_post_meta()
  1163 	 * @uses update_post_meta()
  1056 	 *
  1164 	 *
  1057 	 * @param array $attr Shortcode attributes.
  1165 	 * @param array $attr Shortcode attributes.
  1058 	 * @param string $url The URL attempting to be embeded.
  1166 	 * @param string $url The URL attempting to be embedded.
  1059 	 * @return string The embed HTML on success, otherwise the original URL.
  1167 	 * @return string The embed HTML on success, otherwise the original URL.
  1060 	 */
  1168 	 */
  1061 	function shortcode( $attr, $url = '' ) {
  1169 	function shortcode( $attr, $url = '' ) {
  1062 		global $post;
  1170 		global $post;
  1063 
  1171 
  1064 		if ( empty($url) )
  1172 		if ( empty($url) )
  1065 			return '';
  1173 			return '';
  1066 
  1174 
  1067 		$rawattr = $attr;
  1175 		$rawattr = $attr;
  1068 		$attr = wp_parse_args( $attr, wp_embed_defaults() );
  1176 		$attr = wp_parse_args( $attr, wp_embed_defaults() );
       
  1177 
       
  1178 		// kses converts & into &amp; and we need to undo this
       
  1179 		// See http://core.trac.wordpress.org/ticket/11311
       
  1180 		$url = str_replace( '&amp;', '&', $url );
  1069 
  1181 
  1070 		// Look for known internal handlers
  1182 		// Look for known internal handlers
  1071 		ksort( $this->handlers );
  1183 		ksort( $this->handlers );
  1072 		foreach ( $this->handlers as $priority => $handlers ) {
  1184 		foreach ( $this->handlers as $priority => $handlers ) {
  1073 			foreach ( $handlers as $id => $handler ) {
  1185 			foreach ( $handlers as $id => $handler ) {
  1093 				// Failures are cached
  1205 				// Failures are cached
  1094 				if ( '{{unknown}}' === $cache )
  1206 				if ( '{{unknown}}' === $cache )
  1095 					return $this->maybe_make_link( $url );
  1207 					return $this->maybe_make_link( $url );
  1096 
  1208 
  1097 				if ( !empty($cache) )
  1209 				if ( !empty($cache) )
  1098 					return apply_filters( 'embed_oembed_html', $cache, $url, $attr );
  1210 					return apply_filters( 'embed_oembed_html', $cache, $url, $attr, $post_ID );
  1099 			}
  1211 			}
  1100 
  1212 
  1101 			// Use oEmbed to get the HTML
  1213 			// Use oEmbed to get the HTML
  1102 			$attr['discover'] = ( apply_filters('embed_oembed_discover', false) && author_can( $post_ID, 'unfiltered_html' ) ) ? true : false;
  1214 			$attr['discover'] = ( apply_filters('embed_oembed_discover', false) && author_can( $post_ID, 'unfiltered_html' ) );
  1103 			$html = wp_oembed_get( $url, $attr );
  1215 			$html = wp_oembed_get( $url, $attr );
  1104 
  1216 
  1105 			// Cache the result
  1217 			// Cache the result
  1106 			$cache = ( $html ) ? $html : '{{unknown}}';
  1218 			$cache = ( $html ) ? $html : '{{unknown}}';
  1107 			update_post_meta( $post_ID, $cachekey, $cache );
  1219 			update_post_meta( $post_ID, $cachekey, $cache );
  1108 
  1220 
  1109 			// If there was a result, return it
  1221 			// If there was a result, return it
  1110 			if ( $html )
  1222 			if ( $html )
  1111 				return apply_filters( 'embed_oembed_html', $html, $url, $attr );
  1223 				return apply_filters( 'embed_oembed_html', $html, $url, $attr, $post_ID );
  1112 		}
  1224 		}
  1113 
  1225 
  1114 		// Still unknown
  1226 		// Still unknown
  1115 		return $this->maybe_make_link( $url );
  1227 		return $this->maybe_make_link( $url );
  1116 	}
  1228 	}
  1193 	function maybe_make_link( $url ) {
  1305 	function maybe_make_link( $url ) {
  1194 		$output = ( $this->linkifunknown ) ? '<a href="' . esc_attr($url) . '">' . esc_html($url) . '</a>' : $url;
  1306 		$output = ( $this->linkifunknown ) ? '<a href="' . esc_attr($url) . '">' . esc_html($url) . '</a>' : $url;
  1195 		return apply_filters( 'embed_maybe_make_link', $output, $url );
  1307 		return apply_filters( 'embed_maybe_make_link', $output, $url );
  1196 	}
  1308 	}
  1197 }
  1309 }
  1198 $wp_embed = new WP_Embed();
  1310 $GLOBALS['wp_embed'] = new WP_Embed();
  1199 
  1311 
  1200 /**
  1312 /**
  1201  * Register an embed handler. This function should probably only be used for sites that do not support oEmbed.
  1313  * Register an embed handler. This function should probably only be used for sites that do not support oEmbed.
  1202  *
  1314  *
  1203  * @since 2.9.0
  1315  * @since 2.9.0
  1230 	if ( !empty($GLOBALS['content_width']) )
  1342 	if ( !empty($GLOBALS['content_width']) )
  1231 		$theme_width = (int) $GLOBALS['content_width'];
  1343 		$theme_width = (int) $GLOBALS['content_width'];
  1232 
  1344 
  1233 	$width = get_option('embed_size_w');
  1345 	$width = get_option('embed_size_w');
  1234 
  1346 
  1235 	if ( !$width && !empty($theme_width) )
  1347 	if ( empty($width) && !empty($theme_width) )
  1236 		$width = $theme_width;
  1348 		$width = $theme_width;
  1237 
  1349 
  1238 	if ( !$width )
  1350 	if ( empty($width) )
  1239 		$width = 500;
  1351 		$width = 500;
  1240 
  1352 
       
  1353 	$height = get_option('embed_size_h');
       
  1354 
       
  1355 	if ( empty($height) )
       
  1356 		$height = 700;
       
  1357 
  1241 	return apply_filters( 'embed_defaults', array(
  1358 	return apply_filters( 'embed_defaults', array(
  1242 		'width' => $width,
  1359 		'width'  => $width,
  1243 		'height' => 700,
  1360 		'height' => $height,
  1244 	) );
  1361 	) );
  1245 }
  1362 }
  1246 
  1363 
  1247 /**
  1364 /**
  1248  * Based on a supplied width/height example, return the biggest possible dimensions based on the max width/height.
  1365  * Based on a supplied width/height example, return the biggest possible dimensions based on the max width/height.
  1272  * @see WP_oEmbed
  1389  * @see WP_oEmbed
  1273  *
  1390  *
  1274  * @uses _wp_oembed_get_object()
  1391  * @uses _wp_oembed_get_object()
  1275  * @uses WP_oEmbed::get_html()
  1392  * @uses WP_oEmbed::get_html()
  1276  *
  1393  *
  1277  * @param string $url The URL that should be embeded.
  1394  * @param string $url The URL that should be embedded.
  1278  * @param array $args Addtional arguments and parameters.
  1395  * @param array $args Additional arguments and parameters.
  1279  * @return string The original URL on failure or the embed HTML on success.
  1396  * @return bool|string False on failure or the embed HTML on success.
  1280  */
  1397  */
  1281 function wp_oembed_get( $url, $args = '' ) {
  1398 function wp_oembed_get( $url, $args = '' ) {
  1282 	require_once( 'class-oembed.php' );
  1399 	require_once( ABSPATH . WPINC . '/class-oembed.php' );
  1283 	$oembed = _wp_oembed_get_object();
  1400 	$oembed = _wp_oembed_get_object();
  1284 	return $oembed->get_html( $url, $args );
  1401 	return $oembed->get_html( $url, $args );
  1285 }
  1402 }
  1286 
  1403 
  1287 /**
  1404 /**
  1292  *
  1409  *
  1293  * @uses _wp_oembed_get_object()
  1410  * @uses _wp_oembed_get_object()
  1294  *
  1411  *
  1295  * @param string $format The format of URL that this provider can handle. You can use asterisks as wildcards.
  1412  * @param string $format The format of URL that this provider can handle. You can use asterisks as wildcards.
  1296  * @param string $provider The URL to the oEmbed provider.
  1413  * @param string $provider The URL to the oEmbed provider.
  1297  * @param boolean $regex Whether the $format parameter is in a regex format or not.
  1414  * @param boolean $regex Whether the $format parameter is in a regex format.
  1298  */
  1415  */
  1299 function wp_oembed_add_provider( $format, $provider, $regex = false ) {
  1416 function wp_oembed_add_provider( $format, $provider, $regex = false ) {
  1300 	require_once( 'class-oembed.php' );
  1417 	require_once( ABSPATH . WPINC . '/class-oembed.php' );
  1301 	$oembed = _wp_oembed_get_object();
  1418 	$oembed = _wp_oembed_get_object();
  1302 	$oembed->providers[$format] = array( $provider, $regex );
  1419 	$oembed->providers[$format] = array( $provider, $regex );
  1303 }
  1420 }
       
  1421 
       
  1422 /**
       
  1423  * Determines if default embed handlers should be loaded.
       
  1424  *
       
  1425  * Checks to make sure that the embeds library hasn't already been loaded. If
       
  1426  * it hasn't, then it will load the embeds library.
       
  1427  *
       
  1428  * @since 2.9.0
       
  1429  */
       
  1430 function wp_maybe_load_embeds() {
       
  1431 	if ( ! apply_filters( 'load_default_embeds', true ) )
       
  1432 		return;
       
  1433 	wp_embed_register_handler( 'googlevideo', '#http://video\.google\.([A-Za-z.]{2,5})/videoplay\?docid=([\d-]+)(.*?)#i', 'wp_embed_handler_googlevideo' );
       
  1434 }
       
  1435 
       
  1436 /**
       
  1437  * The Google Video embed handler callback. Google Video does not support oEmbed.
       
  1438  *
       
  1439  * @see WP_Embed::register_handler()
       
  1440  * @see WP_Embed::shortcode()
       
  1441  *
       
  1442  * @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}.
       
  1443  * @param array $attr Embed attributes.
       
  1444  * @param string $url The original URL that was matched by the regex.
       
  1445  * @param array $rawattr The original unmodified attributes.
       
  1446  * @return string The embed HTML.
       
  1447  */
       
  1448 function wp_embed_handler_googlevideo( $matches, $attr, $url, $rawattr ) {
       
  1449 	// If the user supplied a fixed width AND height, use it
       
  1450 	if ( !empty($rawattr['width']) && !empty($rawattr['height']) ) {
       
  1451 		$width  = (int) $rawattr['width'];
       
  1452 		$height = (int) $rawattr['height'];
       
  1453 	} else {
       
  1454 		list( $width, $height ) = wp_expand_dimensions( 425, 344, $attr['width'], $attr['height'] );
       
  1455 	}
       
  1456 
       
  1457 	return apply_filters( 'embed_googlevideo', '<embed type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docid=' . esc_attr($matches[2]) . '&amp;hl=en&amp;fs=true" style="width:' . esc_attr($width) . 'px;height:' . esc_attr($height) . 'px" allowFullScreen="true" allowScriptAccess="always" />', $matches, $attr, $url, $rawattr );
       
  1458 }
       
  1459 
       
  1460 /**
       
  1461  * Prints default plupload arguments.
       
  1462  *
       
  1463  * @since 3.4.0
       
  1464  */
       
  1465 function wp_plupload_default_settings() {
       
  1466 	global $wp_scripts;
       
  1467 
       
  1468 	$max_upload_size = wp_max_upload_size();
       
  1469 
       
  1470 	$defaults = array(
       
  1471 		'runtimes'            => 'html5,silverlight,flash,html4',
       
  1472 		'file_data_name'      => 'async-upload', // key passed to $_FILE.
       
  1473 		'multiple_queues'     => true,
       
  1474 		'max_file_size'       => $max_upload_size . 'b',
       
  1475 		'url'                 => admin_url( 'admin-ajax.php', 'relative' ),
       
  1476 		'flash_swf_url'       => includes_url( 'js/plupload/plupload.flash.swf' ),
       
  1477 		'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ),
       
  1478 		'filters'             => array( array( 'title' => __( 'Allowed Files' ), 'extensions' => '*') ),
       
  1479 		'multipart'           => true,
       
  1480 		'urlstream_upload'    => true,
       
  1481 	);
       
  1482 
       
  1483 	$defaults = apply_filters( 'plupload_default_settings', $defaults );
       
  1484 
       
  1485 	$params = array(
       
  1486 		'action' => 'upload-attachment',
       
  1487 	);
       
  1488 
       
  1489 	$params = apply_filters( 'plupload_default_params', $params );
       
  1490 	$params['_wpnonce'] = wp_create_nonce( 'media-form' );
       
  1491 	$defaults['multipart_params'] = $params;
       
  1492 
       
  1493 	$settings = array(
       
  1494 		'defaults' => $defaults,
       
  1495 		'browser'  => array(
       
  1496 			'mobile'    => wp_is_mobile(),
       
  1497 			'supported' => _device_can_upload(),
       
  1498 		),
       
  1499 	);
       
  1500 
       
  1501 	$script = 'var _wpPluploadSettings = ' . json_encode( $settings ) . ';';
       
  1502 
       
  1503 	$data = $wp_scripts->get_data( 'wp-plupload', 'data' );
       
  1504 	if ( $data )
       
  1505 		$script = "$data\n$script";
       
  1506 
       
  1507 	$wp_scripts->add_data( 'wp-plupload', 'data', $script );
       
  1508 }
       
  1509 add_action( 'customize_controls_enqueue_scripts', 'wp_plupload_default_settings' );