Imsanity - Version 2.7.0

Version Description

  • changed: bulk resizer will resize all images with no limits, use list mode for selective resizing
  • added: see current dimensions and resize individual images in Media Library list mode
  • added: imsanity_disable_convert filter to bypass BMP/PNG to JPG conversion options conditionally
  • added: imsanity_skip_image filter to bypass resizing programmatically
  • added: ability to remove pre-scaled original image backup (in bulk or selectively)
  • changed: PNG images will not be converted if transparency is found
  • fixed: BMP files not converted when server uses image/x-ms-bmp as mime identifier
  • removed: Deep Scan option is the default behavior now, no need for configuration
Download this release

Release Info

Developer nosilver4u
Plugin Icon 128x128 Imsanity
Version 2.7.0
Comparing to
See all releases

Code changes from version 2.6.0 to 2.7.0

Files changed (9) hide show
  1. .travis.yml +3 -2
  2. ajax.php +52 -2
  3. changelog.txt +13 -0
  4. imsanity.php +26 -8
  5. libs/utils.php +147 -11
  6. media.php +130 -0
  7. readme.txt +42 -82
  8. scripts/imsanity.js +117 -76
  9. settings.php +204 -117
.travis.yml CHANGED
@@ -1,4 +1,5 @@
1
- sudo: false
 
2
 
3
  language: php
4
 
@@ -12,7 +13,7 @@ branches:
12
  - master
13
 
14
  php:
15
- - 7.3
16
 
17
  env:
18
  - WP_VERSION=latest WP_MULTISITE=0
1
+ os: linux
2
+ dist: xenial
3
 
4
  language: php
5
 
13
  - master
14
 
15
  php:
16
+ - 7.4
17
 
18
  env:
19
  - WP_VERSION=latest WP_MULTISITE=0
ajax.php CHANGED
@@ -7,6 +7,8 @@
7
 
8
  add_action( 'wp_ajax_imsanity_get_images', 'imsanity_get_images' );
9
  add_action( 'wp_ajax_imsanity_resize_image', 'imsanity_ajax_resize' );
 
 
10
 
11
  /**
12
  * Verifies that the current user has administrator permission and, if not,
@@ -23,7 +25,7 @@ function imsanity_verify_permission() {
23
  )
24
  );
25
  }
26
- if ( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'imsanity-bulk' ) ) {
27
  die(
28
  json_encode(
29
  array(
@@ -43,7 +45,14 @@ function imsanity_verify_permission() {
43
  function imsanity_get_images() {
44
  imsanity_verify_permission();
45
 
 
46
  global $wpdb;
 
 
 
 
 
 
47
  $offset = 0;
48
  $limit = apply_filters( 'imsanity_attachment_query_limit', 3000 );
49
  $results = array();
@@ -118,7 +127,6 @@ function imsanity_ajax_resize() {
118
  imsanity_verify_permission();
119
 
120
  $id = (int) $_POST['id'];
121
-
122
  if ( ! $id ) {
123
  die(
124
  json_encode(
@@ -130,6 +138,48 @@ function imsanity_ajax_resize() {
130
  );
131
  }
132
  $results = imsanity_resize_from_id( $id );
 
 
 
 
133
 
134
  die( json_encode( $results ) );
135
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
  add_action( 'wp_ajax_imsanity_get_images', 'imsanity_get_images' );
9
  add_action( 'wp_ajax_imsanity_resize_image', 'imsanity_ajax_resize' );
10
+ add_action( 'wp_ajax_imsanity_remove_original', 'imsanity_ajax_remove_original' );
11
+ add_action( 'wp_ajax_imsanity_bulk_complete', 'imsanity_ajax_finish' );
12
 
13
  /**
14
  * Verifies that the current user has administrator permission and, if not,
25
  )
26
  );
27
  }
28
+ if ( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'imsanity-bulk' ) && ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'imsanity-manual-resize' ) ) {
29
  die(
30
  json_encode(
31
  array(
45
  function imsanity_get_images() {
46
  imsanity_verify_permission();
47
 
48
+ $resume_id = ! empty( $_POST['resume_id'] ) ? (int) $_POST['resume_id'] : PHP_INT_MAX;
49
  global $wpdb;
50
+ // Load up all the image attachments we can find.
51
+ $attachments = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE ID < %d AND post_type = 'attachment' AND post_mime_type LIKE %s ORDER BY ID DESC", $resume_id, '%%image%%' ) );
52
+ array_walk( $attachments, 'intval' );
53
+ die( json_encode( $attachments ) );
54
+
55
+ // TODO: that's all, get rid of the rest.
56
  $offset = 0;
57
  $limit = apply_filters( 'imsanity_attachment_query_limit', 3000 );
58
  $results = array();
127
  imsanity_verify_permission();
128
 
129
  $id = (int) $_POST['id'];
 
130
  if ( ! $id ) {
131
  die(
132
  json_encode(
138
  );
139
  }
140
  $results = imsanity_resize_from_id( $id );
141
+ if ( ! empty( $_POST['resumable'] ) ) {
142
+ update_option( 'imsanity_resume_id', $id, false );
143
+ sleep( 1 );
144
+ }
145
 
146
  die( json_encode( $results ) );
147
  }
148
+
149
+ /**
150
+ * Resizes the image with the given id according to the configured max width and height settings
151
+ * renders a json response indicating success/failure and dies
152
+ */
153
+ function imsanity_ajax_remove_original() {
154
+ imsanity_verify_permission();
155
+
156
+ $id = (int) $_POST['id'];
157
+ if ( ! $id ) {
158
+ die(
159
+ json_encode(
160
+ array(
161
+ 'success' => false,
162
+ 'message' => esc_html__( 'Missing ID Parameter', 'imsanity' ),
163
+ )
164
+ )
165
+ );
166
+ }
167
+ $remove_original = imsanity_remove_original_image( $id );
168
+ if ( $remove_original && is_array( $remove_original ) ) {
169
+ wp_update_attachment_metadata( $id, $remove_original );
170
+ die( json_encode( array( 'success' => true ) ) );
171
+ }
172
+
173
+ die( json_encode( array( 'success' => false ) ) );
174
+ }
175
+
176
+ /**
177
+ * Finalizes the resizing process.
178
+ */
179
+ function imsanity_ajax_finish() {
180
+ imsanity_verify_permission();
181
+
182
+ update_option( 'imsanity_resume_id', 0, false );
183
+
184
+ die();
185
+ }
changelog.txt CHANGED
@@ -1,3 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  = 2.6.0 =
2
  * added: wp-cli command 'wp help imsanity resize'
3
  * fixed: adding an image to a post in pre-draft status uses wrong settings/dimensions
1
+ = 2.7.0 =
2
+ * changed: bulk resizer will resize all images with no limits, use list mode for selective resizing
3
+ * added: see current dimensions and resize individual images in Media Library list mode
4
+ * added: imsanity_disable_convert filter to bypass BMP/PNG to JPG conversion options conditionally
5
+ * added: imsanity_skip_image filter to bypass resizing programmatically
6
+ * added: ability to remove pre-scaled original image backup (in bulk or selectively)
7
+ * changed: PNG images will not be converted if transparency is found
8
+ * fixed: BMP files not converted when server uses image/x-ms-bmp as mime identifier
9
+ * removed: Deep Scan option is the default behavior now, no need for configuration
10
+
11
+ = 2.6.1 =
12
+ * fixed: wrong parameter passed to imsanity_attachment_path()
13
+
14
  = 2.6.0 =
15
  * added: wp-cli command 'wp help imsanity resize'
16
  * fixed: adding an image to a post in pre-draft status uses wrong settings/dimensions
imsanity.php CHANGED
@@ -15,7 +15,7 @@ Description: Imsanity stops insanely huge image uploads
15
  Author: Exactly WWW
16
  Text Domain: imsanity
17
  Domain Path: /languages
18
- Version: 2.6.0
19
  Author URI: https://ewww.io/
20
  License: GPLv3
21
  */
@@ -24,13 +24,13 @@ if ( ! defined( 'ABSPATH' ) ) {
24
  exit;
25
  }
26
 
27
- define( 'IMSANITY_VERSION', '2.6.0' );
28
  define( 'IMSANITY_SCHEMA_VERSION', '1.1' );
29
 
30
  define( 'IMSANITY_DEFAULT_MAX_WIDTH', 1920 );
31
  define( 'IMSANITY_DEFAULT_MAX_HEIGHT', 1920 );
32
- define( 'IMSANITY_DEFAULT_BMP_TO_JPG', 1 );
33
- define( 'IMSANITY_DEFAULT_PNG_TO_JPG', 0 );
34
  define( 'IMSANITY_DEFAULT_QUALITY', 82 );
35
 
36
  define( 'IMSANITY_SOURCE_POST', 1 );
@@ -67,12 +67,13 @@ function imsanity_init() {
67
  require_once( plugin_dir_path( __FILE__ ) . 'libs/utils.php' );
68
  require_once( plugin_dir_path( __FILE__ ) . 'settings.php' );
69
  require_once( plugin_dir_path( __FILE__ ) . 'ajax.php' );
 
70
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
71
  require_once( plugin_dir_path( __FILE__ ) . 'class-imsanity-cli.php' );
72
  }
73
 
74
  /**
75
- * Use the EWWW IO debugging functions.
76
  *
77
  * @param string $message A message to send to the debugger.
78
  */
@@ -180,8 +181,12 @@ function imsanity_handle_upload( $params ) {
180
  return $params;
181
  }
182
 
 
 
 
 
183
  // If preferences specify so then we can convert an original bmp or png file into jpg.
184
- if ( 'image/bmp' === $params['type'] && imsanity_get_option( 'imsanity_bmp_to_jpg', IMSANITY_DEFAULT_BMP_TO_JPG ) ) {
185
  $params = imsanity_convert_to_jpg( 'bmp', $params );
186
  }
187
 
