Merge pull request #18604 from woocommerce/update/thumbnails

Tweak thumbnails + intermediate sizes
This commit is contained in:
Claudiu Lodromanean 2018-01-26 07:47:56 -08:00 committed by GitHub
commit 18f9bb408f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 387 additions and 261 deletions

View File

@ -7,9 +7,7 @@
* @since 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'WP_Async_Request', false ) ) {
include_once dirname( __FILE__ ) . '/libraries/wp-async-request.php';
@ -32,22 +30,39 @@ class WC_Regenerate_Images_Request extends WP_Background_Process {
$this->prefix = 'wp_' . get_current_blog_id();
$this->action = 'wc_regenerate_images';
// This is needed to prevent timeouts due to threading. See https://core.trac.wordpress.org/ticket/36534.
@putenv( 'MAGICK_THREAD_LIMIT=1' ); // @codingStandardsIgnoreLine.
parent::__construct();
}
/**
* Fires when the job should start
* Limit each task ran per batch to 1 for image regen.
*
* @return void
* @return bool
*/
public function dispatch() {
$log = wc_get_logger();
$log->info( __( 'Starting product image regeneration job.', 'woocommerce' ),
array(
'source' => 'wc-image-regeneration',
)
);
parent::dispatch();
protected function batch_limit_exceeded() {
return true;
}
/**
* Determines whether an attachment can have its thumbnails regenerated.
*
* Adapted from Regenerate Thumbnails by Alex Mills.
*
* @param WP_Post $attachment An attachment's post object.
* @return bool Whether the given attachment can have its thumbnails regenerated.
*/
protected function is_regeneratable( $attachment ) {
if ( 'site-icon' === get_post_meta( $attachment->ID, '_wp_attachment_context', true ) ) {
return false;
}
if ( wp_attachment_is_image( $attachment ) ) {
return true;
}
return false;
}
/**
@ -61,17 +76,19 @@ class WC_Regenerate_Images_Request extends WP_Background_Process {
return false;
}
$attachment_id = absint( $item['attachment_id'] );
$attachment = get_post( $attachment_id );
if ( ! $attachment || 'attachment' !== $attachment->post_type || ! $this->is_regeneratable( $attachment ) ) {
return false;
}
if ( ! function_exists( 'wp_crop_image' ) ) {
include ABSPATH . 'wp-admin/includes/image.php';
}
$attachment_id = absint( $item['attachment_id'] );
$attachment = get_post( $attachment_id );
if ( ! $attachment || 'attachment' !== $attachment->post_type || 'image/' !== substr( $attachment->post_mime_type, 0, 6 ) ) {
return false;
}
$log = wc_get_logger();
// translators: %s: ID of the attachment.
$log->info( sprintf( __( 'Regenerating images for attachment ID: %s', 'woocommerce' ), absint( $attachment->ID ) ),
array(
@ -82,25 +99,118 @@ class WC_Regenerate_Images_Request extends WP_Background_Process {
$fullsizepath = get_attached_file( $attachment->ID );
// Check if the file exists, if not just remove item from queue.
if ( false === $fullsizepath || ! file_exists( $fullsizepath ) ) {
if ( false === $fullsizepath || is_wp_error( $fullsizepath ) || ! file_exists( $fullsizepath ) ) {
return false;
}
$old_metadata = wp_get_attachment_metadata( $attachment->ID );
// We only want to regen WC images.
add_filter( 'intermediate_image_sizes', array( $this, 'adjust_intermediate_image_sizes' ) );
// We only want to resize images if they do not already exist.
add_filter( 'intermediate_image_sizes_advanced', array( $this, 'filter_image_sizes_to_only_missing_thumbnails' ), 10, 3 );
// This function will generate the new image sizes.
$metadata = wp_generate_attachment_metadata( $attachment->ID, $fullsizepath );
$new_metadata = wp_generate_attachment_metadata( $attachment->ID, $fullsizepath );
// Remove custom filters.
remove_filter( 'intermediate_image_sizes', array( $this, 'adjust_intermediate_image_sizes' ) );
remove_filter( 'intermediate_image_sizes_advanced', array( $this, 'filter_image_sizes_to_only_missing_thumbnails' ), 10, 3 );
// If something went wrong lets just remove the item from the queue.
if ( is_wp_error( $metadata ) || empty( $metadata ) ) {
if ( is_wp_error( $new_metadata ) || empty( $new_metadata ) ) {
return false;
}
if ( ! empty( $old_metadata ) && ! empty( $old_metadata['sizes'] ) && is_array( $old_metadata['sizes'] ) ) {
foreach ( $old_metadata['sizes'] as $old_size => $old_size_data ) {
if ( empty( $new_metadata['sizes'][ $old_size ] ) ) {
$new_metadata['sizes'][ $old_size ] = $old_metadata['sizes'][ $old_size ];
}
}
}
// Update the meta data with the new size values.
wp_update_attachment_metadata( $attachment->ID, $metadata );
wp_update_attachment_metadata( $attachment->ID, $new_metadata );
// We made it till the end, now lets remove the item from the queue.
return false;
}
/**
* Filters the list of thumbnail sizes to only include those which have missing files.
*
* @param array $sizes An associative array of registered thumbnail image sizes.
* @param array $metadata An associative array of fullsize image metadata: width, height, file.
* @param int $attachment_id Attachment ID.
* @return array An associative array of image sizes.
*/
public function filter_image_sizes_to_only_missing_thumbnails( $sizes, $metadata, $attachment_id ) {
if ( ! $sizes ) {
return $sizes;
}
$fullsizepath = get_attached_file( $attachment_id );
$editor = wp_get_image_editor( $fullsizepath );
if ( is_wp_error( $editor ) ) {
return $sizes;
}
$metadata = wp_get_attachment_metadata( $attachment_id );
// This is based on WP_Image_Editor_GD::multi_resize() and others.
foreach ( $sizes as $size => $size_data ) {
if ( empty( $metadata['sizes'][ $size ] ) ) {
continue;
}
if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) {
continue;
}
if ( ! isset( $size_data['width'] ) ) {
$size_data['width'] = null;
}
if ( ! isset( $size_data['height'] ) ) {
$size_data['height'] = null;
}
if ( ! isset( $size_data['crop'] ) ) {
$size_data['crop'] = false;
}
list( $orig_w, $orig_h ) = getimagesize( $fullsizepath );
$dimensions = image_resize_dimensions( $orig_w, $orig_h, $size_data['width'], $size_data['height'], $size_data['crop'] );
if ( ! $dimensions || ! is_array( $dimensions ) ) {
continue;
}
$info = pathinfo( $fullsizepath );
$ext = $info['extension'];
$dst_w = $dimensions[4];
$dst_h = $dimensions[5];
$suffix = "{$dst_w}x{$dst_h}";
$dst_rel_path = str_replace( '.' . $ext, '', $fullsizepath );
$thumbnail = "{$dst_rel_path}-{$suffix}.{$ext}";
if ( $dst_w === $metadata['sizes'][ $size ]['width'] && $dst_h === $metadata['sizes'][ $size ]['height'] && file_exists( $thumbnail ) ) {
unset( $sizes[ $size ] );
}
}
return $sizes;
}
/**
* Returns the sizes we want to regenerate.
*
* @param array $sizes Sizes to generate.
* @return array
*/
public function adjust_intermediate_image_sizes( $sizes ) {
return apply_filters( 'woocommerce_regenerate_images_intermediate_image_sizes', array( 'woocommerce_thumbnail', 'woocommerce_thumbnail_2x', 'woocommerce_single' ) );
}
/**
* This runs once the job has completed all items on the queue.
*

View File

@ -4,16 +4,12 @@
*
* All functionality pertaining to regenerating product images in realtime.
*
* @category Images
* @package WooCommerce/Classes
* @author Automattic
* @version 3.3.0
* @since 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
defined( 'ABSPATH' ) || exit;
/**
* Regenerate Images Class
@ -31,7 +27,7 @@ class WC_Regenerate_Images {
* Init function
*/
public static function init() {
include_once( WC_ABSPATH . 'includes/class-wc-regenerate-images-request.php' );
include_once WC_ABSPATH . 'includes/class-wc-regenerate-images-request.php';
self::$background_process = new WC_Regenerate_Images_Request();
if ( apply_filters( 'woocommerce_resize_images', true ) && ! is_admin() ) {
@ -96,21 +92,22 @@ class WC_Regenerate_Images {
}
if ( ! function_exists( 'wp_crop_image' ) ) {
include( ABSPATH . 'wp-admin/includes/image.php' );
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 );
$original_image_file_path = get_attached_file( $attachment->ID );
if ( ! file_exists( $original_image_file_path ) || ! getimagesize( $original_image_file_path ) ) {
return $image;
}
$info = pathinfo( $original_image_file_path );
$ext = $info['extension'];
$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 );

View File

@ -2,15 +2,11 @@
/**
* WooCommerce setup
*
* @author Automattic
* @category API
* @package WooCommerce
* @since 3.2.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
defined( 'ABSPATH' ) || exit;
/**
* Main WooCommerce Class.
@ -255,124 +251,124 @@ final class WooCommerce {
/**
* Class autoloader.
*/
include_once( WC_ABSPATH . 'includes/class-wc-autoloader.php' );
include_once WC_ABSPATH . 'includes/class-wc-autoloader.php';
/**
* Interfaces.
*/
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-abstract-order-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-coupon-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-customer-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-customer-download-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-customer-download-log-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-object-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-order-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-order-item-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-order-item-product-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-order-item-type-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-order-refund-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-payment-token-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-product-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-product-variable-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-shipping-zone-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-logger-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-log-handler-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-webhooks-data-store-interface.php' );
include_once WC_ABSPATH . 'includes/interfaces/class-wc-abstract-order-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-coupon-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-customer-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-customer-download-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-customer-download-log-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-object-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-order-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-order-item-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-order-item-product-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-order-item-type-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-order-refund-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-payment-token-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-product-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-product-variable-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-shipping-zone-data-store-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-logger-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-log-handler-interface.php';
include_once WC_ABSPATH . 'includes/interfaces/class-wc-webhooks-data-store-interface.php';
/**
* Abstract classes.
*/
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-data.php' ); // WC_Data for CRUD.
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-object-query.php' ); // WC_Object_Query for CRUD.
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-payment-token.php' ); // Payment Tokens.
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-product.php' ); // Products.
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-order.php' ); // Orders.
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-settings-api.php' ); // Settings API (for gateways, shipping, and integrations).
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-shipping-method.php' ); // A Shipping method.
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-payment-gateway.php' ); // A Payment gateway.
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-integration.php' ); // An integration with a service.
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-log-handler.php' );
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-deprecated-hooks.php' );
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-session.php' );
include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-data.php';
include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-object-query.php';
include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-payment-token.php';
include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-product.php';
include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-order.php';
include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-settings-api.php';
include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-shipping-method.php';
include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-payment-gateway.php';
include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-integration.php';
include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-log-handler.php';
include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-deprecated-hooks.php';
include_once WC_ABSPATH . 'includes/abstracts/abstract-wc-session.php';
/**
* Core classes.
*/
include_once( WC_ABSPATH . 'includes/wc-core-functions.php' );
include_once( WC_ABSPATH . 'includes/class-wc-datetime.php' );
include_once( WC_ABSPATH . 'includes/class-wc-post-types.php' ); // Registers post types.
include_once( WC_ABSPATH . 'includes/class-wc-install.php' );
include_once( WC_ABSPATH . 'includes/class-wc-geolocation.php' );
include_once( WC_ABSPATH . 'includes/class-wc-download-handler.php' );
include_once( WC_ABSPATH . 'includes/class-wc-comments.php' );
include_once( WC_ABSPATH . 'includes/class-wc-post-data.php' );
include_once( WC_ABSPATH . 'includes/class-wc-ajax.php' );
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-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-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.
include_once( WC_ABSPATH . 'includes/gateways/class-wc-payment-gateway-echeck.php' ); // eCheck Payment Gateway.
include_once( WC_ABSPATH . 'includes/class-wc-countries.php' ); // Defines countries and states.
include_once( WC_ABSPATH . 'includes/class-wc-integrations.php' ); // Loads integrations.
include_once( WC_ABSPATH . 'includes/class-wc-cache-helper.php' ); // Cache Helper.
include_once( WC_ABSPATH . 'includes/class-wc-https.php' ); // https Helper.
include_once( WC_ABSPATH . 'includes/class-wc-deprecated-action-hooks.php' );
include_once( WC_ABSPATH . 'includes/class-wc-deprecated-filter-hooks.php' );
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/customizer/class-wc-shop-customizer.php' );
include_once( WC_ABSPATH . 'includes/class-wc-regenerate-images.php' ); // Image regeneration class.
include_once WC_ABSPATH . 'includes/wc-core-functions.php';
include_once WC_ABSPATH . 'includes/class-wc-datetime.php';
include_once WC_ABSPATH . 'includes/class-wc-post-types.php';
include_once WC_ABSPATH . 'includes/class-wc-install.php';
include_once WC_ABSPATH . 'includes/class-wc-geolocation.php';
include_once WC_ABSPATH . 'includes/class-wc-download-handler.php';
include_once WC_ABSPATH . 'includes/class-wc-comments.php';
include_once WC_ABSPATH . 'includes/class-wc-post-data.php';
include_once WC_ABSPATH . 'includes/class-wc-ajax.php';
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';
include_once WC_ABSPATH . 'includes/class-wc-order-factory.php';
include_once WC_ABSPATH . 'includes/class-wc-order-query.php';
include_once WC_ABSPATH . 'includes/class-wc-product-factory.php';
include_once WC_ABSPATH . 'includes/class-wc-product-query.php';
include_once WC_ABSPATH . 'includes/class-wc-payment-tokens.php';
include_once WC_ABSPATH . 'includes/class-wc-shipping-zone.php';
include_once WC_ABSPATH . 'includes/gateways/class-wc-payment-gateway-cc.php';
include_once WC_ABSPATH . 'includes/gateways/class-wc-payment-gateway-echeck.php';
include_once WC_ABSPATH . 'includes/class-wc-countries.php';
include_once WC_ABSPATH . 'includes/class-wc-integrations.php';
include_once WC_ABSPATH . 'includes/class-wc-cache-helper.php';
include_once WC_ABSPATH . 'includes/class-wc-https.php';
include_once WC_ABSPATH . 'includes/class-wc-deprecated-action-hooks.php';
include_once WC_ABSPATH . 'includes/class-wc-deprecated-filter-hooks.php';
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/customizer/class-wc-shop-customizer.php';
include_once WC_ABSPATH . 'includes/class-wc-regenerate-images.php';
/**
* Data stores - used to store and retrieve CRUD object data from the database.
*/
include_once( WC_ABSPATH . 'includes/class-wc-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-data-store-wp.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-coupon-data-store-cpt.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-product-data-store-cpt.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-product-grouped-data-store-cpt.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-product-variable-data-store-cpt.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-product-variation-data-store-cpt.php' );
include_once( WC_ABSPATH . 'includes/data-stores/abstract-wc-order-item-type-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-order-item-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-order-item-coupon-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-order-item-fee-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-order-item-product-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-order-item-shipping-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-order-item-tax-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-payment-token-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-customer-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-customer-data-store-session.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-customer-download-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-customer-download-log-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-shipping-zone-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/abstract-wc-order-data-store-cpt.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-order-data-store-cpt.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-order-refund-data-store-cpt.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-webhook-data-store.php' );
include_once WC_ABSPATH . 'includes/class-wc-data-store.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-data-store-wp.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-coupon-data-store-cpt.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-product-data-store-cpt.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-product-grouped-data-store-cpt.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-product-variable-data-store-cpt.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-product-variation-data-store-cpt.php';
include_once WC_ABSPATH . 'includes/data-stores/abstract-wc-order-item-type-data-store.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-item-data-store.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-item-coupon-data-store.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-item-fee-data-store.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-item-product-store.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-item-shipping-data-store.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-item-tax-data-store.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-payment-token-data-store.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-customer-data-store.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-customer-data-store-session.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-customer-download-data-store.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-customer-download-log-data-store.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-shipping-zone-data-store.php';
include_once WC_ABSPATH . 'includes/data-stores/abstract-wc-order-data-store-cpt.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-data-store-cpt.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-order-refund-data-store-cpt.php';
include_once WC_ABSPATH . 'includes/data-stores/class-wc-webhook-data-store.php';
/**
* REST API.
*/
include_once( WC_ABSPATH . 'includes/legacy/class-wc-legacy-api.php' );
include_once( WC_ABSPATH . 'includes/class-wc-api.php' ); // API Class.
include_once( WC_ABSPATH . 'includes/class-wc-auth.php' ); // Auth Class.
include_once( WC_ABSPATH . 'includes/class-wc-register-wp-admin-settings.php' );
include_once WC_ABSPATH . 'includes/legacy/class-wc-legacy-api.php';
include_once WC_ABSPATH . 'includes/class-wc-api.php';
include_once WC_ABSPATH . 'includes/class-wc-auth.php';
include_once WC_ABSPATH . 'includes/class-wc-register-wp-admin-settings.php';
if ( defined( 'WP_CLI' ) && WP_CLI ) {
include_once( WC_ABSPATH . 'includes/class-wc-cli.php' );
include_once WC_ABSPATH . 'includes/class-wc-cli.php';
}
if ( $this->is_request( 'admin' ) ) {
include_once( WC_ABSPATH . 'includes/admin/class-wc-admin.php' );
include_once WC_ABSPATH . 'includes/admin/class-wc-admin.php';
}
if ( $this->is_request( 'frontend' ) ) {
@ -380,7 +376,7 @@ final class WooCommerce {
}
if ( $this->is_request( 'cron' ) && 'yes' === get_option( 'woocommerce_allow_tracking', 'no' ) ) {
include_once( WC_ABSPATH . 'includes/class-wc-tracker.php' );
include_once WC_ABSPATH . 'includes/class-wc-tracker.php';
}
$this->theme_support_includes();
@ -397,28 +393,28 @@ final class WooCommerce {
if ( wc_is_active_theme( array( 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' ) ) ) {
switch ( get_template() ) {
case 'twentyten':
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-ten.php' );
include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-ten.php';
break;
case 'twentyeleven':
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-eleven.php' );
include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-eleven.php';
break;
case 'twentytwelve':
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-twelve.php' );
include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-twelve.php';
break;
case 'twentythirteen':
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-thirteen.php' );
include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-thirteen.php';
break;
case 'twentyfourteen':
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-fourteen.php' );
include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-fourteen.php';
break;
case 'twentyfifteen':
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-fifteen.php' );
include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-fifteen.php';
break;
case 'twentysixteen':
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-sixteen.php' );
include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-sixteen.php';
break;
case 'twentyseventeen':
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-seventeen.php' );
include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-seventeen.php';
break;
}
}
@ -428,27 +424,27 @@ final class WooCommerce {
* Include required frontend files.
*/
public function frontend_includes() {
include_once( WC_ABSPATH . 'includes/wc-cart-functions.php' );
include_once( WC_ABSPATH . 'includes/wc-notice-functions.php' );
include_once( WC_ABSPATH . 'includes/wc-template-hooks.php' );
include_once( WC_ABSPATH . 'includes/class-wc-template-loader.php' ); // Template Loader.
include_once( WC_ABSPATH . 'includes/class-wc-frontend-scripts.php' ); // Frontend Scripts.
include_once( WC_ABSPATH . 'includes/class-wc-form-handler.php' ); // Form Handlers.
include_once( WC_ABSPATH . 'includes/class-wc-cart.php' ); // The main cart class.
include_once( WC_ABSPATH . 'includes/class-wc-tax.php' ); // Tax class.
include_once( WC_ABSPATH . 'includes/class-wc-shipping-zones.php' ); // Shipping Zones class.
include_once( WC_ABSPATH . 'includes/class-wc-customer.php' ); // Customer class.
include_once( WC_ABSPATH . 'includes/class-wc-shortcodes.php' ); // Shortcodes class.
include_once( WC_ABSPATH . 'includes/class-wc-embed.php' ); // Embeds.
include_once( WC_ABSPATH . 'includes/class-wc-structured-data.php' ); // Structured Data class.
include_once( WC_ABSPATH . 'includes/class-wc-session-handler.php' ); // Session handler class.
include_once WC_ABSPATH . 'includes/wc-cart-functions.php';
include_once WC_ABSPATH . 'includes/wc-notice-functions.php';
include_once WC_ABSPATH . 'includes/wc-template-hooks.php';
include_once WC_ABSPATH . 'includes/class-wc-template-loader.php';
include_once WC_ABSPATH . 'includes/class-wc-frontend-scripts.php';
include_once WC_ABSPATH . 'includes/class-wc-form-handler.php';
include_once WC_ABSPATH . 'includes/class-wc-cart.php';
include_once WC_ABSPATH . 'includes/class-wc-tax.php';
include_once WC_ABSPATH . 'includes/class-wc-shipping-zones.php';
include_once WC_ABSPATH . 'includes/class-wc-customer.php';
include_once WC_ABSPATH . 'includes/class-wc-shortcodes.php';
include_once WC_ABSPATH . 'includes/class-wc-embed.php';
include_once WC_ABSPATH . 'includes/class-wc-structured-data.php';
include_once WC_ABSPATH . 'includes/class-wc-session-handler.php';
}
/**
* Function used to Init WooCommerce Template Functions - This makes them pluggable by plugins and themes.
*/
public function include_template_functions() {
include_once( WC_ABSPATH . 'includes/wc-template-functions.php' );
include_once WC_ABSPATH . 'includes/wc-template-functions.php';
}
/**
@ -462,11 +458,11 @@ final class WooCommerce {
$this->load_plugin_textdomain();
// Load class instances.
$this->product_factory = new WC_Product_Factory(); // Product Factory to create new product instances.
$this->order_factory = new WC_Order_Factory(); // Order Factory to create new order instances.
$this->countries = new WC_Countries(); // Countries class.
$this->integrations = new WC_Integrations(); // Integrations class.
$this->structured_data = new WC_Structured_Data(); // Structured Data class, generates and handles structured data.
$this->product_factory = new WC_Product_Factory();
$this->order_factory = new WC_Order_Factory();
$this->countries = new WC_Countries();
$this->integrations = new WC_Integrations();
$this->structured_data = new WC_Structured_Data();
$this->deprecated_hook_handlers['actions'] = new WC_Deprecated_Action_Hooks();
$this->deprecated_hook_handlers['filters'] = new WC_Deprecated_Filter_Hooks();
@ -477,10 +473,11 @@ final class WooCommerce {
$this->session = new $session_class();
$this->session->init();
$this->cart = new WC_Cart(); // Cart class, stores the cart contents.
$this->customer = new WC_Customer( get_current_user_id(), true ); // Customer class, handles data such as customer location.
$this->cart = new WC_Cart();
$this->customer = new WC_Customer( get_current_user_id(), true );
add_action( 'shutdown', array( $this->customer, 'save' ), 10 ); // Customer should be saved during shutdown.
// Customer should be saved during shutdown.
add_action( 'shutdown', array( $this->customer, 'save' ), 10 );
}
$this->load_webhooks();
@ -536,10 +533,8 @@ final class WooCommerce {
*
* 3.3 sizes:
*
* thumbnail - Used in product listings.
* single - Used on single product pages for the main image.
*
* shop_thumbnail, shop_single, shop_catalog registered for bw compat. @todo remove in 4.0.
* woocommerce_thumbnail - Used in product listings. We assume these work for a 3 column grid layout.
* woocommerce_single - Used on single product pages for the main image.
*
* @since 2.3
*/
@ -549,6 +544,11 @@ final class WooCommerce {
add_image_size( 'woocommerce_thumbnail', $thumbnail['width'], $thumbnail['height'], $thumbnail['crop'] );
add_image_size( 'woocommerce_single', $single['width'], $single['height'], $single['crop'] );
// 2x thumbnail size for retina, and when showing less columns.
add_image_size( 'woocommerce_thumbnail_2x', $thumbnail['width'] * 2, $thumbnail['height'] * 2, $thumbnail['crop'] );
// Registered for bw compat. @todo remove in 4.0.
add_image_size( 'shop_thumbnail', $thumbnail['width'], $thumbnail['height'], $thumbnail['crop'] );
add_image_size( 'shop_catalog', $thumbnail['width'], $thumbnail['height'], $thumbnail['crop'] );
add_image_size( 'shop_single', $single['width'], $single['height'], $single['crop'] );
@ -599,7 +599,7 @@ final class WooCommerce {
*/
public function api_request_url( $request, $ssl = null ) {
if ( is_null( $ssl ) ) {
$scheme = parse_url( home_url(), PHP_URL_SCHEME );
$scheme = wp_parse_url( home_url(), PHP_URL_SCHEME );
} elseif ( $ssl ) {
$scheme = 'https';
} else {
@ -636,10 +636,10 @@ final class WooCommerce {
*/
public function wpdb_table_fix() {
global $wpdb;
$wpdb->payment_tokenmeta = $wpdb->prefix . 'woocommerce_payment_tokenmeta';
$wpdb->order_itemmeta = $wpdb->prefix . 'woocommerce_order_itemmeta';
$wpdb->tables[] = 'woocommerce_payment_tokenmeta';
$wpdb->tables[] = 'woocommerce_order_itemmeta';
$wpdb->payment_tokenmeta = $wpdb->prefix . 'woocommerce_payment_tokenmeta';
$wpdb->order_itemmeta = $wpdb->prefix . 'woocommerce_order_itemmeta';
$wpdb->tables[] = 'woocommerce_payment_tokenmeta';
$wpdb->tables[] = 'woocommerce_order_itemmeta';
if ( get_option( 'db_version' ) < 34370 ) {
$wpdb->woocommerce_termmeta = $wpdb->prefix . 'woocommerce_termmeta';

View File

@ -1,15 +1,16 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
<?php // @codingStandardsIgnoreLine.
/**
* Abstract WP_Background_Process class.
*
* @abstract
* @package WP-Background-Processing
* @extends WP_Async_Request
*/
defined( 'ABSPATH' ) || exit;
/**
* WP_Background_Process class.
*/
abstract class WP_Background_Process extends WP_Async_Request {
/**
@ -58,14 +59,11 @@ abstract class WP_Background_Process extends WP_Async_Request {
$this->cron_interval_identifier = $this->identifier . '_cron_interval';
add_action( $this->cron_hook_identifier, array( $this, 'handle_cron_healthcheck' ) );
add_filter( 'cron_schedules', array( $this, 'schedule_cron_healthcheck' ) );
add_filter( 'cron_schedules', array( $this, 'schedule_cron_healthcheck' ) ); // @codingStandardsIgnoreLine.
}
/**
* Dispatch
*
* @access public
* @return void
* Dispatch.
*/
public function dispatch() {
// Schedule the cron healthcheck.
@ -122,12 +120,27 @@ abstract class WP_Background_Process extends WP_Async_Request {
/**
* Delete queue
*
* @param string $key Key.
*
* @param string $key Key. Leave blank to delete all batches.
* @return $this
*/
public function delete( $key ) {
delete_site_option( $key );
public function delete( $key = '' ) {
if ( $key ) {
delete_site_option( $key );
} else {
global $wpdb;
$table = $wpdb->options;
$column = 'option_name';
if ( is_multisite() ) {
$table = $wpdb->sitemeta;
$column = 'meta_key';
}
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
$wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE {$column} LIKE %s", $key ) ); // @codingStandardsIgnoreLine.
}
return $this;
}
@ -150,14 +163,14 @@ abstract class WP_Background_Process extends WP_Async_Request {
}
/**
* Maybe process queue
* Maybe process queue.
*
* Checks whether data exists within the queue and that
* the process is not already running.
*/
public function maybe_handle() {
// Don't lock up other requests while processing
session_write_close();
// Don't lock up other requests while processing.
session_write_close(); // @codingStandardsIgnoreLine.
if ( $this->is_process_running() ) {
// Background process already running.
@ -194,11 +207,7 @@ abstract class WP_Background_Process extends WP_Async_Request {
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
$count = $wpdb->get_var( $wpdb->prepare( "
SELECT COUNT(*)
FROM {$table}
WHERE {$column} LIKE %s
", $key ) );
$count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table} WHERE {$column} LIKE %s", $key ) ); // @codingStandardsIgnoreLine.
return ( $count > 0 ) ? false : true;
}
@ -219,7 +228,7 @@ abstract class WP_Background_Process extends WP_Async_Request {
}
/**
* Lock process
* Lock process.
*
* Lock the process so that multiple instances can't run simultaneously.
* Override if applicable, but the duration should be greater than that
@ -269,13 +278,7 @@ abstract class WP_Background_Process extends WP_Async_Request {
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
$query = $wpdb->get_row( $wpdb->prepare( "
SELECT *
FROM {$table}
WHERE {$column} LIKE %s
ORDER BY {$key_column} ASC
LIMIT 1
", $key ) );
$query = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE {$column} LIKE %s ORDER BY {$key_column} ASC LIMIT 1", $key ) ); // @codingStandardsIgnoreLine.
$batch = new stdClass();
$batch->key = $query->$column;
@ -284,6 +287,15 @@ abstract class WP_Background_Process extends WP_Async_Request {
return $batch;
}
/**
* See if the batch limit has been exceeded.
*
* @return bool
*/
protected function batch_limit_exceeded() {
return $this->time_exceeded() || $this->memory_exceeded();
}
/**
* Handle
*
@ -305,7 +317,7 @@ abstract class WP_Background_Process extends WP_Async_Request {
unset( $batch->data[ $key ] );
}
if ( $this->time_exceeded() || $this->memory_exceeded() ) {
if ( $this->batch_limit_exceeded() ) {
// Batch limits reached.
break;
}
@ -317,7 +329,7 @@ abstract class WP_Background_Process extends WP_Async_Request {
} else {
$this->delete( $batch->key );
}
} while ( ! $this->time_exceeded() && ! $this->memory_exceeded() && ! $this->is_queue_empty() );
} while ( ! $this->batch_limit_exceeded() && ! $this->is_queue_empty() );
$this->unlock_process();
@ -417,6 +429,7 @@ abstract class WP_Background_Process extends WP_Async_Request {
// Adds every 5 minutes to the existing schedules.
$schedules[ $this->identifier . '_cron_interval' ] = array(
'interval' => MINUTE_IN_SECONDS * $interval,
/* translators: %d: interval */
'display' => sprintf( __( 'Every %d minutes', 'woocommerce' ), $interval ),
);
@ -470,17 +483,12 @@ abstract class WP_Background_Process extends WP_Async_Request {
* Cancel Process
*
* Stop processing queue items, clear cronjob and delete batch.
*
*/
public function cancel_process() {
if ( ! $this->is_queue_empty() ) {
$batch = $this->get_batch();
$this->delete( $batch->key );
$this->delete();
wp_clear_scheduled_hook( $this->cron_hook_identifier );
}
}
/**
@ -496,5 +504,4 @@ abstract class WP_Background_Process extends WP_Async_Request {
* @return mixed
*/
abstract protected function task( $item );
}

View File

@ -1,15 +1,16 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Eleven support.
*
* @class WC_Twenty_Eleven
* @since 3.3.0
* @package WooCommerce/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* WC_Twenty_Eleven class.
*/
class WC_Twenty_Eleven {
/**
@ -29,8 +30,8 @@ class WC_Twenty_Eleven {
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 130,
'single_image_width' => 280,
'thumbnail_image_width' => 150,
'single_image_width' => 300,
) );
}

View File

@ -1,8 +1,4 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Fifteen support.
*
@ -10,6 +6,12 @@ if ( ! defined( 'ABSPATH' ) ) {
* @since 3.3.0
* @package WooCommerce/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* WC_Twenty_Fifteen class.
*/
class WC_Twenty_Fifteen {
/**
@ -29,8 +31,8 @@ class WC_Twenty_Fifteen {
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 140,
'single_image_width' => 302,
'thumbnail_image_width' => 200,
'single_image_width' => 350,
) );
}

View File

@ -1,8 +1,4 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Fourteen support.
*
@ -10,6 +6,12 @@ if ( ! defined( 'ABSPATH' ) ) {
* @since 3.3.0
* @package WooCommerce/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* WC_Twenty_Fourteen class.
*/
class WC_Twenty_Fourteen {
/**
@ -29,8 +31,8 @@ class WC_Twenty_Fourteen {
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 105,
'single_image_width' => 228,
'thumbnail_image_width' => 150,
'single_image_width' => 300,
) );
}

View File

@ -1,15 +1,16 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Seventeen support.
*
* @class WC_Twenty_Seventeen
* @since 2.6.9
* @package WooCommerce/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* WC_Twenty_Seventeen class.
*/
class WC_Twenty_Seventeen {
/**
@ -28,8 +29,8 @@ class WC_Twenty_Seventeen {
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 150,
'single_image_width' => 322,
'thumbnail_image_width' => 250,
'single_image_width' => 350,
) );
}

View File

@ -1,15 +1,16 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Sixteen support.
*
* @class WC_Twenty_Sixteen
* @since 3.3.0
* @package WooCommerce/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* WC_Twenty_Sixteen class.
*/
class WC_Twenty_Sixteen {
/**
@ -29,8 +30,8 @@ class WC_Twenty_Sixteen {
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 186,
'single_image_width' => 390,
'thumbnail_image_width' => 250,
'single_image_width' => 400,
) );
}

View File

@ -1,15 +1,16 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Ten support.
*
* @class WC_Twenty_Ten
* @since 3.3.0
* @package WooCommerce/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* WC_Twenty_Ten class.
*/
class WC_Twenty_Ten {
/**
@ -29,7 +30,7 @@ class WC_Twenty_Ten {
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 140,
'thumbnail_image_width' => 200,
'single_image_width' => 300,
) );
}

View File

@ -1,8 +1,4 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Thirteen support.
*
@ -10,6 +6,12 @@ if ( ! defined( 'ABSPATH' ) ) {
* @since 3.3.0
* @package WooCommerce/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* WC_Twenty_Thirteen class.
*/
class WC_Twenty_Thirteen {
/**
@ -29,8 +31,8 @@ class WC_Twenty_Thirteen {
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 140,
'single_image_width' => 290,
'thumbnail_image_width' => 200,
'single_image_width' => 300,
) );
}

View File

@ -1,8 +1,4 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Twelve support.
*
@ -10,6 +6,12 @@ if ( ! defined( 'ABSPATH' ) ) {
* @since 3.3.0
* @package WooCommerce/Classes
*/
defined( 'ABSPATH' ) || exit;
/**
* WC_Twenty_Twelve class.
*/
class WC_Twenty_Twelve {
/**
@ -29,7 +31,7 @@ class WC_Twenty_Twelve {
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 140,
'thumbnail_image_width' => 200,
'single_image_width' => 300,
) );
}