public
Last active

Image shortcode for WordPress

  • Download Gist
image-shortcode.php
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
<?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' );
?>

Do you think strtolower is wrong? Images can have uppercase in its name and that can make the query statement return nothing or incorrect attachment ID.

Nice.
It would be great to just hook in this functionality to the 'image_downsize' filter to provide image sizing on the fly for image sizes that haven't been generated
http://core.trac.wordpress.org/browser/tags/3.5.1/wp-includes/media.php#L147

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.