en geleden woocommerce-th-a55d428c84e9a3179fe241ec600a0f03.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-a65b4ddf263e8c410e9bcbfd6e6d72e4.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-a8b73b087444470c8f4396b7142908f6.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-abb904b047b7be3be9d638e2c6144691.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-ae1c49c8c0597593a9c36e106a04bd60.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-aed4ce3ede1d44a8fecfe0edfbf8421c.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-af52ab8cb2e7713cf3037751dd593965.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-afbede9cda22f594a80ae8b178e0e98c.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-afd1e270efc2e8283acfd50ccab18d2b.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-b007baff76144318d6c33cd26f4bfdb9.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-b0a592b6fe83588c5d1b8ed6850b6a74.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-b155b7bf28890099b74a84417cbaafe9.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-b1bb8fbd24d68a9c893faf1a6f7b493b.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-b1bcbab1d6a7ca6b0433d67776f347f1.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-b239ff15197a133498a4b025f002dee5.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-b2e956ee35340f6e47f27f8a54309ac3.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-b31f51fa0bb40ceb060aaa9f77ca1771.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-b3f83696a2cb49f571043ce14a384a76.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-b4bf1e55ca6145f38f1b2f104201da21.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-b826befd7acca93e8e4c12b7cd2fc7f1.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-b9bf1ca91d393a30e2461ef709f8fa10.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-ba8d2fb7c85928310d4f3a907b7d9bdd.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-bb0f027faa1257de4b730158475093de.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-bb5c5935ec0d64e8880b1c7794470460.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-bc1f4f7aec77a0a6dd229cc910f601f1.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-bc9c3f9eda462d6d9968c1dca51e7c62.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-bcb06ab6e8931a862dec9c07c66df45b.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c06829f63f73ae430c10ae700fb1eb6d.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c0faba84c7842505f8893c2c327a9f78.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c13acd243559529a685813d9871026a1.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c1bc39bcdee2da3c0b62bcd5372120f4.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c22945301f466e2d78d6e80404a22664.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c2435bc8dfd186b147aba658416d115e.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c257c024e3db4e010644d2c7be3c7090.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c2d9a34cf502bd5b5a80ca646a1420b3.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c5702ace609dd30ccabd4c999de43096.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c608fe5deda8db7667c8431ca6fd222a.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c6c5331d3afe1391f2ca83e991ccc086.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c70671124b0e00661f88fe1616dfc9f0.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c8cbe8ef95155db152b270d441fc8528.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c8ddf2164475a213274d06873bfbb73a.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-c93706e596cbd46fb0d621f4fe3efb80.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-ca3cd4394cb082bde7555ebd3bb5f143.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-cb71ce5ddcc7c808172e80a0dc9833d5.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-cc16013df9d4b0a0ba45297b90b06f20.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-ccc500b0b722a0c96712f1634cbb7289.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-cd9fc1d9fc46b55bb32d0fd471457690.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-ce3f8f2f3e0f3c58f8aea5b7aa5cc6f4.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-d05ee634b22d05f0055b724443f05a68.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-d0d05e0dda872b433f260969b4d53b30.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-d0fa7cd1cd624e53cc7b4fde655c20af.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-d2b4400b6de0e69404e0f7f61d16bc55.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-d3e57c518feb58ab8ea4f9d2d8e66160.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-d4c505e96199e8c818fc6d24151d9c4a.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-d5ea33028f13b50f40bbcce807e37fc0.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-d6f4faa954a31ef3d5b74c2dfe13f141.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-d7bbe90eb59636eb8a6f31c7979ab6f5.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-d80020dab74131d7f0c108526c0fbebe.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-da92a9b2d4c08762c60d7c4c569eb5db.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-de12a4697822740a2fbaeb47c5062af1.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-deed2aed3392b43c83c7cea296b154af.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-df51042cba56a4e9fcac0e5db643906a.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-dfb09f9953676bbc1de4eb2b9f232c6d.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-dfbfe3d556f60ebbd62c2b5c8e0fa466.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-e03ec35386c2705c11cebd6288b33cf8.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-e0bde0ac58f55fc6b1426844e6697db3.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-e0f9c7d89b1b130a9023c5c2fde2815e.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-e41c58d5fb39f750efcbf65a2b55460b.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-e44671e4528b0da3a0fd6feaf8abadca.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-e4fbc8d7fc7a16bd8cf2e0522a199de0.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-e690486b33a7bb1944a37f6e734d734f.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-e80539b9960e930bf0dcd334d99eb128.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-e885442559cb44e8b827f0e0ca0a14c9.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-e88dc35c02f6fa832e90fac5a122323c.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-ea6fb371f81c4d3584bbc795fa4ac09c.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-ed9b16000a6d37c51bf23c61f4df878e.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-ef5798395d7601ab6fea0f1efd60f40a.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-f31b0aa0c71dd74b7103120610ca6253.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-f34924aeff974b0bdbfac124c23fbfe3.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-f39008456fd28b2f79cdb0964ff294e1.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-f3f1cc4f5811d4bf8a04a58feca06858.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-f56e66fd08c07abc78cd844f7e83af8c.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-f60049653c419cfb1e3dc8876e7a8bdb.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-f686a272add740773cdcb730afdb5454.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-f976da155dfdd080588c50ccda5af747.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-f9c56a0cbb6710505047e6c835953c82.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-fb2ef023bdd44902b5a309e25e0b7792.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-fc1fe56fadfdeeb25d1bc441581d92b6.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-fc4895b6508f32c16c4d8bc69f8162b6.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-fd20fc8ea1484781160e8ea0d229d5e9.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-fffdec5db595ec0ca7d043c87bae79b8.json d01d7cf85d first commit 4 jaren geleden woocommerce-th-wc-admin-app.json d01d7cf85d first commit 4 jaren geleden woocommerce-th.mo d01d7cf85d first commit 4 jaren geleden woocommerce-th.po d01d7cf85d first commit 4 jaren geleden tum/whitesports - Gogs: Simplico Git Service

