├── bower.json
├── component.json
├── composer.json
├── dynamic_img_resize.php
├── package.json
└── readme.md
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "wcm/dynamic-image-resize",
3 | "version" : "1.6.3",
4 | "main" : "dynamic_img_resize.php",
5 | "ignore" : [
6 | ".git",
7 | "assets/scripts/vendor",
8 | "assets/styles/vendor",
9 | "node_modules"
10 | ]
11 | }
--------------------------------------------------------------------------------
/component.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "wcm/dynamic-image-resize",
3 | "version" : "1.6.3",
4 | "description" : "Enables WordPress custom image sizes on the fly. Can be used with a shortcode or a template tag.",
5 | "homepage" : "http://franz-josef-kaiser.github.io/Dynamic-Image-Resize/",
6 | "author" : "Franz Josef Kaiser",
7 | "main" : "dynamic_img_resize.php",
8 | "keywords" : [
9 | "wordpress",
10 | "plugin",
11 | "responsive",
12 | "adaptive",
13 | "dynamic",
14 | "image",
15 | "resize"
16 | ]
17 | }
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "wcm/dynamic-image-resize",
3 | "description" : "Enables WordPress custom image sizes on the fly. Can be used with a shortcode or a template tag.",
4 | "type" : "library",
5 | "homepage" : "http://franz-josef-kaiser.github.io/Dynamic-Image-Resize/",
6 | "license" : "MIT",
7 | "require" : {
8 | "php" : ">=5.2.7",
9 | "composer/installers" : "~1.0"
10 | },
11 | "authors" : [
12 | {
13 | "name" : "Franz Josef Kaiser",
14 | "email" : "franzjosef@unserkaiser.com"
15 | },
16 | {
17 | "name" : "Andrea Carraro",
18 | "email" : "hi@andreacarraro.it"
19 | }
20 | ],
21 | "support" : {
22 | "issues" : "https://github.com/franz-josef-kaiser/Dynamic-Image-Resize/issues",
23 | "source" : "https://github.com/franz-josef-kaiser/Dynamic-Image-Resize"
24 | },
25 | "keywords" : [
26 | "wordpress",
27 | "plugin",
28 | "responsive",
29 | "adaptive",
30 | "dynamic",
31 | "image",
32 | "resize"
33 | ]
34 | }
--------------------------------------------------------------------------------
/dynamic_img_resize.php:
--------------------------------------------------------------------------------
1 | [dynamic_image] shortcode, pseudo-TimThumb but creates resized and cropped image files from existing media library entries. Usage: [dynamic_image src="http://example.org/wp-content/uploads/2012/03/image.png" width="100" height="100"]
. Also offers a template tag.
8 | * Version: 1.6.3
9 | * Author: Franz Josef Kaiser
10 | * Author URI: http://unserkaiser.com
11 | * License: MIT
12 | */
13 |
14 |
15 | if ( ! class_exists( 'oxoDynamicImageResize' ) )
16 | {
17 |
18 | /**
19 | * @author Franz Josef Kaiser
20 | * @link http://unserkaiser.com
21 | * @license MIT
22 | */
23 | class oxoDynamicImageResize
24 | {
25 | /**
26 | * Holds the input attributes
27 | * @var array
28 | * @access private
29 | */
30 | private $atts = array();
31 |
32 | /**
33 | * Holds the HTML MarkUp for height/width Attributes
34 | * @var string
35 | */
36 | private $hw_string = '';
37 |
38 | /**
39 | * Base URL to prefix for all image files.
40 | * @var string
41 | */
42 | private $baseUrl = '';
43 |
44 | /**
45 | * The currently processed Attachments ID.
46 | * @var int|null
47 | */
48 | private $att_id = null;
49 |
50 | /**
51 | * The currently processed Attachment Meta Data Array.
52 | * @var array
53 | */
54 | private $att_meta = array();
55 |
56 | /**
57 | * Constructor
58 | * Adds the shortcode
59 | * @param array $atts
60 | * @return \oxoDynamicImageResize|\WP_Error
61 | */
62 | public function __construct( $atts )
63 | {
64 | if ( ! is_array( $atts ) )
65 | {
66 | return new WP_Error(
67 | 'wrong_arg_type',
68 | __( 'Args need to be an array for the dynamic_image_resize template tag.', 'dyn_textdomain' ),
69 | __FILE__
70 | );
71 | }
72 |
73 | return $this->setAttributes( $atts );
74 | }
75 |
76 | /**
77 | * Set the Attributes
78 | * @param $atts
79 | * @return void
80 | */
81 | public function setAttributes( $atts )
82 | {
83 | $this->atts = $atts;
84 | }
85 |
86 | /**
87 | * Get the Attributes
88 | * @return array
89 | */
90 | public function getAttributes()
91 | {
92 | return $this->atts;
93 | }
94 |
95 | /**
96 | * Returns the image HTML or the Error message.
97 | * @return string
98 | */
99 | public function __toString()
100 | {
101 | return $this->getHTMLOutput();
102 | }
103 |
104 | /**
105 | * Wrapper function that combines the HTML and Error output.
106 | * Makes it easier for extending classes to just override the __toString() method.
107 | * @return mixed|string
108 | */
109 | public function getHTMLOutput()
110 | {
111 | $output = $this->getImage();
112 |
113 | if ( ! is_wp_error( $output ) )
114 | return $output;
115 |
116 | return $this->getErrorMessage( $output );
117 | }
118 |
119 | /**
120 | * Displays an Error Message if an error was found instead of an Image.
121 | * Only displays for logged in users who are allowed to edit posts.
122 | * Only is available when WP_DEBUG is set to TRUE.
123 | * @param $output \WP_Error
124 | * @return string
125 | */
126 | public function getErrorMessage( $output )
127 | {
128 | // No error message for Guests or Subscribers
129 | // Assuming that no one has activated caching plugins when debugging
130 | // and not set WP_DEBUG to TRUE on a live site
131 | if (
132 | ! is_user_logged_in()
133 | AND ! current_user_can( 'edit_posts' )
134 | AND ( ! defined( 'WP_DEBUG' ) OR ! WP_DEBUG )
135 | )
136 | return '';
137 |
138 | // Error output for development
139 | return "{$output->get_error_message( 'no_attachment' )}: {$output->get_error_data()}";
140 |
141 | }
142 |
143 | /**
144 | * Merges the Shortcode Attributes with input Arguments.
145 | * @param array $atts
146 | * @return array $atts
147 | */
148 | public function parseAttributes( $atts )
149 | {
150 | return shortcode_atts(
151 | array(
152 | 'src' => '',
153 | 'width' => '',
154 | 'height' => '',
155 | 'classes' => '',
156 | 'hwmarkup' => 'true',
157 | ),
158 | $atts,
159 | // If the shortcode name changes, this arg must align.
160 | 'dynamic_image'
161 | );
162 | }
163 |
164 | /**
165 | * Sanitize attributes
166 | * @param array $atts
167 | * @return array
168 | */
169 | public function sanitizeAttributes( $atts )
170 | {
171 | // Get rid of eventual leading/trailing white spaces around attributes.
172 | $atts = array_map( 'trim', $atts );
173 |
174 | return array(
175 | 'src' => ! filter_var( $atts['src'], FILTER_VALIDATE_INT )
176 | ? esc_url( $atts['src'] )
177 | : absint( $atts['src'] ),
178 | 'height' => absint( $atts['height'] ),
179 | 'width' => absint( $atts['width'] ),
180 | 'classes' => esc_attr( $atts['classes'] ),
181 | 'hwmarkup' => filter_var( $atts['hwmarkup'], FILTER_VALIDATE_BOOLEAN )
182 | );
183 | }
184 |
185 | /**
186 | * Sets the $hw_string class var that holds the height/width HTML attribute string.
187 | * @param int $width
188 | * @param int $height
189 | * @return void
190 | */
191 | public function setHeightWidthString( $width, $height )
192 | {
193 | $this->hw_string = image_hwstring( $width, $height );
194 | }
195 |
196 | /**
197 | * Gets the height/width HTML string.
198 | * @return string
199 | */
200 | public function getHeightWidthString()
201 | {
202 | return $this->hw_string;
203 | }
204 |
205 | /**
206 | * Builds the image
207 | * @uses image_make_intermediate_size
208 | * @internal param array $atts
209 | * @return mixed string/WP Error $html
210 | */
211 | public function getImage()
212 | {
213 | $atts = $this->getAttributes();
214 | $atts = $this->parseAttributes( $atts );
215 | $atts = $this->sanitizeAttributes( $atts );
216 |
217 | $this->setHeightWidthString(
218 | $atts['width'],
219 | $atts['height']
220 | );
221 | $hw_string = $this->getHeightWidthString();
222 | ! $atts['hwmarkup'] AND $hw_string = '';
223 |
224 | $needs_resize = true;
225 | $file = 'No image';
226 | $error = false;
227 |
228 | // ID as src
229 | if ( is_int( $atts['src'] ) )
230 | {
231 | $att_id = $atts['src'];
232 | // returns false on failure
233 | $atts['src'] = wp_get_attachment_url( $att_id );
234 |
235 | // If nothing was found:
236 | ! $atts['src'] AND $error = true;
237 | }
238 | // Path as src
239 | else
240 | {
241 | // Let's see if the image belongs to our uploads directory…
242 | $img_url = substr(
243 | $atts['src'],
244 | 0,
245 | strlen( $this->getBaseUrl() )
246 | );
247 |
248 | // …And if not: just return the image HTML string
249 | if ( $img_url !== $this->getBaseUrl() )
250 | {
251 | return $this->getMarkUp(
252 | $img_url,
253 | $hw_string,
254 | $atts['classes']
255 | );
256 | }
257 |
258 | // Prepare file name for DB search.
259 | $file = str_replace(
260 | trailingslashit( $this->getBaseUrl() ),
261 | '',
262 | $atts['src']
263 | );
264 | // Look up the file in the database.
265 | $att_id = $this->getAttachment( $file );
266 | // If no attachment record was found: Prepare for an WP_Error.
267 | ! $att_id AND $error = true;
268 | }
269 |
270 | // Abort if the attachment wasn't found
271 | if ( $error )
272 | {
273 | return new WP_Error(
274 | 'no_attachment',
275 | __( 'Attachment not found by the dynamic-image shortcode.', 'dyn_textdomain' ),
276 | $file
277 | );
278 | }
279 |
280 | // Look through the attachment meta data for an image that fits our size.
281 | $meta = wp_get_attachment_metadata( $att_id );
282 | $this->setAttachmentMeta( $meta );
283 | foreach( $meta['sizes'] as $size )
284 | {
285 | if (
286 | $atts['width'] === $size['width']
287 | AND $atts['height'] === $size['height']
288 | )
289 | {
290 | $atts['src'] = str_replace(
291 | basename( $atts['src'] ),
292 | $size['file'],
293 | $atts['src']
294 | );
295 | $needs_resize = false;
296 |
297 | // We found an image. Now abort the loop and process it.
298 | break;
299 | }
300 | }
301 |
302 | // If we need resizing
303 | if ( $needs_resize )
304 | {
305 | // and if an image of such size was not found,…
306 | $attached_file = get_attached_file( $att_id );
307 | // …we can create one.
308 | $resized = image_make_intermediate_size(
309 | $attached_file,
310 | $atts['width'],
311 | $atts['height'],
312 | true
313 | );
314 |
315 | if (
316 | // \WP_Error returned from WP_Image_Editor_Imagick, WP_Image_Editor_GD
317 | // or any other editor that was added using the 'wp_image_editors'-filter.
318 | ! is_wp_error( $resized )
319 | // FALSE returned from image_make_intermediate_size()
320 | // when no width/height were provided.
321 | AND false !== $resized
322 | )
323 | {
324 | // Generate key for new size
325 | $key = sprintf(
326 | 'resized-%dx%d',
327 | $atts['width'],
328 | $atts['height']
329 | );
330 | // Push to Meta Data Array
331 | $meta['sizes'][ $key ] = $resized;
332 |
333 | // Update src for final MarkUp
334 | $atts['src'] = str_replace(
335 | basename( $atts['src'] ),
336 | $resized['file'],
337 | $atts['src']
338 | );
339 |
340 | // Let metadata know about our new size.
341 | wp_update_attachment_metadata( $att_id, $meta );
342 |
343 | // Record in backup sizes, so everything's
344 | // cleaned up when attachment is deleted.
345 | $backup_sizes = get_post_meta(
346 | $att_id,
347 | '_wp_attachment_backup_sizes',
348 | true
349 | );
350 | #
351 | // If an error occurred, we'll get back FALSE
352 | // By default it's not a single meta entry, so we
353 | // should get an array anyway. Unless WP_Cache went off.
354 | ! is_array( $backup_sizes ) AND $backup_sizes = array();
355 |
356 | // Add the new image to the size meta data array.
357 | $backup_sizes[ $key ] = $resized;
358 |
359 | // Update the meta entry.
360 | update_post_meta(
361 | $att_id,
362 | '_wp_attachment_backup_sizes',
363 | $backup_sizes
364 | );
365 | }
366 | }
367 |
368 | // Generate the markup and return:
369 | $html = $this->getMarkUp(
370 | $atts['src'],
371 | $hw_string,
372 | $atts['classes']
373 | );
374 |
375 | return $html;
376 | }
377 |
378 | /**
379 | * Setter for the base URL for the Attachment/Image directory.
380 | */
381 | public function setBaseUrl()
382 | {
383 | $uploaddir = wp_upload_dir();
384 | $this->baseUrl = $uploaddir['baseurl'];
385 | }
386 |
387 | /**
388 | * Get the Base URL
389 | * @return string
390 | */
391 | public function getBaseUrl()
392 | {
393 | if ( !$this->baseUrl ) $this->setBaseUrl();
394 | return $this->baseUrl;
395 | }
396 |
397 | /**
398 | * Sets the currently processed Attachment ID.
399 | * @param int $id
400 | */
401 | public function setAttachmentID( $id )
402 | {
403 | $this->att_id = $id;
404 | }
405 |
406 | /**
407 | * Gets the currently processed Attachment ID.
408 | * @return int|null
409 | */
410 | public function getAttachmentID()
411 | {
412 | return $this->att_id;
413 | }
414 |
415 | /**
416 | * Sets the currently processed Attachment Meta Data.
417 | * Allows extending classes to retrieve the meta data
418 | * to display captions, credits, generate MarkUp for
419 | * responsive stuff, etc. Sky is the limit.
420 | * @param array $data
421 | */
422 | public function setAttachmentMeta( $data )
423 | {
424 | $this->att_meta = $data;
425 | }
426 |
427 | /**
428 | * Gets the currently processed Attachment Meta Data Array.
429 | * @return array
430 | */
431 | public function getAttachmentMeta()
432 | {
433 | return $this->att_meta;
434 | }
435 |
436 | /**
437 | * Query for the file by URl
438 | * @param string $url
439 | * @return mixed string/bool $result Attachment or FALSE if nothing was found (needed for error)
440 | */
441 | public function getAttachment( $url )
442 | {
443 | global $wpdb;
444 |
445 | $result = $wpdb->get_var( $this->getAttachmentSQL( $url ) );
446 |
447 | // FALSE if no result
448 | if ( empty( $result ) )
449 | return false;
450 |
451 | return $result;
452 | }
453 |
454 | /**
455 | * Retrieves the SQL statement that is used to retrieve a single Attachment
456 | * @param string $url
457 | * @return string $sql
458 | */
459 | public function getAttachmentSQL( $url )
460 | {
461 | global $wpdb;
462 |
463 | if (
464 | // Starting from WordPress 4.0 like_escape() is deprecated in favour of $wpdb->esc_like().
465 | // By default use $wpdb->esc_like(), else fall back to like_escape().
466 | method_exists( $wpdb, 'esc_like' )
467 | )
468 | {
469 | $url = $wpdb->prepare( "%s", "%".$wpdb->esc_like( $url )."%" );
470 | }
471 | else
472 | {
473 | $url = $wpdb->prepare( "%s", "%".like_escape( $url )."%" );
474 | }
475 | return <<postmeta}
478 | WHERE meta_key = '_wp_attachment_metadata'
479 | AND meta_value LIKE {$url}
480 | LIMIT 1
481 | SQL;
482 | }
483 |
484 | /**
485 | * Builds the markup
486 | * @param string $src URl to the image
487 | * @param string $hw_string
488 | * @param string $classes
489 | * @return string $html
490 | */
491 | public function getMarkUp( $src, $hw_string, $classes )
492 | {
493 | return sprintf(
494 | '
',
495 | $src,
496 | $hw_string,
497 | ! empty( $classes ) ? " class='{$classes}'" : ''
498 | );
499 | }
500 | } // END Class oxoDynamicImageResize
501 |
502 |
503 | /***********************************
504 | * PUBLIC API
505 | ***********************************/
506 |
507 |
508 | /**
509 | * Retrieve a dynamically/on-the-fly resized image
510 | * @param array $atts Attributes: src(URi/ID), width, height, classes
511 | * @return mixed string/html $html Image mark up
512 | */
513 | function dynamic_image_resize( $atts )
514 | {
515 | return new oxoDynamicImageResize( $atts );
516 | }
517 |
518 |
519 | /**
520 | * Add a short code named [dynamic_image]
521 | * Use the same attributes as for the class
522 | * If the shortcode name changes, the third argument
523 | * for `shortcode_atts()` must change as well.
524 | */
525 | add_shortcode( 'dynamic_image', 'dynamic_image_resize' );
526 |
527 | } // endif;
528 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "wcm/dynamic-image-resize",
3 | "description" : "Enables WordPress custom image sizes on the fly. Can be used with a shortcode or a template tag.",
4 | "version" : "1.6.3",
5 | "homepage" : "http://franz-josef-kaiser.github.io/Dynamic-Image-Resize/",
6 | "main" : "dynamic_img_resize.php",
7 | "readmeFilename" : "README.md",
8 | "private" : false,
9 | "keywords" : [
10 | "wordpress",
11 | "plugin",
12 | "responsive",
13 | "adaptive",
14 | "dynamic",
15 | "image",
16 | "resize"
17 | ],
18 | "repository" : {
19 | "type" : "git",
20 | "url" : "https://github.com/franz-josef-kaiser/Dynamic-Image-Resize"
21 | },
22 | "author" : {
23 | "name" : "Franz Josef Kaiser",
24 | "email" : "wecodemore@gmail.com",
25 | "url" : "http://unserkaiser.com/"
26 | },
27 | "licenses" : [
28 | {
29 | "type" : "MIT",
30 | "url" : "http://www.tldrlegal.com/license/mit-license"
31 | }
32 | ],
33 | "engines" : {
34 | "node" : ">= 0.6.x"
35 | },
36 | "scripts" : {
37 | "dist" : "",
38 | "postinstall" : "",
39 | "start" : ""
40 | }
41 | }
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Dynamic Image resizing in WordPress
2 |
3 | version: _v1.6.3_
4 |
5 | "Dynamic Image Resize" is a WordPress (MU-)plugin that offers a shortcode and a template tag to resize images "on the flight" without the need of TimThumb, but with WP core functions.
6 |
7 | Original Idea, Concept & Script by [Konstantin Kovshenin](http://kovshenin.com/2012/native-image-sizing-on-the-fly-with-wordpress/)
8 |
9 | License: extended MIT/Expat
10 |
11 | Known issues: none
12 |
13 | Visit *Franz Josef Kaiser* at [his homepage](http://unserkaiser.com) or get social on [Google+](https://plus.google.com/+FranzJosefKaiser) or [on Twitter](https://twitter.com/unserkaiser).
14 |
15 | -----
16 |
17 | ## Updates
18 |
19 | If you are really not using Composer to keep your install up to date and don't have this plugin running as mu-plugin or included in your Theme, I recommend [using the GitHub plugin updater](https://github.com/afragen/github-updater). This plugin is compatible.
20 |
21 | -----
22 |
23 | ## Dedicated Project Page
24 |
25 | For further info, please [visit the project page](http://franz-josef-kaiser.github.io/Dynamic-Image-Resize/).
26 |
27 | [](https://bitdeli.com/free "Bitdeli Badge")
28 |
--------------------------------------------------------------------------------