/wp-content/plugins/wp-smushit/lib/class-wp-smush-resize.php

https://gitlab.com/meixnertobias/thaimaidaiproductionwp · PHP · 404 lines · 166 code · 73 blank · 165 comment · 41 complexity · aaae71a1c6e0da33820fb2b95c7a46e7 MD5 · raw file

  1. <?php
  2. /**
  3. * @package WP Smush
  4. * @subpackage Admin
  5. * @version 2.3
  6. *
  7. * @author Umesh Kumar <umesh@incsub.com>
  8. *
  9. * @copyright (c) 2016, Incsub (http://incsub.com)
  10. */
  11. if ( ! class_exists( 'WpSmushResize' ) ) {
  12. /**
  13. * Class WpSmushResize
  14. */
  15. class WpSmushResize {
  16. /**
  17. * @var int Specified width for resizing images
  18. *
  19. */
  20. public $max_w = 0;
  21. /**
  22. * @var int Specified Height for resizing images
  23. *
  24. */
  25. public $max_h = 0;
  26. /**
  27. * @var bool If resizing is enabled or not
  28. */
  29. public $resize_enabled = false;
  30. function __construct() {
  31. /**
  32. * Initialize class variables, after all stuff has been loaded
  33. */
  34. add_action( 'wp_loaded', array( $this, 'initialize' ) );
  35. }
  36. /**
  37. * Get the settings for resizing
  38. */
  39. function initialize() {
  40. //If resizing is enabled
  41. $this->resize_enabled = get_option( WP_SMUSH_PREFIX . 'resize' );
  42. $resize_sizes = get_option( WP_SMUSH_PREFIX . 'resize_sizes', array() );
  43. //Resize width and Height
  44. $this->max_w = ! empty( $resize_sizes['width'] ) ? $resize_sizes['width'] : 0;
  45. $this->max_h = ! empty( $resize_sizes['height'] ) ? $resize_sizes['height'] : 0;
  46. }
  47. /**
  48. * Check whether Image should be resized or not
  49. *
  50. * @param string $params
  51. * @param string $action
  52. *
  53. * @return bool
  54. */
  55. private function should_resize( $id = '' ) {
  56. //If resizing not enabled, or if both max width and height is set to 0, return
  57. if ( ! $this->resize_enabled || ( $this->max_w == 0 && $this->max_h == 0 ) ) {
  58. return false;
  59. }
  60. $file_path = get_attached_file( $id );
  61. if ( ! empty( $file_path ) ) {
  62. // Skip: if "noresize" is included in the filename, Thanks to Imsanity
  63. if ( strpos( $file_path, 'noresize' ) !== false ) {
  64. return false;
  65. }
  66. //If file doesn't exists, return
  67. if ( ! file_exists( $file_path ) ) {
  68. return false;
  69. }
  70. }
  71. //Check for a supported mime type
  72. global $wpsmushit_admin;
  73. //Get image mime type
  74. $mime = get_post_mime_type( $id );
  75. $mime_supported = in_array( $mime, $wpsmushit_admin->mime_types );
  76. //If type of upload doesn't matches the criteria return
  77. if ( ! empty( $mime ) && ! $mime_supported = apply_filters( 'wp_smush_resmush_mime_supported', $mime_supported, $mime ) ) {
  78. return false;
  79. }
  80. //Check if already resized
  81. $resize_meta = get_post_meta( $id, WP_SMUSH_PREFIX . 'resize_savings', true );
  82. if ( ! empty( $resize_meta ) ) {
  83. return false;
  84. }
  85. return true;
  86. }
  87. /**
  88. * Handles the Auto resizing of new uploaded images
  89. *
  90. * @param array $upload
  91. * @param string $action
  92. *
  93. * @return array $upload
  94. */
  95. function auto_resize( $id, $meta ) {
  96. if ( empty( $id ) || ! wp_attachment_is_image( $id ) ) {
  97. return $meta;
  98. }
  99. //Do not perform resize while restoring images/ Editing images
  100. if ( ! empty( $_REQUEST['do'] ) && ( 'restore' == $_REQUEST['do'] || 'scale' == $_REQUEST['do'] ) ) {
  101. return $meta;
  102. }
  103. //Check if the image should be resized or not
  104. $should_resize = $this->should_resize( $id );
  105. /**
  106. * Filter whether the uploaded image should be resized or not
  107. *
  108. * @since 2.3
  109. *
  110. * @param bool $should_resize
  111. *
  112. * @param array $upload {
  113. * Array of upload data.
  114. *
  115. * @type string $file Filename of the newly-uploaded file.
  116. * @type string $url URL of the uploaded file.
  117. * @type string $type File type.
  118. * }
  119. *
  120. * @param string $context The type of upload action. Values include 'upload' or 'sideload'.
  121. *
  122. */
  123. if ( ! $should_resize = apply_filters( 'wp_smush_resize_uploaded_image', $should_resize, $id, $meta ) ) {
  124. return $meta;
  125. }
  126. //Good to go
  127. $file_path = get_attached_file( $id );
  128. $original_file_size = filesize( $file_path );
  129. $resize = $this->perform_resize( $file_path, $original_file_size, $id, $meta );
  130. //If resize wasn't successful
  131. if ( ! $resize ) {
  132. return $meta;
  133. }
  134. //Else Replace the Original file with resized file
  135. $replaced = $this->replcae_original_image( $file_path, $resize, $id, $meta );
  136. if ( $replaced ) {
  137. //Clear Stat Cache, Else the size obtained is same as the original file size
  138. clearstatcache();
  139. //Updated File size
  140. $u_file_size = filesize( $file_path );
  141. $savings['bytes'] = $original_file_size > $u_file_size ? $original_file_size - $u_file_size : 0;
  142. $savings['size_before'] = $original_file_size;
  143. $savings['size_after'] = $u_file_size;
  144. //Store savings in meta data
  145. if ( ! empty( $savings ) ) {
  146. update_post_meta( $id, WP_SMUSH_PREFIX . 'resize_savings', $savings );
  147. }
  148. $meta['width'] = ! empty( $resize['width'] ) ? $resize['width'] : $meta['width'];
  149. $meta['height'] = ! empty( $resize['height'] ) ? $resize['height'] : $meta['height'];
  150. /**
  151. * Called after the image have been successfully resized
  152. * Can be used to update the stored stats
  153. */
  154. do_action( 'wp_smush_image_resized', $id, $savings );
  155. }
  156. return $meta;
  157. }
  158. /**
  159. * Generates the new image for specified width and height,
  160. * Checks if the size of generated image is greater,
  161. *
  162. * @param $file_path Original File path
  163. *
  164. * @return bool, If the image generation was succesfull
  165. */
  166. function perform_resize( $file_path, $original_file_size, $id, $meta = '', $unlink = true ) {
  167. /**
  168. * Filter the resize image dimensions
  169. *
  170. * @since 2.3
  171. *
  172. * @param array $sizes {
  173. * Array of sizes containing max width and height for all the uploaded images.
  174. *
  175. * @type int $width Maximum Width For resizing
  176. * @type int $height Maximum Height for resizing
  177. * }
  178. *
  179. * @param string $file_path Original Image file path
  180. *
  181. * @param array $upload {
  182. * Array of upload data.
  183. *
  184. * @type string $file Filename of the newly-uploaded file.
  185. * @type string $url URL of the uploaded file.
  186. * @type string $type File type.
  187. * }
  188. *
  189. */
  190. $sizes = apply_filters( 'wp_smush_resize_sizes', array(
  191. 'width' => $this->max_w,
  192. 'height' => $this->max_h
  193. ), $file_path, $id );
  194. $data = image_make_intermediate_size( $file_path, $sizes['width'], $sizes['height'] );
  195. //If the image wasn't resized
  196. if ( empty( $data['file'] ) || is_wp_error( $data ) ) {
  197. return false;
  198. }
  199. //Check if file size is lesser than original image
  200. $resize_path = path_join( dirname( $file_path ), $data['file'] );
  201. if ( ! file_exists( $resize_path ) ) {
  202. return false;
  203. }
  204. $data['file_path'] = $resize_path;
  205. $file_size = filesize( $resize_path );
  206. if ( $file_size > $original_file_size ) {
  207. //Don't Unlink for nextgen images
  208. if( $unlink ) {
  209. $this->maybe_unlink( $resize_path, $meta );
  210. }
  211. return false;
  212. }
  213. //Store filesize
  214. $data['filesize'] = $file_size;
  215. return $data;
  216. }
  217. /**
  218. * Replace the original file with resized file
  219. *
  220. * @param $upload
  221. *
  222. * @param $resized
  223. *
  224. */
  225. function replcae_original_image( $file_path, $resized, $attachment_id = '', $meta = '' ) {
  226. $replaced = false;
  227. //Take Backup, if we have to, off by default
  228. $this->backup_image( $file_path, $attachment_id, $meta );
  229. $replaced = @copy( $resized['file_path'], $file_path );
  230. $this->maybe_unlink( $resized['file_path'], $meta );
  231. return $replaced;
  232. }
  233. /**
  234. * Creates a WordPress backup of original image, Disabled by default
  235. *
  236. * @param $upload
  237. *
  238. * @param $attachment_id
  239. *
  240. * @param $meta
  241. */
  242. function backup_image( $path, $attachment_id, $meta ) {
  243. /**
  244. * Allows to turn on the backup for resized image
  245. */
  246. $backup = apply_filters( 'wp_smush_resize_create_backup', false );
  247. //If we don't have a attachment id, return
  248. if ( empty( $attachment_id ) || ! $backup ) {
  249. return;
  250. }
  251. //Creating Backup
  252. $backup_sizes = get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true );
  253. if ( ! is_array( $backup_sizes ) ) {
  254. $backup_sizes = array();
  255. }
  256. //There is alrready a backup, no need to create one
  257. if ( ! empty( $backup_sizes['full-orig'] ) ) {
  258. return;
  259. }
  260. //Create a copy of original
  261. if ( empty( $path ) ) {
  262. $path = get_attached_file( $attachment_id );
  263. }
  264. $path_parts = pathinfo( $path );
  265. $filename = $path_parts['filename'];
  266. $filename .= '-orig';
  267. //Backup Path
  268. $backup_path = path_join( $path_parts['dirname'], $filename ) . ".{$path_parts['extension']}";
  269. //Create a copy
  270. if ( file_exists( $path ) ) {
  271. $copy_created = @copy( $path, $backup_path );
  272. if ( $copy_created ) {
  273. $backup_sizes['full-orig'] = array(
  274. 'file' => basename( $backup_path ),
  275. 'width' => $meta['width'],
  276. 'height' => $meta['height']
  277. );
  278. //Save in Attachment meta
  279. update_post_meta( $attachment_id, '_wp_attachment_backup_sizes', $backup_sizes );
  280. }
  281. }
  282. }
  283. /**
  284. * @param $filename
  285. *
  286. * @return mixed
  287. */
  288. function file_name( $filename ) {
  289. if ( empty( $filename ) ) {
  290. return $filename;
  291. }
  292. return $filename . 'tmp';
  293. }
  294. /**
  295. * Do not unlink the resized file if the name is similar to one of the image sizes
  296. *
  297. * @param $path Image File Path
  298. * @param $meta Image Meta
  299. *
  300. * @return bool
  301. */
  302. function maybe_unlink( $path, $meta ) {
  303. if ( empty( $path ) ) {
  304. return true;
  305. }
  306. //Unlink directly if meta value is not specified
  307. if ( empty( $meta ) || empty( $meta['sizes'] ) ) {
  308. @unlink( $path );
  309. }
  310. $unlink = true;
  311. //Check if the file name is similar to one of the image sizes
  312. $path_parts = pathinfo( $path );
  313. $filename = ! empty( $path_parts['basename'] ) ? $path_parts['basename'] : $path_parts['filename'];
  314. foreach ( $meta['sizes'] as $image_size ) {
  315. if ( false === strpos( $image_size['file'], $filename ) ) {
  316. continue;
  317. }
  318. $unlink = false;
  319. }
  320. if ( $unlink ) {
  321. @unlink( $path );
  322. }
  323. return true;
  324. }
  325. }
  326. /**
  327. * Initialise class
  328. */
  329. global $wpsmush_resize;
  330. $wpsmush_resize = new WpSmushResize();
  331. }