PluginProbe
Imsanity / 2.4.3
Imsanity v2.4.3
2.9.4 2.9.3 2.9.2 trunk 2.4.3 2.5.0 2.6.0 2.7.0 2.7.2 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.9.0 2.9.1
imsanity / imsanity.php

imsanity.php in Imsanity 2.4.3, at imsanity.php

270 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Main file for Imsanity plugin.
4 *
5 * This file includes the core of Imsanity and the top-level image handler.
6 *
7 * @link https://wordpress.org/plugins/imsanity/
8 * @package Imsanity
9 */
10
11 /*
12 Plugin Name: Imsanity
13 Plugin URI: https://wordpress.org/plugins/imsanity/
14 Description: Imsanity stops insanely huge image uploads
15 Author: Exactly WWW
16 Text Domain: imsanity
17 Version: 2.4.3
18 Author URI: https://ewww.io/
19 License: GPLv3
20 */
21
22 if ( ! defined( 'ABSPATH' ) ) {
23 exit;
24 }
25
26 define( 'IMSANITY_VERSION', '2.4.3' );
27 define( 'IMSANITY_SCHEMA_VERSION', '1.1' );
28
29 define( 'IMSANITY_DEFAULT_MAX_WIDTH', 1920 );
30 define( 'IMSANITY_DEFAULT_MAX_HEIGHT', 1920 );
31 define( 'IMSANITY_DEFAULT_BMP_TO_JPG', 1 );
32 define( 'IMSANITY_DEFAULT_PNG_TO_JPG', 0 );
33 define( 'IMSANITY_DEFAULT_QUALITY', 82 );
34
35 define( 'IMSANITY_SOURCE_POST', 1 );
36 define( 'IMSANITY_SOURCE_LIBRARY', 2 );
37 define( 'IMSANITY_SOURCE_OTHER', 4 );
38
39 if ( ! defined( 'IMSANITY_AJAX_MAX_RECORDS' ) ) {
40 define( 'IMSANITY_AJAX_MAX_RECORDS', 250 );
41 }
42
43 /**
44 * Load translations for Imsanity.
45 */
46 function imsanity_init() {
47 load_plugin_textdomain( 'imsanity', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
48 }
49
50 /**
51 * Import supporting libraries.
52 */
53 include_once( plugin_dir_path( __FILE__ ) . 'libs/utils.php' );
54 include_once( plugin_dir_path( __FILE__ ) . 'settings.php' );
55 include_once( plugin_dir_path( __FILE__ ) . 'ajax.php' );
56
57 /**
58 * Inspects the request and determines where the upload came from.
59 *
60 * @return IMSANITY_SOURCE_POST | IMSANITY_SOURCE_LIBRARY | IMSANITY_SOURCE_OTHER
61 */
62 function imsanity_get_source() {
63 $id = array_key_exists( 'post_id', $_REQUEST ) ? (int) $_REQUEST['post_id'] : '';
64 $action = array_key_exists( 'action', $_REQUEST ) ? $_REQUEST['action'] : '';
65
66 // A post_id indicates image is attached to a post.
67 if ( $id > 0 ) {
68 return IMSANITY_SOURCE_POST;
69 }
70
71 // If the referrer is the post editor, that's a good indication the image is attached to a post.
72 if ( ! empty( $_SERVER['HTTP_REFERER'] ) && strpos( $_SERVER['HTTP_REFERER'], '/post.php' ) ) {
73 return IMSANITY_SOURCE_POST;
74 }
75
76 // Post_id of 0 is 3.x otherwise use the action parameter.
77 if ( 0 === $id || 'upload-attachment' === $action ) {
78 return IMSANITY_SOURCE_LIBRARY;
79 }
80
81 // We don't know where this one came from but $_REQUEST['_wp_http_referer'] may contain info.
82 return IMSANITY_SOURCE_OTHER;
83 }
84
85 /**
86 * Given the source, returns the max width/height.
87 *
88 * @example: list( $w, $h ) = imsanity_get_max_width_height( IMSANITY_SOURCE_LIBRARY );
89 * @param int $source One of IMSANITY_SOURCE_POST | IMSANITY_SOURCE_LIBRARY | IMSANITY_SOURCE_OTHER.
90 */
91 function imsanity_get_max_width_height( $source ) {
92 $w = imsanity_get_option( 'imsanity_max_width', IMSANITY_DEFAULT_MAX_WIDTH );
93 $h = imsanity_get_option( 'imsanity_max_height', IMSANITY_DEFAULT_MAX_HEIGHT );
94
95 switch ( $source ) {
96 case IMSANITY_SOURCE_POST:
97 break;
98 case IMSANITY_SOURCE_LIBRARY:
99 $w = imsanity_get_option( 'imsanity_max_width_library', $w );
100 $h = imsanity_get_option( 'imsanity_max_height_library', $h );
101 break;
102 default:
103 $w = imsanity_get_option( 'imsanity_max_width_other', $w );
104 $h = imsanity_get_option( 'imsanity_max_height_other', $h );
105 break;
106 }
107
108 return array( $w, $h );
109 }
110
111 /**
112 * Handler after a file has been uploaded. If the file is an image, check the size
113 * to see if it is too big and, if so, resize and overwrite the original.
114 *
115 * @param Array $params The parameters submitted with the upload.
116 */
117 function imsanity_handle_upload( $params ) {
118
119 // If "noresize" is included in the filename then we will bypass imsanity scaling.
120 if ( strpos( $params['file'], 'noresize' ) !== false ) {
121 return $params;
122 }
123
124 // If preferences specify so then we can convert an original bmp or png file into jpg.
125 if ( 'image/bmp' === $params['type'] && imsanity_get_option( 'imsanity_bmp_to_jpg', IMSANITY_DEFAULT_BMP_TO_JPG ) ) {
126 $params = imsanity_convert_to_jpg( 'bmp', $params );
127 }
128
129 if ( 'image/png' === $params['type'] && imsanity_get_option( 'imsanity_png_to_jpg', IMSANITY_DEFAULT_PNG_TO_JPG ) ) {
130 $params = imsanity_convert_to_jpg( 'png', $params );
131 }
132
133 // Make sure this is a type of image that we want to convert and that it exists.
134 $oldpath = $params['file'];
135
136 if ( ( ! is_wp_error( $params ) ) && is_file( $oldpath ) && is_readable( $oldpath ) && is_writable( $oldpath ) && filesize( $oldpath ) > 0 && in_array( $params['type'], array( 'image/png', 'image/gif', 'image/jpeg' ), true ) ) {
137
138 // figure out where the upload is coming from.
139 $source = imsanity_get_source();
140
141 list( $maxw,$maxh ) = imsanity_get_max_width_height( $source );
142
143 list( $oldw, $oldh ) = getimagesize( $oldpath );
144
145 if ( ( $oldw > $maxw && $maxw > 0 ) || ( $oldh > $maxh && $maxh > 0 ) ) {
146 $quality = imsanity_get_option( 'imsanity_quality', IMSANITY_DEFAULT_QUALITY );
147
148 $ftype = imsanity_quick_mimetype( $oldpath );
149 $orientation = imsanity_get_orientation( $oldpath, $ftype );
150 // If we are going to rotate the image 90 degrees during the resize, swap the existing image dimensions.
151 if ( 6 === (int) $orientation || 8 === (int) $orientation ) {
152 $old_oldw = $oldw;
153 $oldw = $oldh;
154 $oldh = $old_oldw;
155 }
156
157 if ( $oldw > $maxw && $maxw > 0 && $oldh > $maxh && $maxh > 0 && apply_filters( 'imsanity_crop_image', false ) ) {
158 $neww = $maxw;
159 $newh = $maxh;
160 } else {
161 list( $neww, $newh ) = wp_constrain_dimensions( $oldw, $oldh, $maxw, $maxh );
162 }
163
164 remove_filter( 'wp_image_editors', 'ewww_image_optimizer_load_editor', 60 );
165 $resizeresult = imsanity_image_resize( $oldpath, $neww, $newh, apply_filters( 'imsanity_crop_image', false ), null, null, $quality );
166 if ( function_exists( 'ewww_image_optimizer_load_editor' ) ) {
167 add_filter( 'wp_image_editors', 'ewww_image_optimizer_load_editor', 60 );
168 }
169
170 if ( $resizeresult && ! is_wp_error( $resizeresult ) ) {
171 $newpath = $resizeresult;
172
173 if ( is_file( $newpath ) && filesize( $newpath ) < filesize( $oldpath ) ) {
174 // we saved some file space. remove original and replace with resized image.
175 unlink( $oldpath );
176 rename( $newpath, $oldpath );
177 } elseif ( is_file( $newpath ) ) {
178 // theresized image is actually bigger in filesize (most likely due to jpg quality).
179 // keep the old one and just get rid of the resized image.
180 unlink( $newpath );
181 }
182 } elseif ( false === $resizeresult ) {
183 return $params;
184 } elseif ( is_wp_error( $resizeresult ) ) {
185 // resize didn't work, likely because the image processing libraries are missing.
186 // remove the old image so we don't leave orphan files hanging around.
187 unlink( $oldpath );
188
189 $params = wp_handle_upload_error(
190 $oldpath,
191 sprintf(
192 /* translators: 1: error message 2: link to support forums */
193 esc_html__( 'Imsanity was unable to resize this image for the following reason: %1$s. If you continue to see this error message, you may need to install missing server components. If you think you have discovered a bug, please report it on the Imsanity support forum: %2$s', 'imsanity' ),
194 $resizeresult->get_error_message(),
195 'https://wordpress.org/support/plugin/imsanity'
196 )
197 );
198 } else {
199 return $params;
200 }
201 }
202 }
203 clearstatcache();
204 return $params;
205 }
206
207
208 /**
209 * Read in the image file from the params and then save as a new jpg file.
210 * if successful, remove the original image and alter the return
211 * parameters to return the new jpg instead of the original
212 *
213 * @param string $type Type of the image to be converted: 'bmp' or 'png'.
214 * @param array $params The upload parameters.
215 * @return array altered params
216 */
217 function imsanity_convert_to_jpg( $type, $params ) {
218
219 $img = null;
220
221 if ( 'bmp' === $type ) {
222 include_once( 'libs/imagecreatefrombmp.php' );
223 $img = imagecreatefrombmp( $params['file'] );
224 } elseif ( 'png' === $type ) {
225 if ( ! function_exists( 'imagecreatefrompng' ) ) {
226 return wp_handle_upload_error( $params['file'], esc_html__( 'Imsanity requires the GD library to convert PNG images to JPG', 'imsanity' ) );
227 }
228
229 $input = imagecreatefrompng( $params['file'] );
230 // convert png transparency to white.
231 $img = imagecreatetruecolor( imagesx( $input ), imagesy( $input ) );
232 imagefill( $img, 0, 0, imagecolorallocate( $img, 255, 255, 255 ) );
233 imagealphablending( $img, true );
234 imagecopy( $img, $input, 0, 0, 0, 0, imagesx( $input ), imagesy( $input ) );
235 } else {
236 return wp_handle_upload_error( $params['file'], esc_html__( 'Unknown image type specified in imsanity_convert_to_jpg', 'imsanity' ) );
237 }
238
239 // We need to change the extension from the original to .jpg so we have to ensure it will be a unique filename.
240 $uploads = wp_upload_dir();
241 $oldfilename = basename( $params['file'] );
242 $newfilename = basename( str_ireplace( '.' . $type, '.jpg', $oldfilename ) );
243 $newfilename = wp_unique_filename( $uploads['path'], $newfilename );
244
245 $quality = imsanity_get_option( 'imsanity_quality', IMSANITY_DEFAULT_QUALITY );
246
247 if ( imagejpeg( $img, $uploads['path'] . '/' . $newfilename, $quality ) ) {
248 // Conversion succeeded: remove the original bmp & remap the params.
249 unlink( $params['file'] );
250
251 $params['file'] = $uploads['path'] . '/' . $newfilename;
252 $params['url'] = $uploads['url'] . '/' . $newfilename;
253 $params['type'] = 'image/jpeg';
254 } else {
255 unlink( $params['file'] );
256
257 return wp_handle_upload_error(
258 $oldfilename,
259 /* translators: %s: the image mime type */
260 sprintf( esc_html__( 'Imsanity was unable to process the %s file. If you continue to see this error you may need to disable the conversion option in the Imsanity settings.', 'imsanity' ), $type )
261 );
262 }
263
264 return $params;
265 }
266
267 /* add filters to hook into uploads */
268 add_filter( 'wp_handle_upload', 'imsanity_handle_upload' );
269 add_action( 'plugins_loaded', 'imsanity_init' );
270