Skip to content

@kovshenin /image-shortcode.php
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
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' );
?>
@rilwis

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.

@benhuson

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.