ImageMagick Engine - Version 1.6.3

Version Description

  • Clean up code and constant for version (thanks @paulschreiber)
  • Disable warning for is_executable if open_basedir active
Download this release

Release Info

Developer rickardw
Plugin Icon 128x128 ImageMagick Engine
Version 1.6.3
Comparing to
See all releases

Code changes from version 1.6.2 to 1.6.3

Files changed (3) hide show
  1. imagemagick-engine.php +616 -511
  2. js/ime-admin.js +109 -104
  3. readme.txt +10 -2
imagemagick-engine.php CHANGED
@@ -1,137 +1,156 @@
1
  <?php
2
  /*
3
- Plugin Name: ImageMagick Engine
4
- Plugin URI: https://wordpress.org/plugins/imagemagick-engine/
5
- Description: Improve the quality of re-sized images by replacing standard GD library with ImageMagick
6
- Author: Orangelab
7
- Author URI: https://orangelab.com/
8
- Version: 1.6.2
9
- Text Domain: imagemagick-engine
10
-
11
- Copyright @ 2020 Orangelab AB
12
-
13
- Licenced under the GNU GPL:
14
-
15
- This program is free software; you can redistribute it and/or modify
16
- it under the terms of the GNU General Public License as published by
17
- the Free Software Foundation; either version 2 of the License, or
18
- (at your option) any later version.
19
-
20
- This program is distributed in the hope that it will be useful,
21
- but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
- GNU General Public License for more details.
24
-
25
- You should have received a copy of the GNU General Public License
26
- along with this program; if not, write to the Free Software
27
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
  */
29
 
30
- if (!defined('ABSPATH'))
31
- die('Must not be called directly');
 
32
 
33
  /*
34
  * Constants
35
  */
36
- define('IME_OPTION_VERSION', 1);
 
37
 
38
  /*
39
  * Global variables
40
  */
41
 
42
  // Plugin options default values -- change on plugin admin page
43
- $ime_options_default = array('enabled' => false
44
- , 'mode' => null
45
- , 'cli_path' => null
46
- , 'handle_sizes' => array('thumbnail' => 'size', 'medium' => 'quality', 'medium_large' => 'quality', 'large' => 'quality')
47
- , 'quality' => array('quality' => -1, 'size' => 70)
48
- , 'quality' => ''
49
- , 'version' => constant('IME_OPTION_VERSION')
50
- );
 
 
 
 
 
 
 
 
 
51
 
52
  // Available modes
53
- $ime_available_modes = array( 'php' => __( 'Imagick PHP module', 'imagemagick-engine' )
54
- , 'cli' => __( 'ImageMagick command-line', 'imagemagick-engine' ) );
 
 
55
 
56
  // Available quality modes
57
- $ime_available_quality_modes = array( 'quality', 'size', 'skip' );
58
 
59
  // Current options
60
  $ime_options = null;
61
 
62
  // Keep track of attachment file & sizes between different filters
63
  $ime_image_sizes = null;
64
- $ime_image_file = null;
65
 
66
 
67
  /*
68
  * Functions
69
  */
70
- add_action('plugins_loaded', 'ime_init_early');
71
- add_action('init', 'ime_init');
72
 
73
  /* Plugin setup (early) */
74
  function ime_init_early() {
75
- load_plugin_textdomain('imagemagick-engine', false, dirname(plugin_basename(__FILE__)) . '/languages');
76
 
77
- if (ime_active()) {
78
- add_filter('intermediate_image_sizes_advanced', 'ime_filter_image_sizes', 99, 1);
79
- add_filter('wp_read_image_metadata', 'ime_filter_read_image_metadata', 10, 3);
80
- add_filter('wp_generate_attachment_metadata', 'ime_filter_attachment_metadata', 10, 2);
81
  }
82
  }
83
 
84
  /* Plugin setup */
85
  function ime_init() {
86
- if (is_admin()) {
87
- add_action('admin_menu', 'ime_admin_menu');
88
- add_filter('plugin_action_links', 'ime_filter_plugin_actions', 10, 2 );
89
- add_filter('media_meta', 'ime_filter_media_meta', 10, 2);
 
 
 
 
90
 
91
- add_action('wp_ajax_ime_test_im_path', 'ime_ajax_test_im_path');
92
- add_action('wp_ajax_ime_process_image', 'ime_ajax_process_image');
93
- add_action('wp_ajax_ime_regeneration_get_images','ime_ajax_regeneration_get_images');
94
-
95
- wp_register_script('ime-admin', plugins_url('/js/ime-admin.js?v=1.6.2', __FILE__), array('jquery', 'jquery-ui-progressbar'));
96
  }
97
  }
98
 
99
  /* Are we enabled with valid mode? */
100
  function ime_active() {
101
- return ime_get_option("enabled") && ime_mode_valid();
102
  }
103
 
104
  /* Check if mode is valid */
105
- function ime_mode_valid($mode = null) {
106
- if (empty($mode))
107
- $mode = ime_get_option("mode");
 
108
  $fn = 'ime_im_' . $mode . '_valid';
109
- return (!empty($mode) && function_exists($fn) && call_user_func($fn));
110
  }
111
 
112
  // Check version of a registered WordPress script
113
- function ime_script_version_compare($handle, $version, $compare = '>=') {
114
  global $wp_scripts;
115
- if ( !is_a($wp_scripts, 'WP_Scripts') )
116
  $wp_scripts = new WP_Scripts();
 
117
 
118
- $query = $wp_scripts->query($handle, 'registered');
119
- if (!$query)
120
  return false;
 
121
 
122
- return version_compare($query->ver, $version, $compare);
123
  }
124
 
125
  // Get array of available image sizes
126
  function ime_available_image_sizes() {
127
  global $_wp_additional_image_sizes;
128
- $sizes = array('thumbnail' => __('Thumbnail', 'imagemagick-engine')
129
- , 'medium' => __('Medium', 'imagemagick-engine')
130
- , 'medium_large' => __('Medium Large', 'imagemagick-engine')
131
- , 'large' => __('Large', 'imagemagick-engine')); // Standard sizes
 
 
132
  if ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) ) {
133
- foreach ($_wp_additional_image_sizes as $name => $spec)
134
- $sizes[$name] = $name;
 
135
  }
136
 
137
  return $sizes;
@@ -148,26 +167,27 @@ function ime_setup_options() {
148
  global $ime_options;
149
 
150
  // Already setup?
151
- if (is_array($ime_options))
152
  return;
 
153
 
154
- $ime_options = get_option("ime_options");
155
 
156
  // No stored options yet?
157
- if (!is_array($ime_options)) {
158
  global $ime_options_default;
159
  $ime_options = $ime_options_default;
160
  }
161
 
162
  // Do we need to upgrade options?
163
- if (!array_key_exists('version', $ime_options)
164
- || $ime_options['version'] < constant('IME_OPTION_VERSION')) {
165
-
166
  /*
167
  * Future compatability code goes here!
168
  */
169
-
170
- $ime_options['version'] = constant('IME_OPTION_VERSION');
171
  ime_store_options();
172
  }
173
  }
@@ -178,64 +198,73 @@ function ime_store_options() {
178
 
179
  ime_setup_options();
180
 
181
- $stored_options = get_option("ime_options");
182
-
183
- if ($stored_options === false)
184
- add_option("ime_options", $ime_options, null, false);
185
- else
186
- update_option("ime_options", $ime_options);
 
187
  }
188
 
189
  // Get plugin option
190
- function ime_get_option($option_name, $default = null) {
191
  ime_setup_options();
192
-
193
  global $ime_options, $ime_options_default;
194
 
195
- if (is_array($ime_options) && array_key_exists($option_name, $ime_options))
196
- return $ime_options[$option_name];
 
197
 
198
- if (!is_null($default))
199
  return $default;
 
200
 
201
- if (is_array($ime_options_default) && array_key_exists($option_name, $ime_options_default))
202
- return $ime_options_default[$option_name];
 
203
 
204
  return null;
205
  }
206
 
207
  // Set plugin option
208
- function ime_set_option($option_name, $option_value, $store = false) {
209
  ime_setup_options();
210
-
211
  global $ime_options;
212
 
213
- $ime_options[$option_name] = $option_value;
214
 
215
- if ($store)
216
  ime_store_options();
 
217
  }
218
 
219
  // Get image quality setting for type
220
- function ime_get_quality($resize_mode = 'quality') {
221
- $quality = ime_get_option('quality', '-1');
222
- if (!$quality)
223
  return -1;
224
- if (!is_array($quality))
 
225
  return $quality;
226
- if (isset($quality[$resize_mode]))
227
- return $quality[$resize_mode];
228
-
 
 
229
  return -1;
230
  }
231
 
232
  // Get resize mode for size
233
  function ime_get_resize_mode( $size ) {
234
- $handle_sizes = ime_get_option('handle_sizes');
235
- if ( isset( $handle_sizes[ $size ] ) && is_string( $handle_sizes[ $size ] ) )
236
  return $handle_sizes[ $size ];
237
- else
238
  return 'quality'; // default to quality
 
239
  }
240
 
241
 