説明なし

class-wc-regenerate-images.php 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. <?php
  2. /**
  3. * Regenerate Images Functionality
  4. *
  5. * All functionality pertaining to regenerating product images in realtime.
  6. *
  7. * @package WooCommerce\Classes
  8. * @version 3.5.0
  9. * @since 3.3.0
  10. */
  11. defined( 'ABSPATH' ) || exit;
  12. /**
  13. * Regenerate Images Class
  14. */
  15. class WC_Regenerate_Images {
  16. /**
  17. * Background process to regenerate all images
  18. *
  19. * @var WC_Regenerate_Images_Request
  20. */
  21. protected static $background_process;
  22. /**
  23. * Stores size being generated on the fly.
  24. *
  25. * @var string
  26. */
  27. protected static $regenerate_size;
  28. /**
  29. * Init function
  30. */
  31. public static function init() {
  32. add_action( 'image_get_intermediate_size', array( __CLASS__, 'filter_image_get_intermediate_size' ), 10, 3 );
  33. add_filter( 'wp_generate_attachment_metadata', array( __CLASS__, 'add_uncropped_metadata' ) );
  34. add_filter( 'wp_get_attachment_image_src', array( __CLASS__, 'maybe_resize_image' ), 10, 4 );
  35. // Not required when Jetpack Photon is in use.
  36. if ( method_exists( 'Jetpack', 'is_module_active' ) && Jetpack::is_module_active( 'photon' ) ) {
  37. return;
  38. }
  39. if ( apply_filters( 'woocommerce_background_image_regeneration', true ) ) {
  40. include_once WC_ABSPATH . 'includes/class-wc-regenerate-images-request.php';
  41. self::$background_process = new WC_Regenerate_Images_Request();
  42. add_action( 'admin_init', array( __CLASS__, 'regenerating_notice' ) );
  43. add_action( 'woocommerce_hide_regenerating_thumbnails_notice', array( __CLASS__, 'dismiss_regenerating_notice' ) );
  44. // Regenerate thumbnails in the background after settings changes. Not ran on multisite to avoid multiple simultanious jobs.
  45. if ( ! is_multisite() ) {
  46. add_action( 'customize_save_after', array( __CLASS__, 'maybe_regenerate_images' ) );
  47. add_action( 'after_switch_theme', array( __CLASS__, 'maybe_regenerate_images' ) );
  48. }
  49. }
  50. }
  51. /**
  52. * If an intermediate size meta differs from the actual image size (settings were changed?) return false so the wrong size is not used.
  53. *
  54. * @param array $data Size data.
  55. * @param int $attachment_id Attachment ID.
  56. * @param string $size Size name.
  57. * @return array
  58. */
  59. public static function filter_image_get_intermediate_size( $data, $attachment_id, $size ) {
  60. if ( ! is_string( $size ) || ! in_array( $size, apply_filters( 'woocommerce_image_sizes_to_resize', array( 'woocommerce_thumbnail', 'woocommerce_gallery_thumbnail', 'woocommerce_single', 'shop_thumbnail', 'shop_catalog', 'shop_single' ) ), true ) ) {
  61. return $data;
  62. }
  63. // If we don't have sizes, we cannot proceed.
  64. if ( ! isset( $data['width'], $data['height'] ) ) {
  65. return $data;
  66. }
  67. // See if the image size has changed from our settings.
  68. if ( ! self::image_size_matches_settings( $data, $size ) ) {
  69. // If Photon is running we can just return false and let Jetpack handle regeneration.
  70. if ( method_exists( 'Jetpack', 'is_module_active' ) && Jetpack::is_module_active( 'photon' ) ) {
  71. return false;
  72. } else {
  73. // If we get here, Jetpack is not running and we don't have the correct image sized stored. Try to return closest match.
  74. $size_data = wc_get_image_size( $size );
  75. return image_get_intermediate_size( $attachment_id, array( absint( $size_data['width'] ), absint( $size_data['height'] ) ) );
  76. }
  77. }
  78. return $data;
  79. }
  80. /**
  81. * We need to track if uncropped was on or off when generating the images.
  82. *
  83. * @param array $meta_data Array of meta data.
  84. * @return array
  85. */
  86. public static function add_uncropped_metadata( $meta_data ) {
  87. $size_data = wc_get_image_size( 'woocommerce_thumbnail' );
  88. if ( isset( $meta_data['sizes'], $meta_data['sizes']['woocommerce_thumbnail'] ) ) {
  89. $meta_data['sizes']['woocommerce_thumbnail']['uncropped'] = empty( $size_data['height'] );
  90. }
  91. return $meta_data;
  92. }
  93. /**
  94. * See if an image's dimensions match actual settings.
  95. *
  96. * @param array $image Image dimensions array.
  97. * @param string $size Named size.
  98. * @return bool True if they match. False if they do not (may trigger regen).
  99. */
  100. protected static function image_size_matches_settings( $image, $size ) {
  101. $target_size = wc_get_image_size( $size );
  102. $uncropped = '' === $target_size['width'] || '' === $target_size['height'];
  103. if ( ! $uncropped ) {
  104. $ratio_match = wp_image_matches_ratio( $image['width'], $image['height'], $target_size['width'], $target_size['height'] );
  105. // Size is invalid if the widths or crop setting don't match.
  106. if ( $ratio_match && $target_size['width'] !== $image['width'] ) {
  107. return false;
  108. }
  109. // Size is invalid if the heights don't match.
  110. if ( $ratio_match && $target_size['height'] && $target_size['height'] !== $image['height'] ) {
  111. return false;
  112. }
  113. }
  114. // If cropping mode has changed, regenerate the image.
  115. if ( $uncropped && empty( $image['uncropped'] ) ) {
  116. return false;
  117. }
  118. return true;
  119. }
  120. /**
  121. * Show notice when job is running in background.
  122. */
  123. public static function regenerating_notice() {
  124. if ( ! self::$background_process->is_running() ) {
  125. WC_Admin_Notices::add_notice( 'regenerating_thumbnails' );
  126. } else {
  127. WC_Admin_Notices::remove_notice( 'regenerating_thumbnails' );
  128. }
  129. }
  130. /**
  131. * Dismiss notice and cancel jobs.
  132. */
  133. public static function dismiss_regenerating_notice() {
  134. if ( self::$background_process ) {
  135. self::$background_process->kill_process();
  136. $log = wc_get_logger();
  137. $log->info(
  138. __( 'Cancelled product image regeneration job.', 'woocommerce' ),
  139. array(
  140. 'source' => 'wc-image-regeneration',
  141. )
  142. );
  143. }
  144. WC_Admin_Notices::remove_notice( 'regenerating_thumbnails' );
  145. }
  146. /**
  147. * Regenerate images if the settings have changed since last re-generation.
  148. *
  149. * @return void
  150. */
  151. public static function maybe_regenerate_images() {
  152. $size_hash = md5(
  153. wp_json_encode(
  154. array(
  155. wc_get_image_size( 'thumbnail' ),
  156. wc_get_image_size( 'single' ),
  157. wc_get_image_size( 'gallery_thumbnail' ),
  158. )
  159. )
  160. );
  161. if ( update_option( 'woocommerce_maybe_regenerate_images_hash', $size_hash ) ) {
  162. // Size settings have changed. Trigger regen.
  163. self::queue_image_regeneration();
  164. }
  165. }
  166. /**
  167. * Check if we should maybe generate a new image size if not already there.
  168. *
  169. * @param array $image Properties of the image.
  170. * @param int $attachment_id Attachment ID.
  171. * @param string|array $size Image size.
  172. * @param bool $icon If icon or not.
  173. * @return array
  174. */
  175. public static function maybe_resize_image( $image, $attachment_id, $size, $icon ) {
  176. if ( ! apply_filters( 'woocommerce_resize_images', true ) ) {
  177. return $image;
  178. }
  179. // List of sizes we want to resize. Ignore others.
  180. if ( ! $image || ! in_array( $size, apply_filters( 'woocommerce_image_sizes_to_resize', array( 'woocommerce_thumbnail', 'woocommerce_gallery_thumbnail', 'woocommerce_single', 'shop_thumbnail', 'shop_catalog', 'shop_single' ) ), true ) ) {
  181. return $image;
  182. }
  183. $target_size = wc_get_image_size( $size );
  184. $image_width = $image[1];
  185. $image_height = $image[2];
  186. $ratio_match = false;
  187. $target_uncropped = '' === $target_size['width'] || '' === $target_size['height'] || ! $target_size['crop'];
  188. // If '' is passed to either size, we test ratios against the original file. It's uncropped.
  189. if ( $target_uncropped ) {
  190. $full_size = self::get_full_size_image_dimensions( $attachment_id );
  191. if ( ! $full_size || ! $full_size['width'] || ! $full_size['height'] ) {
  192. return $image;
  193. }
  194. $ratio_match = wp_image_matches_ratio( $image_width, $image_height, $full_size['width'], $full_size['height'] );
  195. } else {
  196. $ratio_match = wp_image_matches_ratio( $image_width, $image_height, $target_size['width'], $target_size['height'] );
  197. }
  198. if ( ! $ratio_match ) {
  199. $full_size = self::get_full_size_image_dimensions( $attachment_id );
  200. if ( ! $full_size ) {
  201. return $image;
  202. }
  203. // Check if the actual image has a larger dimension than the requested image size. Smaller images are not zoom-cropped.
  204. if ( $image_width === $target_size['width'] && $full_size['height'] < $target_size['height'] ) {
  205. return $image;
  206. }
  207. if ( $image_height === $target_size['height'] && $full_size['width'] < $target_size['width'] ) {
  208. return $image;
  209. }
  210. // If the full size image is smaller both ways, don't scale it up.
  211. if ( $full_size['height'] < $target_size['height'] && $full_size['width'] < $target_size['width'] ) {
  212. return $image;
  213. }
  214. return self::resize_and_return_image( $attachment_id, $image, $size, $icon );
  215. }
  216. return $image;
  217. }
  218. /**
  219. * Get full size image dimensions.
  220. *
  221. * @param int $attachment_id Attachment ID of image.
  222. * @return array Width and height. Empty array if the dimensions cannot be found.
  223. */
  224. private static function get_full_size_image_dimensions( $attachment_id ) {
  225. $imagedata = wp_get_attachment_metadata( $attachment_id );
  226. if ( ! $imagedata ) {
  227. return array();
  228. }
  229. if ( ! isset( $imagedata['file'] ) && isset( $imagedata['sizes']['full'] ) ) {
  230. $imagedata['height'] = $imagedata['sizes']['full']['height'];
  231. $imagedata['width'] = $imagedata['sizes']['full']['width'];
  232. }
  233. return array(
  234. 'width' => $imagedata['width'],
  235. 'height' => $imagedata['height'],
  236. );
  237. }
  238. /**
  239. * Ensure we are dealing with the correct image attachment
  240. *
  241. * @param int|WP_Post $attachment Attachment object or ID.
  242. * @return boolean
  243. */
  244. public static function is_regeneratable( $attachment ) {
  245. if ( 'site-icon' === get_post_meta( is_object( $attachment ) ? $attachment->ID : $attachment, '_wp_attachment_context', true ) ) {
  246. return false;
  247. }
  248. if ( wp_attachment_is_image( $attachment ) ) {
  249. return true;
  250. }
  251. return false;
  252. }
  253. /**
  254. * Only regenerate images for the requested size.
  255. *
  256. * @param array $sizes Array of image sizes.
  257. * @return array
  258. */
  259. public static function adjust_intermediate_image_sizes( $sizes ) {
  260. return array( self::$regenerate_size );
  261. }
  262. /**
  263. * Generate the thumbnail filename and dimensions for a given file.
  264. *
  265. * @param string $fullsizepath Path to full size image.
  266. * @param int $thumbnail_width The width of the thumbnail.
  267. * @param int $thumbnail_height The height of the thumbnail.
  268. * @param bool $crop Whether to crop or not.
  269. * @return array|false An array of the filename, thumbnail width, and thumbnail height, or false on failure to resize such as the thumbnail being larger than the fullsize image.
  270. */
  271. private static function get_image( $fullsizepath, $thumbnail_width, $thumbnail_height, $crop ) {
  272. list( $fullsize_width, $fullsize_height ) = getimagesize( $fullsizepath );
  273. $dimensions = image_resize_dimensions( $fullsize_width, $fullsize_height, $thumbnail_width, $thumbnail_height, $crop );
  274. $editor = wp_get_image_editor( $fullsizepath );
  275. if ( is_wp_error( $editor ) ) {
  276. return false;
  277. }
  278. if ( ! $dimensions || ! is_array( $dimensions ) ) {
  279. return false;
  280. }
  281. list( , , , , $dst_w, $dst_h ) = $dimensions;
  282. $suffix = "{$dst_w}x{$dst_h}";
  283. $file_ext = strtolower( pathinfo( $fullsizepath, PATHINFO_EXTENSION ) );
  284. return array(
  285. 'filename' => $editor->generate_filename( $suffix, null, $file_ext ),
  286. 'width' => $dst_w,
  287. 'height' => $dst_h,
  288. );
  289. }
  290. /**
  291. * Regenerate the image according to the required size
  292. *
  293. * @param int $attachment_id Attachment ID.
  294. * @param array $image Original Image.
  295. * @param string $size Size to return for new URL.
  296. * @param bool $icon If icon or not.
  297. * @return string
  298. */
  299. private static function resize_and_return_image( $attachment_id, $image, $size, $icon ) {
  300. if ( ! self::is_regeneratable( $attachment_id ) ) {
  301. return $image;
  302. }
  303. $fullsizepath = get_attached_file( $attachment_id );
  304. if ( false === $fullsizepath || is_wp_error( $fullsizepath ) || ! file_exists( $fullsizepath ) ) {
  305. return $image;
  306. }
  307. if ( ! function_exists( 'wp_crop_image' ) ) {
  308. include ABSPATH . 'wp-admin/includes/image.php';
  309. }
  310. self::$regenerate_size = is_customize_preview() ? $size . '_preview' : $size;
  311. if ( is_customize_preview() ) {
  312. $image_size = wc_get_image_size( $size );
  313. // Make sure registered image size matches the size we're requesting.
  314. add_image_size( self::$regenerate_size, absint( $image_size['width'] ), absint( $image_size['height'] ), $image_size['crop'] );
  315. $thumbnail = self::get_image( $fullsizepath, absint( $image_size['width'] ), absint( $image_size['height'] ), $image_size['crop'] );
  316. // If the file is already there perhaps just load it if we're using the customizer. No need to store in meta data.
  317. if ( $thumbnail && file_exists( $thumbnail['filename'] ) ) {
  318. $wp_uploads = wp_upload_dir( null, false );
  319. $wp_uploads_dir = $wp_uploads['basedir'];
  320. $wp_uploads_url = $wp_uploads['baseurl'];
  321. return array(
  322. 0 => str_replace( $wp_uploads_dir, $wp_uploads_url, $thumbnail['filename'] ),
  323. 1 => $thumbnail['width'],
  324. 2 => $thumbnail['height'],
  325. );
  326. }
  327. }
  328. $metadata = wp_get_attachment_metadata( $attachment_id );
  329. // Fix for images with no metadata.
  330. if ( ! is_array( $metadata ) ) {
  331. $metadata = array();
  332. }
  333. // We only want to regen a specific image size.
  334. add_filter( 'intermediate_image_sizes', array( __CLASS__, 'adjust_intermediate_image_sizes' ) );
  335. // This function will generate the new image sizes.
  336. $new_metadata = wp_generate_attachment_metadata( $attachment_id, $fullsizepath );
  337. // Remove custom filter.
  338. remove_filter( 'intermediate_image_sizes', array( __CLASS__, 'adjust_intermediate_image_sizes' ) );
  339. // If something went wrong lets just return the original image.
  340. if ( is_wp_error( $new_metadata ) || empty( $new_metadata ) ) {
  341. return $image;
  342. }
  343. if ( isset( $new_metadata['sizes'][ self::$regenerate_size ] ) ) {
  344. $metadata['sizes'][ self::$regenerate_size ] = $new_metadata['sizes'][ self::$regenerate_size ];
  345. wp_update_attachment_metadata( $attachment_id, $metadata );
  346. }
  347. // Now we've done our regen, attempt to return the new size.
  348. $new_image = self::unfiltered_image_downsize( $attachment_id, self::$regenerate_size );
  349. return $new_image ? $new_image : $image;
  350. }
  351. /**
  352. * Image downsize, without this classes filtering on the results.
  353. *
  354. * @param int $attachment_id Attachment ID.
  355. * @param string $size Size to downsize to.
  356. * @return string New image URL.
  357. */
  358. private static function unfiltered_image_downsize( $attachment_id, $size ) {
  359. remove_action( 'image_get_intermediate_size', array( __CLASS__, 'filter_image_get_intermediate_size' ), 10, 3 );
  360. $return = image_downsize( $attachment_id, $size );
  361. add_action( 'image_get_intermediate_size', array( __CLASS__, 'filter_image_get_intermediate_size' ), 10, 3 );
  362. return $return;
  363. }
  364. /**
  365. * Get list of images and queue them for regeneration
  366. *
  367. * @return void
  368. */
  369. public static function queue_image_regeneration() {
  370. global $wpdb;
  371. // First lets cancel existing running queue to avoid running it more than once.
  372. self::$background_process->kill_process();
  373. // Now lets find all product image attachments IDs and pop them onto the queue.
  374. $images = $wpdb->get_results( // @codingStandardsIgnoreLine
  375. "SELECT ID
  376. FROM $wpdb->posts
  377. WHERE post_type = 'attachment'
  378. AND post_mime_type LIKE 'image/%'
  379. ORDER BY ID DESC"
  380. );
  381. foreach ( $images as $image ) {
  382. self::$background_process->push_to_queue(
  383. array(
  384. 'attachment_id' => $image->ID,
  385. )
  386. );
  387. }
  388. // Lets dispatch the queue to start processing.
  389. self::$background_process->save()->dispatch();
  390. }
  391. }
  392. add_action( 'init', array( 'WC_Regenerate_Images', 'init' ) );