diff --git a/assets/css/woocommerce-smallscreen.scss b/assets/css/woocommerce-smallscreen.scss index 0309d868849..9c7cf8cd6f3 100644 --- a/assets/css/woocommerce-smallscreen.scss +++ b/assets/css/woocommerce-smallscreen.scss @@ -41,7 +41,7 @@ text-align: right !important; // Important to overwrite order status inline styling &.order-actions { - text-align: left !important; + text-align: left !important; // This must always align left on handheld } &:before { @@ -109,7 +109,7 @@ &:nth-child(2n) { float: right; - clear: none !important; + clear: none !important; // This should never clear. } } } diff --git a/assets/css/woocommerce.scss b/assets/css/woocommerce.scss index 296f391165b..53daff01c87 100644 --- a/assets/css/woocommerce.scss +++ b/assets/css/woocommerce.scss @@ -69,13 +69,13 @@ p.demo_store { text-align: center; line-height: 1; border-radius: 100%; - color: red !important; + color: red !important; // Required for default theme compatibility text-decoration: none; font-weight: 700; border: 0; &:hover { - color: #fff !important; + color: #fff !important; // Required for default theme compatibility background: red; } } @@ -1496,13 +1496,13 @@ p.demo_store { .woocommerce-message, .woocommerce-error, .woocommerce-info { - padding: 1em 2em 1em 3.5em !important; - margin: 0 0 2em !important; + padding: 1em 2em 1em 3.5em; + margin: 0 0 2em; position: relative; background-color: lighten($secondary,5%); color: $secondarytext; border-top: 3px solid $primary; - list-style: none outside !important; + list-style: none outside; @include clearfix(); width: auto; word-wrap: break-word; @@ -1521,9 +1521,9 @@ p.demo_store { } li { - list-style: none outside !important; - padding-left: 0 !important; - margin-left: 0 !important; + list-style: none outside !important; // Required for default theme compatibility + padding-left: 0 !important; // Required for default theme compatibility + margin-left: 0 !important; // Required for default theme compatibility } } diff --git a/includes/abstracts/abstract-wc-order.php b/includes/abstracts/abstract-wc-order.php index 7e58fb15bec..c4f478aa3b1 100644 --- a/includes/abstracts/abstract-wc-order.php +++ b/includes/abstracts/abstract-wc-order.php @@ -1205,6 +1205,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { // Inherit tax class from items if ( '' === $shipping_tax_class ) { + $tax_rates = array(); $tax_classes = WC_Tax::get_tax_classes(); $found_tax_classes = $this->get_items_tax_classes(); diff --git a/includes/abstracts/abstract-wc-rest-posts-controller.php b/includes/abstracts/abstract-wc-rest-posts-controller.php index 6b634c0bf49..bea36577bcf 100644 --- a/includes/abstracts/abstract-wc-rest-posts-controller.php +++ b/includes/abstracts/abstract-wc-rest-posts-controller.php @@ -521,6 +521,8 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { if ( 'include' === $query_args['orderby'] ) { $query_args['orderby'] = 'post__in'; + } elseif ( 'id' === $query_args['orderby'] ) { + $query_args['orderby'] = 'ID'; // ID must be capitalized } return $query_args; diff --git a/includes/admin/class-wc-admin-status.php b/includes/admin/class-wc-admin-status.php index 82191147e07..c1de87bc8d0 100644 --- a/includes/admin/class-wc-admin-status.php +++ b/includes/admin/class-wc-admin-status.php @@ -368,7 +368,7 @@ class WC_Admin_Status { } if ( ! empty( $_REQUEST[ 'handle' ] ) ) { - $logger = new WC_Logger(); + $logger = wc_get_logger(); $logger->remove( $_REQUEST[ 'handle' ] ); } diff --git a/includes/admin/wc-admin-functions.php b/includes/admin/wc-admin-functions.php index 3f0fdbad604..45805de5405 100644 --- a/includes/admin/wc-admin-functions.php +++ b/includes/admin/wc-admin-functions.php @@ -62,9 +62,7 @@ function wc_create_page( $slug, $option = '', $page_title = '', $page_content = $option_value = get_option( $option ); - if ( $option_value > 0 ) { - $page_object = get_post( $option_value ); - + if ( $option_value > 0 && ( $page_object = get_post( $option_value ) ) ) { if ( 'page' === $page_object->post_type && ! in_array( $page_object->post_status, array( 'pending', 'trash', 'future', 'auto-draft' ) ) ) { // Valid page is already in place return $page_object->ID; diff --git a/includes/api/class-wc-rest-coupons-controller.php b/includes/api/class-wc-rest-coupons-controller.php index c42cfb5c11c..cd8badb979e 100644 --- a/includes/api/class-wc-rest-coupons-controller.php +++ b/includes/api/class-wc-rest-coupons-controller.php @@ -246,8 +246,8 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller { // Content. $data->post_content = ''; - // Excerpt. - if ( ! empty( $schema['properties']['excerpt'] ) && isset( $request['description'] ) ) { + // Coupon description (excerpt). + if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) { $data->post_excerpt = wp_filter_post_kses( $request['description'] ); } diff --git a/includes/class-wc-background-updater.php b/includes/class-wc-background-updater.php index df0b2cda78b..02837f977a7 100644 --- a/includes/class-wc-background-updater.php +++ b/includes/class-wc-background-updater.php @@ -36,7 +36,7 @@ class WC_Background_Updater extends WP_Background_Process { */ public function dispatch() { $dispatched = parent::dispatch(); - $logger = new WC_Logger(); + $logger = wc_get_logger(); if ( is_wp_error( $dispatched ) ) { $logger->add( 'wc_db_updates', sprintf( 'Unable to dispatch WooCommerce updater: %s', $dispatched->get_error_message() ) ); @@ -97,7 +97,7 @@ class WC_Background_Updater extends WP_Background_Process { define( 'WC_UPDATING', true ); } - $logger = new WC_Logger(); + $logger = wc_get_logger(); include_once( dirname( __FILE__ ) . '/wc-update-functions.php' ); @@ -119,7 +119,7 @@ class WC_Background_Updater extends WP_Background_Process { * performed, or, call parent::complete(). */ protected function complete() { - $logger = new WC_Logger(); + $logger = wc_get_logger(); $logger->add( 'wc_db_updates', 'Data update complete' ); WC_Install::update_db_version(); parent::complete(); diff --git a/includes/class-wc-cart.php b/includes/class-wc-cart.php index 83a785d6a66..4ad64013e66 100644 --- a/includes/class-wc-cart.php +++ b/includes/class-wc-cart.php @@ -1289,8 +1289,8 @@ class WC_Cart { // Apply discounts and get the discounted price FOR A SINGLE ITEM $discounted_price = $this->get_discounted_price( $values, $adjusted_price, true ); - // Convert back to line price and round nicely - $discounted_line_price = round( $discounted_price * $values['quantity'], $this->dp ); + // Convert back to line price + $discounted_line_price = $discounted_price * $values['quantity']; // Now use rounded line price to get taxes. $discounted_taxes = WC_Tax::calc_tax( $discounted_line_price, $item_tax_rates, true ); @@ -1312,8 +1312,8 @@ class WC_Cart { // Calc prices and tax (discounted) $discounted_price = $this->get_discounted_price( $values, $base_price, true ); - // Convert back to line price and round nicely - $discounted_line_price = round( $discounted_price * $values['quantity'], $this->dp ); + // Convert back to line price + $discounted_line_price = $discounted_price * $values['quantity']; // Now use rounded line price to get taxes. $discounted_taxes = WC_Tax::calc_tax( $discounted_line_price, $item_tax_rates, true ); @@ -1356,14 +1356,26 @@ class WC_Cart { // Cart contents total is based on discounted prices and is used for the final total calculation $this->cart_contents_total += $line_total; - // Store costs + taxes for lines - $this->cart_contents[ $cart_item_key ]['line_total'] = $line_total; - $this->cart_contents[ $cart_item_key ]['line_tax'] = $line_tax; - $this->cart_contents[ $cart_item_key ]['line_subtotal'] = $line_subtotal; - $this->cart_contents[ $cart_item_key ]['line_subtotal_tax'] = $line_subtotal_tax; - - // Store rates ID and costs - Since 2.2 - $this->cart_contents[ $cart_item_key ]['line_tax_data'] = array( 'total' => $discounted_taxes, 'subtotal' => $taxes ); + /** + * Store costs + taxes for lines. For tax inclusive prices, we do some extra rounding logic so the stored + * values "add up" when viewing the order in admin. This does have the disadvatage of not being able to + * recalculate the tax total/subtotal accurately in the future, but it does ensure the data looks correct. + * + * Tax exclusive prices are not affected. + */ + if ( ! $_product->is_taxable() || $this->prices_include_tax ) { + $this->cart_contents[ $cart_item_key ]['line_total'] = round( $line_total + $line_tax - wc_round_tax_total( $line_tax ), $this->dp ); + $this->cart_contents[ $cart_item_key ]['line_subtotal'] = round( $line_subtotal + $line_subtotal_tax - wc_round_tax_total( $line_subtotal_tax ), $this->dp ); + $this->cart_contents[ $cart_item_key ]['line_tax'] = wc_round_tax_total( $line_tax ); + $this->cart_contents[ $cart_item_key ]['line_subtotal_tax'] = wc_round_tax_total( $line_subtotal_tax ); + $this->cart_contents[ $cart_item_key ]['line_tax_data'] = array( 'total' => array_map( 'wc_round_tax_total', $discounted_taxes ), 'subtotal' => array_map( 'wc_round_tax_total', $taxes ) ); + } else { + $this->cart_contents[ $cart_item_key ]['line_total'] = $line_total; + $this->cart_contents[ $cart_item_key ]['line_subtotal'] = $line_subtotal; + $this->cart_contents[ $cart_item_key ]['line_tax'] = $line_tax; + $this->cart_contents[ $cart_item_key ]['line_subtotal_tax'] = $line_subtotal_tax; + $this->cart_contents[ $cart_item_key ]['line_tax_data'] = array( 'total' => $discounted_taxes, 'subtotal' => $taxes ); + } } // Only calculate the grand total + shipping if on the cart/checkout diff --git a/includes/class-wc-form-handler.php b/includes/class-wc-form-handler.php index e35deb7354d..cd194fc8f5e 100644 --- a/includes/class-wc-form-handler.php +++ b/includes/class-wc-form-handler.php @@ -146,7 +146,7 @@ class WC_Form_Handler { do_action( 'woocommerce_customer_save_address', $user_id, $load_address ); - wp_safe_redirect( wc_get_page_permalink( 'myaccount' ) ); + wp_safe_redirect( wc_get_endpoint_url( 'edit-address', '', wc_get_page_permalink( 'myaccount' ) ) ); exit; } } diff --git a/includes/class-wc-geo-ip.php b/includes/class-wc-geo-ip.php index 1dcfed3c555..fa26a6fe59e 100644 --- a/includes/class-wc-geo-ip.php +++ b/includes/class-wc-geo-ip.php @@ -1168,12 +1168,8 @@ class WC_Geo_IP { * @param string $message */ public static function log( $message ) { - if ( ! class_exists( 'WC_Logger' ) ) { - include_once( dirname( __FILE__ ) . '/class-wc-logger.php' ); - } - if ( empty( self::$log ) ) { - self::$log = new WC_Logger(); + self::$log = wc_get_logger(); } self::$log->add( 'geoip', $message ); } diff --git a/includes/class-wc-geolocation.php b/includes/class-wc-geolocation.php index f22d6f7b9be..5aa3899e70c 100644 --- a/includes/class-wc-geolocation.php +++ b/includes/class-wc-geolocation.php @@ -176,7 +176,7 @@ class WC_Geolocation { * Update geoip database. Adapted from https://wordpress.org/plugins/geoip-detect/. */ public static function update_database() { - $logger = new WC_Logger(); + $logger = wc_get_logger(); if ( ! is_callable( 'gzopen' ) ) { $logger->add( 'geolocation', 'Server does not support gzopen' ); diff --git a/includes/class-wc-install.php b/includes/class-wc-install.php index 5bea84ac6bc..04d8cb730f0 100644 --- a/includes/class-wc-install.php +++ b/includes/class-wc-install.php @@ -221,7 +221,7 @@ class WC_Install { */ private static function update() { $current_db_version = get_option( 'woocommerce_db_version' ); - $logger = new WC_Logger(); + $logger = wc_get_logger(); $update_queued = false; foreach ( self::$db_updates as $version => $update_callbacks ) { diff --git a/includes/emails/class-wc-email.php b/includes/emails/class-wc-email.php index 86bccb1c6cd..da968484645 100644 --- a/includes/emails/class-wc-email.php +++ b/includes/emails/class-wc-email.php @@ -411,7 +411,7 @@ class WC_Email extends WC_Settings_API { $emogrifier = new Emogrifier( $content, $css ); $content = $emogrifier->emogrify(); } catch ( Exception $e ) { - $logger = new WC_Logger(); + $logger = wc_get_logger(); $logger->add( 'emogrifier', $e->getMessage() ); } } diff --git a/includes/gateways/paypal/class-wc-gateway-paypal.php b/includes/gateways/paypal/class-wc-gateway-paypal.php index 645bff371d1..4b4a9831662 100644 --- a/includes/gateways/paypal/class-wc-gateway-paypal.php +++ b/includes/gateways/paypal/class-wc-gateway-paypal.php @@ -79,7 +79,7 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { public static function log( $message ) { if ( self::$log_enabled ) { if ( empty( self::$log ) ) { - self::$log = new WC_Logger(); + self::$log = wc_get_logger(); } self::$log->add( 'paypal', $message ); } diff --git a/includes/wc-core-functions.php b/includes/wc-core-functions.php index 93fba552936..7823a3c9569 100644 --- a/includes/wc-core-functions.php +++ b/includes/wc-core-functions.php @@ -1415,3 +1415,16 @@ function wc_get_rounding_precision() { } return $precision; } + +/** + * Returns a new instance of a WC Logger. + * Use woocommerce_logging_class filter to change the logging class. + * @return WC_Logger + */ +function wc_get_logger() { + if ( ! class_exists( 'WC_Logger' ) ) { + include_once( dirname( __FILE__ ) . '/class-wc-logger.php' ); + } + $class = apply_filters( 'woocommerce_logging_class', 'WC_Logger' ); + return new $class; +} diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index c0428a08660..4d7a5396b71 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -423,7 +423,7 @@ if ( ! function_exists( 'woocommerce_content' ) ) { woocommerce_product_loop_start( false ), 'after' => woocommerce_product_loop_end( false ) ) ) ) : ?> - + woocommerce_product_loop_start( false ), 'after' => woocommerce_product_loop_end( false ) ) ) ) : ?> - + diff --git a/tests/unit-tests/util/log.php b/tests/unit-tests/util/log.php index 152ff08b952..3e77ccf83b4 100644 --- a/tests/unit-tests/util/log.php +++ b/tests/unit-tests/util/log.php @@ -16,7 +16,7 @@ class WC_Tests_Log extends WC_Unit_Test_Case { * @since 2.4 */ public function test_add() { - $log = new WC_Logger(); + $log = wc_get_logger(); $log->add( 'unit-tests', 'this is a message' ); @@ -30,7 +30,7 @@ class WC_Tests_Log extends WC_Unit_Test_Case { * @since 2.4 */ public function test_clear() { - $log = new WC_Logger(); + $log = wc_get_logger(); $log->add( 'unit-tests', 'this is a message' ); $log->clear( 'unit-tests' );