@@ -252,15 +281,16 @@ function ime_get_resize_mode( $size ) {
252
  * The reason we do things this way is so we do not resize image twize (once
253
  * by WordPress using GD, and then again by us).
254
  */
255
- function ime_filter_image_sizes($sizes) {
256
  global $ime_image_sizes;
257
 
258
- $handle_sizes = ime_get_option('handle_sizes');
259
- foreach ($handle_sizes as $s => $handle) {
260
- if (!$handle || $handle == 'skip' || !array_key_exists($s, $sizes))
261
  continue;
262
- $ime_image_sizes[$s] = $sizes[$s];
263
- unset($sizes[$s]);
 
264
  }
265
  return $sizes;
266
  }
@@ -271,9 +301,9 @@ function ime_filter_image_sizes($sizes) {
271
  * Function wp_generate_attachment_metadata calls wp_read_image_metadata which
272
  * gives us a hook to get the target filename.
273
  */
274
- function ime_filter_read_image_metadata($metadata, $file, $ignore) {
275
  global $ime_image_file;
276
-
277
  $ime_image_file = $file;
278
 
279
  return $metadata;
@@ -286,17 +316,19 @@ function ime_filter_read_image_metadata($metadata, $file, $ignore) {
286
  *
287
  * Parts of function copied from wp-includes/media.php:image_resize()
288
  */
289
- function ime_filter_attachment_metadata($metadata, $attachment_id) {
290
  global $ime_image_sizes, $ime_image_file;
291
 
292
  // Any sizes we are interested in?
293
- if (empty($ime_image_sizes))
294
  return $metadata;
 
295
 
296
  // Get size & image type of original image
297
- $old_stats = @getimagesize($ime_image_file);
298
- if (!$old_stats)
299
  return $metadata;
 
300
 
301
  list($orig_w, $orig_h, $orig_type) = $old_stats;
302
 
@@ -305,52 +337,58 @@ function ime_filter_attachment_metadata($metadata, $attachment_id) {
305
  *
306
  * If image type is PNG or GIF keep it, otherwise make sure it is JPG
307
  */
308
- $info = pathinfo($ime_image_file);
309
- $dir = $info['dirname'];
310
- $ext = $info['extension'];
311
- $namebase = basename($ime_image_file, ".{$ext}");
312
- if ($orig_type == IMAGETYPE_PNG || $orig_type == IMAGETYPE_GIF)
313
  $new_ext = $ext;
314
- else
315
- $new_ext = "jpg";
 
316
 
317
  /*
318
  * Do the actual resize
319
  */
320
- foreach ($ime_image_sizes as $size => $size_data) {
321
- $width = $size_data['width'];
322
  $height = $size_data['height'];
323
 
324
  // ignore sizes equal to or larger than original size
325
- if ($orig_w <= $width && $orig_h <= $height)
326
  continue;
 
327
 
328
  $crop = $size_data['crop'];
329
-
330
- $dims = image_resize_dimensions($orig_w, $orig_h, $width, $height, $crop);
331
- if ( !$dims )
332
  continue;
 
333
  list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims;
334
 
335
- $suffix = "{$dst_w}x{$dst_h}";
336
  $new_filename = "{$dir}/{$namebase}-{$suffix}.{$new_ext}";
337
 
338
  $resized = ime_im_resize( $ime_image_file, $new_filename, $dst_w, $dst_h, $crop, ime_get_resize_mode( $size ) );
339
- if (!$resized)
340
  continue;
 
341
 
342
- $metadata['sizes'][$size] = array('file' => basename($new_filename)
343
- , 'width' => $dst_w
344
- , 'height' => $dst_h
345
- );
 
346
 
347
- if (!isset($metadata['image-converter']) || !is_array($metadata['image-converter']))
348
- $metadata['image-converter'] = array();
349
-
350
- $metadata['image-converter'][$size] = 'IME';
 
351
 
352
  // Set correct file permissions
353
- $stat = stat( dirname( $new_filename ));
354
  $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits
355
  @ chmod( $new_filename, $perms );
356
  }
@@ -361,28 +399,29 @@ function ime_filter_attachment_metadata($metadata, $attachment_id) {
361
 
362
  // Resize file by calling mode specific resize function
363
  function ime_im_resize( $old_file, $new_file, $width, $height, $crop, $resize_mode = 'quality' ) {
364
- $mode = ime_get_option("mode");
365
- $fn = 'ime_im_' . $mode . '_valid';
366
- if (empty($mode) || !function_exists($fn) || !call_user_func($fn))
367
  return false;
 
368
 
369
- $fn = 'ime_im_' . $mode . '_resize';
370
  $success = ( function_exists( $fn ) && call_user_func( $fn, $old_file, $new_file, $width, $height, $crop, $resize_mode ) );
371
  do_action( 'ime_after_resize', $success, $old_file, $new_file, $width, $height, $crop, $resize_mode );
372
  return $success;
373
  }
374
 
375
  // Is this the filename of a jpeg?
376
- function ime_im_filename_is_jpg($filename) {
377
- $info = pathinfo($filename);
378
- $ext = $info['extension'];
379
- return (strcasecmp($ext, 'jpg') == 0) || (strcasecmp($ext, 'jpeg') == 0);
380
  }
381
 
382
  // Get file extenstion
383
- function ime_im_get_filetype($filename) {
384
- $info = pathinfo($filename);
385
- return strtolower($info['extension']);
386
  }
387
 
388
  /*
@@ -391,25 +430,27 @@ function ime_im_get_filetype($filename) {
391
 
392
  // Does class exist?
393
  function ime_im_php_valid() {
394
- return class_exists('Imagick');
395
  }
396
 
397
  // Resize file using PHP Imagick class
398
  function ime_im_php_resize( $old_file, $new_file, $width, $height, $crop, $resize_mode = 'quality' ) {
399
  $im = new Imagick( $old_file );
400
- if ( ! $im->valid() )
401
  return false;
 
402
 
403
  try {
404
- $im->setImageFormat( ime_im_get_filetype( $old_file) );
405
  $quality = ime_get_quality( $resize_mode );
406
  if ( is_numeric( $quality ) && $quality >= 0 && $quality <= 100 && ime_im_filename_is_jpg( $new_file ) ) {
407
  $im->setImageCompression( Imagick::COMPRESSION_JPEG );
408
  $im->setImageCompressionQuality( $quality );
409
  }
410
-
411
- if ( $resize_mode == 'size' )
412
  $im->stripImage();
 
413
 
414
  if ( $crop ) {
415
  /*
@@ -419,25 +460,25 @@ function ime_im_php_resize( $old_file, $new_file, $width, $height, $crop, $resiz
419
  * Crop an area proportional to target $width and $height and
420
  * fall through to scaleImage() below.
421
  */
422
-
423
- $geo = $im->getImageGeometry();
424
- $orig_width = $geo[ 'width' ];
425
- $orig_height = $geo[ 'height' ];
426
 
427
- if( ( $orig_width / $width ) < ( $orig_height / $height ) ) {
428
- $crop_width = $orig_width;
 
 
 
 
429
  $crop_height = ceil( ( $height * $orig_width ) / $width );
430
- $off_x = 0;
431
- $off_y = ceil( ( $orig_height - $crop_height ) / 2 );
432
  } else {
433
- $crop_width = ceil( ( $width * $orig_height ) / $height );
434
  $crop_height = $orig_height;
435
- $off_x = ceil( ( $orig_width - $crop_width ) / 2 );
436
- $off_y = 0;
437
  }
438
  $im->cropImage( $crop_width, $crop_height, $off_x, $off_y );
439
  }
440
-
441
  $im->scaleImage( $width, $height, true );
442
 
443
  $im->setImagePage( $width, $height, 0, 0 ); // to make sure canvas is correct
@@ -456,19 +497,20 @@ function ime_im_php_resize( $old_file, $new_file, $width, $height, $crop, $resiz
456
  // Do we have a valid ImageMagick executable set?
457
  function ime_im_cli_valid() {
458
  $cmd = ime_im_cli_command();
459
- return !empty($cmd) && is_executable($cmd);
460
  }
461
 
462
  // Test if we are allowed to exec executable!
463
  function ime_im_cli_check_executable($fullpath) {
464
- if (!is_executable($fullpath))
465
  return false;
 
466
 
467
- @exec('"' . $fullpath . '" --version', $output);
468
 
469
  ime_set_option( 'imagemagick_version', $output, true );
470
 
471
- return count($output) > 0;
472
  }
473
 
474
  /*
@@ -476,89 +518,99 @@ function ime_im_cli_check_executable($fullpath) {
476
  *
477
  * This won't work if there is open_basename restrictions.
478
  */
479
- function ime_try_realpath($path) {
480
- $realpath = @realpath($path);
481
- if ($realpath)
482
  return $realpath;
483
- else
484
  return $path;
 
485
  }
486
 
487
  // Check if path leads to ImageMagick executable
488
- function ime_im_cli_check_command($path, $executable='convert') {
489
- $path = ime_try_realpath($path);
490
 
491
  $cmd = $path . '/' . $executable;
492
- if (ime_im_cli_check_executable($cmd))
493
  return $cmd;
 
494
 
495
  $cmd = $cmd . '.exe';
496
- if (ime_im_cli_check_executable($cmd))
497
  return $cmd;
 
498
 
499
  return null;
500
  }
501
 
502
  // Try to find a valid ImageMagick executable
503
- function ime_im_cli_find_command($executable='convert') {
504
- $possible_paths = array("/usr/bin", "/usr/local/bin");
505
 
506
- foreach ($possible_paths AS $path) {
507
- if (ime_im_cli_check_command($path, $executable))
508
  return $path;
 
509
  }
510
 
511
  return null;
512
  }
513
 
514
  // Get ImageMagick executable
515
- function ime_im_cli_command($executable='convert') {
516
- $path = ime_get_option("cli_path");
517
- if (!empty($path))
518
- return ime_im_cli_check_command($path, $executable);
 
519
 
520
- $path = ime_im_cli_find_command($executable);
521
- if (empty($path))
522
  return null;
523
- ime_set_option("cli_path", $path, true);
524
- return ime_im_cli_check_command($path, $executable);
 
525
  }
526
 
527
  // Check if we are running under Windows (which differs for character escape)
528
  function ime_is_windows() {
529
- return (constant('PHP_SHLIB_SUFFIX') == 'dll');
530
  }
531
 
532
  // Resize using ImageMagick executable
533
  function ime_im_cli_resize( $old_file, $new_file, $width, $height, $crop, $resize_mode = 'quality' ) {
534
  $cmd = ime_im_cli_command();
535
- if (empty($cmd))
536
  return false;
 
537
 
538
- $old_file = addslashes($old_file);
539
- $new_file = addslashes($new_file);
540
 
541
  $geometry = $width . 'x' . $height;
542
 
543
  // limits are 150mb and 128mb
544
  $cmd = "\"$cmd\" \"$old_file\" -limit memory 157286400 -limit map 134217728 -resize $geometry";
545
- if ($crop) {
546
  // '^' is an escape character on Windows
547
- $cmd .= (ime_is_windows() ? '^^' : '^') . " -gravity center -extent $geometry";
548
- } else
549
- $cmd .= "!"; // force these dimensions
 
550
 
551
  $quality = ime_get_quality( $resize_mode );
552
- if (is_numeric($quality) && $quality >= 0 && $quality <= 100 && ime_im_filename_is_jpg($new_file))
553
- $cmd .= " -quality " . intval($quality);
 
554
 
555
- if ( $resize_mode == 'size' )
556
  $cmd .= ' -strip';
 
557
 
558
- $cmd .= ' "' . $new_file . '"';
559
- exec($cmd);
560
 
561
- return file_exists($new_file);
562
  }
563
 
564
 
@@ -568,103 +620,121 @@ function ime_im_cli_resize( $old_file, $new_file, $width, $height, $crop, $resiz
568
 
569
  // Test if a path is correct for IM binary
570
  function ime_ajax_test_im_path() {
571
- if (!current_user_can('manage_options'))
572
  die();
573
- $r = ime_im_cli_check_command($_REQUEST['cli_path']);
574
- echo empty($r) ? "0" : "1";
 
575
  die();
576
  }
577
 
578
  // Get list of attachments to regenerate
579
  function ime_ajax_regeneration_get_images() {
580
  global $wpdb;
581
-
582
- if (!current_user_can('manage_options'))
583
- wp_die('Sorry, but you do not have permissions to perform this action.');
584
-
 
585
  // Query for the IDs only to reduce memory usage
586
  $images = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'image/%'" );
587
-
588
  // Generate the list of IDs
589
- $ids = array();
590
- foreach ( $images as $image )
591
  $ids[] = $image->ID;
 
592
  $ids = implode( ',', $ids );
593
-
594
- die($ids);
595
  }
596
 
597
  // Process single attachment ID
598
  function ime_ajax_process_image() {
599
  global $ime_image_sizes, $ime_image_file, $_wp_additional_image_sizes;
600
-
601
- error_reporting(E_ERROR | E_WARNING);
602
 
603
- if (!current_user_can('manage_options') || !ime_mode_valid())
604
- die('-1');
 
 
 
605
 
606
- if (!isset($_REQUEST['id']))
607
- die('-1');
 
608
 
609
- $id = intval($_REQUEST['id']);
610
- if ($id <= 0)
611
- die('-1');
 
612
 
613
  $temp_sizes = $_REQUEST['sizes'];
614
- if (empty($temp_sizes))
615
- die('-1');
616
- $temp_sizes = explode('|', $temp_sizes);
617
- if (count($temp_sizes) < 1)
618
- die('-1');
 
 
619
 
620
  $temp_sizes = apply_filters( 'intermediate_image_sizes', $temp_sizes );
621
 
622
  foreach ( $temp_sizes as $s ) {
623
- $sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => FALSE );
624
- if ( isset( $_wp_additional_image_sizes[$s]['width'] ) )
625
- $sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] ); // For theme-added sizes
626
- else
627
- $sizes[$s]['width'] = get_option( "{$s}_size_w" ); // For default sizes set in options
628
- if ( isset( $_wp_additional_image_sizes[$s]['height'] ) )
629
- $sizes[$s]['height'] = intval( $_wp_additional_image_sizes[$s]['height'] ); // For theme-added sizes
630
- else
631
- $sizes[$s]['height'] = get_option( "{$s}_size_h" ); // For default sizes set in options
632
- if ( isset( $_wp_additional_image_sizes[$s]['crop'] ) )
633
- $sizes[$s]['crop'] = intval( $_wp_additional_image_sizes[$s]['crop'] ); // For theme-added sizes
634
- else
635
- $sizes[$s]['crop'] = get_option( "{$s}_crop" ); // For default sizes set in options
636
- }
637
-
638
- remove_filter('intermediate_image_sizes_advanced', 'ime_filter_image_sizes', 99, 1);
 
 
 
 
 
 
 
639
  $sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes );
640
 
641
- $force = isset($_REQUEST['force']) && !! $_REQUEST['force'];
642
 
643
- $ime_image_file = get_attached_file($id);
644
 
645
- if (false === $ime_image_file || !file_exists($ime_image_file))
646
- die('-1');
 
647
 
648
- $metadata = wp_get_attachment_metadata($id);
649
 
650
  // Do not re-encode IME images unless forced
651
- if (!$force && isset($metadata['image-converter']) && is_array($metadata['image-converter'])) {
652
  $converter = $metadata['image-converter'];
653
-
654
- foreach ($sizes AS $s => $ignore) {
655
- if (isset($converter[$s]) && $converter[$s] == 'IME')
656
- unset($sizes[$s]);
 
 
 
 
657
  }
658
- if (count($sizes) < 1)
659
- die(1);
660
  }
661
 
662
  $ime_image_sizes = $sizes;
663
 
664
- set_time_limit(60);
665
 
666
- $new_meta = ime_filter_attachment_metadata($metadata, $id);
667
- wp_update_attachment_metadata($id, $new_meta);
668
 
669
  /*
670
  * Normally the old file gets overwritten by the new one when
@@ -677,30 +747,33 @@ function ime_ajax_process_image() {
677
  */
678
 
679
  // No old sizes, nothing to check
680
- if (!isset($metadata['sizes']) || empty($metadata['sizes']))
681
- die('1');
682
-
683
- $dir = trailingslashit(dirname($ime_image_file));
684
 
685
- foreach ($metadata['sizes'] as $size => $sizeinfo) {
 
 
686
  $old_file = $sizeinfo['file'];
687
 
688
  // Does file exist in new meta?
689
  $exists = false;
690
- foreach ($new_meta['sizes'] as $ignore => $new_sizeinfo) {
691
- if ($old_file != $new_sizeinfo['file'])
692
  continue;
 
693
  $exists = true;
694
  break;
695
  }
696
- if ($exists)
697
  continue;
 
698
 
699
  // Old file did not exist in new meta. Delete it!
700
- @ unlink($dir . $old_file);
701
  }
702
-
703
- die('1');
704
  }
705
 
706
 
@@ -710,38 +783,39 @@ function ime_ajax_process_image() {
710
 
711
  /* Add admin page */
712
  function ime_admin_menu() {
713
- $ime_page = add_options_page('ImageMagick Engine', 'ImageMagick Engine', 'manage_options', 'imagemagick-engine', 'ime_option_page');
714
 
715
- $script_pages = array( $ime_page, 'media.php', 'media-new.php', 'media-upload.php', 'media-upload-popup', 'post.php', 'upload.php' );
716
- foreach ($script_pages as $page) {
717
- add_action('admin_print_scripts-' . $page, 'ime_admin_print_scripts');
718
- add_action('admin_print_styles-' . $page, 'ime_admin_print_styles');
719
  }
720
  }
721
 
722
  /* Enqueue admin page scripts */
723
  function ime_admin_print_scripts() {
724
- wp_enqueue_script('ime-admin');
725
-
726
- $data = array('noimg' => __('You dont have any images to regenerate', 'imagemagick-engine')
727
- , 'done' => __('All done!', 'imagemagick-engine')
728
- , 'processed_fmt' => __('Processed %d images', 'imagemagick-engine')
729
- , 'failed' => '<strong>' . __('Failed to resize image!', 'imagemagick-engine') . '</strong>'
730
- , 'resized' => __('Resized using ImageMagick Engine', 'imagemagick-engine')
731
- );
732
- wp_localize_script('ime-admin', 'ime_admin', $data);
 
733
  }
734
 
735
  /* Enqueue admin page style */
736
  function ime_admin_print_styles() {
737
- wp_enqueue_style( 'ime-admin-style', plugins_url('/css/ime-admin.css', __FILE__), array());
738
  }
739
 
740
  /* Add settings to plugin action links */
741
- function ime_filter_plugin_actions($links, $file) {
742
- if($file == plugin_basename(__FILE__)) {
743
- $settings_link = "<a href=\"options-general.php?page=imagemagick-engine\">"
744
- . __('Settings', 'imagemagick-engine') . '</a>';
745
  array_unshift( $links, $settings_link ); // before other links
746
  }
747
 
@@ -751,31 +825,33 @@ function ime_filter_plugin_actions($links, $file) {
751
  /*
752
  * Add admin information if attachment is converted using plugin
753
  */
754
- function ime_filter_media_meta($content, $post) {
755
  global $wp_version;
756
 
757
- if (!ime_mode_valid())
758
  return $content;
 
759
 
760
- if (version_compare($wp_version, '3.5.0', '>=')) {
761
  // WordPress 3.5 and newer
762
- if (!wp_image_editor_supports(array('mime_type' => $post->post_mime_type))) {
763
  return $content;
764
  }
765
  } else {
766
  // WordPress older than 3.5
767
- if (!gd_edit_image_support($post->post_mime_type)) {
768
  return $content;
769
  }
770
  }
771
 
772
- $metadata = wp_get_attachment_metadata($post->ID);
773
 
774
  $ime = false;
775
- if (is_array($metadata) && array_key_exists('image-converter', $metadata)) {
776
- foreach ($metadata['image-converter'] as $size => $converter) {
777
- if ($converter != 'IME')
778
  continue;
 
779
 
780
  $ime = true;
781
  break;
@@ -783,46 +859,49 @@ function ime_filter_media_meta($content, $post) {
783
  }
784
 
785
  $content .= '</p><p>';
786
- if ($ime) {
787
- $message = ' <div class="ime-media-message" id="ime-message-' . $post->ID . '">' . __('Resized using ImageMagick Engine', 'imagemagick-engine') . '</div>';
788
- $resize = __('Resize image', 'imagemagick-engine');
789
- $force = '1';
790
  } else {
791
  $message = '<div class="ime-media-message" id="ime-message-' . $post->ID . '" style="display: none;"></div>';
792
- $resize = __('Resize using ImageMagick Engine', 'imagemagick-engine');
793
- $force = '0';
794
  }
795
- $handle_sizes = ime_get_option('handle_sizes');
796
- $sizes = array();
797
- foreach ($handle_sizes as $s => $h) {
798
- if (!$h)
799
  continue;
 
800
  $sizes[] = $s;
801
  }
802
- $sizes = implode('|', $sizes);
803
  $resize_call = 'imeRegenMediaImage(' . $post->ID . ', \'' . $sizes . '\', ' . $force . '); return false;';
804
- $content .= '<a href="#" id="ime-regen-link-' . $post->ID . '" class="button ime-regen-button" onclick="' . $resize_call . '">' . $resize . '</a> ' . $message . ' <div id="ime-spinner-' . $post->ID . '" class="ime-spinner"><img src="' . admin_url('images/wpspin_light.gif') . '" /></div>';
805
-
806
  return $content;
807
  }
808
 
809
  // Url to admin images
810
  function ime_option_admin_images_url() {
811
- return get_bloginfo('wpurl') . '/wp-admin/images/';
812
  }
813
 
814
  // Url to status icon
815
- function ime_option_status_icon($yes = true) {
816
- return ime_option_admin_images_url() . ($yes ? 'yes' : 'no') . '.png';
817
  }
818
 
819
  // Display, or not
820
- function ime_option_display($display = true, $echo = true) {
821
- if ($display)
822
  return '';
 
823
  $s = ' style="display: none" ';
824
- if ($echo)
825
  echo $s;
 
826
  return $s;
827
  }
828
 
@@ -830,253 +909,279 @@ function ime_option_display($display = true, $echo = true) {
830
  function ime_option_page() {
831
  global $ime_available_modes, $ime_available_quality_modes;
832
 
833
- if (!current_user_can('manage_options'))
834
- wp_die('Sorry, but you do not have permissions to change settings.');
 
835
 
836
  /* Make sure post was from this page */
837
- if (count($_POST) > 0)
838
- check_admin_referer('ime-options');
 
839
 
840
  $sizes = ime_available_image_sizes();
841
 
842
- if (isset($_POST['regenerate-images'])) {
843
- ime_show_regenerate_images(array_keys($sizes));
844
  return;
845
  }
846
 
847
  /* Should we update settings? */
848
- if (isset($_POST['update_settings'])) {
849
- $new_enabled = isset($_POST['enabled']) && !! $_POST['enabled'];
850
- ime_set_option('enabled', $new_enabled);
851
- if (isset($_POST['mode']) && array_key_exists($_POST['mode'], $ime_available_modes))
852
- ime_set_option('mode', $_POST['mode']);
853
- if (isset($_POST['cli_path']))
854
- ime_set_option('cli_path', ime_try_realpath(trim($_POST['cli_path'])));
855
-
856
- $new_quality = array( 'quality' => -1, 'size' => 70 );
857
- if ( isset( $_POST[ 'quality-quality' ] ) ) {
858
- if ( is_numeric( $_POST[ 'quality-quality' ] ) )
859
- $new_quality[ 'quality' ] = min( 100, max( 0, intval( $_POST[ 'quality-quality' ] ) ) );
860
- else if ( empty( $_POST[ 'quality-quality' ] ) )
861
- $new_quality[ 'quality' ] = -1;
862
  }
863
- if ( isset( $_POST[ 'quality-size' ] ) ) {
864
- if ( is_numeric( $_POST[ 'quality-size' ] ) )
865
- $new_quality[ 'quality-size' ] = min( 100, max( 0, intval( $_POST[ 'quality-size' ] ) ) );
866
- else if ( empty( $_POST[ 'quality-size' ] ) )
867
- $new_quality[ 'quality-size' ] = -1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
868
  }
869
  ime_set_option( 'quality', $new_quality );
870
 
871
- $new_handle_sizes = array();
872
- foreach ($sizes AS $s => $name) {
873
  $new_mode = isset( $_POST[ 'handle-mode-' . $s ] ) ? $_POST[ 'handle-mode-' . $s ] : 'skip';
874
- if ( in_array( $new_mode, $ime_available_quality_modes ) )
875
  $mode = $new_mode;
876
- else
877
  $mode = 'quality';
 
878
 
879
  $new_handle_sizes[ $s ] = $mode;
880
  }
881
  ime_set_option( 'handle_sizes', $new_handle_sizes );
882
 
883
  ime_store_options();
884
-
885
  echo '<div id="message" class="updated fade"><p>'
886
- . __('Settings updated', 'imagemagick-engine')
887
  . '</p></div>';
888
  }
889
 
890
  $modes_valid = $ime_available_modes;
891
- $any_valid = false;
892
- foreach($modes_valid AS $m => $ignore) {
893
- $modes_valid[$m] = ime_mode_valid($m);
894
- if ($modes_valid[$m])
895
  $any_valid = true;
 
896
  }
897
 
898
- $current_mode = ime_get_option('mode');
899
- if (!isset($modes_valid[$current_mode]) || !$modes_valid[$current_mode])
900
  $current_mode = null;
901
- if (is_null($current_mode) && $any_valid) {
902
- foreach ($modes_valid AS $m => $valid) {
903
- if ($valid) {
 
904
  $current_mode = $m;
905
  break;
906
  }
907
  }
908
  }
909
 
910
- $enabled = ime_get_option('enabled') && $current_mode;
911
-
912
- $cli_path = ime_get_option('cli_path');
913
- if (is_null($cli_path))
914
  $cli_path = ime_im_cli_command();
915
- $cli_path_ok = ime_im_cli_check_command($cli_path);
 
916
 
917
- $quality = ime_get_option('quality');
918
  if ( ! is_array( $quality ) ) {
919
- $n = array( 'quality' => -1, 'size' => 70 );
920
- if ( is_numeric( $quality ) && $quality > 0 )
921
- $n[ 'quality' ] = $quality;
 
 
 
 
922
  $quality = $n;
923
  }
924
 
925
- $handle_sizes = ime_get_option('handle_sizes');
926
 
927
- if (!$any_valid)
928
  echo '<div id="warning" class="error"><p>'
929
- . sprintf(__('No valid ImageMagick mode found! Please check %sFAQ%s for installation instructions.', 'imagemagick-engine'), '<a href="http://wp.orangelab.se/imagemagick-engine/documentation#installation">', '</a>')
930
  . '</p></div>';
931
- elseif (!$enabled)
932
  echo '<div id="warning" class="error"><p>'
933
- . __('ImageMagick Engine is not enabled.', 'imagemagick-engine')
934
  . '</p></div>';
935
- ?>
 
936
  <div class="wrap">
937
- <div id="regen-message" class="hidden updated fade"></div>
938
- <h2><?php _e('ImageMagick Engine Settings','imagemagick-engine'); ?></h2>
939
- <div id="ime-regeneration" title="<?php _e('Regenerating images', 'imagemagick-engine'); ?>...">
940
- <noscript><p><em><?php _e( 'You must enable Javascript in order to proceed!', 'imagemagick-engine' ) ?></em></p></noscript>
941
- <p><strong><?php _e('Regenerating images', 'imagemagick-engine'); ?>...</strong></p>
942
- <div id="ime-regenbar">
943
- <div id="ime-regenbar-percent"></div>
 
944
  </div>
945
- </div>
946
- <form action="options-general.php?page=imagemagick-engine" method="post" name="update_options">
947
- <?php wp_nonce_field('ime-options'); ?>
948
- <div id="poststuff" class="metabox-holder has-right-sidebar">
949
- <div class="inner-sidebar">
950
- <div class="meta-box-sortables ui-sortable">
951
  <div id="regenerate-images-metabox" class="postbox">
952
- <h3 class="hndle"><span><?php _e('Regenerate Images','imagemagick-engine'); ?></span></h3>
953
- <div class="inside">
954
- <div class="submitbox">
955
- <table border=0>
956
  <tr>
957
- <td scope="row" valign="top" style="padding-right: 20px;"><?php _e('Sizes','imagemagick-engine'); ?>:</td>
958
- <td>
959
- <?php
960
- foreach($sizes AS $s => $name) {
961
- echo '<input type="checkbox" name="regen-size-' . $s . '" value="1" ' . ( ( isset( $handle_sizes[ $s ] ) && $handle_sizes[ $s ] != 'skip' && $handle_sizes[ $s ] != false ) ? ' checked="checked" ' : '' ) . ' /> ' . $name . '<br />';
962
- }
963
- ?>
964
- </td>
965
- </tr>
966
- </table>
967
- <p><?php _e('ImageMagick images too','imagemagick-engine'); ?>:
968
- <input type="checkbox" name="force" id="force" value="1" /></p>
969
- <?php
970
- if (!ime_active())
971
- echo '<p class="howto">' . __('Resize will use standard WordPress functions.', 'imagemagick-engine') . '</p>';
972
- ?>
973
- <p><input class="button-primary" type="button" id="regenerate-images" value="<?php _e('Regenerate', 'imagemagick-engine'); ?>" /></p>
974
- <p class="description"><?php _e('(this can take a long time)', 'imagemagick-engine'); ?></p>
975
- </div>
 
 
 
 
976
  </div>
977
- </div>
978
- </div>
979
- </div>
980
- <div id="post-body">
981
- <div id="post-body-content">
982
- <div id="ime-settings" class="postbox">
983
- <h3 class="hndle"><span><?php _e('Settings', 'imagemagick-engine'); ?></span></h3>
984
  <div class="inside">
985
- <table class="form-table">
986
- <tr>
987
- <th scope="row" valign="top"><?php _e('Enable enhanced image engine','imagemagick-engine'); ?>:</th>
988
- <td>
989
- <input type="checkbox" id="enabled" name="enabled" value="1" <?php echo $enabled ? " CHECKED " : ""; echo $any_valid ? '' : ' disabled=disabled '; ?> />
990
- </td>
991
- </tr>
992
- <tr>
993
- <th scope="row" valign="top"><?php _e('Image engine','imagemagick-engine'); ?>:</th>
994
- <td>
 
 
 
 
 
995
  <select id="ime-select-mode" name="mode">
996
- <?php
997
- foreach($modes_valid AS $m => $valid) {
998
- echo '<option value="' . $m . '"';
999
- if ($m == $current_mode)
1000
- echo ' selected=selected ';
1001
- echo '>' . $ime_available_modes[$m] . '</option>';
1002
- }
1003
- ?>
 
1004
  </select>
1005
- </td>
1006
- </tr>
1007
- <tr id="ime-row-php">
1008
- <th scope="row" valign="top"><?php _e('Imagick PHP module','imagemagick-engine'); ?>:</th>
1009
- <td>
1010
- <img src="<?php echo ime_option_status_icon($modes_valid['php']); ?>" />
1011
- <?php echo $modes_valid['php'] ? __('Imagick PHP module found', 'imagemagick-engine') : __('Imagick PHP module not found', 'imagemagick-engine'); ?>
1012
- </td>
1013
- </tr>
1014
- <tr id="ime-row-cli">
1015
- <th scope="row" valign="top"><?php _e('ImageMagick path','imagemagick-engine'); ?>:</th>
1016
- <td>
1017
- <img id="cli_path_yes" class="cli_path_icon" src="<?php echo ime_option_status_icon(true); ?>" alt="" <?php ime_option_display($cli_path_ok); ?> />
1018
- <img id="cli_path_no" class="cli_path_icon" src="<?php echo ime_option_status_icon(false); ?>" alt="<?php _e('Command not found', 'qp-qie'); ?>" <?php ime_option_display(!$cli_path_ok); ?> />
1019
- <img id="cli_path_progress" src="<?php echo ime_option_admin_images_url(); ?>wpspin_light.gif" alt="<?php _e('Testing command...', 'qp-qie'); ?>" <?php ime_option_display(false); ?> />
1020
- <input id="cli_path" type="text" name="cli_path" size="<?php echo max(30, strlen($cli_path) + 5); ?>" value="<?php echo $cli_path; ?>" />
1021
- <input type="button" name="ime_cli_path_test" id="ime_cli_path_test" value="<?php _e('Test path', 'imagemagick-engine'); ?>" class="button-secondary" />
1022
- <span <?php ime_option_display($cli_path_ok); ?>><br><br><?php echo ime_get_option('imagemagick_version')[0]; ?></span>
1023
- </td>
1024
- </tr>
1025
- <tr>
1026
- <th scope="row" valign="top"><?php _e('ImageMagick quality','imagemagick-engine'); ?>:</th>
1027
- <td>
1028
- <p><input id="quality-quality" type="text" name="quality-quality" size="3" value="<?php echo ( ( isset( $quality[ 'quality' ] ) && $quality[ 'quality' ] > 0 ) ? $quality[ 'quality' ] : '' ); ?>" /> <?php _e( 'Optimize for quality','imagemagick-engine' ); ?></p>
1029
- <p><input id="quality-size" type="text" name="quality-size" size="3" value="<?php echo ( ( isset( $quality[ 'size' ] ) && $quality[ 'size' ] > 0 ) ? $quality[ 'size' ] : '' ); ?>" /> <?php _e( 'Optimize for size','imagemagick-engine' ); ?></p>
1030
  <p class="ime-description"><?php _e( 'Set to 0-100. Higher value gives better image quality but larger file size. Leave empty for default value, computed dynamically.', 'imagemagick-engine' ); ?></p>
1031
- </td>
1032
- </tr>
1033
- <tr>
1034
- <td colspan="2" class="ime-handle-table-wrapper">
1035
  <table border='0' class="ime-handle-table" id="ime-handle-table">
1036
- <tr>
1037
- <th scope="row" class="ime-headline" valign="top"><?php _e( 'Optimize for','imagemagick-engine' ); ?></th>
1038
- <td class="ime-headline ime-fixed-width"><?php _e( 'Quality','imagemagick-engine' ); ?></td>
1039
- <td class="ime-headline ime-fixed-width"><?php _e( 'Size','imagemagick-engine' ); ?></td>
1040
- <td class="ime-headline"><?php _e( 'None (use WP instead)','imagemagick-engine' ); ?></td>
1041
- </tr>
1042
- <?php
1043
- foreach($sizes AS $s => $name) {
1044
- // fixup for old (pre 1.5.0) options
1045
- if ( ! isset( $handle_sizes[ $s] ) || ! $handle_sizes[ $s ] )
1046
- $handle_sizes[ $s ] = 'skip';
1047
- elseif ( $handle_sizes[ $s ] === true )
1048
- $handle_sizes[ $s ] = 'quality';
1049
- ?>
1050
- <tr>
1051
- <th scope="row" valign="top"><?php echo $name; ?></th>
1052
- <td class="ime-fixed-width">
1053
- <input type="radio" name="handle-mode-<?php echo $s; ?>" value="quality" <?php checked( 'quality', $handle_sizes[ $s ] ); ?> />
1054
- </td>
1055
- <td class="ime-fixed-width">
1056
- <input type="radio" name="handle-mode-<?php echo $s; ?>" value="size" <?php checked( 'size', $handle_sizes[ $s ] ); ?> />
1057
- </td>
1058
- <td>
1059
- <input type="radio" name="handle-mode-<?php echo $s; ?>" value="skip" <?php checked( 'skip', $handle_sizes[ $s ] ); ?> />
1060
- </td>
1061
- </tr>
1062
- <?php
1063
- }
1064
- ?>
 
 
 
 
 
 
 
 
 
1065
  </table>
1066
- </td>
1067
- </tr>
1068
- <tr>
1069
- <td>
1070
- <input class="button-primary" type="submit" name="update_settings" value="<?php _e('Save Changes', 'imagemagick-engine'); ?>" />
1071
- </td>
1072
- </tr>
1073
- </table>
1074
  </div>
1075
- </div>
1076
- </div>
1077
- </div>
1078
- </form>
1079
  </div>
1080
- <?php
1081
  }
1082
  ?>
1
  <?php
2
  /*
3
+ Plugin Name: ImageMagick Engine
4
+ Plugin URI: https://wordpress.org/plugins/imagemagick-engine/
5
+ Description: Improve the quality of re-sized images by replacing standard GD library with ImageMagick
6
+ Author: Orangelab
7
+ Author URI: https://orangelab.com/
8
+ Version: 1.6.3
9
+ Text Domain: imagemagick-engine
10
+
11
+ Copyright @ 2020 Orangelab AB
12
+
13
+ Licenced under the GNU GPL:
14
+
15
+ This program is free software; you can redistribute it and/or modify
16
+ it under the terms of the GNU General Public License as published by
17
+ the Free Software Foundation; either version 2 of the License, or
18
+ (at your option) any later version.
19
+
20
+ This program is distributed in the hope that it will be useful,
21
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ GNU General Public License for more details.
24
+
25
+ You should have received a copy of the GNU General Public License
26
+ along with this program; if not, write to the Free Software
27
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
  */
29
 
30
+ if ( ! defined( 'ABSPATH' ) ) {
31
+ die( 'Must not be called directly' );
32
+ }
33
 
34
  /*
35
  * Constants
36
  */
37
+ define( 'IME_OPTION_VERSION', 1 );
38
+ define( 'IME_VERSION', '1.6.3' );
39
 
40
  /*
41
  * Global variables
42
  */
43
 
44
  // Plugin options default values -- change on plugin admin page
45
+ $ime_options_default = [
46
+ 'enabled' => false,
47
+ 'mode' => null,
48
+ 'cli_path' => null,
49
+ 'handle_sizes' => [
50
+ 'thumbnail' => 'size',
51
+ 'medium' => 'quality',
52
+ 'medium_large' => 'quality',
53
+ 'large' => 'quality',
54
+ ],
55
+ 'quality' => [
56
+ 'quality' => -1,
57
+ 'size' => 70,
58
+ ],
59
+ 'quality' => '',
60
+ 'version' => constant( 'IME_OPTION_VERSION' ),
61
+ ];
62
 
63
  // Available modes
64
+ $ime_available_modes = [
65
+ 'php' => __( 'Imagick PHP module', 'imagemagick-engine' ),
66
+ 'cli' => __( 'ImageMagick command-line', 'imagemagick-engine' ),
67
+ ];
68
 
69
  // Available quality modes
70
+ $ime_available_quality_modes = [ 'quality', 'size', 'skip' ];
71
 
72
  // Current options
73
  $ime_options = null;
74
 
75
  // Keep track of attachment file & sizes between different filters
76
  $ime_image_sizes = null;
77
+ $ime_image_file = null;
78
 
79
 
80
  /*
81
  * Functions
82
  */
83
+ add_action( 'plugins_loaded', 'ime_init_early' );
84
+ add_action( 'init', 'ime_init' );
85
 
86
  /* Plugin setup (early) */
87
  function ime_init_early() {
88
+ load_plugin_textdomain( 'imagemagick-engine', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
89
 
90
+ if ( ime_active() ) {
91
+ add_filter( 'intermediate_image_sizes_advanced', 'ime_filter_image_sizes', 99, 1 );
92
+ add_filter( 'wp_read_image_metadata', 'ime_filter_read_image_metadata', 10, 3 );
93
+ add_filter( 'wp_generate_attachment_metadata', 'ime_filter_attachment_metadata', 10, 2 );
94
  }
95
  }
96
 
97
  /* Plugin setup */
98
  function ime_init() {
99
+ if ( is_admin() ) {
100
+ add_action( 'admin_menu', 'ime_admin_menu' );
101
+ add_filter( 'plugin_action_links', 'ime_filter_plugin_actions', 10, 2 );
102
+ add_filter( 'media_meta', 'ime_filter_media_meta', 10, 2 );
103
+
104
+ add_action( 'wp_ajax_ime_test_im_path', 'ime_ajax_test_im_path' );
105
+ add_action( 'wp_ajax_ime_process_image', 'ime_ajax_process_image' );
106
+ add_action( 'wp_ajax_ime_regeneration_get_images', 'ime_ajax_regeneration_get_images' );
107
 
108
+ wp_register_script( 'ime-admin', plugins_url( '/js/ime-admin.js', __FILE__ ), [ 'jquery', 'jquery-ui-progressbar' ], constant('IME_VERSION') );
 
 
 
 
109
  }
110
  }
111
 
112
  /* Are we enabled with valid mode? */
113
  function ime_active() {
114
+ return ime_get_option( 'enabled' ) && ime_mode_valid();
115
  }
116
 
117
  /* Check if mode is valid */
118
+ function ime_mode_valid( $mode = null ) {
119
+ if ( empty( $mode ) ) {
120
+ $mode = ime_get_option( 'mode' );
121
+ }
122
  $fn = 'ime_im_' . $mode . '_valid';
123
+ return ( ! empty( $mode ) && function_exists( $fn ) && call_user_func( $fn ) );
124
  }
125
 
126
  // Check version of a registered WordPress script
127
+ function ime_script_version_compare( $handle, $version, $compare = '>=' ) {
128
  global $wp_scripts;
129
+ if ( ! is_a( $wp_scripts, 'WP_Scripts' ) ) {
130
  $wp_scripts = new WP_Scripts();
131
+ }
132
 
133
+ $query = $wp_scripts->query( $handle, 'registered' );
134
+ if ( ! $query ) {
135
  return false;
136
+ }
137
 
138
+ return version_compare( $query->ver, $version, $compare );
139
  }
140
 
141
  // Get array of available image sizes
142
  function ime_available_image_sizes() {
143
  global $_wp_additional_image_sizes;
144
+ $sizes = [
145
+ 'thumbnail' => __( 'Thumbnail', 'imagemagick-engine' ),
146
+ 'medium' => __( 'Medium', 'imagemagick-engine' ),
147
+ 'medium_large' => __( 'Medium Large', 'imagemagick-engine' ),
148
+ 'large' => __( 'Large', 'imagemagick-engine' ),
149
+ ]; // Standard sizes
150
  if ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) ) {
151
+ foreach ( $_wp_additional_image_sizes as $name => $spec ) {
152
+ $sizes[ $name ] = $name;
153
+ }
154
  }
155
 
156
  return $sizes;
167
  global $ime_options;
168
 
169
  // Already setup?
170
+ if ( is_array( $ime_options ) ) {
171
  return;
172
+ }
173
 
174
+ $ime_options = get_option( 'ime_options' );
175
 
176
  // No stored options yet?
177
+ if ( ! is_array( $ime_options ) ) {
178
  global $ime_options_default;
179
  $ime_options = $ime_options_default;
180
  }
181
 
182
  // Do we need to upgrade options?
183
+ if ( ! array_key_exists( 'version', $ime_options )
184
+ || $ime_options['version'] < constant( 'IME_OPTION_VERSION' ) ) {
185
+
186
  /*
187
  * Future compatability code goes here!
188
  */
189
+
190
+ $ime_options['version'] = constant( 'IME_OPTION_VERSION' );
191
  ime_store_options();
192
  }
193
  }
198
 
199
  ime_setup_options();
200
 
201
+ $stored_options = get_option( 'ime_options' );
202
+
203
+ if ( $stored_options === false ) {
204
+ add_option( 'ime_options', $ime_options, null, false );
205
+ } else {
206
+ update_option( 'ime_options', $ime_options );
207
+ }
208
  }
209
 
210
  // Get plugin option
211
+ function ime_get_option( $option_name, $default = null ) {
212
  ime_setup_options();
213
+
214
  global $ime_options, $ime_options_default;
215
 
216
+ if ( is_array( $ime_options ) && array_key_exists( $option_name, $ime_options ) ) {
217
+ return $ime_options[ $option_name ];
218
+ }
219
 
220
+ if ( ! is_null( $default ) ) {
221
  return $default;
222
+ }
223
 
224
+ if ( is_array( $ime_options_default ) && array_key_exists( $option_name, $ime_options_default ) ) {
225
+ return $ime_options_default[ $option_name ];
226
+ }
227
 
228
  return null;
229
  }
230
 
231
  // Set plugin option
232
+ function ime_set_option( $option_name, $option_value, $store = false ) {
233
  ime_setup_options();
234
+
235
  global $ime_options;
236
 
237
+ $ime_options[ $option_name ] = $option_value;
238
 
239
+ if ( $store ) {
240
  ime_store_options();
241
+ }
242
  }
243
 
244
  // Get image quality setting for type
245
+ function ime_get_quality( $resize_mode = 'quality' ) {
246
+ $quality = ime_get_option( 'quality', '-1' );
247
+ if ( ! $quality ) {
248
  return -1;
249
+ }
250
+ if ( ! is_array( $quality ) ) {
251
  return $quality;
252
+ }
253
+ if ( isset( $quality[ $resize_mode ] ) ) {
254
+ return $quality[ $resize_mode ];
255
+ }
256
+
257
  return -1;
258
  }
259
 
260
  // Get resize mode for size
261
  function ime_get_resize_mode( $size ) {
262
+ $handle_sizes = ime_get_option( 'handle_sizes' );
263
+ if ( isset( $handle_sizes[ $size ] ) && is_string( $handle_sizes[ $size ] ) ) {
264
  return $handle_sizes[ $size ];
265
+ } else {
266
  return 'quality'; // default to quality
267
+ }
268
  }
269
 
270
 
281
  * The reason we do things this way is so we do not resize image twize (once
282
  * by WordPress using GD, and then again by us).
283
  */
284
+ function ime_filter_image_sizes( $sizes ) {
285
  global $ime_image_sizes;
286
 
287
+ $handle_sizes = ime_get_option( 'handle_sizes' );
288
+ foreach ( $handle_sizes as $s => $handle ) {
289
+ if ( ! $handle || $handle == 'skip' || ! array_key_exists( $s, $sizes ) ) {
290
  continue;
291
+ }
292
+ $ime_image_sizes[ $s ] = $sizes[ $s ];
293
+ unset( $sizes[ $s ] );
294
  }
295
  return $sizes;
296
  }
301
  * Function wp_generate_attachment_metadata calls wp_read_image_metadata which
302
  * gives us a hook to get the target filename.
303
  */
304
+ function ime_filter_read_image_metadata( $metadata, $file, $ignore ) {
305
  global $ime_image_file;
306
+
307
  $ime_image_file = $file;
308
 
309
  return $metadata;
316
  *
317
  * Parts of function copied from wp-includes/media.php:image_resize()
318
  */
319
+ function ime_filter_attachment_metadata( $metadata, $attachment_id ) {
320
  global $ime_image_sizes, $ime_image_file;
321
 
322
  // Any sizes we are interested in?
323
+ if ( empty( $ime_image_sizes ) ) {
324
  return $metadata;
325
+ }
326
 
327
  // Get size & image type of original image
328
+ $old_stats = @getimagesize( $ime_image_file );
329
+ if ( ! $old_stats ) {
330
  return $metadata;
331
+ }
332
 
333
  list($orig_w, $orig_h, $orig_type) = $old_stats;
334
 
337
  *
338
  * If image type is PNG or GIF keep it, otherwise make sure it is JPG
339
  */
340
+ $info = pathinfo( $ime_image_file );
341
+ $dir = $info['dirname'];
342
+ $ext = $info['extension'];
343
+ $namebase = basename( $ime_image_file, ".{$ext}" );
344
+ if ( $orig_type == IMAGETYPE_PNG || $orig_type == IMAGETYPE_GIF ) {
345
  $new_ext = $ext;
346
+ } else {
347
+ $new_ext = 'jpg';
348
+ }
349
 
350
  /*
351
  * Do the actual resize
352
  */
353
+ foreach ( $ime_image_sizes as $size => $size_data ) {
354
+ $width = $size_data['width'];
355
  $height = $size_data['height'];
356
 
357
  // ignore sizes equal to or larger than original size
358
+ if ( $orig_w <= $width && $orig_h <= $height ) {
359
  continue;
360
+ }
361
 
362
  $crop = $size_data['crop'];
363
+
364
+ $dims = image_resize_dimensions( $orig_w, $orig_h, $width, $height, $crop );
365
+ if ( ! $dims ) {
366
  continue;
367
+ }
368
  list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims;
369
 
370
+ $suffix = "{$dst_w}x{$dst_h}";
371
  $new_filename = "{$dir}/{$namebase}-{$suffix}.{$new_ext}";
372
 
373
  $resized = ime_im_resize( $ime_image_file, $new_filename, $dst_w, $dst_h, $crop, ime_get_resize_mode( $size ) );
374
+ if ( ! $resized ) {
375
  continue;
376
+ }
377
 
378
+ $metadata['sizes'][ $size ] = [
379
+ 'file' => basename( $new_filename ),
380
+ 'width' => $dst_w,
381
+ 'height' => $dst_h,
382
+ ];
383
 
384
+ if ( ! isset( $metadata['image-converter'] ) || ! is_array( $metadata['image-converter'] ) ) {
385
+ $metadata['image-converter'] = [];
386
+ }
387
+
388
+ $metadata['image-converter'][ $size ] = 'IME';
389
 
390
  // Set correct file permissions
391
+ $stat = stat( dirname( $new_filename ) );
392
  $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits
393
  @ chmod( $new_filename, $perms );
394
  }
399
 
400
  // Resize file by calling mode specific resize function
401
  function ime_im_resize( $old_file, $new_file, $width, $height, $crop, $resize_mode = 'quality' ) {
402
+ $mode = ime_get_option( 'mode' );
403
+ $fn = 'ime_im_' . $mode . '_valid';
404
+ if ( empty( $mode ) || ! function_exists( $fn ) || ! call_user_func( $fn ) ) {
405
  return false;
406
+ }
407
 
408
+ $fn = 'ime_im_' . $mode . '_resize';
409
  $success = ( function_exists( $fn ) && call_user_func( $fn, $old_file, $new_file, $width, $height, $crop, $resize_mode ) );
410
  do_action( 'ime_after_resize', $success, $old_file, $new_file, $width, $height, $crop, $resize_mode );
411
  return $success;
412
  }
413
 
414
  // Is this the filename of a jpeg?
415
+ function ime_im_filename_is_jpg( $filename ) {
416
+ $info = pathinfo( $filename );
417
+ $ext = $info['extension'];
418
+ return ( strcasecmp( $ext, 'jpg' ) == 0 ) || ( strcasecmp( $ext, 'jpeg' ) == 0 );
419
  }
420
 
421
  // Get file extenstion
422
+ function ime_im_get_filetype( $filename ) {
423
+ $info = pathinfo( $filename );
424
+ return strtolower( $info['extension'] );
425
  }
426
 
427
  /*
430
 
431
  // Does class exist?
432
  function ime_im_php_valid() {
433
+ return class_exists( 'Imagick' );
434
  }
435
 
436
  // Resize file using PHP Imagick class
437
  function ime_im_php_resize( $old_file, $new_file, $width, $height, $crop, $resize_mode = 'quality' ) {
438
  $im = new Imagick( $old_file );
439
+ if ( ! $im->valid() ) {
440
  return false;
441
+ }
442
 
443
  try {
444
+ $im->setImageFormat( ime_im_get_filetype( $old_file ) );
445
  $quality = ime_get_quality( $resize_mode );
446
  if ( is_numeric( $quality ) && $quality >= 0 && $quality <= 100 && ime_im_filename_is_jpg( $new_file ) ) {
447
  $im->setImageCompression( Imagick::COMPRESSION_JPEG );
448
  $im->setImageCompressionQuality( $quality );
449
  }
450
+
451
+ if ( $resize_mode == 'size' ) {
452
  $im->stripImage();
453
+ }
454
 
455
  if ( $crop ) {
456
  /*
460
  * Crop an area proportional to target $width and $height and
461
  * fall through to scaleImage() below.
462
  */
 
 
 
 
463
 
464
+ $geo = $im->getImageGeometry();
465
+ $orig_width = $geo['width'];
466
+ $orig_height = $geo['height'];
467
+
468
+ if ( ( $orig_width / $width ) < ( $orig_height / $height ) ) {
469
+ $crop_width = $orig_width;
470
  $crop_height = ceil( ( $height * $orig_width ) / $width );
471
+ $off_x = 0;
472
+ $off_y = ceil( ( $orig_height - $crop_height ) / 2 );
473
  } else {
474
+ $crop_width = ceil( ( $width * $orig_height ) / $height );
475
  $crop_height = $orig_height;
476
+ $off_x = ceil( ( $orig_width - $crop_width ) / 2 );
477
+ $off_y = 0;
478
  }
479
  $im->cropImage( $crop_width, $crop_height, $off_x, $off_y );
480
  }
481
+
482
  $im->scaleImage( $width, $height, true );
483
 
484
  $im->setImagePage( $width, $height, 0, 0 ); // to make sure canvas is correct
497
  // Do we have a valid ImageMagick executable set?
498
  function ime_im_cli_valid() {
499
  $cmd = ime_im_cli_command();
500
+ return !empty($cmd) && @is_executable($cmd);
501
  }
502
 
503
  // Test if we are allowed to exec executable!
504
  function ime_im_cli_check_executable($fullpath) {
505
+ if (!@is_executable($fullpath)) {
506
  return false;
507
+ }
508
 
509
+ @exec( '"' . $fullpath . '" --version', $output );
510
 
511
  ime_set_option( 'imagemagick_version', $output, true );
512
 
513
+ return count( $output ) > 0;
514
  }
515
 
516
  /*
518
  *
519
  * This won't work if there is open_basename restrictions.
520
  */
521
+ function ime_try_realpath( $path ) {
522
+ $realpath = @realpath( $path );
523
+ if ( $realpath ) {
524
  return $realpath;
525
+ } else {
526
  return $path;
527
+ }
528
  }
529
 
530
  // Check if path leads to ImageMagick executable
531
+ function ime_im_cli_check_command( $path, $executable = 'convert' ) {
532
+ $path = ime_try_realpath( $path );
533
 
534
  $cmd = $path . '/' . $executable;
535
+ if ( ime_im_cli_check_executable( $cmd ) ) {
536
  return $cmd;
537
+ }
538
 
539
  $cmd = $cmd . '.exe';
540
+ if ( ime_im_cli_check_executable( $cmd ) ) {
541
  return $cmd;
542
+ }
543
 
544
  return null;
545
  }
546
 
547
  // Try to find a valid ImageMagick executable
548
+ function ime_im_cli_find_command( $executable = 'convert' ) {
549
+ $possible_paths = [ '/usr/bin', '/usr/local/bin' ];
550
 
551
+ foreach ( $possible_paths as $path ) {
552
+ if ( ime_im_cli_check_command( $path, $executable ) ) {
553
  return $path;
554
+ }
555
  }
556
 
557
  return null;
558
  }
559
 
560
  // Get ImageMagick executable
561
+ function ime_im_cli_command( $executable = 'convert' ) {
562
+ $path = ime_get_option( 'cli_path' );
563
+ if ( ! empty( $path ) ) {
564
+ return ime_im_cli_check_command( $path, $executable );
565
+ }
566
 
567
+ $path = ime_im_cli_find_command( $executable );
568
+ if ( empty( $path ) ) {
569
  return null;
570
+ }
571
+ ime_set_option( 'cli_path', $path, true );
572
+ return ime_im_cli_check_command( $path, $executable );
573
  }
574
 
575
  // Check if we are running under Windows (which differs for character escape)
576
  function ime_is_windows() {
577
+ return ( constant( 'PHP_SHLIB_SUFFIX' ) == 'dll' );
578
  }
579
 
580
  // Resize using ImageMagick executable
581
  function ime_im_cli_resize( $old_file, $new_file, $width, $height, $crop, $resize_mode = 'quality' ) {
582
  $cmd = ime_im_cli_command();
583
+ if ( empty( $cmd ) ) {
584
  return false;
585
+ }
586
 
587
+ $old_file = addslashes( $old_file );
588
+ $new_file = addslashes( $new_file );
589
 
590
  $geometry = $width . 'x' . $height;
591
 
592
  // limits are 150mb and 128mb
593
  $cmd = "\"$cmd\" \"$old_file\" -limit memory 157286400 -limit map 134217728 -resize $geometry";
594
+ if ( $crop ) {
595
  // '^' is an escape character on Windows
596
+ $cmd .= ( ime_is_windows() ? '^^' : '^' ) . " -gravity center -extent $geometry";
597
+ } else {
598
+ $cmd .= '!'; // force these dimensions
599
+ }
600
 
601
  $quality = ime_get_quality( $resize_mode );
602
+ if ( is_numeric( $quality ) && $quality >= 0 && $quality <= 100 && ime_im_filename_is_jpg( $new_file ) ) {
603
+ $cmd .= ' -quality ' . intval( $quality );
604
+ }
605
 
606
+ if ( $resize_mode == 'size' ) {
607
  $cmd .= ' -strip';
608
+ }
609
 
610
+ $cmd .= ' "' . $new_file . '"';
611
+ exec( $cmd );
612
 
613
+ return file_exists( $new_file );
614
  }
615
 
616
 
620
 
621
  // Test if a path is correct for IM binary
622
  function ime_ajax_test_im_path() {
623
+ if ( ! current_user_can( 'manage_options' ) ) {
624
  die();
625
+ }
626
+ $r = ime_im_cli_check_command( $_REQUEST['cli_path'] );
627
+ echo empty( $r ) ? '0' : '1';
628
  die();
629
  }
630
 
631
  // Get list of attachments to regenerate
632
  function ime_ajax_regeneration_get_images() {
633
  global $wpdb;
634
+
635
+ if ( ! current_user_can( 'manage_options' ) ) {
636
+ wp_die( 'Sorry, but you do not have permissions to perform this action.' );
637
+ }
638
+
639
  // Query for the IDs only to reduce memory usage
640
  $images = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'image/%'" );
641
+
642
  // Generate the list of IDs
643
+ $ids = [];
644
+ foreach ( $images as $image ) {
645
  $ids[] = $image->ID;
646
+ }
647
  $ids = implode( ',', $ids );
648
+
649
+ die( $ids );
650
  }
651
 
652
  // Process single attachment ID
653
  function ime_ajax_process_image() {
654
  global $ime_image_sizes, $ime_image_file, $_wp_additional_image_sizes;
 
 
655
 
656
+ error_reporting( E_ERROR | E_WARNING );
657
+
658
+ if ( ! current_user_can( 'manage_options' ) || ! ime_mode_valid() ) {
659
+ die( '-1' );
660
+ }
661
 
662
+ if ( ! isset( $_REQUEST['id'] ) ) {
663
+ die( '-1' );
664
+ }
665
 
666
+ $id = intval( $_REQUEST['id'] );
667
+ if ( $id <= 0 ) {
668
+ die( '-1' );
669
+ }
670
 
671
  $temp_sizes = $_REQUEST['sizes'];
672
+ if ( empty( $temp_sizes ) ) {
673
+ die( '-1' );
674
+ }
675
+ $temp_sizes = explode( '|', $temp_sizes );
676
+ if ( count( $temp_sizes ) < 1 ) {
677
+ die( '-1' );
678
+ }
679
 
680
  $temp_sizes = apply_filters( 'intermediate_image_sizes', $temp_sizes );
681
 
682
  foreach ( $temp_sizes as $s ) {
683
+ $sizes[ $s ] = [
684
+ 'width' => '',
685
+ 'height' => '',
686
+ 'crop' => false,
687
+ ];
688
+ if ( isset( $_wp_additional_image_sizes[ $s ]['width'] ) ) {
689
+ $sizes[ $s ]['width'] = intval( $_wp_additional_image_sizes[ $s ]['width'] ); // For theme-added sizes
690
+ } else {
691
+ $sizes[ $s ]['width'] = get_option( "{$s}_size_w" ); // For default sizes set in options
692
+ }
693
+ if ( isset( $_wp_additional_image_sizes[ $s ]['height'] ) ) {
694
+ $sizes[ $s ]['height'] = intval( $_wp_additional_image_sizes[ $s ]['height'] ); // For theme-added sizes
695
+ } else {
696
+ $sizes[ $s ]['height'] = get_option( "{$s}_size_h" ); // For default sizes set in options
697
+ }
698
+ if ( isset( $_wp_additional_image_sizes[ $s ]['crop'] ) ) {
699
+ $sizes[ $s ]['crop'] = intval( $_wp_additional_image_sizes[ $s ]['crop'] ); // For theme-added sizes
700
+ } else {
701
+ $sizes[ $s ]['crop'] = get_option( "{$s}_crop" ); // For default sizes set in options
702
+ }
703
+ }
704
+
705
+ remove_filter( 'intermediate_image_sizes_advanced', 'ime_filter_image_sizes', 99, 1 );
706
  $sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes );
707
 
708
+ $force = isset( $_REQUEST['force'] ) && ! ! $_REQUEST['force'];
709
 
710
+ $ime_image_file = get_attached_file( $id );
711
 
712
+ if ( false === $ime_image_file || ! file_exists( $ime_image_file ) ) {
713
+ die( '-1' );
714
+ }
715
 
716
+ $metadata = wp_get_attachment_metadata( $id );
717
 
718
  // Do not re-encode IME images unless forced
719
+ if ( ! $force && isset( $metadata['image-converter'] ) && is_array( $metadata['image-converter'] ) ) {
720
  $converter = $metadata['image-converter'];
721
+
722
+ foreach ( $sizes as $s => $ignore ) {
723
+ if ( isset( $converter[ $s ] ) && $converter[ $s ] == 'IME' ) {
724
+ unset( $sizes[ $s ] );
725
+ }
726
+ }
727
+ if ( count( $sizes ) < 1 ) {
728
+ die( 1 );
729
  }
 
 
730
  }
731
 
732
  $ime_image_sizes = $sizes;
733
 
734
+ set_time_limit( 60 );
735
 
736
+ $new_meta = ime_filter_attachment_metadata( $metadata, $id );
737
+ wp_update_attachment_metadata( $id, $new_meta );
738
 
739
  /*
740
  * Normally the old file gets overwritten by the new one when
747
  */
748
 
749
  // No old sizes, nothing to check
750
+ if ( ! isset( $metadata['sizes'] ) || empty( $metadata['sizes'] ) ) {
751
+ die( '1' );
752
+ }
 
753
 
754
+ $dir = trailingslashit( dirname( $ime_image_file ) );
755
+
756
+ foreach ( $metadata['sizes'] as $size => $sizeinfo ) {
757
  $old_file = $sizeinfo['file'];
758
 
759
  // Does file exist in new meta?
760
  $exists = false;
761
+ foreach ( $new_meta['sizes'] as $ignore => $new_sizeinfo ) {
762
+ if ( $old_file != $new_sizeinfo['file'] ) {
763
  continue;
764
+ }
765
  $exists = true;
766
  break;
767
  }
768
+ if ( $exists ) {
769
  continue;
770
+ }
771
 
772
  // Old file did not exist in new meta. Delete it!
773
+ @ unlink( $dir . $old_file );
774
  }
775
+
776
+ die( '1' );
777
  }
778
 
779
 
783
 
784
  /* Add admin page */
785
  function ime_admin_menu() {
786
+ $ime_page = add_options_page( 'ImageMagick Engine', 'ImageMagick Engine', 'manage_options', 'imagemagick-engine', 'ime_option_page' );
787
 
788
+ $script_pages = [ $ime_page, 'media.php', 'media-new.php', 'media-upload.php', 'media-upload-popup', 'post.php', 'upload.php' ];
789
+ foreach ( $script_pages as $page ) {
790
+ add_action( 'admin_print_scripts-' . $page, 'ime_admin_print_scripts' );
791
+ add_action( 'admin_print_styles-' . $page, 'ime_admin_print_styles' );
792
  }
793
  }
794
 
795
  /* Enqueue admin page scripts */
796
  function ime_admin_print_scripts() {
797
+ wp_enqueue_script( 'ime-admin' );
798
+
799
+ $data = [
800
+ 'noimg' => __( 'You dont have any images to regenerate', 'imagemagick-engine' ),
801
+ 'done' => __( 'All done!', 'imagemagick-engine' ),
802
+ 'processed_fmt' => __( 'Processed %d images', 'imagemagick-engine' ),
803
+ 'failed' => '<strong>' . __( 'Failed to resize image!', 'imagemagick-engine' ) . '</strong>',
804
+ 'resized' => __( 'Resized using ImageMagick Engine', 'imagemagick-engine' ),
805
+ ];
806
+ wp_localize_script( 'ime-admin', 'ime_admin', $data );
807
  }
808
 
809
  /* Enqueue admin page style */
810
  function ime_admin_print_styles() {
811
+ wp_enqueue_style( 'ime-admin-style', plugins_url( '/css/ime-admin.css', __FILE__ ), [] );
812
  }
813
 
814
  /* Add settings to plugin action links */
815
+ function ime_filter_plugin_actions( $links, $file ) {
816
+ if ( $file == plugin_basename( __FILE__ ) ) {
817
+ $settings_link = '<a href="options-general.php?page=imagemagick-engine">'
818
+ . __( 'Settings', 'imagemagick-engine' ) . '</a>';
819
  array_unshift( $links, $settings_link ); // before other links
820
  }
821
 
825
  /*
826
  * Add admin information if attachment is converted using plugin
827
  */
828
+ function ime_filter_media_meta( $content, $post ) {
829
  global $wp_version;
830
 
831
+ if ( ! ime_mode_valid() ) {
832
  return $content;
833
+ }
834
 
835
+ if ( version_compare( $wp_version, '3.5.0', '>=' ) ) {
836
  // WordPress 3.5 and newer
837
+ if ( ! wp_image_editor_supports( [ 'mime_type' => $post->post_mime_type ] ) ) {
838
  return $content;
839
  }
840
  } else {
841
  // WordPress older than 3.5
842
+ if ( ! gd_edit_image_support( $post->post_mime_type ) ) {
843
  return $content;
844
  }
845
  }
846
 
847
+ $metadata = wp_get_attachment_metadata( $post->ID );
848
 
849
  $ime = false;
850
+ if ( is_array( $metadata ) && array_key_exists( 'image-converter', $metadata ) ) {
851
+ foreach ( $metadata['image-converter'] as $size => $converter ) {
852
+ if ( $converter != 'IME' ) {
853
  continue;
854
+ }
855
 
856
  $ime = true;
857
  break;
859
  }
860
 
861
  $content .= '</p><p>';
862
+ if ( $ime ) {
863
+ $message = ' <div class="ime-media-message" id="ime-message-' . $post->ID . '">' . __( 'Resized using ImageMagick Engine', 'imagemagick-engine' ) . '</div>';
864
+ $resize = __( 'Resize image', 'imagemagick-engine' );
865
+ $force = '1';
866
  } else {
867
  $message = '<div class="ime-media-message" id="ime-message-' . $post->ID . '" style="display: none;"></div>';
868
+ $resize = __( 'Resize using ImageMagick Engine', 'imagemagick-engine' );
869
+ $force = '0';
870
  }
871
+ $handle_sizes = ime_get_option( 'handle_sizes' );
872
+ $sizes = [];
873
+ foreach ( $handle_sizes as $s => $h ) {
874
+ if ( ! $h ) {
875
  continue;
876
+ }
877
  $sizes[] = $s;
878
  }
879
+ $sizes = implode( '|', $sizes );
880
  $resize_call = 'imeRegenMediaImage(' . $post->ID . ', \'' . $sizes . '\', ' . $force . '); return false;';
881
+ $content .= '<a href="#" id="ime-regen-link-' . $post->ID . '" class="button ime-regen-button" onclick="' . $resize_call . '">' . $resize . '</a> ' . $message . ' <div id="ime-spinner-' . $post->ID . '" class="ime-spinner"><img src="' . admin_url( 'images/wpspin_light.gif' ) . '" /></div>';
882
+
883
  return $content;
884
  }
885
 
886
  // Url to admin images
887
  function ime_option_admin_images_url() {
888
+ return get_bloginfo( 'wpurl' ) . '/wp-admin/images/';
889
  }
890
 
891
  // Url to status icon
892
+ function ime_option_status_icon( $yes = true ) {
893
+ return ime_option_admin_images_url() . ( $yes ? 'yes' : 'no' ) . '.png';
894
  }
895
 
896
  // Display, or not
897
+ function ime_option_display( $display = true, $echo = true ) {
898
+ if ( $display ) {
899
  return '';
900
+ }
901
  $s = ' style="display: none" ';
902
+ if ( $echo ) {
903
  echo $s;
904
+ }
905
  return $s;
906
  }
907
 
909
  function ime_option_page() {
910
  global $ime_available_modes, $ime_available_quality_modes;
911
 
912
+ if ( ! current_user_can( 'manage_options' ) ) {
913
+ wp_die( 'Sorry, but you do not have permissions to change settings.' );
914
+ }
915
 
916
  /* Make sure post was from this page */
917
+ if ( count( $_POST ) > 0 ) {
918
+ check_admin_referer( 'ime-options' );
919
+ }
920
 
921
  $sizes = ime_available_image_sizes();
922
 
923
+ if ( isset( $_POST['regenerate-images'] ) ) {
924
+ ime_show_regenerate_images( array_keys( $sizes ) );
925
  return;
926
  }
927
 
928
  /* Should we update settings? */
929
+ if ( isset( $_POST['update_settings'] ) ) {
930
+ $new_enabled = isset( $_POST['enabled'] ) && ! ! $_POST['enabled'];
931
+ ime_set_option( 'enabled', $new_enabled );
932
+ if ( isset( $_POST['mode'] ) && array_key_exists( $_POST['mode'], $ime_available_modes ) ) {
933
+ ime_set_option( 'mode', $_POST['mode'] );
 
 
 
 
 
 
 
 
 
934
  }
935
+ if ( isset( $_POST['cli_path'] ) ) {
936
+ ime_set_option( 'cli_path', ime_try_realpath( trim( $_POST['cli_path'] ) ) );
937
+ }
938
+
939
+ $new_quality = [
940
+ 'quality' => -1,
941
+ 'size' => 70,
942
+ ];
943
+ if ( isset( $_POST['quality-quality'] ) ) {
944
+ if ( is_numeric( $_POST['quality-quality'] ) ) {
945
+ $new_quality['quality'] = min( 100, max( 0, intval( $_POST['quality-quality'] ) ) );
946
+ } elseif ( empty( $_POST['quality-quality'] ) ) {
947
+ $new_quality['quality'] = -1;
948
+ }
949
+ }
950
+ if ( isset( $_POST['quality-size'] ) ) {
951
+ if ( is_numeric( $_POST['quality-size'] ) ) {
952
+ $new_quality['quality-size'] = min( 100, max( 0, intval( $_POST['quality-size'] ) ) );
953
+ } elseif ( empty( $_POST['quality-size'] ) ) {
954
+ $new_quality['quality-size'] = -1;
955
+ }
956
  }
957
  ime_set_option( 'quality', $new_quality );
958
 
959
+ $new_handle_sizes = [];
960
+ foreach ( $sizes as $s => $name ) {
961
  $new_mode = isset( $_POST[ 'handle-mode-' . $s ] ) ? $_POST[ 'handle-mode-' . $s ] : 'skip';
962
+ if ( in_array( $new_mode, $ime_available_quality_modes ) ) {
963
  $mode = $new_mode;
964
+ } else {
965
  $mode = 'quality';
966
+ }
967
 
968
  $new_handle_sizes[ $s ] = $mode;
969
  }
970
  ime_set_option( 'handle_sizes', $new_handle_sizes );
971
 
972
  ime_store_options();
973
+
974
  echo '<div id="message" class="updated fade"><p>'
975
+ . __( 'Settings updated', 'imagemagick-engine' )
976
  . '</p></div>';
977
  }
978
 
979
  $modes_valid = $ime_available_modes;
980
+ $any_valid = false;
981
+ foreach ( $modes_valid as $m => $ignore ) {
982
+ $modes_valid[ $m ] = ime_mode_valid( $m );
983
+ if ( $modes_valid[ $m ] ) {
984
  $any_valid = true;
985
+ }
986
  }
987
 
988
+ $current_mode = ime_get_option( 'mode' );
989
+ if ( ! isset( $modes_valid[ $current_mode ] ) || ! $modes_valid[ $current_mode ] ) {
990
  $current_mode = null;
991
+ }
992
+ if ( is_null( $current_mode ) && $any_valid ) {
993
+ foreach ( $modes_valid as $m => $valid ) {
994
+ if ( $valid ) {
995
  $current_mode = $m;
996
  break;
997
  }
998
  }
999
  }
1000
 
1001
+ $enabled = ime_get_option( 'enabled' ) && $current_mode;
1002
+
1003
+ $cli_path = ime_get_option( 'cli_path' );
1004
+ if ( is_null( $cli_path ) ) {
1005
  $cli_path = ime_im_cli_command();
1006
+ }
1007
+ $cli_path_ok = ime_im_cli_check_command( $cli_path );
1008
 
1009
+ $quality = ime_get_option( 'quality' );
1010
  if ( ! is_array( $quality ) ) {
1011
+ $n = [
1012
+ 'quality' => -1,
1013
+ 'size' => 70,
1014
+ ];
1015
+ if ( is_numeric( $quality ) && $quality > 0 ) {
1016
+ $n['quality'] = $quality;
1017
+ }
1018
  $quality = $n;
1019
  }
1020
 
1021
+ $handle_sizes = ime_get_option( 'handle_sizes' );
1022
 
1023
+ if ( ! $any_valid ) {
1024
  echo '<div id="warning" class="error"><p>'
1025
+ . sprintf( __( 'No valid ImageMagick mode found! Please check %1$sFAQ%2$s for installation instructions.', 'imagemagick-engine' ), '<a href="http://wp.orangelab.se/imagemagick-engine/documentation#installation">', '</a>' )
1026
  . '</p></div>';
1027
+ } elseif ( ! $enabled ) {
1028
  echo '<div id="warning" class="error"><p>'
1029
+ . __( 'ImageMagick Engine is not enabled.', 'imagemagick-engine' )
1030
  . '</p></div>';
1031
+ }
1032
+ ?>
1033
  <div class="wrap">
1034
+ <div id="regen-message" class="hidden updated fade"></div>
1035
+ <h2><?php _e( 'ImageMagick Engine Settings', 'imagemagick-engine' ); ?></h2>
1036
+ <div id="ime-regeneration" title="<?php _e( 'Regenerating images', 'imagemagick-engine' ); ?>...">
1037
+ <noscript><p><em><?php _e( 'You must enable Javascript in order to proceed!', 'imagemagick-engine' ); ?></em></p></noscript>
1038
+ <p><strong><?php _e( 'Regenerating images', 'imagemagick-engine' ); ?>...</strong></p>
1039
+ <div id="ime-regenbar">
1040
+ <div id="ime-regenbar-percent"></div>
1041
+ </div>
1042
  </div>
1043
+ <form action="options-general.php?page=imagemagick-engine" method="post" name="update_options">
1044
+ <?php wp_nonce_field( 'ime-options' ); ?>
1045
+ <div id="poststuff" class="metabox-holder has-right-sidebar">
1046
+ <div class="inner-sidebar">
1047
+ <div class="meta-box-sortables ui-sortable">
 
1048
  <div id="regenerate-images-metabox" class="postbox">
1049
+ <h3 class="hndle"><span><?php _e( 'Regenerate Images', 'imagemagick-engine' ); ?></span></h3>
1050
+ <div class="inside">
1051
+ <div class="submitbox">
1052
+ <table border=0>
1053
  <tr>
1054
+ <td scope="row" valign="top" style="padding-right: 20px;"><?php _e( 'Sizes', 'imagemagick-engine' ); ?>:</td>
1055
+ <td>
1056
+ <?php
1057
+ foreach ( $sizes as $s => $name ) {
1058
+ echo '<input type="checkbox" name="regen-size-' . $s . '" value="1" ' . ( ( isset( $handle_sizes[ $s ] ) && $handle_sizes[ $s ] != 'skip' && $handle_sizes[ $s ] != false ) ? ' checked="checked" ' : '' ) . ' /> ' . $name . '<br />';
1059
+ }
1060
+ ?>
1061
+ </td>
1062
+ </tr>
1063
+ </table>
1064
+ <p><?php _e( 'ImageMagick images too', 'imagemagick-engine' ); ?>:
1065
+ <input type="checkbox" name="force" id="force" value="1" /></p>
1066
+ <?php
1067
+ if ( ! ime_active() ) {
1068
+ echo '<p class="howto">' . __( 'Resize will use standard WordPress functions.', 'imagemagick-engine' ) . '</p>';
1069
+ }
1070
+ ?>
1071
+ <p><input class="button-primary" type="button" id="regenerate-images" value="<?php _e( 'Regenerate', 'imagemagick-engine' ); ?>" /></p>
1072
+ <p class="description"><?php _e( '(this can take a long time)', 'imagemagick-engine' ); ?></p>
1073
+ </div>
1074
+ </div>
1075
+ </div>
1076
+ </div>
1077
  </div>
1078
+ <div id="post-body">
1079
+ <div id="post-body-content">
1080
+ <div id="ime-settings" class="postbox">
1081
+ <h3 class="hndle"><span><?php _e( 'Settings', 'imagemagick-engine' ); ?></span></h3>
 
 
 
1082
  <div class="inside">
1083
+ <table class="form-table">
1084
+ <tr>
1085
+ <th scope="row" valign="top"><?php _e( 'Enable enhanced image engine', 'imagemagick-engine' ); ?>:</th>
1086
+ <td>
1087
+ <input type="checkbox" id="enabled" name="enabled" value="1"
1088
+ <?php
1089
+ echo $enabled ? ' CHECKED ' : '';
1090
+ echo $any_valid ? '' : ' disabled=disabled ';
1091
+ ?>
1092
+ />
1093
+ </td>
1094
+ </tr>
1095
+ <tr>
1096
+ <th scope="row" valign="top"><?php _e( 'Image engine', 'imagemagick-engine' ); ?>:</th>
1097
+ <td>
1098
  <select id="ime-select-mode" name="mode">
1099
+ <?php
1100
+ foreach ( $modes_valid as $m => $valid ) {
1101
+ echo '<option value="' . $m . '"';
1102
+ if ( $m == $current_mode ) {
1103
+ echo ' selected=selected ';
1104
+ }
1105
+ echo '>' . $ime_available_modes[ $m ] . '</option>';
1106
+ }
1107
+ ?>
1108
  </select>
1109
+ </td>
1110
+ </tr>
1111
+ <tr id="ime-row-php">
1112
+ <th scope="row" valign="top"><?php _e( 'Imagick PHP module', 'imagemagick-engine' ); ?>:</th>
1113
+ <td>
1114
+ <img src="<?php echo ime_option_status_icon( $modes_valid['php'] ); ?>" />
1115
+ <?php echo $modes_valid['php'] ? __( 'Imagick PHP module found', 'imagemagick-engine' ) : __( 'Imagick PHP module not found', 'imagemagick-engine' ); ?>
1116
+ </td>
1117
+ </tr>
1118
+ <tr id="ime-row-cli">
1119
+ <th scope="row" valign="top"><?php _e( 'ImageMagick path', 'imagemagick-engine' ); ?>:</th>
1120
+ <td>
1121
+ <img id="cli_path_yes" class="cli_path_icon" src="<?php echo ime_option_status_icon( true ); ?>" alt="" <?php ime_option_display( $cli_path_ok ); ?> />
1122
+ <img id="cli_path_no" class="cli_path_icon" src="<?php echo ime_option_status_icon( false ); ?>" alt="<?php _e( 'Command not found', 'qp-qie' ); ?>" <?php ime_option_display( ! $cli_path_ok ); ?> />
1123
+ <img id="cli_path_progress" src="<?php echo ime_option_admin_images_url(); ?>wpspin_light.gif" alt="<?php _e( 'Testing command...', 'qp-qie' ); ?>" <?php ime_option_display( false ); ?> />
1124
+ <input id="cli_path" type="text" name="cli_path" size="<?php echo max( 30, strlen( $cli_path ) + 5 ); ?>" value="<?php echo $cli_path; ?>" />
1125
+ <input type="button" name="ime_cli_path_test" id="ime_cli_path_test" value="<?php _e( 'Test path', 'imagemagick-engine' ); ?>" class="button-secondary" />
1126
+ <span <?php ime_option_display( $cli_path_ok ); ?>><br><br><?php echo ime_get_option( 'imagemagick_version' )[0]; ?></span>
1127
+ </td>
1128
+ </tr>
1129
+ <tr>
1130
+ <th scope="row" valign="top"><?php _e( 'ImageMagick quality', 'imagemagick-engine' ); ?>:</th>
1131
+ <td>
1132
+ <p><input id="quality-quality" type="text" name="quality-quality" size="3" value="<?php echo ( ( isset( $quality['quality'] ) && $quality['quality'] > 0 ) ? $quality['quality'] : '' ); ?>" /> <?php _e( 'Optimize for quality', 'imagemagick-engine' ); ?></p>
1133
+ <p><input id="quality-size" type="text" name="quality-size" size="3" value="<?php echo ( ( isset( $quality['size'] ) && $quality['size'] > 0 ) ? $quality['size'] : '' ); ?>" /> <?php _e( 'Optimize for size', 'imagemagick-engine' ); ?></p>
1134
  <p class="ime-description"><?php _e( 'Set to 0-100. Higher value gives better image quality but larger file size. Leave empty for default value, computed dynamically.', 'imagemagick-engine' ); ?></p>
1135
+ </td>
1136
+ </tr>
1137
+ <tr>
1138
+ <td colspan="2" class="ime-handle-table-wrapper">
1139
  <table border='0' class="ime-handle-table" id="ime-handle-table">
1140
+ <tr>
1141
+ <th scope="row" class="ime-headline" valign="top"><?php _e( 'Optimize for', 'imagemagick-engine' ); ?></th>
1142
+ <td class="ime-headline ime-fixed-width"><?php _e( 'Quality', 'imagemagick-engine' ); ?></td>
1143
+ <td class="ime-headline ime-fixed-width"><?php _e( 'Size', 'imagemagick-engine' ); ?></td>
1144
+ <td class="ime-headline"><?php _e( 'None (use WP instead)', 'imagemagick-engine' ); ?></td>
1145
+ </tr>
1146
+ <?php
1147
+ foreach ( $sizes as $s => $name ) {
1148
+ // fixup for old (pre 1.5.0) options
1149
+ if ( ! isset( $handle_sizes[ $s ] ) || ! $handle_sizes[ $s ] ) {
1150
+ $handle_sizes[ $s ] = 'skip';
1151
+ } elseif ( $handle_sizes[ $s ] === true ) {
1152
+ $handle_sizes[ $s ] = 'quality';
1153
+ }
1154
+ ?>
1155
+ <tr>
1156
+ <th scope="row" valign="top"><?php echo $name; ?></th>
1157
+ <td class="ime-fixed-width">
1158
+ <input type="radio" name="handle-mode-<?php echo $s; ?>" value="quality" <?php checked( 'quality', $handle_sizes[ $s ] ); ?> />
1159
+ </td>
1160
+ <td class="ime-fixed-width">
1161
+ <input type="radio" name="handle-mode-<?php echo $s; ?>" value="size" <?php checked( 'size', $handle_sizes[ $s ] ); ?> />
1162
+ </td>
1163
+ <td>
1164
+ <input type="radio" name="handle-mode-<?php echo $s; ?>" value="skip" <?php checked( 'skip', $handle_sizes[ $s ] ); ?> />
1165
+ </td>
1166
+ </tr>
1167
+ <?php
1168
+ }
1169
+ ?>
1170
+ </table>
1171
+ </td>
1172
+ </tr>
1173
+ <tr>
1174
+ <td>
1175
+ <input class="button-primary" type="submit" name="update_settings" value="<?php _e( 'Save Changes', 'imagemagick-engine' ); ?>" />
1176
+ </td>
1177
+ </tr>
1178
  </table>
 
 
 
 
 
 
 
 
1179
  </div>
1180
+ </div>
1181
+ </div>
1182
+ </div>
1183
+ </form>
1184
  </div>
1185
+ <?php
1186
  }
1187
  ?>
js/ime-admin.js CHANGED
@@ -1,151 +1,156 @@
1
  //Variables
2
- var rt_images = "";
3
  var rt_total = 1;
4
  var rt_count = 1;
5
  var rt_force = 0;
6
  var rt_precision = 0;
7
- var rt_sizes = "";
8
 
9
  // Ajax test IM path
10
- function imeTestPath () {
11
- jQuery('.cli_path_icon').hide();
12
- jQuery('#cli_path_progress').show();
13
- jQuery.get(ajaxurl, {
14
- action: "ime_test_im_path",
15
- cli_path: jQuery('#cli_path').val()
16
- }, function(data) {
17
- jQuery('#cli_path_progress').hide();
18
- r = parseInt(data);
19
- if (r > 0) {
20
- jQuery('#cli_path_yes').show();
21
- jQuery('#cli_path_no').hide();
22
  } else {
23
- jQuery('#cli_path_yes').hide();
24
- jQuery('#cli_path_no').show();
25
  }
26
- });
27
  }
28
 
29
  function imeStartResize() {
30
- rt_sizes = "";
31
- rt_force = 0;
32
-
33
- jQuery('#regenerate-images-metabox input').each(function(){
34
- var i = jQuery(this);
35
- var name = i.attr('name');
36
-
37
- if(i.is(':checked') && name && name.substring(0,11) == "regen-size-") {
38
- rt_sizes = rt_sizes + name.substring(11) + "|";
39
  }
40
- });
41
-
42
- if (jQuery('#force').is(':checked'))
43
- rt_force = 1;
44
-
45
- if (rt_total > 20000)
46
- rt_precision = 3;
47
- else if (rt_total > 2000)
48
- rt_precision = 2;
49
- else if (rt_total > 200)
50
- rt_precision = 1;
51
- else
52
- rt_precision = 0;
53
-
54
- var rt_percent = 0;
55
-
56
- rt_count = 1;
57
- jQuery("#ime-regenbar").progressbar();
58
- jQuery("#ime-regenbar-percent").html( rt_percent.toFixed(rt_precision) + " %" );
59
- jQuery('#ime-regeneration').addClass( 'working' );
60
-
61
- imeRegenImages( rt_images.shift() );
 
 
62
  }
63
 
64
  //Regeneration of progressbar
65
  function imeRegenImages( id ) {
66
- jQuery.post(ajaxurl, { action: "ime_process_image", id: id, sizes: rt_sizes, force: rt_force }, function(data) {
67
- var n = parseInt(data, 10);
68
- if (isNaN(n)) {
69
- alert(data);
70
  }
71
 
72
  // todo: test and handle negative return
73
 
74
  if ( rt_images.length <= 0 ) {
75
- jQuery('#regen-message').removeClass('hidden').html("<p><strong>" + ime_admin.done + "</strong> " + ime_admin.processed_fmt.replace('%d', rt_total) + ".</p>");
76
- jQuery('#ime-regeneration').removeClass('working');
77
- jQuery("#ime-regenbar").progressbar( "value", 0 );
78
- return;
79
  }
80
 
81
  var next_id = rt_images.shift();
82
  var rt_percent = ( rt_count / rt_total ) * 100;
83
- jQuery("#ime-regenbar").progressbar( "value", rt_percent );
84
- jQuery("#ime-regenbar-percent").html( rt_percent.toFixed(rt_precision) + " %" );
85
  rt_count = rt_count + 1;
86
 
87
  // tail recursion
88
- imeRegenImages(next_id);
89
- });
90
  }
91
 
92
  // Regen single image on media pages
93
  function imeRegenMediaImage( id, sizes, force ) {
94
- var link = jQuery('#ime-regen-link-' + id);
95
 
96
- if (link.hasClass('disabled'))
97
- return false;
 
98
 
99
- link.addClass('disabled');
100
 
101
- var spinner = jQuery('#ime-spinner-' + id).children('img');
102
- spinner.show();
103
 
104
- var message = jQuery('#ime-message-' + id).show();
105
- jQuery.post(ajaxurl, { action: "ime_process_image", id: id, sizes: sizes, force: force }, function(data) {
106
  spinner.hide();
107
- link.removeClass('disabled');
108
 
109
- var n = parseInt(data, 10);
110
- if (isNaN(n) || n < 0) {
111
- message.html(ime_admin.failed);
112
- if (isNaN(n))
113
- alert(data);
 
114
  } else {
115
- message.html(ime_admin.resized);
116
  }
117
- });
118
  }
119
 
120
  function imeUpdateMode() {
121
- jQuery("#ime-select-mode option").each(function(i,e) {
122
- var o = jQuery(this);
123
  var mode = o.val();
124
- if (o.is(':selected'))
125
- jQuery('#ime-row-' + mode).show();
126
- else
127
- jQuery('#ime-row-' + mode).hide();
128
- });
 
129
  }
130
 
131
- jQuery(document).ready(function($) {
132
- jQuery('#ime_cli_path_test').click(imeTestPath);
133
-
134
- imeUpdateMode();
135
- jQuery('#ime-select-mode').change(imeUpdateMode);
136
-
137
- $('#regenerate-images').click(function(){
138
- $('#regenerate-images-metabox img.ajax-feedback').show();
139
- $.post(ajaxurl, { action: "ime_regeneration_get_images" }, function(data) {
140
- jQuery('#regen-message').addClass('hidden');
141
- rt_images = data.split(",");
142
- rt_total = rt_images.length;
143
-
144
- if(rt_total > 0) {
145
- imeStartResize();
146
- } else {
147
- alert(ime_admin.noimg);
148
- }
149
- });
150
- });
151
- });
1
  //Variables
2
+ var rt_images = '';
3
  var rt_total = 1;
4
  var rt_count = 1;
5
  var rt_force = 0;
6
  var rt_precision = 0;
7
+ var rt_sizes = '';
8
 
9
  // Ajax test IM path
10
+ function imeTestPath() {
11
+ jQuery( '.cli_path_icon' ).hide();
12
+ jQuery( '#cli_path_progress' ).show();
13
+ jQuery.get( ajaxurl, {
14
+ action: 'ime_test_im_path',
15
+ cli_path: jQuery( '#cli_path' ).val()
16
+ }, function( data ) {
17
+ jQuery( '#cli_path_progress' ).hide();
18
+ r = parseInt( data );
19
+ if ( r > 0 ) {
20
+ jQuery( '#cli_path_yes' ).show();
21
+ jQuery( '#cli_path_no' ).hide();
22
  } else {
23
+ jQuery( '#cli_path_yes' ).hide();
24
+ jQuery( '#cli_path_no' ).show();
25
  }
26
+ } );
27
  }
28
 
29
  function imeStartResize() {
30
+ rt_sizes = '';
31
+ rt_force = 0;
32
+
33
+ jQuery( '#regenerate-images-metabox input' ).each( function() {
34
+ var i = jQuery( this );
35
+ var name = i.attr( 'name' );
36
+
37
+ if ( i.is( ':checked' ) && name && 'regen-size-' == name.substring( 0, 11 ) ) {
38
+ rt_sizes = rt_sizes + name.substring( 11 ) + '|';
39
  }
40
+ } );
41
+
42
+ if ( jQuery( '#force' ).is( ':checked' ) ) {
43
+ rt_force = 1;
44
+ }
45
+
46
+ if ( rt_total > 20000 ) {
47
+ rt_precision = 3;
48
+ } else if ( rt_total > 2000 ) {
49
+ rt_precision = 2;
50
+ } else if ( rt_total > 200 ) {
51
+ rt_precision = 1;
52
+ } else {
53
+ rt_precision = 0;
54
+ }
55
+
56
+ var rt_percent = 0;
57
+
58
+ rt_count = 1;
59
+ jQuery( '#ime-regenbar' ).progressbar();
60
+ jQuery( '#ime-regenbar-percent' ).html( rt_percent.toFixed( rt_precision ) + ' %' );
61
+ jQuery( '#ime-regeneration' ).addClass( 'working' );
62
+
63
+ imeRegenImages( rt_images.shift() );
64
  }
65
 
66
  //Regeneration of progressbar
67
  function imeRegenImages( id ) {
68
+ jQuery.post( ajaxurl, { action: 'ime_process_image', id: id, sizes: rt_sizes, force: rt_force }, function( data ) {
69
+ var n = parseInt( data, 10 );
70
+ if ( isNaN( n ) ) {
71
+ alert( data );
72
  }
73
 
74
  // todo: test and handle negative return
75
 
76
  if ( rt_images.length <= 0 ) {
77
+ jQuery( '#regen-message' ).removeClass( 'hidden' ).html( '<p><strong>' + ime_admin.done + '</strong> ' + ime_admin.processed_fmt.replace( '%d', rt_total ) + '.</p>' );
78
+ jQuery( '#ime-regeneration' ).removeClass( 'working' );
79
+ jQuery( '#ime-regenbar' ).progressbar( 'value', 0 );
80
+ return;
81
  }
82
 
83
  var next_id = rt_images.shift();
84
  var rt_percent = ( rt_count / rt_total ) * 100;
85
+ jQuery( '#ime-regenbar' ).progressbar( 'value', rt_percent );
86
+ jQuery( '#ime-regenbar-percent' ).html( rt_percent.toFixed( rt_precision ) + ' %' );
87
  rt_count = rt_count + 1;
88
 
89
  // tail recursion
90
+ imeRegenImages( next_id );
91
+ } );
92
  }
93
 
94
  // Regen single image on media pages
95
  function imeRegenMediaImage( id, sizes, force ) {
96
+ var link = jQuery( '#ime-regen-link-' + id );
97
 
98
+ if ( link.hasClass( 'disabled' ) ) {
99
+ return false;
100
+ }
101
 
102
+ link.addClass( 'disabled' );
103
 
104
+ var spinner = jQuery( '#ime-spinner-' + id ).children( 'img' );
105
+ spinner.show();
106
 
107
+ var message = jQuery( '#ime-message-' + id ).show();
108
+ jQuery.post( ajaxurl, { action: 'ime_process_image', id: id, sizes: sizes, force: force }, function( data ) {
109
  spinner.hide();
110
+ link.removeClass( 'disabled' );
111
 
112
+ var n = parseInt( data, 10 );
113
+ if ( isNaN( n ) || n < 0 ) {
114
+ message.html( ime_admin.failed );
115
+ if ( isNaN( n ) ) {
116
+ alert( data );
117
+ }
118
  } else {
119
+ message.html( ime_admin.resized );
120
  }
121
+ } );
122
  }
123
 
124
  function imeUpdateMode() {
125
+ jQuery( '#ime-select-mode option' ).each( function( i, e ) {
126
+ var o = jQuery( this );
127
  var mode = o.val();
128
+ if ( o.is( ':selected' ) ) {
129
+ jQuery( '#ime-row-' + mode ).show();
130
+ } else {
131
+ jQuery( '#ime-row-' + mode ).hide();
132
+ }
133
+ } );
134
  }
135
 
136
+ jQuery( document ).ready( function( $ ) {
137
+ jQuery( '#ime_cli_path_test' ).click( imeTestPath );
138
+
139
+ imeUpdateMode();
140
+ jQuery( '#ime-select-mode' ).change( imeUpdateMode );
141
+
142
+ $( '#regenerate-images' ).click( function() {
143
+ $( '#regenerate-images-metabox img.ajax-feedback' ).show();
144
+ $.post( ajaxurl, { action: 'ime_regeneration_get_images' }, function( data ) {
145
+ jQuery( '#regen-message' ).addClass( 'hidden' );
146
+ rt_images = data.split( ',' );
147
+ rt_total = rt_images.length;
148
+
149
+ if ( rt_total > 0 ) {
150
+ imeStartResize();
151
+ } else {
152
+ alert( ime_admin.noimg );
153
+ }
154
+ } );
155
+ } );
156
+ } );
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: rickardw, orangelab
3
  Tags: image, images, picture, imagemagick, gd
4
  Requires at least: 3.0
5
- Tested up to: 5.3.2
6
- Stable tag: 1.6.2
7
 
8
  Improve the quality of re-sized images by replacing standard GD library with ImageMagick.
9
 
@@ -74,6 +74,10 @@ You'll probably have problems with various other plugins too unless you fix this
74
 
75
  == Changelog ==
76
 
 
 
 
 
77
  = 1.6.2 =
78
  * Added medium_large image size by default
79
  * Display version of ImageMagick CLI (thanks @marcissimus)
@@ -172,3 +176,7 @@ You'll probably have problems with various other plugins too unless you fix this
172
 
173
  = 1.2.0 =
174
  Fixes plugin jQuery UI script incompatibility for WordPress 3.1
 
 
 
 
2
  Contributors: rickardw, orangelab
3
  Tags: image, images, picture, imagemagick, gd
4
  Requires at least: 3.0
5
+ Tested up to: 5.4.1
6
+ Stable tag: 1.6.3
7
 
8
  Improve the quality of re-sized images by replacing standard GD library with ImageMagick.
9
 
74
 
75
  == Changelog ==
76
 
77
+ = 1.6.3 =
78
+ * Clean up code and constant for version (thanks @paulschreiber)
79
+ * Disable warning for is_executable if open_basedir active
80
+
81
  = 1.6.2 =
82
  * Added medium_large image size by default
83
  * Display version of ImageMagick CLI (thanks @marcissimus)
176
 
177
  = 1.2.0 =
178
  Fixes plugin jQuery UI script incompatibility for WordPress 3.1
179
+
180
+ == Contribute ==
181
+
182
+ Code repo available on https://github.com/orangelabweb/imagemagick-engine/