@@ -298,12 +303,20 @@ function imsanity_handle_upload( $params ) {
298
  */
299
  function imsanity_convert_to_jpg( $type, $params ) {
300
 
 
 
 
 
301
  $img = null;
302
 
303
  if ( 'bmp' === $type ) {
304
  include_once( 'libs/imagecreatefrombmp.php' );
305
  $img = imagecreatefrombmp( $params['file'] );
306
  } elseif ( 'png' === $type ) {
 
 
 
 
307
  if ( ! function_exists( 'imagecreatefrompng' ) ) {
308
  return wp_handle_upload_error( $params['file'], esc_html__( 'Imsanity requires the GD library to convert PNG images to JPG', 'imsanity' ) );
309
  }
@@ -320,8 +333,8 @@ function imsanity_convert_to_jpg( $type, $params ) {
320
 
321
  // We need to change the extension from the original to .jpg so we have to ensure it will be a unique filename.
322
  $uploads = wp_upload_dir();
323
- $oldfilename = basename( $params['file'] );
324
- $newfilename = basename( str_ireplace( '.' . $type, '.jpg', $oldfilename ) );
325
  $newfilename = wp_unique_filename( $uploads['path'], $newfilename );
326
 
327
  $quality = imsanity_get_option( 'imsanity_quality', IMSANITY_DEFAULT_QUALITY );
@@ -350,3 +363,8 @@ function imsanity_convert_to_jpg( $type, $params ) {
350
  add_filter( 'wp_handle_upload', 'imsanity_handle_upload' );
351
  // Run necessary actions on init (loading translations mostly).
352
  add_action( 'plugins_loaded', 'imsanity_init' );
 
 
 
 
 
15
  Author: Exactly WWW
16
  Text Domain: imsanity
17
  Domain Path: /languages
18
+ Version: 2.7.0
19
  Author URI: https://ewww.io/
20
  License: GPLv3
21
  */
24
  exit;
25
  }
26
 
27
+ define( 'IMSANITY_VERSION', '2.7.0' );
28
  define( 'IMSANITY_SCHEMA_VERSION', '1.1' );
29
 
30
  define( 'IMSANITY_DEFAULT_MAX_WIDTH', 1920 );
31
  define( 'IMSANITY_DEFAULT_MAX_HEIGHT', 1920 );
32
+ define( 'IMSANITY_DEFAULT_BMP_TO_JPG', true );
33
+ define( 'IMSANITY_DEFAULT_PNG_TO_JPG', false );
34
  define( 'IMSANITY_DEFAULT_QUALITY', 82 );
35
 
36
  define( 'IMSANITY_SOURCE_POST', 1 );
67
  require_once( plugin_dir_path( __FILE__ ) . 'libs/utils.php' );
68
  require_once( plugin_dir_path( __FILE__ ) . 'settings.php' );
69
  require_once( plugin_dir_path( __FILE__ ) . 'ajax.php' );
70
+ require_once( plugin_dir_path( __FILE__ ) . 'media.php' );
71
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
72
  require_once( plugin_dir_path( __FILE__ ) . 'class-imsanity-cli.php' );
73
  }
74
 
75
  /**
76
+ * Use the EWWW IO debugging functions (if available).
77
  *
78
  * @param string $message A message to send to the debugger.
79
  */
181
  return $params;
182
  }
183
 
184
+ if ( apply_filters( 'imsanity_skip_image', false, $params['file'] ) ) {
185
+ return $params;
186
+ }
187
+
188
  // If preferences specify so then we can convert an original bmp or png file into jpg.
189
+ if ( ( 'image/bmp' === $params['type'] || 'image/x-ms-bmp' === $params['type'] ) && imsanity_get_option( 'imsanity_bmp_to_jpg', IMSANITY_DEFAULT_BMP_TO_JPG ) ) {
190
  $params = imsanity_convert_to_jpg( 'bmp', $params );
191
  }
192
 
303
  */
304
  function imsanity_convert_to_jpg( $type, $params ) {
305
 
306
+ if ( apply_filters( 'imsanity_disable_convert', false, $type, $params ) ) {
307
+ return $params;
308
+ }
309
+
310
  $img = null;
311
 
312
  if ( 'bmp' === $type ) {
313
  include_once( 'libs/imagecreatefrombmp.php' );
314
  $img = imagecreatefrombmp( $params['file'] );
315
  } elseif ( 'png' === $type ) {
316
+ // Prevent converting PNG images with alpha/transparency, unless overridden by the user.
317
+ if ( apply_filters( 'imsanity_skip_alpha', imsanity_has_alpha( $params['file'] ), $params['file'] ) ) {
318
+ return $params;
319
+ }
320
  if ( ! function_exists( 'imagecreatefrompng' ) ) {
321
  return wp_handle_upload_error( $params['file'], esc_html__( 'Imsanity requires the GD library to convert PNG images to JPG', 'imsanity' ) );
322
  }
333
 
334
  // We need to change the extension from the original to .jpg so we have to ensure it will be a unique filename.
335
  $uploads = wp_upload_dir();
336
+ $oldfilename = wp_basename( $params['file'] );
337
+ $newfilename = wp_basename( str_ireplace( '.' . $type, '.jpg', $oldfilename ) );
338
  $newfilename = wp_unique_filename( $uploads['path'], $newfilename );
339
 
340
  $quality = imsanity_get_option( 'imsanity_quality', IMSANITY_DEFAULT_QUALITY );
363
  add_filter( 'wp_handle_upload', 'imsanity_handle_upload' );
364
  // Run necessary actions on init (loading translations mostly).
365
  add_action( 'plugins_loaded', 'imsanity_init' );
366
+
367
+ // Adds a column to the media library list view to display optimization results.
368
+ add_filter( 'manage_media_columns', 'imsanity_media_columns' );
369
+ // Outputs the actual column information for each attachment.
370
+ add_action( 'manage_media_custom_column', 'imsanity_custom_column', 10, 2 );
libs/utils.php CHANGED
@@ -102,6 +102,61 @@ function imsanity_get_orientation( $file, $type ) {
102
  return false;
103
  }
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  /**
106
  * Output a fatal error and optionally die.
107
  *
@@ -136,8 +191,36 @@ function imsanity_resize_from_id( $id = 0 ) {
136
  $meta = wp_get_attachment_metadata( $id );
137
 
138
  if ( $meta && is_array( $meta ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  $uploads = wp_upload_dir();
140
- $oldpath = imsanity_attachment_path( $meta['file'], $id, '', false );
141
  if ( empty( $oldpath ) || ! is_writable( $oldpath ) ) {
142
  /* translators: %s: File-name of the image */
143
  $msg = sprintf( esc_html__( '%s is not writable', 'imsanity' ), $meta['file'] );
@@ -147,6 +230,15 @@ function imsanity_resize_from_id( $id = 0 ) {
147
  );
148
  }
149
 
 
 
 
 
 
 
 
 
 
150
  $maxw = imsanity_get_option( 'imsanity_max_width', IMSANITY_DEFAULT_MAX_WIDTH );
151
  $maxh = imsanity_get_option( 'imsanity_max_height', IMSANITY_DEFAULT_MAX_HEIGHT );
152
 
@@ -180,13 +272,13 @@ function imsanity_resize_from_id( $id = 0 ) {
180
  $meta['width'] = $neww;
181
  $meta['height'] = $newh;
182
 
183
- wp_update_attachment_metadata( $id, $meta );
184
 
185
  $results = array(
186
  'success' => true,
187
  'id' => $id,
188
- /* translators: %s: File-name of the image */
189
- 'message' => sprintf( esc_html__( 'OK: %s', 'imsanity' ), $oldpath ),
190
  );
191
  } elseif ( $newpath !== $oldpath ) {
192
  // the resized image is actually bigger in filesize (most likely due to jpg quality).
@@ -198,14 +290,14 @@ function imsanity_resize_from_id( $id = 0 ) {
198
  'success' => false,
199
  'id' => $id,
200
  /* translators: 1: File-name of the image 2: the error message, translated elsewhere */
201
- 'message' => sprintf( esc_html__( 'ERROR: %1$s (%2$s)', 'imsanity' ), $oldpath, esc_html__( 'Resized image was larger than the original', 'imsanity' ) ),
202
  );
203
  } else {
204
  $results = array(
205
  'success' => false,
206
  'id' => $id,
207
  /* translators: 1: File-name of the image 2: the error message, translated elsewhere */
208
- 'message' => sprintf( esc_html__( 'ERROR: %1$s (%2$s)', 'imsanity' ), $oldpath, esc_html__( 'Unknown error, resizing function returned the same filename', 'imsanity' ) ),
209
  );
210
  }
211
  } elseif ( false === $resizeresult ) {
@@ -213,14 +305,14 @@ function imsanity_resize_from_id( $id = 0 ) {
213
  'success' => false,
214
  'id' => $id,
215
  /* translators: 1: File-name of the image 2: the error message, translated elsewhere */
216
- 'message' => sprintf( esc_html__( 'ERROR: %1$s (%2$s)', 'imsanity' ), $oldpath, esc_html__( 'wp_get_image_editor missing', 'imsanity' ) ),
217
  );
218
  } else {
219
  $results = array(
220
  'success' => false,
221
  'id' => $id,
222
  /* translators: 1: File-name of the image 2: the error message, translated elsewhere */
223
- 'message' => sprintf( esc_html__( 'ERROR: %1$s (%2$s)', 'imsanity' ), $oldpath, htmlentities( $resizeresult->get_error_message() ) ),
224
  );
225
  }
226
  } else {
@@ -228,7 +320,7 @@ function imsanity_resize_from_id( $id = 0 ) {
228
  'success' => true,
229
  'id' => $id,
230
  /* translators: %s: File-name of the image */
231
- 'message' => sprintf( esc_html__( 'SKIPPED: %s (Resize not required)', 'imsanity' ), $oldpath ) . " -- $oldw x $oldh",
232
  );
233
  if ( empty( $meta['width'] ) || empty( $meta['height'] ) ) {
234
  if ( empty( $meta['width'] ) || $meta['width'] > $oldw ) {
@@ -237,9 +329,17 @@ function imsanity_resize_from_id( $id = 0 ) {
237
  if ( empty( $meta['height'] ) || $meta['height'] > $oldh ) {
238
  $meta['height'] = $oldh;
239
  }
240
- wp_update_attachment_metadata( $id, $meta );
241
  }
242
  }
 
 
 
 
 
 
 
 
243
  } else {
244
  $results = array(
245
  'success' => false,
@@ -254,8 +354,44 @@ function imsanity_resize_from_id( $id = 0 ) {
254
 
255
  return $results;
256
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
  /**
258
- * Replacement for deprecated image_resize function
259
  *
260
  * @param string $file Image file path.
261
  * @param int $max_w Maximum width to resize to.
102
  return false;
103
  }
104
 
105
+ /**
106
+ * Check an image to see if it has transparency.
107
+ *
108
+ * @param string $filename The name of the image file.
109
+ * @return bool True if transparency is found.
110
+ */
111
+ function imsanity_has_alpha( $filename ) {
112
+ if ( ! is_file( $filename ) ) {
113
+ return false;
114
+ }
115
+ if ( false !== strpos( $filename, '../' ) ) {
116
+ return false;
117
+ }
118
+ $file_contents = file_get_contents( $filename );
119
+ // Determine what color type is stored in the file.
120
+ $color_type = ord( substr( $file_contents, 25, 1 ) );
121
+ // If we do not have GD and the PNG color type is RGB alpha or Grayscale alpha.
122
+ if ( ! imsanity_gd_support() && ( 4 === $color_type || 6 === $color_type ) ) {
123
+ return true;
124
+ } elseif ( imsanity_gd_support() ) {
125
+ $image = imagecreatefrompng( $filename );
126
+ if ( imagecolortransparent( $image ) >= 0 ) {
127
+ return true;
128
+ }
129
+ list( $width, $height ) = getimagesize( $filename );
130
+ for ( $y = 0; $y < $height; $y++ ) {
131
+ for ( $x = 0; $x < $width; $x++ ) {
132
+ $color = imagecolorat( $image, $x, $y );
133
+ $rgb = imagecolorsforindex( $image, $color );
134
+ if ( $rgb['alpha'] > 0 ) {
135
+ return true;
136
+ }
137
+ }
138
+ }
139
+ }
140
+ return false;
141
+ }
142
+
143
+ /**
144
+ * Check for GD support of both PNG and JPG.
145
+ *
146
+ * @return bool True if full GD support is detected.
147
+ */
148
+ function imsanity_gd_support() {
149
+ if ( function_exists( 'gd_info' ) ) {
150
+ $gd_support = gd_info();
151
+ if ( is_iterable( $gd_support ) ) {
152
+ if ( ( ! empty( $gd_support['JPEG Support'] ) || ! empty( $gd_support['JPG Support'] ) ) && ! empty( $gd_support['PNG Support'] ) ) {
153
+ return true;
154
+ }
155
+ }
156
+ }
157
+ return false;
158
+ }
159
+
160
  /**
161
  * Output a fatal error and optionally die.
162
  *
191
  $meta = wp_get_attachment_metadata( $id );
192
 
193
  if ( $meta && is_array( $meta ) ) {
194
+ $update_meta = false;
195
+ // If "noresize" is included in the filename then we will bypass imsanity scaling.
196
+ if ( ! empty( $meta['file'] ) && false !== strpos( $meta['file'], 'noresize' ) ) {
197
+ /* translators: %s: File-name of the image */
198
+ $msg = sprintf( esc_html__( 'SKIPPED: %s (noresize)', 'imsanity' ), $meta['file'] );
199
+ return array(
200
+ 'success' => false,
201
+ 'message' => $msg,
202
+ );
203
+ }
204
+
205
+ // Let folks filter the allowed mime-types for resizing.
206
+ $allowed_types = apply_filters( 'imsanity_allowed_mimes', array( 'image/png', 'image/gif', 'image/jpeg' ), $meta['file'] );
207
+ if ( is_string( $allowed_types ) ) {
208
+ $allowed_types = array( $allowed_types );
209
+ } elseif ( ! is_array( $allowed_types ) ) {
210
+ $allowed_types = array();
211
+ }
212
+ $ftype = imsanity_quick_mimetype( $meta['file'] );
213
+ if ( ! in_array( $ftype, $allowed_types, true ) ) {
214
+ /* translators: %s: File type of the image */
215
+ $msg = sprintf( esc_html__( '%1$s does not have an allowed file type (%2$s)', 'imsanity' ), $meta['file'], $ftype );
216
+ return array(
217
+ 'success' => false,
218
+ 'message' => $msg,
219
+ );
220
+ }
221
+
222
  $uploads = wp_upload_dir();
223
+ $oldpath = imsanity_attachment_path( $meta, $id, '', false );
224
  if ( empty( $oldpath ) || ! is_writable( $oldpath ) ) {
225
  /* translators: %s: File-name of the image */
226
  $msg = sprintf( esc_html__( '%s is not writable', 'imsanity' ), $meta['file'] );
230
  );
231
  }
232
 
233
+ if ( apply_filters( 'imsanity_skip_image', false, $oldpath ) ) {
234
+ /* translators: %s: File-name of the image */
235
+ $msg = sprintf( esc_html__( 'SKIPPED: %s (by user exclusion)', 'imsanity' ), $meta['file'] );
236
+ return array(
237
+ 'success' => false,
238
+ 'message' => $msg,
239
+ );
240
+ }
241
+
242
  $maxw = imsanity_get_option( 'imsanity_max_width', IMSANITY_DEFAULT_MAX_WIDTH );
243
  $maxh = imsanity_get_option( 'imsanity_max_height', IMSANITY_DEFAULT_MAX_HEIGHT );
244
 
272
  $meta['width'] = $neww;
273
  $meta['height'] = $newh;
274
 
275
+ $update_meta = true;
276
 
277
  $results = array(
278
  'success' => true,
279
  'id' => $id,
280
+ /* translators: 1: File-name of the image */
281
+ 'message' => sprintf( esc_html__( 'OK: %1$s resized to %2$s x %3$s', 'imsanity' ), $meta['file'], $neww . 'w', $newh . 'h' ),
282
  );
283
  } elseif ( $newpath !== $oldpath ) {
284
  // the resized image is actually bigger in filesize (most likely due to jpg quality).
290
  'success' => false,
291
  'id' => $id,
292
  /* translators: 1: File-name of the image 2: the error message, translated elsewhere */
293
+ 'message' => sprintf( esc_html__( 'ERROR: %1$s (%2$s)', 'imsanity' ), $meta['file'], esc_html__( 'File size of resized image was larger than the original', 'imsanity' ) ),
294
  );
295
  } else {
296
  $results = array(
297
  'success' => false,
298
  'id' => $id,
299
  /* translators: 1: File-name of the image 2: the error message, translated elsewhere */
300
+ 'message' => sprintf( esc_html__( 'ERROR: %1$s (%2$s)', 'imsanity' ), $meta['file'], esc_html__( 'Unknown error, resizing function returned the same filename', 'imsanity' ) ),
301
  );
302
  }
303
  } elseif ( false === $resizeresult ) {
305
  'success' => false,
306
  'id' => $id,
307
  /* translators: 1: File-name of the image 2: the error message, translated elsewhere */
308
+ 'message' => sprintf( esc_html__( 'ERROR: %1$s (%2$s)', 'imsanity' ), $meta['file'], esc_html__( 'wp_get_image_editor missing', 'imsanity' ) ),
309
  );
