From 016cfabb75273b1e0c95108ad0a30d312132c6cc Mon Sep 17 00:00:00 2001 From: Gerhard Potgieter Date: Tue, 14 Nov 2017 14:39:28 +0200 Subject: [PATCH] On the fly image regeneration. --- includes/class-wc-regenerate-images.php | 177 ++++++++++++++++++++++++ includes/class-woocommerce.php | 37 ++--- includes/wc-core-functions.php | 4 +- 3 files changed, 198 insertions(+), 20 deletions(-) create mode 100644 includes/class-wc-regenerate-images.php diff --git a/includes/class-wc-regenerate-images.php b/includes/class-wc-regenerate-images.php new file mode 100644 index 00000000000..9f9de828be8 --- /dev/null +++ b/includes/class-wc-regenerate-images.php @@ -0,0 +1,177 @@ +post_type || 'image/' != substr( $attachment->post_mime_type, 0, 6 ) ) { + return $image; + } + + if ( ! function_exists( 'wp_crop_image' ) ) { + include( ABSPATH . 'wp-admin/includes/image.php' ); + } + + $wp_uploads = wp_upload_dir( null, false ); + $wp_uploads_dir = $wp_uploads['basedir']; + $wp_uploads_url = $wp_uploads['baseurl']; + + $original_image_file_path = get_attached_file( $attachment->ID ); + + $rel_path = str_replace( $wp_uploads_dir, '', $original_image_file_path ); + + if ( ! file_exists( $original_image_file_path ) || ! getimagesize( $original_image_file_path ) ) { + return $image; + } + + $info = pathinfo( $original_image_file_path ); + $ext = $info['extension']; + list( $orig_w, $orig_h ) = getimagesize( $original_image_file_path ); + // Get image size after cropping. + $image_size = wc_get_image_size( $size ); + $dimensions = image_resize_dimensions( $orig_w, $orig_h, $image_size['width'], $image_size['height'], $image_size['crop'] ); + if ( ! $dimensions || ! is_array( $dimensions ) ) { + return $image; + } + + $dst_w = $dimensions[4]; + $dst_h = $dimensions[5]; + $suffix = "{$dst_w}x{$dst_h}"; + $dst_rel_path = str_replace( '.' . $ext, '', $original_image_file_path ); + $destfilename = "{$dst_rel_path}-{$suffix}.{$ext}"; + + // If the file is already there perhaps just load it. + if ( file_exists( $destfilename ) ) { + return array( + 0 => str_replace( $wp_uploads_dir, $wp_uploads_url, $destfilename ), + 1 => $image_size['width'], + 2 => $image_size['height'], + ); + } + + // Lets resize the image if it does not exist yet. + $editor = wp_get_image_editor( $original_image_file_path ); + if ( is_wp_error( $editor ) || is_wp_error( $editor->resize( $image_size['width'], $image_size['height'], $image_size['crop'] ) ) ) { + return $image; + } + $resized_file = $editor->save(); + if ( ! is_wp_error( $resized_file ) ) { + $img_url = str_replace( $wp_uploads_dir, $wp_uploads_url, $resized_file['path'] ); + return array( + 0 => $img_url, + 1 => $image_size['width'], + 2 => $image_size['height'], + ); + } + + // Lets just add this here as a fallback. + return $image; + } + + /** + * Regenerate the image sizes + * + * @param int $attachment_id Attachment ID. + * @param array $image Original Image. + * @param string $size Size to return for new URL. + * @param bool $icon If icon or not. + * @return string + */ + private static function resize_and_return_image_background( $attachment_id, $image, $size, $icon ) { + $attachment = get_post( $attachment_id ); + if ( ! $attachment || 'attachment' !== $attachment->post_type || 'image/' != substr( $attachment->post_mime_type, 0, 6 ) ) { + return $image; + } + + $fullsizepath = get_attached_file( $attachment->ID ); + + // Check if the file exists, if not just return the original image. + if ( false === $fullsizepath || ! file_exists( $fullsizepath ) ) { + return $image; + } + + // This function will generate the new image sizes. + $metadata = wp_generate_attachment_metadata( $attachment->ID, $fullsizepath ); + + // If something went wrong lets just return the original image. + if ( is_wp_error( $metadata ) || empty( $metadata ) ) { + return $image; + } + + // Update the meta data with the new size values. + wp_update_attachment_metadata( $attachment->ID, $metadata ); + + $new_image = wp_get_attachment_image_src( $attachment->ID, $size, $icon ); + if ( false === $new_image ) { + return $image; + } + return $new_image; + } +} +WC_Regenerate_Images::init(); diff --git a/includes/class-woocommerce.php b/includes/class-woocommerce.php index 56273cffbf5..fc325073c7b 100644 --- a/includes/class-woocommerce.php +++ b/includes/class-woocommerce.php @@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) { * Main WooCommerce Class. * * @class WooCommerce - * @version 3.2.0 + * @version 3.2.0 */ final class WooCommerce { @@ -237,13 +237,13 @@ final class WooCommerce { */ private function is_request( $type ) { switch ( $type ) { - case 'admin' : + case 'admin': return is_admin(); - case 'ajax' : + case 'ajax': return defined( 'DOING_AJAX' ); - case 'cron' : + case 'cron': return defined( 'DOING_CRON' ); - case 'frontend' : + case 'frontend': return ( ! is_admin() || defined( 'DOING_AJAX' ) ) && ! defined( 'DOING_CRON' ); } } @@ -319,11 +319,11 @@ final class WooCommerce { include_once( WC_ABSPATH . 'includes/class-wc-emails.php' ); include_once( WC_ABSPATH . 'includes/class-wc-data-exception.php' ); include_once( WC_ABSPATH . 'includes/class-wc-query.php' ); - include_once( WC_ABSPATH . 'includes/class-wc-meta-data.php' ); // Meta data internal object + include_once( WC_ABSPATH . 'includes/class-wc-meta-data.php' ); // Meta data internal object. include_once( WC_ABSPATH . 'includes/class-wc-order-factory.php' ); // Order factory. include_once( WC_ABSPATH . 'includes/class-wc-order-query.php' ); // Order query. include_once( WC_ABSPATH . 'includes/class-wc-product-factory.php' ); // Product factory. - include_once( WC_ABSPATH . 'includes/class-wc-product-query.php' ); // Product query + include_once( WC_ABSPATH . 'includes/class-wc-product-query.php' ); // Product query. include_once( WC_ABSPATH . 'includes/class-wc-payment-tokens.php' ); // Payment tokens controller. include_once( WC_ABSPATH . 'includes/class-wc-shipping-zone.php' ); include_once( WC_ABSPATH . 'includes/gateways/class-wc-payment-gateway-cc.php' ); // CC Payment Gateway. @@ -337,6 +337,7 @@ final class WooCommerce { include_once( WC_ABSPATH . 'includes/class-wc-background-emailer.php' ); include_once( WC_ABSPATH . 'includes/class-wc-discounts.php' ); include_once( WC_ABSPATH . 'includes/class-wc-cart-totals.php' ); + include_once( WC_ABSPATH . 'includes/class-wc-regenerate-images.php' ); // Image regeneration class. /** * Data stores - used to store and retrieve CRUD object data from the database. @@ -407,28 +408,28 @@ final class WooCommerce { if ( $this->is_active_theme( array( 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' ) ) ) { switch ( get_template() ) { - case 'twentyten' : + case 'twentyten': include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-ten.php' ); break; - case 'twentyeleven' : + case 'twentyeleven': include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-eleven.php' ); break; - case 'twentytwelve' : + case 'twentytwelve': include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-twelve.php' ); break; - case 'twentythirteen' : + case 'twentythirteen': include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-thirteen.php' ); break; - case 'twentyfourteen' : + case 'twentyfourteen': include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-fourteen.php' ); break; - case 'twentyfifteen' : + case 'twentyfifteen': include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-fifteen.php' ); break; - case 'twentysixteen' : + case 'twentysixteen': include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-sixteen.php' ); break; - case 'twentyseventeen' : + case 'twentyseventeen': include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-seventeen.php' ); break; } @@ -556,7 +557,7 @@ final class WooCommerce { */ private function add_image_sizes() { $thumbnail = wc_get_image_size( 'thumbnail' ); - $single = wc_get_image_size( 'single' ); + $single = wc_get_image_size( 'single' ); add_image_size( 'woocommerce_thumbnail', $thumbnail['width'], $thumbnail['height'], $thumbnail['crop'] ); add_image_size( 'woocommerce_single', $single['width'], $single['height'], $single['crop'] ); @@ -639,12 +640,12 @@ final class WooCommerce { return; } - if ( false === ( $webhooks = get_transient( 'woocommerce_webhook_ids' ) ) ) { + if ( false === ( $webhooks = get_transient( 'woocommerce_webhook_ids' ) ) ) { // @codingStandardsIgnoreLine $webhooks = get_posts( array( 'fields' => 'ids', 'post_type' => 'shop_webhook', 'post_status' => 'publish', - 'posts_per_page' => -1, + 'posts_per_page' => -1, // @codingStandardsIgnoreLine ) ); set_transient( 'woocommerce_webhook_ids', $webhooks ); } diff --git a/includes/wc-core-functions.php b/includes/wc-core-functions.php index 978bd3da9ca..872dd218131 100644 --- a/includes/wc-core-functions.php +++ b/includes/wc-core-functions.php @@ -686,7 +686,7 @@ function wc_get_image_size( $image_size ) { 'crop' => isset( $image_size[2] ) ? $image_size[2] : 1, ); $image_size = $size['width'] . '_' . $size['height']; - } elseif ( in_array( $image_size, array( 'single', 'shop_single' ), true ) ) { + } elseif ( in_array( $image_size, array( 'single', 'shop_single', 'woocommerce_single' ), true ) ) { // If the theme supports woocommerce, take image sizes from that definition. if ( isset( $theme_support[ 'single_image_width' ] ) ) { $size['width'] = $theme_support[ 'single_image_width' ]; @@ -696,7 +696,7 @@ function wc_get_image_size( $image_size ) { $size['height'] = 9999999999; $size['crop'] = 0; $image_size = 'single'; - } elseif ( in_array( $image_size, array( 'thumbnail', 'shop_thumbnail', 'shop_catalog' ), true ) ) { + } elseif ( in_array( $image_size, array( 'thumbnail', 'shop_thumbnail', 'shop_catalog', 'woocommerce_thumbnail' ), true ) ) { // If the theme supports woocommerce, take image sizes from that definition. if ( isset( $theme_support[ 'thumbnail_image_width' ] ) ) { $size['width'] = $theme_support[ 'thumbnail_image_width' ];