bainternet
3/19/2012 - 10:55 AM

Image shortcode for WordPress

Image shortcode for WordPress

<?php
/**
 * Image shortcode callback
 *
 * Enables the [kovshenin_image] shortcode, pseudo-TimThumb but creates resized and cropped image files
 * from existing media library entries. Usage: 
 * [kovshenin_image src="http://example.org/wp-content/uploads/2012/03/image.png" width="100" height="100"]
 *
 * @uses image_make_intermediate_size
 */
function kovshenin_image_shortcode( $atts ) {
	extract( shortcode_atts( array(
		'src' => '',
		'width' => '',
		'height' => '',
	), $atts ) );

	global $wpdb;

	// Sanitize
	$height = absint( $height );
	$width = absint( $width );
	$src = esc_url( strtolower( $src ) );
	$needs_resize = true;

	$upload_dir = wp_upload_dir();
	$base_url = strtolower( $upload_dir['baseurl'] );
	
	// Let's see if the image belongs to our uploads directory.
	if ( substr( $src, 0, strlen( $base_url ) ) != $base_url ) {
		return "Error: external images are not supported.";
	}
	
	// Look the file up in the database.
	$file = str_replace( trailingslashit( $base_url ), '', $src );
	$attachment_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s LIMIT 1;", '%"' . like_escape( $file ) . '"%' ) );

	// If an attachment record was not found.
	if ( ! $attachment_id ) {
		return "Error: attachment not found.";
	}
	
	// Look through the attachment meta data for an image that fits our size.
	$meta = wp_get_attachment_metadata( $attachment_id );
	foreach( $meta['sizes'] as $key => $size ) {
		if ( $size['width'] == $width && $size['height'] == $height ) {
			$src = str_replace( basename( $src ), $size['file'], $src );
			$needs_resize = false;
			break;
		}
	}
	
	// If an image of such size was not found, we can create one.
	if ( $needs_resize ) {
		$attached_file = get_attached_file( $attachment_id );
		$resized = image_make_intermediate_size( $attached_file, $width, $height, true );
		if ( ! is_wp_error( $resized ) ) {
			
			// Let metadata know about our new size.
			$key = sprintf( 'resized-%dx%d', $width, $height );
			$meta['sizes'][$key] = $resized;
			$src = str_replace( basename( $src ), $resized['file'], $src );
			wp_update_attachment_metadata( $attachment_id, $meta );
			
			// Record in backup sizes so everything's cleaned up when attachment is deleted.
			$backup_sizes = get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true );
			if ( ! is_array( $backup_sizes ) ) $backup_sizes = array();
			$backup_sizes[$key] = $resized;
			update_post_meta( $attachment_id, '_wp_attachment_backup_sizes', $backup_sizes );
		}
	}
	
	// Generate the markup and return.
	$width = ( $width ) ? 'width="' . absint( $width ) . '"' : '';
	$height = ( $height ) ? 'height="' . absint( $height ) . '"' : '';
 	return sprintf( '<img src="%s" %s %s />', esc_url( $src ), $width, $height );
}
add_shortcode( 'kovshenin_image', 'kovshenin_image_shortcode' );
?>