310
  } else {
311
  $results = array(
312
  'success' => false,
313
  'id' => $id,
314
  /* translators: 1: File-name of the image 2: the error message, translated elsewhere */
315
+ 'message' => sprintf( esc_html__( 'ERROR: %1$s (%2$s)', 'imsanity' ), $meta['file'], htmlentities( $resizeresult->get_error_message() ) ),
316
  );
317
  }
318
  } else {
320
  'success' => true,
321
  'id' => $id,
322
  /* translators: %s: File-name of the image */
323
+ 'message' => sprintf( esc_html__( 'SKIPPED: %s (Resize not required)', 'imsanity' ), $meta['file'] ) . " -- $oldw x $oldh",
324
  );
325
  if ( empty( $meta['width'] ) || empty( $meta['height'] ) ) {
326
  if ( empty( $meta['width'] ) || $meta['width'] > $oldw ) {
329
  if ( empty( $meta['height'] ) || $meta['height'] > $oldh ) {
330
  $meta['height'] = $oldh;
331
  }
332
+ $update_meta = true;
333
  }
334
  }
335
+ $remove_original = imsanity_remove_original_image( $id, $meta );
336
+ if ( $remove_original && is_array( $remove_original ) ) {
337
+ $meta = $remove_original;
338
+ $update_meta = true;
339
+ }
340
+ if ( ! empty( $update_meta ) ) {
341
+ wp_update_attachment_metadata( $id, $meta );
342
+ }
343
  } else {
344
  $results = array(
345
  'success' => false,
354
 
355
  return $results;
356
  }
357
+
358
+ /**
359
+ * Remove the backed-up original_image stored by WP 5.3+.
360
+ *
361
+ * @param int $id The attachment ID number.
362
+ * @param array $meta The attachment metadata. Optional, default to null.
363
+ * @return bool True on success, false on failure.
364
+ */
365
+ function imsanity_remove_original_image( $id, $meta = null ) {
366
+ $id = (int) $id;
367
+ if ( empty( $id ) ) {
368
+ return false;
369
+ }
370
+ if ( is_null( $meta ) ) {
371
+ $meta = wp_get_attachment_metadata( $id );
372
+ }
373
+
374
+ if (
375
+ $meta && is_array( $meta ) &&
376
+ imsanity_get_option( 'imsanity_delete_originals', false ) &&
377
+ ! empty( $meta['original_image'] ) && function_exists( 'wp_get_original_image_path' )
378
+ ) {
379
+ $original_image = wp_get_original_image_path( $id );
380
+ if ( empty( $original_image ) || ! is_file( $original_image ) ) {
381
+ $original_image = wp_get_original_image_path( $id, true );
382
+ }
383
+ if ( ! empty( $original_image ) && is_file( $original_image ) && is_writable( $original_image ) ) {
384
+ if ( unlink( $original_image ) ) {
385
+ unset( $meta['original_image'] );
386
+ return $meta;
387
+ }
388
+ }
389
+ }
390
+ return false;
391
+ }
392
+
393
  /**
394
+ * Resize an image using the WP_Image_Editor.
395
  *
396
  * @param string $file Image file path.
397
  * @param int $max_w Maximum width to resize to.
media.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Imsanity Media Library functions.
4
+ *
5
+ * @package Imsanity
6
+ */
7
+
8
+ /**
9
+ * Add column header for Imsanity info/actions in the media library listing.
10
+ *
11
+ * @param array $columns A list of columns in the media library.
12
+ * @return array The new list of columns.
13
+ */
14
+ function imsanity_media_columns( $columns ) {
15
+ $columns['imsanity'] = esc_html__( 'Imsanity', 'imsanity' );
16
+ return $columns;
17
+ }
18
+
19
+ /**
20
+ * Print Imsanity info/actions in the media library.
21
+ *
22
+ * @param string $column_name The name of the column being displayed.
23
+ * @param int $id The attachment ID number.
24
+ * @param array $meta Optional. The attachment metadata. Default null.
25
+ */
26
+ function imsanity_custom_column( $column_name, $id, $meta = null ) {
27
+ // Once we get to the EWWW IO custom column.
28
+ if ( 'imsanity' === $column_name ) {
29
+ $id = (int) $id;
30
+ if ( is_null( $meta ) ) {
31
+ // Retrieve the metadata.
32
+ $meta = wp_get_attachment_metadata( $id );
33
+ }
34
+ echo '<div id="imsanity-media-status-' . (int) $id . '" class="imsanity-media-status" data-id="' . (int) $id . '">';
35
+ if ( false && function_exists( 'print_r' ) ) {
36
+ $print_meta = print_r( $meta, true );
37
+ $print_meta = preg_replace( array( '/ /', '/\n+/' ), array( '&nbsp;', '<br />' ), $print_meta );
38
+ echo "<div id='imsanity-debug-meta-" . (int) $id . "' style='font-size: 10px;padding: 10px;margin:3px -10px 10px;line-height: 1.1em;'>" . wp_kses_post( $print_meta ) . '</div>';
39
+ }
40
+ if ( is_array( $meta ) && ! empty( $meta['file'] ) && false !== strpos( $meta['file'], 'https://images-na.ssl-images-amazon.com' ) ) {
41
+ echo esc_html__( 'Amazon-hosted image', 'imsanity' ) . '</div>';
42
+ return;
43
+ }
44
+ if ( is_array( $meta ) && ! empty( $meta['cloudinary'] ) ) {
45
+ echo esc_html__( 'Cloudinary image', 'imsanity' ) . '</div>';
46
+ return;
47
+ }
48
+ if ( is_array( $meta ) & class_exists( 'WindowsAzureStorageUtil' ) && ! empty( $meta['url'] ) ) {
49
+ echo '<div>' . esc_html__( 'Azure Storage image', 'imsanity' ) . '</div>';
50
+ return;
51
+ }
52
+ if ( is_array( $meta ) && class_exists( 'Amazon_S3_And_CloudFront' ) && preg_match( '/^(http|s3|gs)\w*:/', get_attached_file( $id ) ) ) {
53
+ echo '<div>' . esc_html__( 'Offloaded Media', 'imsanity' ) . '</div>';
54
+ return;
55
+ }
56
+ if ( is_array( $meta ) && class_exists( 'S3_Uploads' ) && preg_match( '/^(http|s3|gs)\w*:/', get_attached_file( $id ) ) ) {
57
+ echo '<div>' . esc_html__( 'Amazon S3 image', 'imsanity' ) . '</div>';
58
+ return;
59
+ }
60
+ if ( is_array( $meta ) & class_exists( 'wpCloud\StatelessMedia' ) && ! empty( $meta['gs_link'] ) ) {
61
+ echo '<div>' . esc_html__( 'WP Stateless image', 'imsanity' ) . '</div>';
62
+ return;
63
+ }
64
+ $file_path = imsanity_attachment_path( $meta, $id );
65
+ if ( is_array( $meta ) & function_exists( 'ilab_get_image_sizes' ) && ! empty( $meta['s3'] ) && empty( $file_path ) ) {
66
+ echo esc_html__( 'Media Cloud image', 'imsanity' ) . '</div>';
67
+ return;
68
+ }
69
+ // If the file does not exist.
70
+ if ( empty( $file_path ) ) {
71
+ echo esc_html__( 'Could not retrieve file path.', 'imsanity' ) . '</div>';
72
+ return;
73
+ }
74
+ // Let folks filter the allowed mime-types for resizing.
75
+ $allowed_types = apply_filters( 'imsanity_allowed_mimes', array( 'image/png', 'image/gif', 'image/jpeg' ), $meta['file'] );
76
+ if ( is_string( $allowed_types ) ) {
77
+ $allowed_types = array( $allowed_types );
78
+ } elseif ( ! is_array( $allowed_types ) ) {
79
+ $allowed_types = array();
80
+ }
81
+ $ftype = imsanity_quick_mimetype( $meta['file'] );
82
+ if ( ! in_array( $ftype, $allowed_types, true ) ) {
83
+ echo '</div>';
84
+ return;
85
+ }
86
+
87
+ list( $imagew, $imageh ) = getimagesize( $file_path );
88
+ if ( empty( $imagew ) || empty( $imageh ) ) {
89
+ $imagew = $meta['width'];
90
+ $imageh = $meta['height'];
91
+ }
92
+
93
+ if ( empty( $imagew ) || empty( $imageh ) ) {
94
+ echo esc_html( 'Unknown dimensions', 'imsanity' );
95
+ return;
96
+ }
97
+ echo '<div>' . (int) $imagew . 'w x ' . (int) $imageh . 'h</div>';
98
+
99
+ $maxw = imsanity_get_option( 'imsanity_max_width', IMSANITY_DEFAULT_MAX_WIDTH );
100
+ $maxh = imsanity_get_option( 'imsanity_max_height', IMSANITY_DEFAULT_MAX_HEIGHT );
101
+ if ( $imagew > $maxw || $imageh > $maxh ) {
102
+ if ( current_user_can( 'activate_plugins' ) ) {
103
+ $manual_nonce = wp_create_nonce( 'imsanity-manual-resize' );
104
+ // Give the user the option to optimize the image right now.
105
+ printf(
106
+ '<div><button class="imsanity-manual-resize button button-secondary" data-id="%1$d" data-nonce="%2$s">%3$s</button>',
107
+ $id,
108
+ esc_attr( $manual_nonce ),
109
+ esc_html__( 'Resize Image', 'imsanity' )
110
+ );
111
+ }
112
+ } elseif ( current_user_can( 'activate_plugins' ) && imsanity_get_option( 'imsanity_delete_originals', false ) && ! empty( $meta['original_image'] ) && function_exists( 'wp_get_original_image_path' ) ) {
113
+ $original_image = wp_get_original_image_path( $id );
114
+ if ( empty( $original_image ) || ! is_file( $original_image ) ) {
115
+ $original_image = wp_get_original_image_path( $id, true );
116
+ }
117
+ if ( ! empty( $original_image ) && is_file( $original_image ) && is_writable( $original_image ) ) {
118
+ $manual_nonce = wp_create_nonce( 'imsanity-manual-resize' );
119
+ // Give the user the option to optimize the image right now.
120
+ printf(
121
+ '<div><button class="imsanity-manual-remove-original button button-secondary" data-id="%1$d" data-nonce="%2$s">%3$s</button>',
122
+ $id,
123
+ esc_attr( $manual_nonce ),
124
+ esc_html__( 'Remove Original', 'imsanity' )
125
+ );
126
+ }
127
+ }
128
+ echo '</div>';
129
+ }
130
+ }
readme.txt CHANGED
@@ -1,39 +1,30 @@
1
  === Imsanity ===
2
  Contributors: nosilver4u
3
  Donate link: https://ewww.io/donate/
4
- Tags: image, scale, resize, space saver, quality
5
  Requires at least: 5.0
6
- Tested up to: 5.4
7
  Requires PHP: 5.6
8
- Stable tag: 2.6.0
9
  License: GPLv3
10
 
11
- Imsanity automatically resizes huge image uploads. Are contributors uploading huge photos? Tired of manually scaling? Imsanity to the rescue!
12
 
13
  == Description ==
14
 
15
- Imsanity automatically resizes huge image uploads down to a size that is
16
- more reasonable for display in browser, yet still more than large enough for typical website use.
17
- The plugin is configurable with a max width, height and quality. When a contributor uploads an
18
- image that is larger than the configured size, Imsanity will automatically scale it down to the
19
- configured size and replace the original image.
20
 
21
- Imsanity also provides a bulk-resize feature to selectively resize previously uploaded images
22
- to free up disk space.
23
 
24
- This plugin is ideal for blogs that do not require hi-resolution original images
25
- to be stored and/or the contributors don't want (or understand how) to scale images
26
- before uploading.
27
-
28
- [](http://coderisk.com/wp/plugin/imsanity/RIPS-YIn4SbnOjz)
29
 
30
  = Features =
31
 
32
  * Automatically scales large image uploads to a more "sane" size
33
- * Bulk-resize feature to selectively resize existing images
34
- * Allows configuration of max width/height and jpg quality
35
- * Optionally converts BMP files to JPG so image can be scaled
36
- * Option to convert PNG files to JPG format for higher compression
37
  * Once enabled, Imsanity requires no actions on the part of the user
38
  * Uses WordPress built-in image scaling functions
39
 
@@ -66,70 +57,48 @@ Manual Installation:
66
 
67
  == Frequently Asked Questions ==
68
 
69
- = What is Imsanity? =
70
 
71
- Imsanity is a plugin that automatically resizes uploaded images that are larger than the configured max width/height
72
 
73
- = Will installing the Imsanity plugin alter existing images in my blog? =
74
 
75
- Activating Imsanity will not alter any existing images. Imsanity resizes images as they are uploaded so
76
- it does not affect existing images unless you specifically use the "Bulk Image Resize" feature on
77
- the Imsanity settings page. The "Bulk Image Resize" feature allows you to selectively resize existing images.
78
 
79
- = Why aren't all of my images detected when I try to use the bulk resize feature? =
80
 
81
- Imsanity doesn't search your file system to find large files, instead it looks at the "metadata"
82
- in the WordPress media library database. To override this behavior, enable deep scanning.
83
 
84
- = Why am I getting an error saying that my "File is not an image" ? =
85
 
86
- WordPress uses the GD library to handle the image manipulation. GD can be installed and configured to support
87
- various types of images. If GD is not configured to handle a particular image type then you will get
88
- this message when you try to upload it. For more info see http://php.net/manual/en/image.installation.php
89
 
90
- = How can I tell Imsanity to ignore a certain image so I can upload it without being resized? =
91
 
92
- You can re-name your file and add "-noresize" to the filename. For example if your file is named
93
- "photo.jpg" you can rename it "photo-noresize.jpg" and Imsanity will ignore it, allowing you
94
- to upload the full-sized image.
95
 
96
- Optionally you can temporarily adjust the max image size settings and set them to a number that is
97
- higher than the resolution of the image you wish to upload
98
 
99
  = Why would I need this plugin? =
100
 
101
- Photos taken on any modern camera and even most cellphones are too large for display full-size in a browser.
102
- In the case of modern DSLR cameras, the image sizes are intended for high-quality printing and are ridiculously
103
- over-sized for display on a web page.
104
 
105
- Imsanity allows you to set a sanity limit so that all uploaded images will be constrained
106
- to a reasonable size which is still more than large enough for the needs of a typical website.
107
- Imsanity hooks into WordPress immediately after the image upload, but before WordPress processing
108
- occurs. So WordPress behaves exactly the same in all ways, except it will be as if the contributor
109
- had scaled their image to a reasonable size before uploading.
110
 
111
- The size limit that imsanity uses is configurable. The default value is large enough to fill
112
- the average vistors entire screen without scaling so it is still more than large enough for
113
- typical usage.
114
 
115
  = Why would I NOT want to use this plugin? =
116
 
117
- You might not want to use Imsanity if you use WordPress as a stock art download
118
- site, provide high-res images for print or use WordPress as a high-res photo
119
- storage archive. If you are doing any of these things then most likely
120
- you already have a good understanding of image resolution.
121
 
122
  = Doesn't WordPress already automatically scale images? =
123
 
124
- When an image is uploaded WordPress keeps the original and, depending on the size of the original,
125
- will create up to 4 smaller sized copies of the file (Large, Medium-Large, Medium, Thumbnail) which are intended
126
- for embedding on your pages. Unless you have special photographic needs, the original usually sits
127
- there unused, but taking up disk quota.
128
 
129
  = Why did you spell Insanity wrong? =
130
 
131
- Imsanity is short for "Image Sanity Limit". A sanity limit is a term for limiting something down to
132
- a size or value that is reasonable.
133
 
134
  = Where do I go for support? =
135
 
@@ -137,6 +106,19 @@ Questions may be posted on the support forum at https://wordpress.org/support/pl
137
 
138
  == Changelog ==
139
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  = 2.6.0 =
141
  * added: wp-cli command 'wp help imsanity resize'
142
  * fixed: adding an image to a post in pre-draft status uses wrong settings/dimensions
@@ -151,28 +133,6 @@ Questions may be posted on the support forum at https://wordpress.org/support/pl
151
  * fixed: crop filter not applied if max width or height is equal to existing dimension
152
  * fixed: invalid capabilities used for settings page - props @cfoellmann
153
 
154
- = 2.4.3 =
155
- * changed: default size from 2048 to 1920
156
- * fixed: WP Import plugin breaks during Media imports
157
- * fixed: setting a value to 0 causes errors on multi-site
158
- * fixed: conversion settings not displaying correctly on multi-site
159
-
160
- = 2.4.2 =
161
- * changed: noresize in filename also works in batch processing
162
- * fixed: error message does not contain filename when file is missing
163
- * fixed: notice on network settings when deep scan option has not been set before
164
-
165
- = 2.4.1 =
166
- * fixed: bulk resizer scan returning incorrect results
167
- * fixed: sprintf error during resizing and upload
168
-
169
- = 2.4.0 =
170
- * added: deep scanning option for when attachment metadata isn't updating properly
171
- * fixed: uploads from Gutenberg not detected properly
172
- * fixed: some other plugin(s) trying to muck with the Imsanity settings links and breaking things
173
- * fixed: undefined notice for query during ajax operation
174
- * fixed: stale metadata could prevent further resizing
175
-
176
  = Earlier versions =
177
  Please refer to the separate changelog.txt file.
178
 
1
  === Imsanity ===
2
  Contributors: nosilver4u
3
  Donate link: https://ewww.io/donate/
4
+ Tags: image, scale, resize, space saver, quality, upload
5
  Requires at least: 5.0
6
+ Tested up to: 5.6
7
  Requires PHP: 5.6
8
+ Stable tag: 2.7.0
9
  License: GPLv3
10
 
11
+ Imsanity automatically resizes huge image uploads. Are contributors uploading huge photos? Tired of manually resizing your images? Imsanity to the rescue!
12
 
13
  == Description ==
14
 
15
+ Automatically resize huge image uploads with Imsanity. Choose whatever size and quality you like, and let Imsanity do the rest. When a contributor uploads an image that is larger than the configured size, Imsanity will automatically scale it down to the configured size and replace the original image.
 
 
 
 
16
 
17
+ Imsanity also provides a bulk-resize feature to resize previously uploaded images and free up disk space. You may resize individual images from the Media Library's List View.
 
18
 
19
+ This plugin is ideal for blogs that do not require hi-resolution original images to be stored and/or the contributors don't want (or understand how) to scale images before uploading.
 
 
 
 
20
 
21
  = Features =
22
 
23
  * Automatically scales large image uploads to a more "sane" size
24
+ * Bulk resize feature to resize existing images
25
+ * Selectively resize images directly in the Media Library (List View)
26
+ * Allows configuration of max width/height and JPG quality
27
+ * Optionally converts BMP and PNG files to JPG for more savings
28
  * Once enabled, Imsanity requires no actions on the part of the user
29
  * Uses WordPress built-in image scaling functions
30
 
57
 
58
  == Frequently Asked Questions ==
59
 
60
+ = Will installing the Imsanity plugin alter existing images in my blog? =
61
 
62
+ Activating Imsanity will not alter any existing images. Imsanity resizes images as they are uploaded so it does not affect existing images unless you specifically use the "Bulk Image Resize" feature on the Imsanity settings page. The Bulk Resize feature allows you to quickly resize existing images.
63
 
64
+ = Why am I getting an error saying that my "File is not an image" ? =
65
 
66
+ WordPress uses the GD library to handle the image manipulation. GD can be installed and configured to support various types of images. If GD is not configured to handle a particular image type then you will get this message when you try to upload it. For more info see http://php.net/manual/en/image.installation.php
 
 
67
 
68
+ = How can I tell Imsanity to ignore a certain image so I can upload it without being resized? =
69
 
70
+ You can re-name your file and add "-noresize" to the filename. For example if your file is named "photo.jpg" you can rename it "photo-noresize.jpg" and Imsanity will ignore it, allowing you to upload the full-sized image.
 
71
 
72
+ If you are a developer (or have one handy), you can also use the 'imsanity_skip_image' filter to bypass resizing for any image.
73
 
74
+ = Does Imsanity compress or optimize my images? =
 
 
75
 
76
+ While Imsanity does compress JPG images in the process of resizing them, it uses the standard WordPress compression. Thus, the resulting images are not efficiently encoded and can be optimized further (without quality loss) by the EWWW Image Optimizer and many other image optimization plugins.
77
 
78
+ = Will Imsanity resize images from plugin X, Y, or Z? =
 
 
79
 
80
+ If the images can be found in the Media Library of your site, then it is likely Imsanity will resize them. Imsanity uses the wp_handle_upload hook to process new uploads and can resize any existing images in the Media Library using the Bulk Resizer. If the images are not in the Media Library, you can use the EWWW Image Optimizer to resize them.
 
81
 
82
  = Why would I need this plugin? =
83
 
84
+ Photos taken on any modern camera and most cellphones are too large to display full-size in a browser.
85
+ This wastes space on your web server, and wastes bandwidth for your visitors to view these files.
 
86
 
87
+ Imsanity allows you to set a sanity limit so that all uploaded images will be constrained to a reasonable size which is still more than large enough for the needs of a typical website. Imsanity hooks into WordPress immediately after the image upload, but before WordPress processing occurs. So WordPress behaves exactly the same in all ways, except it will be as if the contributor had scaled their image to a reasonable size before uploading.
 
 
 
 
88
 
89
+ The size limit that imsanity uses is configurable. The default value is large enough to fill the average vistor's entire screen without scaling so it is still more than large enough for typical usage.
 
 
90
 
91
  = Why would I NOT want to use this plugin? =
92
 
93
+ You might not want to use Imsanity if you use WordPress as a stock art download site, to provide hi-resolution images for print or use WordPress as a hi-resolution photo storage archive.
 
 
 
94
 
95
  = Doesn't WordPress already automatically scale images? =
96
 
97
+ When an image is uploaded WordPress keeps the original and, depending on the size of the original, will create up to 4 smaller sized copies of the file (Large, Medium-Large, Medium, Thumbnail) which are intended for embedding on your pages. Unless you have special photographic needs, the original usually sits there unused, but taking up disk quota.
 
 
 
98
 
99
  = Why did you spell Insanity wrong? =
100
 
101
+ Imsanity is short for "Image Sanity Limit". A sanity limit is a term for limiting something down to a size or value that is reasonable.
 
102
 
103
  = Where do I go for support? =
104
 
106
 
107
  == Changelog ==
108
 
109
+ = 2.7.0 =
110
+ * changed: bulk resizer will resize all images with no limits, use list mode for selective resizing
111
+ * added: see current dimensions and resize individual images in Media Library list mode
112
+ * added: imsanity_disable_convert filter to bypass BMP/PNG to JPG conversion options conditionally
113
+ * added: imsanity_skip_image filter to bypass resizing programmatically
114
+ * added: ability to remove pre-scaled original image backup (in bulk or selectively)
115
+ * changed: PNG images will not be converted if transparency is found
116
+ * fixed: BMP files not converted when server uses image/x-ms-bmp as mime identifier
117
+ * removed: Deep Scan option is the default behavior now, no need for configuration
118
+
119
+ = 2.6.1 =
120
+ * fixed: wrong parameter passed to imsanity_attachment_path()
121
+
122
  = 2.6.0 =
123
  * added: wp-cli command 'wp help imsanity resize'
124
  * fixed: adding an image to a post in pre-draft status uses wrong settings/dimensions
133
  * fixed: crop filter not applied if max width or height is equal to existing dimension
134
  * fixed: invalid capabilities used for settings page - props @cfoellmann
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  = Earlier versions =
137
  Please refer to the separate changelog.txt file.
138
 
scripts/imsanity.js CHANGED
@@ -4,55 +4,107 @@
4
 
5
  jQuery(document).ready(function($) {$(".fade").fadeTo(5000,1).fadeOut(3000);});
6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  /**
8
  * Begin the process of re-sizing all of the checked images
9
  */
10
- function imsanity_resize_images()
11
- {
12
- var images = [];
13
- jQuery('.imsanity_image_cb:checked').each(function(i) {
14
- images.push(this.value);
15
- });
16
-
17
- var target = jQuery('#resize_results');
18
- target.html('');
19
- //jQuery(document).scrollTop(target.offset().top);
20
-
21
  // start the recursion
22
- imsanity_resize_next(images,0);
23
  }
24
 
25
  /**
26
  * recursive function for resizing images
27
  */
28
- function imsanity_resize_next(images,next_index)
29
- {
30
- if (next_index >= images.length) return imsanity_resize_complete();
 
 
31
 
32
  jQuery.post(
33
  ajaxurl, // (defined by wordpress - points to admin-ajax.php)
34
- {_wpnonce: imsanity_vars._wpnonce, action: 'imsanity_resize_image', id: images[next_index]},
35
- function(response)
36
- {
37
  var result;
38
- var target = jQuery('#resize_results');
39
- target.show();
40
 
41
  try {
42
  result = JSON.parse(response);
43
- target.append('<div>' + (next_index+1) + '/' + images.length + ' &gt;&gt; ' + result['message'] +'</div>');
44
- }
45
- catch(e) {
46
  target.append('<div>' + imsanity_vars.invalid_response + '</div>');
47
  if (console) {
48
- console.warn(images[next_index] + ': '+ e.message);
49
  console.warn('Invalid JSON Response: ' + response);
50
  }
51
- }
52
 
53
  target.animate({scrollTop: target.prop('scrollHeight')}, 200);
54
  // recurse
55
- imsanity_resize_next(images,next_index+1);
56
  }
57
  );
58
  }
@@ -60,64 +112,53 @@ function imsanity_resize_next(images,next_index)
60
  /**
61
  * fired when all images have been resized
62
  */
63
- function imsanity_resize_complete()
64
- {
65
  var target = jQuery('#resize_results');
66
- target.append('<div><strong>' + imsanity_vars.resizing_complete + '</strong></div>');
 
 
 
 
 
 
 
67
  target.animate({scrollTop: target.prop('scrollHeight')});
68
  }
69
 
70
  /**
71
- * ajax post to return all images that are candidates for resizing
72
  * @param string the id of the html element into which results will be appended
73
  */
74
- function imsanity_load_images(container_id)
75
- {
76
- var container = jQuery('#'+container_id);
77
-
78
- var target = jQuery('#imsanity_target');
79
- target.show();
80
- jQuery('.imsanity-selection').remove();
81
  jQuery('#imsanity_loading').show();
82
 
83
- target.animate({height: [250,'swing']},500, function()
84
- {
85
- jQuery(document).scrollTop(container.offset().top);
86
-
87
- jQuery.post(
88
- ajaxurl, // (global defined by wordpress - points to admin-ajax.php)
89
- {_wpnonce: imsanity_vars._wpnonce, action: 'imsanity_get_images'},
90
- function(response) {
91
- var is_json = true;
92
- try {
93
- var images = jQuery.parseJSON(response);
94
- } catch ( err ) {
95
- is_json = false;
96
- }
97
- if ( ! is_json ) {
98
- console.log( response );
99
- return false;
100
- }
101
-
102
- jQuery('#imsanity_loading').hide();
103
- if (images.length > 0)
104
- {
105
- target.append('<div class="imsanity-selection"><input id="imsanity_check_all" type="checkbox" checked="checked" onclick="jQuery(\'.imsanity_image_cb\').attr(\'checked\', this.checked);" /> Select All</div>');
106
- for (var i = 0; i < images.length; i++)
107
- {
108
- target.append('<div class="imsanity-selection"><input class="imsanity_image_cb" name="imsanity_images" value="' + images[i].id + '" type="checkbox" checked="checked" />' + imsanity_vars.image + ' ' + images[i].id + ': ' + images[i].file +' ('+images[i].width+' x '+images[i].height+')</div>');
109
- }
110
- if ( ! jQuery( '#resize-submit' ).length ) {
111
- container.append('<p id="resize-submit" class="submit"><button class="button-primary" onclick="imsanity_resize_images();">' + imsanity_vars.resize_selected + '</button></p>');
112
- container.append('<div id="resize_results" style="display: none; border: solid 2px #666666; padding: 10px; height: 250px; overflow: auto;" />');
113
- }
114
- }
115
- else
116
- {
117
- target.html('<div>' + imsanity_vars.none_found + '</div>');
118
 
119
- }
120
- }
121
- );
122
- });
 
 
 
 
 
 
 
123
  }
4
 
5
  jQuery(document).ready(function($) {$(".fade").fadeTo(5000,1).fadeOut(3000);});
6
 
7
+ // Handle a manual resize from the media library.
8
+ jQuery(document).on('click', '.imsanity-manual-resize', function() {
9
+ var post_id = jQuery(this).data('id');
10
+ var imsanity_nonce = jQuery(this).data('nonce');
11
+ jQuery('#imsanity-media-status-' + post_id ).html( imsanity_vars.resizing );
12
+ jQuery.post(
13
+ ajaxurl,
14
+ {_wpnonce: imsanity_nonce, action: 'imsanity_resize_image', id: post_id},
15
+ function(response) {
16
+ var target = jQuery('#imsanity-media-status-' + post_id );
17
+ try {
18
+ var result = JSON.parse(response);
19
+ target.html(result['message']);
20
+ } catch(e) {
21
+ target.html(imsanity_vars.invalid_response);
22
+ if (console) {
23
+ console.warn(post_id + ': '+ e.message);
24
+ console.warn('Invalid JSON Response: ' + response);
25
+ }
26
+ }
27
+ }
28
+ );
29
+ return false;
30
+ });
31
+
32
+ // Handle an original image removal request from the media library.
33
+ jQuery(document).on('click', '.imsanity-manual-remove-original', function() {
34
+ var post_id = jQuery(this).data('id');
35
+ var imsanity_nonce = jQuery(this).data('nonce');
36
+ jQuery('#imsanity-media-status-' + post_id ).html( imsanity_vars.resizing );
37
+ jQuery.post(
38
+ ajaxurl,
39
+ {_wpnonce: imsanity_nonce, action: 'imsanity_remove_original', id: post_id},
40
+ function(response) {
41
+ var target = jQuery('#imsanity-media-status-' + post_id );
42
+ try {
43
+ var result = JSON.parse(response);
44
+ if (! result['success']) {
45
+ target.html(imsanity_vars.removal_failed);
46
+ } else {
47
+ target.html(imsanity_vars.removal_succeeded);
48
+ }
49
+ } catch(e) {
50
+ target.html(imsanity_vars.invalid_response);
51
+ if (console) {
52
+ console.warn(post_id + ': '+ e.message);
53
+ console.warn('Invalid JSON Response: ' + response);
54
+ }
55
+ }
56
+ }
57
+ );
58
+ return false;
59
+ });
60
+
61
+ jQuery(document).on('submit', '#imsanity-bulk-stop', function() {
62
+ jQuery(this).hide();
63
+ imsanity_vars.stopped = true;
64
+ imsanity_vars.attachments = [];
65
+ jQuery('#imsanity_loading').html(imsanity_vars.operation_stopped);
66
+ jQuery('#imsanity_loading').show();
67
+ return false;
68
+ });
69
+
70
  /**
71
  * Begin the process of re-sizing all of the checked images
72
  */
73
+ function imsanity_resize_images() {
 
 
 
 
 
 
 
 
 
 
74
  // start the recursion
75
+ imsanity_resize_next(0);
76
  }
77
 
78
  /**
79
  * recursive function for resizing images
80
  */
81
+ function imsanity_resize_next(next_index) {
82
+ if (next_index >= imsanity_vars.attachments.length) return imsanity_resize_complete();
83
+ var total_images = imsanity_vars.attachments.length;
84
+ var target = jQuery('#resize_results');
85
+ target.show();
86
 
87
  jQuery.post(
88
  ajaxurl, // (defined by wordpress - points to admin-ajax.php)
89
+ {_wpnonce: imsanity_vars._wpnonce, action: 'imsanity_resize_image', id: imsanity_vars.attachments[next_index], resumable: 1},
90
+ function (response) {
 
91
  var result;
92
+ jQuery('#bulk-resize-beginning').hide();
 
93
 
94
  try {
95
  result = JSON.parse(response);
96
+ target.append('<div>' + (next_index+1) + '/' + total_images + ' &gt;&gt; ' + result['message'] +'</div>');
97
+ } catch(e) {
 
98
  target.append('<div>' + imsanity_vars.invalid_response + '</div>');
99
  if (console) {
100
+ console.warn(imsanity_vars.attachments[next_index] + ': '+ e.message);
101
  console.warn('Invalid JSON Response: ' + response);
102
  }
103
+ }
104
 
105
  target.animate({scrollTop: target.prop('scrollHeight')}, 200);
106
  // recurse
107
+ imsanity_resize_next(next_index+1);
108
  }
109
  );
110
  }
112
  /**
113
  * fired when all images have been resized
114
  */
115
+ function imsanity_resize_complete() {
 
116
  var target = jQuery('#resize_results');
117
+ if (! imsanity_vars.stopped) {
118
+ jQuery('#imsanity-bulk-stop').hide();
119
+ target.append('<div><strong>' + imsanity_vars.resizing_complete + '</strong></div>');
120
+ jQuery.post(
121
+ ajaxurl, // (global defined by wordpress - points to admin-ajax.php)
122
+ {_wpnonce: imsanity_vars._wpnonce, action: 'imsanity_bulk_complete'}
123
+ );
124
+ }
125
  target.animate({scrollTop: target.prop('scrollHeight')});
126
  }
127
 
128
  /**
129
+ * ajax post to return all images from the library
130
  * @param string the id of the html element into which results will be appended
131
  */
132
+ function imsanity_load_images() {
133
+ jQuery('#imsanity-examine-button').hide();
134
+ jQuery('.imsanity-bulk-text').hide();
135
+ jQuery('#imsanity-bulk-reset').hide();
 
 
 
136
  jQuery('#imsanity_loading').show();
137
 
138
+ jQuery.post(
139
+ ajaxurl, // (global defined by wordpress - points to admin-ajax.php)
140
+ {_wpnonce: imsanity_vars._wpnonce, action: 'imsanity_get_images', resume_id: imsanity_vars.resume_id},
141
+ function(response) {
142
+ var is_json = true;
143
+ try {
144
+ var images = jQuery.parseJSON(response);
145
+ } catch ( err ) {
146
+ is_json = false;
147
+ }
148
+ if ( ! is_json ) {
149
+ console.log( response );
150
+ return false;
151
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
 
153
+ jQuery('#imsanity_loading').hide();
154
+ if (images.length > 0) {
155
+ imsanity_vars.attachments = images;
156
+ imsanity_vars.stopped = false;
157
+ jQuery('#imsanity-bulk-stop').show();
158
+ imsanity_resize_images();
159
+ } else {
160
+ jQuery('#imsanity_loading').html('<div>' + imsanity_vars.none_found + '</div>');
161
+ }
162
+ }
163
+ );
164
  }
settings.php CHANGED
@@ -88,9 +88,14 @@ function imsanity_settings_link( $links ) {
88
  */
89
  function imsanity_queue_script( $hook ) {
90
  // Make sure we are being called from the settings page.
91
- if ( strpos( $hook, 'settings_page_imsanity' ) !== 0 ) {
92
  return;
93
  }
 
 
 
 
 
94
  // Register the scripts that are used by the bulk resizer.
95
  wp_enqueue_script( 'imsanity_script', plugins_url( '/scripts/imsanity.js', __FILE__ ), array( 'jquery' ), IMSANITY_VERSION );
96
  wp_localize_script(
@@ -98,13 +103,20 @@ function imsanity_queue_script( $hook ) {
98
  'imsanity_vars',
99
  array(
100
  '_wpnonce' => wp_create_nonce( 'imsanity-bulk' ),
101
- 'resizing_complete' => esc_html__( 'Resizing Complete', 'imsanity' ),
102
  'resize_selected' => esc_html__( 'Resize Selected Images', 'imsanity' ),
 
 
 
 
103
  'image' => esc_html__( 'Image', 'imsanity' ),
104
  'invalid_response' => esc_html__( 'Received an invalid response, please check for errors in the Developer Tools console of your browser.', 'imsanity' ),
105
  'none_found' => esc_html__( 'There are no images that need to be resized.', 'imsanity' ),
 
106
  )
107
  );
 
 
108
  add_action( 'admin_print_scripts', 'imsanity_settings_css' );
109
  }
110
 
@@ -157,8 +169,8 @@ function imsanity_get_default_multisite_settings() {
157
  $data->imsanity_max_width_other = IMSANITY_DEFAULT_MAX_WIDTH;
158
  $data->imsanity_bmp_to_jpg = IMSANITY_DEFAULT_BMP_TO_JPG;
159
  $data->imsanity_png_to_jpg = IMSANITY_DEFAULT_PNG_TO_JPG;
160
- $data->imsanity_deep_scan = false;
161
  $data->imsanity_quality = IMSANITY_DEFAULT_QUALITY;
 
162
  return $data;
163
  }
164
 
@@ -260,69 +272,81 @@ function imsanity_network_settings() {
260
  <input type="hidden" name="update_imsanity_settings" value="1" />
261
  <?php wp_nonce_field( 'imsanity_network_options' ); ?>
262
  <table class="form-table">
263
- <tr>
264
- <th scope="row"><label for="imsanity_override_site"><?php esc_html_e( 'Global Settings Override', 'imsanity' ); ?></label></th>
265
- <td>
266
- <select name="imsanity_override_site">
267
- <option value="0" <?php selected( $settings->imsanity_override_site, '0' ); ?> ><?php esc_html_e( 'Allow each site to configure Imsanity settings', 'imsanity' ); ?></option>
268
- <option value="1" <?php selected( $settings->imsanity_override_site, '1' ); ?> ><?php esc_html_e( 'Use global Imsanity settings (below) for all sites', 'imsanity' ); ?></option>
269
- </select>
270
- <p class="description"><?php esc_html_e( 'If you allow per-site configuration, the settings below will be used as the defaults. Single-site defaults will be set the first time you visit the site admin after activating Imsanity.', 'imsanity' ); ?></p>
271
- </td>
272
- </tr>
273
-
274
- <tr>
275
- <th scope="row"><?php esc_html_e( 'Images uploaded within a Page/Post', 'imsanity' ); ?></th>
276
- <td>
277
- <label for="imsanity_max_width"><?php esc_html_e( 'Max Width', 'imsanity' ); ?></label> <input type="number" step="1" min="0" class='small-text' name="imsanity_max_width" value="<?php echo (int) $settings->imsanity_max_width; ?>" />
278
- <label for="imsanity_max_height"><?php esc_html_e( 'Max Height', 'imsanity' ); ?></label> <input type="number" step="1" min="0" class="small-text" name="imsanity_max_height" value="<?php echo (int) $settings->imsanity_max_height; ?>" /> <?php esc_html_e( 'in pixels, enter 0 to disable', 'imsanity' ); ?>
279
- <p class="description"><?php esc_html_e( 'These dimensions are used for Bulk Resizing also.', 'imsanity' ); ?></p>
280
- </td>
281
- </tr>
282
-
283
- <tr>
284
- <th scope="row"><?php esc_html_e( 'Images uploaded directly to the Media Library', 'imsanity' ); ?></th>
285
- <td>
286
- <label for="imsanity_max_width_library"><?php esc_html_e( 'Max Width', 'imsanity' ); ?></label> <input type="number" step="1" min="0" class='small-text' name="imsanity_max_width_library" value="<?php echo (int) $settings->imsanity_max_width_library; ?>" />
287
- <label for="imsanity_max_height_library"><?php esc_html_e( 'Max Height', 'imsanity' ); ?></label> <input type="number" step="1" min="0" class="small-text" name="imsanity_max_height_library" value="<?php echo (int) $settings->imsanity_max_height_library; ?>" /> <?php esc_html_e( 'in pixels, enter 0 to disable', 'imsanity' ); ?>
288
- </td>
289
- </tr>
290
-
291
- <tr>
292
- <th scope="row"><?php esc_html_e( 'Images uploaded elsewhere (Theme headers, backgrounds, logos, etc)', 'imsanity' ); ?></th>
293
- <td>
294
- <label for="imsanity_max_width_other"><?php esc_html_e( 'Max Width', 'imsanity' ); ?></label> <input type="number" step="1" min="0" class='small-text' name="imsanity_max_width_other" value="<?php echo (int) $settings->imsanity_max_width_other; ?>" />
295
- <label for="imsanity_max_height_other"><?php esc_html_e( 'Max Height', 'imsanity' ); ?></label> <input type="number" step="1" min="0" class="small-text" name="imsanity_max_height_other" value="<?php echo (int) $settings->imsanity_max_height_other; ?>" /> <?php esc_html_e( 'in pixels, enter 0 to disable', 'imsanity' ); ?>
296
- </td>
297
- </tr>
298
-
299
- <tr>
300
- <th scope="row"><label for"imsanity_bmp_to_jpg"><?php esc_html_e( 'Convert BMP to JPG', 'imsanity' ); ?></label></th>
301
- <td><select name="imsanity_bmp_to_jpg">
302
- <option value="1" <?php selected( $settings->imsanity_bmp_to_jpg, '1' ); ?> ><?php esc_html_e( 'Yes', 'imsanity' ); ?></option>
303
- <option value="0" <?php selected( $settings->imsanity_bmp_to_jpg, '0' ); ?> ><?php esc_html_e( 'No', 'imsanity' ); ?></option>
304
- </select></td>
305
- </tr>
306
-
307
- <tr>
308
- <th scope="row"><label for="imsanity_png_to_jpg"><?php esc_html_e( 'Convert PNG to JPG', 'imsanity' ); ?></label></th>
309
- <td><select name="imsanity_png_to_jpg">
310
- <option value="1" <?php selected( $settings->imsanity_png_to_jpg, '1' ); ?> ><?php esc_html_e( 'Yes', 'imsanity' ); ?></option>
311
- <option value="0" <?php selected( $settings->imsanity_png_to_jpg, '0' ); ?> ><?php esc_html_e( 'No', 'imsanity' ); ?></option>
312
- </select></td>
313
- </tr>
314
-
315
- <tr>
316
- <th scope="row"><label for='imsanity_quality' ><?php esc_html_e( 'JPG image quality', 'imsanity' ); ?></th>
317
- <td><input type='text' id='imsanity_quality' name='imsanity_quality' class='small-text' value='<?php echo (int) $settings->imsanity_quality; ?>' /> <?php esc_html_e( 'Valid values are 1-100.', 'imsanity' ); ?>
318
- <p class='description'><?php esc_html_e( 'Only used when resizing images, does not affect thumbnails.', 'imsanity' ); ?></p></td>
319
- </tr>
320
-
321
- <tr>
322
- <th scope="row"><label for="imsanity_deep_scan"><?php esc_html_e( 'Deep Scan', 'imsanity' ); ?></label></th>
323
- <td><input type="checkbox" id="imsanity_deep_scan" name="imsanity_deep_scan" value="true"<?php echo ( $settings->imsanity_deep_scan ) ? " checked='true'" : ''; ?> /><?php esc_html_e( 'If searching repeatedly returns the same images, deep scanning will check the actual image dimensions instead of relying on metadata from the database.', 'imsanity' ); ?></td>
324
- </tr>
325
-
 
 
 
 
 
 
 
 
 
 
 
 
326
  </table>
327
 
328
  <p class="submit"><input type="submit" class="button-primary" value="<?php esc_attr_e( 'Update Settings', 'imsanity' ); ?>" /></p>
@@ -358,10 +382,10 @@ function imsanity_network_settings_update() {
358
  $data->imsanity_max_width_library = sanitize_text_field( $_POST['imsanity_max_width_library'] );
359
  $data->imsanity_max_height_other = sanitize_text_field( $_POST['imsanity_max_height_other'] );
360
  $data->imsanity_max_width_other = sanitize_text_field( $_POST['imsanity_max_width_other'] );
361
- $data->imsanity_bmp_to_jpg = (bool) $_POST['imsanity_bmp_to_jpg'];
362
- $data->imsanity_png_to_jpg = (bool) $_POST['imsanity_png_to_jpg'];
363
  $data->imsanity_quality = imsanity_jpg_quality( $_POST['imsanity_quality'] );
364
- $data->imsanity_deep_scan = empty( $_POST['imsanity_deep_scan'] ) ? 0 : 1;
365
 
366
  $success = $wpdb->update(
367
  $wpdb->imsanity_ms,
@@ -412,10 +436,10 @@ function imsanity_get_multisite_settings() {
412
  $_imsanity_multisite_settings->imsanity_max_width_other = $_imsanity_multisite_settings->imsanity_max_width;
413
  }
414
  $_imsanity_multisite_settings->imsanity_override_site = ! empty( $_imsanity_multisite_settings->imsanity_override_site ) ? '1' : '0';
415
- $_imsanity_multisite_settings->imsanity_bmp_to_jpg = ! empty( $_imsanity_multisite_settings->imsanity_bmp_to_jpg ) ? '1' : '0';
416
- $_imsanity_multisite_settings->imsanity_png_to_jpg = ! empty( $_imsanity_multisite_settings->imsanity_png_to_jpg ) ? '1' : '0';
417
- if ( ! property_exists( $_imsanity_multisite_settings, 'imsanity_deep_scan' ) ) {
418
- $_imsanity_multisite_settings->imsanity_deep_scan = false;
419
  }
420
  }
421
  return $_imsanity_multisite_settings;
@@ -472,10 +496,10 @@ function imsanity_set_defaults() {
472
  add_option( 'imsanity_max_height_library', $settings->imsanity_max_height_library, '', false );
473
  add_option( 'imsanity_max_width_other', $settings->imsanity_max_width_other, '', false );
474
  add_option( 'imsanity_max_height_other', $settings->imsanity_max_height_other, '', false );
475
- add_option( 'imsanity_png_to_jpg', $settings->imsanity_png_to_jpg, '', false );
476
  add_option( 'imsanity_bmp_to_jpg', $settings->imsanity_bmp_to_jpg, '', false );
 
477
  add_option( 'imsanity_quality', $settings->imsanity_quality, '', false );
478
- add_option( 'imsanity_deep_scan', $settings->imsanity_deep_scan, '', false );
479
  if ( ! get_option( 'imsanity_version' ) ) {
480
  global $wpdb;
481
  $wpdb->query( "UPDATE $wpdb->options SET autoload='no' WHERE option_name LIKE 'imsanity_%'" );
@@ -492,16 +516,16 @@ function imsanity_register_settings() {
492
  imsanity_network_settings_update();
493
  }
494
  // Register our settings.
495
- register_setting( 'imsanity-settings-group', 'imsanity_max_height' );
496
- register_setting( 'imsanity-settings-group', 'imsanity_max_width' );
497
- register_setting( 'imsanity-settings-group', 'imsanity_max_height_library' );
498
- register_setting( 'imsanity-settings-group', 'imsanity_max_width_library' );
499
- register_setting( 'imsanity-settings-group', 'imsanity_max_height_other' );
500
- register_setting( 'imsanity-settings-group', 'imsanity_max_width_other' );
501
- register_setting( 'imsanity-settings-group', 'imsanity_bmp_to_jpg' );
502
- register_setting( 'imsanity-settings-group', 'imsanity_png_to_jpg' );
503
  register_setting( 'imsanity-settings-group', 'imsanity_quality', 'imsanity_jpg_quality' );
504
- register_setting( 'imsanity-settings-group', 'imsanity_deep_scan' );
505
  }
506
 
507
  /**
@@ -603,6 +627,11 @@ function imsanity_settings_page() {
603
  ?>
604
  <div class="wrap">
605
  <h1><?php esc_html_e( 'Imsanity Settings', 'imsanity' ); ?></h1>
 
 
 
 
 
606
 
607
  <div id="ewwwio-promo">
608
  <p>
@@ -637,34 +666,64 @@ function imsanity_settings_page() {
637
  <h2 style="margin-top: 0px;"><?php esc_html_e( 'Bulk Resize Images', 'imsanity' ); ?></h2>
638
 
639
  <div id="imsanity_header">
640
- <p><?php esc_html_e( 'If you have existing images that were uploaded prior to installing Imsanity, you may resize them all in bulk to recover disk space. To begin, click the "Search Images" button to search all existing attachments for images that are larger than the configured limit.', 'imsanity' ); ?></p>
641
- <?php /* translators: %s: the WP-CLI command to run */ ?>
642
- <p><?php printf( esc_html__( 'You may also use WP-CLI to resize your images: %s', 'imsanity' ), '<code>wp help imsanity resize</code>' ); ?></p>
643
- <?php /* translators: %d: the number of images */ ?>
644
- <p><?php printf( esc_html__( 'NOTE: To give you greater control over the resizing process, a maximum of %d images will be returned at one time. Bitmap images cannot be bulk resized and will not appear in the search results.', 'imsanity' ), IMSANITY_AJAX_MAX_RECORDS ); ?></p>
 
 
 
 
 
 
645
  </div>
646
 
647
- <div style="border: solid 1px #ff6666; background-color: #ffbbbb; padding: 0 10px;">
648
  <h4><?php esc_html_e( 'WARNING: Bulk Resize will alter your original images and cannot be undone!', 'imsanity' ); ?></h4>
649
- <p><?php esc_html_e( 'It is HIGHLY recommended that you backup your wp-content/uploads folder before proceeding. You will have a chance to preview and select the images to convert.', 'imsanity' ); ?><br>
650
- <?php esc_html_e( 'It is also recommended that you initially select only 1 or 2 images and verify that everything is working properly before processing your entire library.', 'imsanity' ); ?></p>
 
 
 
 
 
 
 
 
651
  </div>
652
 
 
 
 
 
 
 
 
653
  <p class="submit" id="imsanity-examine-button">
654
- <button class="button-primary" onclick="imsanity_load_images('imsanity_image_list');"><?php esc_html_e( 'Search Images...', 'imsanity' ); ?></button>
655
  </p>
656
- <div id='imsanity_image_list'>
657
- <div id="imsanity_target" style="display: none; border: solid 2px #666666; padding: 10px; height: 0px; overflow: auto;">
658
- <div id="imsanity_loading" style="display: none;"><img src="<?php echo plugins_url( 'images/ajax-loader.gif', __FILE__ ); ?>" style="margin-bottom: .25em; vertical-align:middle;" />
659
- <?php esc_html_e( 'Scanning existing images. This may take a moment.', 'imsanity' ); ?>
660
- </div>
661
- </div>
 
 
 
 
 
 
 
 
 
 
662
  </div>
663
 
664
  <?php
665
 
666
  echo '</div>';
667
-
668
  }
669
 
670
  /**
@@ -678,6 +737,16 @@ function imsanity_settings_page_notice() {
678
  <?php
679
  }
680
 
 
 
 
 
 
 
 
 
 
 
681
  /**
682
  * Render the site settings form. This is processed by
683
  * WordPress built-in options persistance mechanism
@@ -715,30 +784,48 @@ function imsanity_settings_page_form() {
715
 
716
 
717
  <tr>
718
- <th scope="row"><label for='imsanity_quality' ><?php esc_html_e( 'JPG image quality', 'imsanity' ); ?></th>
719
- <td><input type='text' id='imsanity_quality' name='imsanity_quality' class='small-text' value='<?php echo imsanity_jpg_quality(); ?>' /> <?php esc_html_e( 'Valid values are 1-100.', 'imsanity' ); ?>
720
- <p class='description'><?php esc_html_e( 'Only used when resizing images, does not affect thumbnails.', 'imsanity' ); ?></p></td>
 
 
 
 
 
721
  </tr>
722
 
723
  <tr>
724
- <th scope="row"><label for="imsanity_bmp_to_jpg"><?php esc_html_e( 'Convert BMP To JPG', 'imsanity' ); ?></label></th>
725
- <td><select name="imsanity_bmp_to_jpg">
726
- <option <?php selected( get_option( 'imsanity_bmp_to_jpg', IMSANITY_DEFAULT_BMP_TO_JPG ), '1' ); ?> value="1"><?php esc_html_e( 'Yes', 'imsanity' ); ?></option>
727
- <option <?php selected( get_option( 'imsanity_bmp_to_jpg', IMSANITY_DEFAULT_BMP_TO_JPG ), '0' ); ?> value="0"><?php esc_html_e( 'No', 'imsanity' ); ?></option>
728
- </select></td>
 
 
729
  </tr>
730
-
731
  <tr>
732
- <th scope="row"><label for="imsanity_png_to_jpg"><?php esc_html_e( 'Convert PNG To JPG', 'imsanity' ); ?></label></th>
733
- <td><select name="imsanity_png_to_jpg">
734
- <option <?php selected( get_option( 'imsanity_png_to_jpg', IMSANITY_DEFAULT_PNG_TO_JPG ), '1' ); ?> value="1"><?php esc_html_e( 'Yes', 'imsanity' ); ?></option>
735
- <option <?php selected( get_option( 'imsanity_png_to_jpg', IMSANITY_DEFAULT_PNG_TO_JPG ), '0' ); ?> value="0"><?php esc_html_e( 'No', 'imsanity' ); ?></option>
736
- </select></td>
 
 
 
 
 
 
 
 
737
  </tr>
738
-
739
  <tr>
740
- <th scope="row"><label for="imsanity_deep_scan"><?php esc_html_e( 'Deep Scan', 'imsanity' ); ?></label></th>
741
- <td><input type="checkbox" id="imsanity_deep_scan" name="imsanity_deep_scan" value="true"<?php echo ( get_option( 'imsanity_deep_scan' ) ) ? " checked='true'" : ''; ?> /><?php esc_html_e( 'If searching repeatedly returns the same images, deep scanning will check the actual image dimensions instead of relying on metadata from the database.', 'imsanity' ); ?></td>
 
 
 
 
 
742
  </tr>
743
  </table>
744
 
88
  */
89
  function imsanity_queue_script( $hook ) {
90
  // Make sure we are being called from the settings page.
91
+ if ( strpos( $hook, 'settings_page_imsanity' ) !== 0 && 'upload.php' !== $hook ) {
92
  return;
93
  }
94
+ if ( ! empty( $_REQUEST['imsanity_reset'] ) && ! empty( $_REQUEST['imsanity_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['imsanity_wpnonce'] ), 'imsanity-bulk-reset' ) ) {
95
+ update_option( 'imsanity_resume_id', 0, false );
96
+ }
97
+ $resume_id = (int) get_option( 'imsanity_resume_id' );
98
+ $loading_image = plugins_url( '/images/ajax-loader.gif', __FILE__ );
99
  // Register the scripts that are used by the bulk resizer.
100
  wp_enqueue_script( 'imsanity_script', plugins_url( '/scripts/imsanity.js', __FILE__ ), array( 'jquery' ), IMSANITY_VERSION );
101
  wp_localize_script(
103
  'imsanity_vars',
104
  array(
105
  '_wpnonce' => wp_create_nonce( 'imsanity-bulk' ),
106
+ 'resizing_complete' => esc_html__( 'Resizing Complete', 'imsanity' ) . ' - <a target="_blank" href="https://wordpress.org/support/plugin/imsanity/reviews/#new-post">' . esc_html__( 'Leave a Review', 'imsanity' ) . '</a>',
107
  'resize_selected' => esc_html__( 'Resize Selected Images', 'imsanity' ),
108
+ 'resizing' => '<p>' . esc_html__( 'Please wait...', 'imsanity' ) . "&nbsp;<img src='$loading_image' /></p>",
109
+ 'removal_failed' => esc_html__( 'Removal Failed', 'imsanity' ),
110
+ 'removal_succeeded' => esc_html__( 'Removal Complete', 'imsanity' ),
111
+ 'operation_stopped' => esc_html__( 'Resizing stopped, reload page to resume.', 'imsanity' ),
112
  'image' => esc_html__( 'Image', 'imsanity' ),
113
  'invalid_response' => esc_html__( 'Received an invalid response, please check for errors in the Developer Tools console of your browser.', 'imsanity' ),
114
  'none_found' => esc_html__( 'There are no images that need to be resized.', 'imsanity' ),
115
+ 'resume_id' => $resume_id,
116
  )
117
  );
118
+ add_action( 'admin_notices', 'imsanity_missing_gd_admin_notice' );
119
+ add_action( 'network_admin_notices', 'imsanity_missing_gd_admin_notice' );
120
  add_action( 'admin_print_scripts', 'imsanity_settings_css' );
121
  }
122
 
169
  $data->imsanity_max_width_other = IMSANITY_DEFAULT_MAX_WIDTH;
170
  $data->imsanity_bmp_to_jpg = IMSANITY_DEFAULT_BMP_TO_JPG;
171
  $data->imsanity_png_to_jpg = IMSANITY_DEFAULT_PNG_TO_JPG;
 
172
  $data->imsanity_quality = IMSANITY_DEFAULT_QUALITY;
173
+ $data->imsanity_delete_originals = false;
174
  return $data;
175
  }
176
 
272
  <input type="hidden" name="update_imsanity_settings" value="1" />
273
  <?php wp_nonce_field( 'imsanity_network_options' ); ?>
274
  <table class="form-table">
275
+ <tr>
276
+ <th scope="row"><label for="imsanity_override_site"><?php esc_html_e( 'Global Settings Override', 'imsanity' ); ?></label></th>
277
+ <td>
278
+ <select name="imsanity_override_site">
279
+ <option value="0" <?php selected( $settings->imsanity_override_site, '0' ); ?> ><?php esc_html_e( 'Allow each site to configure Imsanity settings', 'imsanity' ); ?></option>
280
+ <option value="1" <?php selected( $settings->imsanity_override_site, '1' ); ?> ><?php esc_html_e( 'Use global Imsanity settings (below) for all sites', 'imsanity' ); ?></option>
281
+ </select>
282
+ <p class="description"><?php esc_html_e( 'If you allow per-site configuration, the settings below will be used as the defaults. Single-site defaults will be set the first time you visit the site admin after activating Imsanity.', 'imsanity' ); ?></p>
283
+ </td>
284
+ </tr>
285
+ <tr>
286
+ <th scope="row"><?php esc_html_e( 'Images uploaded within a Page/Post', 'imsanity' ); ?></th>
287
+ <td>
288
+ <label for="imsanity_max_width"><?php esc_html_e( 'Max Width', 'imsanity' ); ?></label> <input type="number" step="1" min="0" class='small-text' name="imsanity_max_width" value="<?php echo (int) $settings->imsanity_max_width; ?>" />
289
+ <label for="imsanity_max_height"><?php esc_html_e( 'Max Height', 'imsanity' ); ?></label> <input type="number" step="1" min="0" class="small-text" name="imsanity_max_height" value="<?php echo (int) $settings->imsanity_max_height; ?>" /> <?php esc_html_e( 'in pixels, enter 0 to disable', 'imsanity' ); ?>
290
+ <p class="description"><?php esc_html_e( 'These dimensions are used for Bulk Resizing also.', 'imsanity' ); ?></p>
291
+ </td>
292
+ </tr>
293
+ <tr>
294
+ <th scope="row"><?php esc_html_e( 'Images uploaded directly to the Media Library', 'imsanity' ); ?></th>
295
+ <td>
296
+ <label for="imsanity_max_width_library"><?php esc_html_e( 'Max Width', 'imsanity' ); ?></label> <input type="number" step="1" min="0" class='small-text' name="imsanity_max_width_library" value="<?php echo (int) $settings->imsanity_max_width_library; ?>" />
297
+ <label for="imsanity_max_height_library"><?php esc_html_e( 'Max Height', 'imsanity' ); ?></label> <input type="number" step="1" min="0" class="small-text" name="imsanity_max_height_library" value="<?php echo (int) $settings->imsanity_max_height_library; ?>" /> <?php esc_html_e( 'in pixels, enter 0 to disable', 'imsanity' ); ?>
298
+ </td>
299
+ </tr>
300
+ <tr>
301
+ <th scope="row"><?php esc_html_e( 'Images uploaded elsewhere (Theme headers, backgrounds, logos, etc)', 'imsanity' ); ?></th>
302
+ <td>
303
+ <label for="imsanity_max_width_other"><?php esc_html_e( 'Max Width', 'imsanity' ); ?></label> <input type="number" step="1" min="0" class='small-text' name="imsanity_max_width_other" value="<?php echo (int) $settings->imsanity_max_width_other; ?>" />
304
+ <label for="imsanity_max_height_other"><?php esc_html_e( 'Max Height', 'imsanity' ); ?></label> <input type="number" step="1" min="0" class="small-text" name="imsanity_max_height_other" value="<?php echo (int) $settings->imsanity_max_height_other; ?>" /> <?php esc_html_e( 'in pixels, enter 0 to disable', 'imsanity' ); ?>
305
+ </td>
306
+ </tr>
307
+ <tr>
308
+ <th scope="row">
309
+ <label for='imsanity_quality'><?php esc_html_e( 'JPG image quality', 'imsanity' ); ?>
310
+ </th>
311
+ <td>
312
+ <input type='text' id='imsanity_quality' name='imsanity_quality' class='small-text' value='<?php echo (int) $settings->imsanity_quality; ?>' />
313
+ <?php esc_html_e( 'Valid values are 1-100.', 'imsanity' ); ?>
314
+ <p class='description'><?php esc_html_e( 'Only used when resizing images, does not affect thumbnails.', 'imsanity' ); ?></p>
315
+ </td>
316
+ </tr>
317
+ <tr>
318
+ <th scope="row">
319
+ <label for"imsanity_bmp_to_jpg"><?php esc_html_e( 'Convert BMP to JPG', 'imsanity' ); ?></label>
320
+ </th>
321
+ <td>
322
+ <input type="checkbox" id="imsanity_bmp_to_jpg" name="imsanity_bmp_to_jpg" value="true" <?php checked( $settings->imsanity_bmp_to_jpg ); ?> />
323
+ <?php esc_html_e( 'Only applies to new image uploads, existing BMP images cannot be converted or resized.', 'imsanity' ); ?>
324
+ </td>
325
+ </tr>
326
+ <tr>
327
+ <th scope="row">
328
+ <label for="imsanity_png_to_jpg"><?php esc_html_e( 'Convert PNG to JPG', 'imsanity' ); ?></label>
329
+ </th>
330
+ <td>
331
+ <input type="checkbox" id="imsanity_png_to_jpg" name="imsanity_png_to_jpg" value="true" <?php checked( $settings->imsanity_png_to_jpg ); ?> />
332
+ <?php
333
+ printf(
334
+ /* translators: %s: link to install EWWW Image Optimizer plugin */
335
+ esc_html__( 'Only applies to new image uploads, existing images may be converted with %s.', 'imsanity' ),
336
+ '<a href="' . admin_url( 'plugin-install.php?s=ewww+image+optimizer&tab=search&type=term' ) . '">EWWW Image Optimizer</a>'
337
+ );
338
+ ?>
339
+ </td>
340
+ </tr>
341
+ <tr>
342
+ <th scope="row">
343
+ <label for="imsanity_delete_originals"><?php esc_html_e( 'Delete Originals', 'imsanity' ); ?></label>
344
+ </th>
345
+ <td>
346
+ <input type="checkbox" id="imsanity_delete_originals" name="imsanity_delete_originals" value="true" <?php checked( $settings->imsanity_delete_originals ); ?> />
347
+ <?php esc_html_e( 'Remove the large pre-scaled originals that WordPress retains for thumbnail generation.', 'imsanity' ); ?>
348
+ </td>
349
+ </tr>
350
  </table>
351
 
352
  <p class="submit"><input type="submit" class="button-primary" value="<?php esc_attr_e( 'Update Settings', 'imsanity' ); ?>" /></p>
382
  $data->imsanity_max_width_library = sanitize_text_field( $_POST['imsanity_max_width_library'] );
383
  $data->imsanity_max_height_other = sanitize_text_field( $_POST['imsanity_max_height_other'] );
384
  $data->imsanity_max_width_other = sanitize_text_field( $_POST['imsanity_max_width_other'] );
385
+ $data->imsanity_bmp_to_jpg = ! empty( $_POST['imsanity_bmp_to_jpg'] );
386
+ $data->imsanity_png_to_jpg = ! empty( $_POST['imsanity_png_to_jpg'] );
387
  $data->imsanity_quality = imsanity_jpg_quality( $_POST['imsanity_quality'] );
388
+ $data->imsanity_delete_originals = ! empty( $_POST['imsanity_delete_originals'] );
389
 
390
  $success = $wpdb->update(
391
  $wpdb->imsanity_ms,
436
  $_imsanity_multisite_settings->imsanity_max_width_other = $_imsanity_multisite_settings->imsanity_max_width;
437
  }
438
  $_imsanity_multisite_settings->imsanity_override_site = ! empty( $_imsanity_multisite_settings->imsanity_override_site ) ? '1' : '0';
439
+ $_imsanity_multisite_settings->imsanity_bmp_to_jpg = ! empty( $_imsanity_multisite_settings->imsanity_bmp_to_jpg ) ? true : false;
440
+ $_imsanity_multisite_settings->imsanity_png_to_jpg = ! empty( $_imsanity_multisite_settings->imsanity_png_to_jpg ) ? true : false;
441
+ if ( ! property_exists( $_imsanity_multisite_settings, 'imsanity_delete_originals' ) ) {
442
+ $_imsanity_multisite_settings->imsanity_delete_originals = false;
443
  }
444
  }
445
  return $_imsanity_multisite_settings;
496
  add_option( 'imsanity_max_height_library', $settings->imsanity_max_height_library, '', false );
497
  add_option( 'imsanity_max_width_other', $settings->imsanity_max_width_other, '', false );
498
  add_option( 'imsanity_max_height_other', $settings->imsanity_max_height_other, '', false );
 
499
  add_option( 'imsanity_bmp_to_jpg', $settings->imsanity_bmp_to_jpg, '', false );
500
+ add_option( 'imsanity_png_to_jpg', $settings->imsanity_png_to_jpg, '', false );
501
  add_option( 'imsanity_quality', $settings->imsanity_quality, '', false );
502
+ add_option( 'imsanity_delete_originals', $settings->imsanity_delete_originals, '', false );
503
  if ( ! get_option( 'imsanity_version' ) ) {
504
  global $wpdb;
505
  $wpdb->query( "UPDATE $wpdb->options SET autoload='no' WHERE option_name LIKE 'imsanity_%'" );
516
  imsanity_network_settings_update();
517
  }
518
  // Register our settings.
519
+ register_setting( 'imsanity-settings-group', 'imsanity_max_height', 'intval' );
520
+ register_setting( 'imsanity-settings-group', 'imsanity_max_width', 'intval' );
521
+ register_setting( 'imsanity-settings-group', 'imsanity_max_height_library', 'intval' );
522
+ register_setting( 'imsanity-settings-group', 'imsanity_max_width_library', 'intval' );
523
+ register_setting( 'imsanity-settings-group', 'imsanity_max_height_other', 'intval' );
524
+ register_setting( 'imsanity-settings-group', 'imsanity_max_width_other', 'intval' );
525
+ register_setting( 'imsanity-settings-group', 'imsanity_bmp_to_jpg', 'boolval' );
526
+ register_setting( 'imsanity-settings-group', 'imsanity_png_to_jpg', 'boolval' );
527
  register_setting( 'imsanity-settings-group', 'imsanity_quality', 'imsanity_jpg_quality' );
528
+ register_setting( 'imsanity-settings-group', 'imsanity_delete_originals', 'boolval' );
529
  }
530
 
531
  /**
627
  ?>
628
  <div class="wrap">
629
  <h1><?php esc_html_e( 'Imsanity Settings', 'imsanity' ); ?></h1>
630
+ <p>
631
+ <a target="_blank" href="https://wordpress.org/plugins/imsanity/#faq-header"><?php esc_html_e( 'FAQ', 'imsanity' ); ?></a> |
632
+ <a target="_blank" href="https://wordpress.org/support/plugin/imsanity/"><?php esc_html_e( 'Support', 'imsanity' ); ?></a> |
633
+ <a target="_blank" href="https://wordpress.org/support/plugin/imsanity/reviews/#new-post"><?php esc_html_e( 'Leave a Review', 'imsanity' ); ?></a>
634
+ </p>
635
 
636
  <div id="ewwwio-promo">
637
  <p>
666
  <h2 style="margin-top: 0px;"><?php esc_html_e( 'Bulk Resize Images', 'imsanity' ); ?></h2>
667
 
668
  <div id="imsanity_header">
669
+ <p><?php esc_html_e( 'If you have existing images that were uploaded prior to installing Imsanity, you may resize them all in bulk to recover disk space (below).', 'imsanity' ); ?></p>
670
+ <p>
671
+ <?php
672
+ printf(
673
+ /* translators: 1: List View in the Media Library 2: the WP-CLI command */
674
+ esc_html__( 'You may also use %1$s to selectively resize images or WP-CLI to resize your images in bulk: %2$s', 'imsanity' ),
675
+ '<a href="' . esc_url( admin_url( 'upload.php?mode=list' ) ) . '">' . esc_html__( 'List View in the Media Library', 'imsanity' ) . '</a>',
676
+ '<code>wp help imsanity resize</code>'
677
+ );
678
+ ?>
679
+ </p>
680
  </div>
681
 
682
+ <div style="border: solid 1px #ff6666; background-color: #ffbbbb; padding: 0 10px;margin-bottom:1em;">
683
  <h4><?php esc_html_e( 'WARNING: Bulk Resize will alter your original images and cannot be undone!', 'imsanity' ); ?></h4>
684
+ <p>
685
+ <?php esc_html_e( 'It is HIGHLY recommended that you backup your images before proceeding.', 'imsanity' ); ?><br>
686
+ <?php
687
+ printf(
688
+ /* translators: %s: List View in the Media Library */
689
+ esc_html__( 'You may also resize 1 or 2 images using %s to verify that everything is working properly before processing your entire library.', 'imsanity' ),
690
+ '<a href="' . esc_url( admin_url( 'upload.php?mode=list' ) ) . '">' . esc_html__( 'List View in the Media Library', 'imsanity' ) . '</a>'
691
+ );
692
+ ?>
693
+ </p>
694
  </div>
695
 
696
+ <?php
697
+ $button_text = __( 'Start Resizing All Images', 'imsanity' );
698
+ if ( get_option( 'imsanity_resume_id' ) ) {
699
+ $button_text = __( 'Continue Resizing', 'imsanity' );
700
+ }
701
+ ?>
702
+
703
  <p class="submit" id="imsanity-examine-button">
704
+ <button class="button-primary" onclick="imsanity_load_images();"><?php echo esc_html( $button_text ); ?></button>
705
  </p>
706
+ <form id="imsanity-bulk-stop" style="display:none;margin:1em 0 1em;" method="post" action="">
707
+ <button type="submit" class="button-secondary action"><?php esc_html_e( 'Stop Resizing', 'imsanity' ); ?></button>
708
+ </form>
709
+ <?php if ( get_option( 'imsanity_resume_id' ) ) : ?>
710
+ <p class="imsanity-bulk-text" style="margin-top:1em;"><?php esc_html_e( 'Would you like to start back at the beginning?', 'imsanity' ); ?></p>
711
+ <form class="imsanity-bulk-form" method="post" action="">
712
+ <?php wp_nonce_field( 'imsanity-bulk-reset', 'imsanity_wpnonce' ); ?>
713
+ <input type="hidden" name="imsanity_reset" value="1">
714
+ <button id="imsanity-bulk-reset" type="submit" class="button-secondary action"><?php esc_html_e( 'Start Over', 'imsanity' ); ?></button>
715
+ </form>
716
+ <?php endif; ?>
717
+ <div id="imsanity_loading" style="display: none;margin:1em 0 1em;"><img src="<?php echo plugins_url( 'images/ajax-loader.gif', __FILE__ ); ?>" style="margin-bottom: .25em; vertical-align:middle;" />
718
+ <?php esc_html_e( 'Searching for images. This may take a moment.', 'imsanity' ); ?>
719
+ </div>
720
+ <div id="resize_results" style="display: none; border: solid 2px #666666; padding: 10px; height: 400px; overflow: auto;">
721
+ <div id="bulk-resize-beginning"><?php esc_html_e( 'Resizing...', 'imsanity' ); ?> <img src="<?php echo plugins_url( 'images/ajax-loader.gif', __FILE__ ); ?>" style="margin-bottom: .25em; vertical-align:middle;" /></div>
722
  </div>
723
 
724
  <?php
725
 
726
  echo '</div>';
 
727
  }
728
 
729
  /**
737
  <?php
738
  }
739
 
740
+ /**
741
+ * Check to see if GD is missing, and alert the user.
742
+ */
743
+ function imsanity_missing_gd_admin_notice() {
744
+ if ( imsanity_gd_support() ) {
745
+ return;
746
+ }
747
+ echo "<div id='imsanity-missing-gd' class='notice notice-warning'><p>" . esc_html__( 'The GD extension is not enabled in PHP, Imsanity may not function correctly. Enable GD or contact your web host for assistance.', 'imsanity' ) . '</p></div>';
748
+ }
749
+
750
  /**
751
  * Render the site settings form. This is processed by
752
  * WordPress built-in options persistance mechanism
784
 
785
 
786
  <tr>
787
+ <th scope="row">
788
+ <label for='imsanity_quality' ><?php esc_html_e( 'JPG image quality', 'imsanity' ); ?>
789
+ </th>
790
+ <td>
791
+ <input type='text' id='imsanity_quality' name='imsanity_quality' class='small-text' value='<?php echo imsanity_jpg_quality(); ?>' />
792
+ <?php esc_html_e( 'Valid values are 1-100.', 'imsanity' ); ?>
793
+ <p class='description'><?php esc_html_e( 'Only used when resizing images, does not affect thumbnails.', 'imsanity' ); ?></p>
794
+ </td>
795
  </tr>
796
 
797
  <tr>
798
+ <th scope="row">
799
+ <label for="imsanity_bmp_to_jpg"><?php esc_html_e( 'Convert BMP To JPG', 'imsanity' ); ?></label>
800
+ </th>
801
+ <td>
802
+ <input type="checkbox" id="imsanity_bmp_to_jpg" name="imsanity_bmp_to_jpg" value="true" <?php checked( (bool) get_option( 'imsanity_bmp_to_jpg', IMSANITY_DEFAULT_BMP_TO_JPG ) ); ?> />
803
+ <?php esc_html_e( 'Only applies to new image uploads, existing BMP images cannot be converted or resized.', 'imsanity' ); ?>
804
+ </td>
805
  </tr>
 
806
  <tr>
807
+ <th scope="row">
808
+ <label for="imsanity_png_to_jpg"><?php esc_html_e( 'Convert PNG To JPG', 'imsanity' ); ?></label>
809
+ </th>
810
+ <td>
811
+ <input type="checkbox" id="imsanity_png_to_jpg" name="imsanity_png_to_jpg" value="true" <?php checked( (bool) get_option( 'imsanity_png_to_jpg', IMSANITY_DEFAULT_PNG_TO_JPG ) ); ?> />
812
+ <?php
813
+ printf(
814
+ /* translators: %s: link to install EWWW Image Optimizer plugin */
815
+ esc_html__( 'Only applies to new image uploads, existing images may be converted with %s.', 'imsanity' ),
816
+ '<a href="' . admin_url( 'plugin-install.php?s=ewww+image+optimizer&tab=search&type=term' ) . '">EWWW Image Optimizer</a>'
817
+ );
818
+ ?>
819
+ </td>
820
  </tr>
 
821
  <tr>
822
+ <th scope="row">
823
+ <label for="imsanity_delete_originals"><?php esc_html_e( 'Delete Originals', 'imsanity' ); ?></label>
824
+ </th>
825
+ <td>
826
+ <input type="checkbox" id="imsanity_delete_originals" name="imsanity_delete_originals" value="true" <?php checked( get_option( 'imsanity_delete_originals' ) ); ?> />
827
+ <?php esc_html_e( 'Remove the large pre-scaled originals that WordPress retains for thumbnail generation.', 'imsanity' ); ?>
828
+ </td>
829
  </tr>
830
  </table>
831