From 67adc818148e4319f4cddc79b09d14f345d74134 Mon Sep 17 00:00:00 2001 From: JeroenSormani Date: Fri, 12 Feb 2016 13:51:08 +0100 Subject: [PATCH 01/20] Use real checkout fields for getting value --- includes/class-wc-checkout.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/includes/class-wc-checkout.php b/includes/class-wc-checkout.php index 51fb97bdee1..7f99fef889b 100644 --- a/includes/class-wc-checkout.php +++ b/includes/class-wc-checkout.php @@ -765,18 +765,22 @@ class WC_Checkout { } // Get the billing_ and shipping_ address fields - $address_fields = array_merge( WC()->countries->get_address_fields(), WC()->countries->get_address_fields( '', 'shipping_' ) ); + if ( isset( $this->checkout_fields['shipping'] ) && isset( $this->checkout_fields['billing'] ) ) { - if ( is_user_logged_in() && array_key_exists( $input, $address_fields ) ) { - $current_user = wp_get_current_user(); + $address_fields = array_merge( $this->checkout_fields['billing'], $this->checkout_fields['shipping'] ); - if ( $meta = get_user_meta( $current_user->ID, $input, true ) ) { - return $meta; + if ( is_user_logged_in() && is_array( $address_fields ) && array_key_exists( $input, $address_fields ) ) { + $current_user = wp_get_current_user(); + + if ( $meta = get_user_meta( $current_user->ID, $input, true ) ) { + return $meta; + } + + if ( $input == 'billing_email' ) { + return $current_user->user_email; + } } - if ( $input == 'billing_email' ) { - return $current_user->user_email; - } } switch ( $input ) { From ce90c440cb48a91bb3979a03d516671884aeaa2e Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Thu, 11 Feb 2016 00:26:41 -0600 Subject: [PATCH 02/20] Cart ajax: apply coupon Adds an ajax call for applying coupons while on the cart screen (not checkout, as it already has this.) This is the first commit to add ajax calls to the cart update functions. See issue #6734 --- assets/js/frontend/cart.js | 48 ++++++++++++++++++++++++++ assets/js/frontend/cart.min.js | 2 +- includes/class-wc-ajax.php | 17 +++++++++ includes/class-wc-frontend-scripts.php | 1 + 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index e6ae0396dc0..07fb6e8caaa 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -37,4 +37,52 @@ jQuery( function( $ ) { }); $( '.shipping-calculator-form' ).hide(); + + // Update the cart after something has changed. + var update_cart_totals = function() { + $( 'div.cart_totals' ).block({ + message: null, + overlayCSS: { + background: '#fff', + opacity: 0.6 + } + }); + + var url = wc_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_cart_totals' ); + + $.ajax( { + url: url, + success: function( response ) { + $( 'div.cart_totals' ).replaceWith( response ); + } + }); + }; + + // Coupon code + $( '[name="apply_coupon"]' ).on( 'click', function( evt ) { + evt.preventDefault(); + + var text_field = $( '#coupon_code' ); + var coupon_code = text_field.val(); + text_field.val( '' ); + + var url = wc_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'apply_coupon' ); + var data = { + security: wc_cart_params.apply_coupon_nonce, + coupon_code: coupon_code + }; + + $.ajax( { + type: 'POST', + url: url, + data: data, + success: function( response ) { + window.console.log( 'apply coupon response:' ); + window.console.log( response ); + }, + complete: function() { + update_cart_totals(); + } + }); + }); }); diff --git a/assets/js/frontend/cart.min.js b/assets/js/frontend/cart.min.js index a1a3317cac9..42f1639a182 100644 --- a/assets/js/frontend/cart.min.js +++ b/assets/js/frontend/cart.min.js @@ -1 +1 @@ -jQuery(function(a){return"undefined"==typeof wc_cart_params?!1:(a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var b=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){b[a(this).data("index")]=a(this).val()}),a("div.cart_totals").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_cart_params.update_shipping_method_nonce,shipping_method:b};a.post(wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","update_shipping_method"),c,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),void a(".shipping-calculator-form").hide())}); \ No newline at end of file +jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var b=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){b[a(this).data("index")]=a(this).val()}),a("div.cart_totals").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_cart_params.update_shipping_method_nonce,shipping_method:b};a.post(wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","update_shipping_method"),c,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var b=function(){a("div.cart_totals").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var b=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","get_cart_totals");a.ajax({url:b,success:function(b){a("div.cart_totals").replaceWith(b)}})};a('[name="apply_coupon"]').on("click",function(c){c.preventDefault();var d=a("#coupon_code"),e=d.val();d.val("");var f=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),g={security:wc_cart_params.apply_coupon_nonce,coupon_code:e};a.ajax({type:"POST",url:f,data:g,success:function(a){window.console.log("apply coupon response:"),window.console.log(a)},complete:function(){b()}})})}); \ No newline at end of file diff --git a/includes/class-wc-ajax.php b/includes/class-wc-ajax.php index bb10caa2760..a80f5123848 100644 --- a/includes/class-wc-ajax.php +++ b/includes/class-wc-ajax.php @@ -94,6 +94,7 @@ class WC_AJAX { 'apply_coupon' => true, 'remove_coupon' => true, 'update_shipping_method' => true, + 'get_cart_totals' => true, 'update_order_review' => true, 'add_to_cart' => true, 'checkout' => true, @@ -254,6 +255,22 @@ class WC_AJAX { die(); } + /** + * AJAX receive updated cart_totals div. + */ + public static function get_cart_totals() { + + if ( !defined( 'WOOCOMMERCE_CART' ) ) { + define( 'WOOCOMMERCE_CART', true ); + } + + WC()->cart->calculate_totals(); + + woocommerce_cart_totals(); + + die(); + } + /** * AJAX update order review on checkout. */ diff --git a/includes/class-wc-frontend-scripts.php b/includes/class-wc-frontend-scripts.php index 10ca99535db..01fe26abe8e 100644 --- a/includes/class-wc-frontend-scripts.php +++ b/includes/class-wc-frontend-scripts.php @@ -289,6 +289,7 @@ class WC_Frontend_Scripts { 'ajax_url' => WC()->ajax_url(), 'wc_ajax_url' => WC_AJAX::get_endpoint( "%%endpoint%%" ), 'update_shipping_method_nonce' => wp_create_nonce( "update-shipping-method" ), + 'apply_coupon_nonce' => wp_create_nonce( "apply-coupon" ), ); break; case 'wc-cart-fragments' : From 4cc7e99ab71d5e197dd45632d79520e5694e3c0f Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Thu, 11 Feb 2016 12:51:29 -0600 Subject: [PATCH 03/20] Add notice to add coupon in cart. Add the notice to when a coupon is added to the cart, or the error if the coupon was not added for some reason. --- assets/js/frontend/cart.js | 24 ++++++++++++++++-------- assets/js/frontend/cart.min.js | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index 07fb6e8caaa..fea8ebf9662 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -58,13 +58,21 @@ jQuery( function( $ ) { }); }; + // Clears previous notices and shows new one above form. + var show_notice = function( html_element ) { + var $form = $( 'div.woocommerce > form' ); + + $( '.woocommerce-error, .woocommerce-message' ).remove(); + $form.before( html_element ); + }; + // Coupon code $( '[name="apply_coupon"]' ).on( 'click', function( evt ) { evt.preventDefault(); - var text_field = $( '#coupon_code' ); - var coupon_code = text_field.val(); - text_field.val( '' ); + var $text_field = $( '#coupon_code' ); + var coupon_code = $text_field.val(); + $text_field.val( '' ); var url = wc_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'apply_coupon' ); var data = { @@ -73,12 +81,12 @@ jQuery( function( $ ) { }; $.ajax( { - type: 'POST', - url: url, - data: data, + type: 'POST', + url: url, + data: data, + dataType: 'html', success: function( response ) { - window.console.log( 'apply coupon response:' ); - window.console.log( response ); + show_notice( response ); }, complete: function() { update_cart_totals(); diff --git a/assets/js/frontend/cart.min.js b/assets/js/frontend/cart.min.js index 42f1639a182..d4757dfdb29 100644 --- a/assets/js/frontend/cart.min.js +++ b/assets/js/frontend/cart.min.js @@ -1 +1 @@ -jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var b=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){b[a(this).data("index")]=a(this).val()}),a("div.cart_totals").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_cart_params.update_shipping_method_nonce,shipping_method:b};a.post(wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","update_shipping_method"),c,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var b=function(){a("div.cart_totals").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var b=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","get_cart_totals");a.ajax({url:b,success:function(b){a("div.cart_totals").replaceWith(b)}})};a('[name="apply_coupon"]').on("click",function(c){c.preventDefault();var d=a("#coupon_code"),e=d.val();d.val("");var f=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),g={security:wc_cart_params.apply_coupon_nonce,coupon_code:e};a.ajax({type:"POST",url:f,data:g,success:function(a){window.console.log("apply coupon response:"),window.console.log(a)},complete:function(){b()}})})}); \ No newline at end of file +jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var b=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){b[a(this).data("index")]=a(this).val()}),a("div.cart_totals").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_cart_params.update_shipping_method_nonce,shipping_method:b};a.post(wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","update_shipping_method"),c,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var b=function(){a("div.cart_totals").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var b=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","get_cart_totals");a.ajax({url:b,success:function(b){a("div.cart_totals").replaceWith(b)}})},c=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(d){d.preventDefault();var e=a("#coupon_code"),f=e.val();e.val("");var g=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),h={security:wc_cart_params.apply_coupon_nonce,coupon_code:f};a.ajax({type:"POST",url:g,data:h,dataType:"html",success:function(a){c(a)},complete:function(){b()}})})}); \ No newline at end of file From 191b58eba0fe18a03d372a2ca2f0c33e1a527f04 Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Thu, 11 Feb 2016 13:01:20 -0600 Subject: [PATCH 04/20] Block cart form while applying coupon. Add code to block the cart form during the apply operation until completion. Refactor block/unblock into local methods for reuse. --- assets/js/frontend/cart.js | 48 +++++++++++++++++++++++----------- assets/js/frontend/cart.min.js | 2 +- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index fea8ebf9662..6ee7ebc1fd8 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -1,6 +1,27 @@ /* global wc_cart_params */ jQuery( function( $ ) { + // Check if a node is blocked for processing. + var is_blocked = function( $node ) { + return $node.is( '.processing' ); + }; + + // Block a node for processing. + var block = function( $node ) { + $node.addClass( 'processing' ).block( { + message: null, + overlayCSS: { + background: '#fff', + opacity: 0.6 + } + }); + }; + + // Unblock a node after processing is complete. + var unblock = function( $node ) { + $node.removeClass( 'processing' ).unblock(); + }; + // wc_cart_params is required to continue, ensure the object exists if ( typeof wc_cart_params === 'undefined' ) { return false; @@ -17,13 +38,7 @@ jQuery( function( $ ) { shipping_methods[ $( this ).data( 'index' ) ] = $( this ).val(); }); - $( 'div.cart_totals' ).block({ - message: null, - overlayCSS: { - background: '#fff', - opacity: 0.6 - } - }); + block( $( 'div.cart_totals' ) ); var data = { security: wc_cart_params.update_shipping_method_nonce, @@ -40,13 +55,7 @@ jQuery( function( $ ) { // Update the cart after something has changed. var update_cart_totals = function() { - $( 'div.cart_totals' ).block({ - message: null, - overlayCSS: { - background: '#fff', - opacity: 0.6 - } - }); + block( $( 'div.cart_totals' ) ); var url = wc_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_cart_totals' ); @@ -70,9 +79,16 @@ jQuery( function( $ ) { $( '[name="apply_coupon"]' ).on( 'click', function( evt ) { evt.preventDefault(); + var $form = $( 'div.woocommerce > form' ); + + if ( is_blocked( $form ) ) { + return false; + } + + block( $form ); + var $text_field = $( '#coupon_code' ); var coupon_code = $text_field.val(); - $text_field.val( '' ); var url = wc_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'apply_coupon' ); var data = { @@ -89,6 +105,8 @@ jQuery( function( $ ) { show_notice( response ); }, complete: function() { + unblock( $form ); + $text_field.val( '' ); update_cart_totals(); } }); diff --git a/assets/js/frontend/cart.min.js b/assets/js/frontend/cart.min.js index d4757dfdb29..c464d8789a3 100644 --- a/assets/js/frontend/cart.min.js +++ b/assets/js/frontend/cart.min.js @@ -1 +1 @@ -jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var b=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){b[a(this).data("index")]=a(this).val()}),a("div.cart_totals").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_cart_params.update_shipping_method_nonce,shipping_method:b};a.post(wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","update_shipping_method"),c,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var b=function(){a("div.cart_totals").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var b=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","get_cart_totals");a.ajax({url:b,success:function(b){a("div.cart_totals").replaceWith(b)}})},c=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(d){d.preventDefault();var e=a("#coupon_code"),f=e.val();e.val("");var g=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),h={security:wc_cart_params.apply_coupon_nonce,coupon_code:f};a.ajax({type:"POST",url:g,data:h,dataType:"html",success:function(a){c(a)},complete:function(){b()}})})}); \ No newline at end of file +jQuery(function(a){var b=function(a){return a.is(".processing")},c=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},d=function(a){a.removeClass("processing").unblock()};if("undefined"==typeof wc_cart_params)return!1;a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var b=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){b[a(this).data("index")]=a(this).val()}),c(a("div.cart_totals"));var d={security:wc_cart_params.update_shipping_method_nonce,shipping_method:b};a.post(wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","update_shipping_method"),d,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var e=function(){c(a("div.cart_totals"));var b=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","get_cart_totals");a.ajax({url:b,success:function(b){a("div.cart_totals").replaceWith(b)}})},f=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(g){g.preventDefault();var h=a("div.woocommerce > form");if(b(h))return!1;c(h);var i=a("#coupon_code"),j=i.val(),k=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:j};a.ajax({type:"POST",url:k,data:l,dataType:"html",success:function(a){f(a)},complete:function(){d(h),i.val(""),e()}})})}); \ No newline at end of file From 30a272e58aa8a08365e20ea27974b6f34417c51f Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Thu, 11 Feb 2016 13:55:34 -0600 Subject: [PATCH 05/20] Add remove coupon ajax handling in cart. Add code to handle ajax call for removing a coupon from the cart. --- assets/js/frontend/cart.js | 29 ++++++++++++++++++++++++++ assets/js/frontend/cart.min.js | 2 +- includes/class-wc-frontend-scripts.php | 1 + 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index 6ee7ebc1fd8..76b8a9d22ad 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -111,4 +111,33 @@ jQuery( function( $ ) { } }); }); + + $( document ).on( 'click', 'a.woocommerce-remove-coupon', function( evt ) { + evt.preventDefault(); + + var $tr = $( this ).parents( 'tr' ); + var coupon = $( this ).attr( 'data-coupon' ); + + block( $tr.parents( 'table' ) ); + + var url = wc_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'remove_coupon' ); + var data = { + security: wc_cart_params.remove_coupon_nonce, + coupon: coupon + }; + + $.ajax( { + type: 'POST', + url: url, + data: data, + dataType: 'html', + success: function( response ) { + show_notice( response ); + unblock( $tr.parents( 'table' ) ); + }, + complete: function() { + update_cart_totals(); + } + }); + }); }); diff --git a/assets/js/frontend/cart.min.js b/assets/js/frontend/cart.min.js index c464d8789a3..124f944134c 100644 --- a/assets/js/frontend/cart.min.js +++ b/assets/js/frontend/cart.min.js @@ -1 +1 @@ -jQuery(function(a){var b=function(a){return a.is(".processing")},c=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},d=function(a){a.removeClass("processing").unblock()};if("undefined"==typeof wc_cart_params)return!1;a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var b=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){b[a(this).data("index")]=a(this).val()}),c(a("div.cart_totals"));var d={security:wc_cart_params.update_shipping_method_nonce,shipping_method:b};a.post(wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","update_shipping_method"),d,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var e=function(){c(a("div.cart_totals"));var b=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","get_cart_totals");a.ajax({url:b,success:function(b){a("div.cart_totals").replaceWith(b)}})},f=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(g){g.preventDefault();var h=a("div.woocommerce > form");if(b(h))return!1;c(h);var i=a("#coupon_code"),j=i.val(),k=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:j};a.ajax({type:"POST",url:k,data:l,dataType:"html",success:function(a){f(a)},complete:function(){d(h),i.val(""),e()}})})}); \ No newline at end of file +jQuery(function(a){var b=function(a){return a.is(".processing")},c=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},d=function(a){a.removeClass("processing").unblock()};if("undefined"==typeof wc_cart_params)return!1;a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var b=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){b[a(this).data("index")]=a(this).val()}),c(a("div.cart_totals"));var d={security:wc_cart_params.update_shipping_method_nonce,shipping_method:b};a.post(wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","update_shipping_method"),d,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var e=function(){c(a("div.cart_totals"));var b=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","get_cart_totals");a.ajax({url:b,success:function(b){a("div.cart_totals").replaceWith(b)}})},f=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(g){g.preventDefault();var h=a("div.woocommerce > form");if(b(h))return!1;c(h);var i=a("#coupon_code"),j=i.val(),k=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:j};a.ajax({type:"POST",url:k,data:l,dataType:"html",success:function(a){f(a)},complete:function(){d(h),i.val(""),e()}})}),a(document).on("click","a.woocommerce-remove-coupon",function(b){b.preventDefault();var g=a(this).parents("tr"),h=a(this).attr("data-coupon");c(g.parents("table"));var i=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","remove_coupon"),j={security:wc_cart_params.remove_coupon_nonce,coupon:h};a.ajax({type:"POST",url:i,data:j,dataType:"html",success:function(a){f(a),d(g.parents("table"))},complete:function(){e()}})})}); \ No newline at end of file diff --git a/includes/class-wc-frontend-scripts.php b/includes/class-wc-frontend-scripts.php index 01fe26abe8e..82a23703a47 100644 --- a/includes/class-wc-frontend-scripts.php +++ b/includes/class-wc-frontend-scripts.php @@ -290,6 +290,7 @@ class WC_Frontend_Scripts { 'wc_ajax_url' => WC_AJAX::get_endpoint( "%%endpoint%%" ), 'update_shipping_method_nonce' => wp_create_nonce( "update-shipping-method" ), 'apply_coupon_nonce' => wp_create_nonce( "apply-coupon" ), + 'remove_coupon_nonce' => wp_create_nonce( "remove-coupon" ), ); break; case 'wc-cart-fragments' : From 1c361bb29fdd779d46a4c25bf353b95ce88a49cf Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Thu, 11 Feb 2016 14:13:01 -0600 Subject: [PATCH 06/20] cart.js: Consolidate url calculation. DRY the url calculation code within a single function to make the code more readable and succinct. --- assets/js/frontend/cart.js | 23 ++++++++++++++--------- assets/js/frontend/cart.min.js | 2 +- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index 76b8a9d22ad..86e872bed11 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -1,6 +1,14 @@ /* global wc_cart_params */ jQuery( function( $ ) { + // Gets a url for a given AJAX endpoint. + var get_url = function( endpoint ) { + return wc_cart_params.wc_ajax_url.toString().replace( + '%%endpoint%%', + endpoint + ); + }; + // Check if a node is blocked for processing. var is_blocked = function( $node ) { return $node.is( '.processing' ); @@ -45,7 +53,7 @@ jQuery( function( $ ) { shipping_method: shipping_methods }; - $.post( wc_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'update_shipping_method' ), data, function( response ) { + $.post( get_url( 'update_shipping_method' ), data, function( response ) { $( 'div.cart_totals' ).replaceWith( response ); $( document.body ).trigger( 'updated_shipping_method' ); }); @@ -57,17 +65,16 @@ jQuery( function( $ ) { var update_cart_totals = function() { block( $( 'div.cart_totals' ) ); - var url = wc_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_cart_totals' ); - $.ajax( { - url: url, + url: get_url( 'get_cart_totals' ), + dataType: 'html', success: function( response ) { $( 'div.cart_totals' ).replaceWith( response ); } }); }; - // Clears previous notices and shows new one above form. + // clears previous notices and shows new one above form. var show_notice = function( html_element ) { var $form = $( 'div.woocommerce > form' ); @@ -90,7 +97,6 @@ jQuery( function( $ ) { var $text_field = $( '#coupon_code' ); var coupon_code = $text_field.val(); - var url = wc_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'apply_coupon' ); var data = { security: wc_cart_params.apply_coupon_nonce, coupon_code: coupon_code @@ -98,7 +104,7 @@ jQuery( function( $ ) { $.ajax( { type: 'POST', - url: url, + url: get_url( 'apply_coupon' ), data: data, dataType: 'html', success: function( response ) { @@ -120,7 +126,6 @@ jQuery( function( $ ) { block( $tr.parents( 'table' ) ); - var url = wc_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'remove_coupon' ); var data = { security: wc_cart_params.remove_coupon_nonce, coupon: coupon @@ -128,7 +133,7 @@ jQuery( function( $ ) { $.ajax( { type: 'POST', - url: url, + url: get_url( 'remove_coupon' ), data: data, dataType: 'html', success: function( response ) { diff --git a/assets/js/frontend/cart.min.js b/assets/js/frontend/cart.min.js index 124f944134c..eb93d184d8a 100644 --- a/assets/js/frontend/cart.min.js +++ b/assets/js/frontend/cart.min.js @@ -1 +1 @@ -jQuery(function(a){var b=function(a){return a.is(".processing")},c=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},d=function(a){a.removeClass("processing").unblock()};if("undefined"==typeof wc_cart_params)return!1;a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var b=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){b[a(this).data("index")]=a(this).val()}),c(a("div.cart_totals"));var d={security:wc_cart_params.update_shipping_method_nonce,shipping_method:b};a.post(wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","update_shipping_method"),d,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var e=function(){c(a("div.cart_totals"));var b=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","get_cart_totals");a.ajax({url:b,success:function(b){a("div.cart_totals").replaceWith(b)}})},f=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(g){g.preventDefault();var h=a("div.woocommerce > form");if(b(h))return!1;c(h);var i=a("#coupon_code"),j=i.val(),k=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:j};a.ajax({type:"POST",url:k,data:l,dataType:"html",success:function(a){f(a)},complete:function(){d(h),i.val(""),e()}})}),a(document).on("click","a.woocommerce-remove-coupon",function(b){b.preventDefault();var g=a(this).parents("tr"),h=a(this).attr("data-coupon");c(g.parents("table"));var i=wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","remove_coupon"),j={security:wc_cart_params.remove_coupon_nonce,coupon:h};a.ajax({type:"POST",url:i,data:j,dataType:"html",success:function(a){f(a),d(g.parents("table"))},complete:function(){e()}})})}); \ No newline at end of file +jQuery(function(a){var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()};if("undefined"==typeof wc_cart_params)return!1;a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var f=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},g=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(h){h.preventDefault();var i=a("div.woocommerce > form");if(c(i))return!1;d(i);var j=a("#coupon_code"),k=j.val(),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:k};a.ajax({type:"POST",url:b("apply_coupon"),data:l,dataType:"html",success:function(a){g(a)},complete:function(){e(i),j.val(""),f()}})}),a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var h=a(this).parents("tr"),i=a(this).attr("data-coupon");d(h.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){g(a),e(h.parents("table"))},complete:function(){f()}})})}); \ No newline at end of file From d4ada2c4d7cb628b4879e0c25bb5316d968190a0 Mon Sep 17 00:00:00 2001 From: Diego Zanella Date: Sat, 13 Feb 2016 23:23:10 +0000 Subject: [PATCH 07/20] Added new filter in Shipping Zone * The filter will allow 3rd parties to process the INSTANCES of the shipping methods loaded for a zone. --- includes/class-wc-shipping-zone.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-shipping-zone.php b/includes/class-wc-shipping-zone.php index f2dd568d246..11e90179696 100644 --- a/includes/class-wc-shipping-zone.php +++ b/includes/class-wc-shipping-zone.php @@ -249,7 +249,7 @@ class WC_Shipping_Zone implements WC_Data { } } - return $methods; + return apply_filters( 'woocommerce_shipping_zone_shipping_methods', $methods, $raw_methods, $allowed_classes, $this ); } /** From e99e75b5b96e899ef30d630b75e1f6331bad258b Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Sun, 14 Feb 2016 21:56:42 -0600 Subject: [PATCH 08/20] Fix spacing. Add space after ! --- includes/class-wc-ajax.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-ajax.php b/includes/class-wc-ajax.php index a80f5123848..b2e90ddddb1 100644 --- a/includes/class-wc-ajax.php +++ b/includes/class-wc-ajax.php @@ -260,7 +260,7 @@ class WC_AJAX { */ public static function get_cart_totals() { - if ( !defined( 'WOOCOMMERCE_CART' ) ) { + if ( ! defined( 'WOOCOMMERCE_CART' ) ) { define( 'WOOCOMMERCE_CART', true ); } From 9a43b897dad31338aa0bd7eec00c3641dce6ed0d Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Sun, 14 Feb 2016 21:57:14 -0600 Subject: [PATCH 09/20] Cart AJAX: Add update call. Since the code is built to use a form submit for all the quanitities already, I just made this an ajax call instead of a whole page call. The result is the exactly the same and the .woocommerce div is replaced with the resulting HTML. --- assets/js/frontend/cart.js | 27 +++++++++++++++++++++++++++ assets/js/frontend/cart.min.js | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index 86e872bed11..7831343e125 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -145,4 +145,31 @@ jQuery( function( $ ) { } }); }); + + // Quantity Update + $( document ).on( 'click', '[name=update_cart]', function( evt ) { + evt.preventDefault(); + + var $form = $( 'div.woocommerce > form' ); + + // Provide the submit button value because wc-form-handler expects it. + $( '').attr( 'type', 'hidden' ) + .attr( 'name', 'update_cart' ) + .attr( 'value', 'Update Cart' ) + .appendTo( $form ); + + // Make call to actual form post URL. + $.ajax( { + type: $form.attr( 'method' ), + url: $form.attr( 'action' ), + data: $form.serialize(), + dataType: 'html', + success: function( response ) { + // Grab html response and replace the new .woocommerce div. + var $html = $.parseHTML( response ); + var $new_div = $( 'div.woocommerce', $html ); + $( 'div.woocommerce').replaceWith( $new_div ); + } + }); + }); }); diff --git a/assets/js/frontend/cart.min.js b/assets/js/frontend/cart.min.js index eb93d184d8a..f4f227ae995 100644 --- a/assets/js/frontend/cart.min.js +++ b/assets/js/frontend/cart.min.js @@ -1 +1 @@ -jQuery(function(a){var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()};if("undefined"==typeof wc_cart_params)return!1;a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var f=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},g=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(h){h.preventDefault();var i=a("div.woocommerce > form");if(c(i))return!1;d(i);var j=a("#coupon_code"),k=j.val(),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:k};a.ajax({type:"POST",url:b("apply_coupon"),data:l,dataType:"html",success:function(a){g(a)},complete:function(){e(i),j.val(""),f()}})}),a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var h=a(this).parents("tr"),i=a(this).attr("data-coupon");d(h.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){g(a),e(h.parents("table"))},complete:function(){f()}})})}); \ No newline at end of file +jQuery(function(a){var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()};if("undefined"==typeof wc_cart_params)return!1;a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var f=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},g=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(h){h.preventDefault();var i=a("div.woocommerce > form");if(c(i))return!1;d(i);var j=a("#coupon_code"),k=j.val(),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:k};a.ajax({type:"POST",url:b("apply_coupon"),data:l,dataType:"html",success:function(a){g(a)},complete:function(){e(i),j.val(""),f()}})}),a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var h=a(this).parents("tr"),i=a(this).attr("data-coupon");d(h.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){g(a),e(h.parents("table"))},complete:function(){f()}})}),a(document).on("click","[name=update_cart]",function(b){b.preventDefault();var c=a("div.woocommerce > form");a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:function(b){var c=a.parseHTML(b),d=a("div.woocommerce",c);a("div.woocommerce").replaceWith(d)}})})}); \ No newline at end of file From e416ba0e2b5f92736fa0a6ac4dad05f15893f75f Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Sun, 14 Feb 2016 22:55:47 -0600 Subject: [PATCH 10/20] Cart AJAX: Add cart item remove. Add cart item remove, using same technique as the cart update. Make the normal call via AJAX and update the HTML afterwards. --- assets/js/frontend/cart.js | 36 ++++++++++++++++++++++++---------- assets/js/frontend/cart.min.js | 2 +- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index 7831343e125..d5d489da92a 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -1,6 +1,11 @@ /* global wc_cart_params */ jQuery( function( $ ) { + // wc_cart_params is required to continue, ensure the object exists + if ( typeof wc_cart_params === 'undefined' ) { + return false; + } + // Gets a url for a given AJAX endpoint. var get_url = function( endpoint ) { return wc_cart_params.wc_ajax_url.toString().replace( @@ -30,10 +35,12 @@ jQuery( function( $ ) { $node.removeClass( 'processing' ).unblock(); }; - // wc_cart_params is required to continue, ensure the object exists - if ( typeof wc_cart_params === 'undefined' ) { - return false; - } + // Updates the .woocommerce div with a string of html. + var update_wc_div = function( html_str ) { + var $html = $.parseHTML( html_str ); + var $new_div = $( 'div.woocommerce', $html ); + $( 'div.woocommerce').replaceWith( $new_div ); + }; // Shipping calculator $( document ).on( 'click', '.shipping-calculator-button', function() { @@ -164,12 +171,21 @@ jQuery( function( $ ) { url: $form.attr( 'action' ), data: $form.serialize(), dataType: 'html', - success: function( response ) { - // Grab html response and replace the new .woocommerce div. - var $html = $.parseHTML( response ); - var $new_div = $( 'div.woocommerce', $html ); - $( 'div.woocommerce').replaceWith( $new_div ); - } + success: update_wc_div + }); + }); + + // Item Remove + $( document ).on( 'click', 'td.product-remove > a', function( evt ) { + evt.preventDefault(); + + var $a = $( evt.target ); + + $.ajax( { + type: 'GET', + url: $a.attr( 'href' ), + dataType: 'html', + success: update_wc_div }); }); }); diff --git a/assets/js/frontend/cart.min.js b/assets/js/frontend/cart.min.js index f4f227ae995..9c46244f2d4 100644 --- a/assets/js/frontend/cart.min.js +++ b/assets/js/frontend/cart.min.js @@ -1 +1 @@ -jQuery(function(a){var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()};if("undefined"==typeof wc_cart_params)return!1;a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var f=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},g=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(h){h.preventDefault();var i=a("div.woocommerce > form");if(c(i))return!1;d(i);var j=a("#coupon_code"),k=j.val(),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:k};a.ajax({type:"POST",url:b("apply_coupon"),data:l,dataType:"html",success:function(a){g(a)},complete:function(){e(i),j.val(""),f()}})}),a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var h=a(this).parents("tr"),i=a(this).attr("data-coupon");d(h.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){g(a),e(h.parents("table"))},complete:function(){f()}})}),a(document).on("click","[name=update_cart]",function(b){b.preventDefault();var c=a("div.woocommerce > form");a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:function(b){var c=a.parseHTML(b),d=a("div.woocommerce",c);a("div.woocommerce").replaceWith(d)}})})}); \ No newline at end of file +jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a("div.woocommerce",c);a("div.woocommerce").replaceWith(d)};a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var g=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},h=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(f){f.preventDefault();var i=a("div.woocommerce > form");if(c(i))return!1;d(i);var j=a("#coupon_code"),k=j.val(),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:k};a.ajax({type:"POST",url:b("apply_coupon"),data:l,dataType:"html",success:function(a){h(a)},complete:function(){e(i),j.val(""),g()}})}),a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var f=a(this).parents("tr"),i=a(this).attr("data-coupon");d(f.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){h(a),e(f.parents("table"))},complete:function(){g()}})}),a(document).on("click","[name=update_cart]",function(b){b.preventDefault();var c=a("div.woocommerce > form");a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:f})}),a(document).on("click","td.product-remove > a",function(b){b.preventDefault();var c=a(b.target);a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f})})}); \ No newline at end of file From ef4debace74e84e1bef40e3fc7810cad693cda49 Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Mon, 15 Feb 2016 08:10:25 -0600 Subject: [PATCH 11/20] Cart AJAX: Block form during update Apply the JQuery Block UI to the form during an AJAX update. Also correct a few small style issues. --- assets/js/frontend/cart.js | 24 +++++++++++++++++------- assets/js/frontend/cart.min.js | 2 +- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index d5d489da92a..ef56b46a6f7 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -39,7 +39,7 @@ jQuery( function( $ ) { var update_wc_div = function( html_str ) { var $html = $.parseHTML( html_str ); var $new_div = $( 'div.woocommerce', $html ); - $( 'div.woocommerce').replaceWith( $new_div ); + $( 'div.woocommerce' ).replaceWith( $new_div ); }; // Shipping calculator @@ -160,10 +160,12 @@ jQuery( function( $ ) { var $form = $( 'div.woocommerce > form' ); // Provide the submit button value because wc-form-handler expects it. - $( '').attr( 'type', 'hidden' ) - .attr( 'name', 'update_cart' ) - .attr( 'value', 'Update Cart' ) - .appendTo( $form ); + $( '' ).attr( 'type', 'hidden' ) + .attr( 'name', 'update_cart' ) + .attr( 'value', 'Update Cart' ) + .appendTo( $form ); + + block( $form ); // Make call to actual form post URL. $.ajax( { @@ -171,7 +173,10 @@ jQuery( function( $ ) { url: $form.attr( 'action' ), data: $form.serialize(), dataType: 'html', - success: update_wc_div + success: update_wc_div, + complete: function() { + unblock( $form ); + } }); }); @@ -181,11 +186,16 @@ jQuery( function( $ ) { var $a = $( evt.target ); + block( $a.parent( 'form' ) ); + $.ajax( { type: 'GET', url: $a.attr( 'href' ), dataType: 'html', - success: update_wc_div + success: update_wc_div, + complete: function() { + unblock( $a.parent( 'form' ) ); + } }); }); }); diff --git a/assets/js/frontend/cart.min.js b/assets/js/frontend/cart.min.js index 9c46244f2d4..7eb50d3dc0e 100644 --- a/assets/js/frontend/cart.min.js +++ b/assets/js/frontend/cart.min.js @@ -1 +1 @@ -jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a("div.woocommerce",c);a("div.woocommerce").replaceWith(d)};a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var g=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},h=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(f){f.preventDefault();var i=a("div.woocommerce > form");if(c(i))return!1;d(i);var j=a("#coupon_code"),k=j.val(),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:k};a.ajax({type:"POST",url:b("apply_coupon"),data:l,dataType:"html",success:function(a){h(a)},complete:function(){e(i),j.val(""),g()}})}),a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var f=a(this).parents("tr"),i=a(this).attr("data-coupon");d(f.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){h(a),e(f.parents("table"))},complete:function(){g()}})}),a(document).on("click","[name=update_cart]",function(b){b.preventDefault();var c=a("div.woocommerce > form");a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:f})}),a(document).on("click","td.product-remove > a",function(b){b.preventDefault();var c=a(b.target);a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f})})}); \ No newline at end of file +jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a("div.woocommerce",c);a("div.woocommerce").replaceWith(d)};a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var g=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},h=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(f){f.preventDefault();var i=a("div.woocommerce > form");if(c(i))return!1;d(i);var j=a("#coupon_code"),k=j.val(),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:k};a.ajax({type:"POST",url:b("apply_coupon"),data:l,dataType:"html",success:function(a){h(a)},complete:function(){e(i),j.val(""),g()}})}),a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var f=a(this).parents("tr"),i=a(this).attr("data-coupon");d(f.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){h(a),e(f.parents("table"))},complete:function(){g()}})}),a(document).on("click","[name=update_cart]",function(b){b.preventDefault();var c=a("div.woocommerce > form");a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(c),d(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:f,complete:function(){e(c)}})}),a(document).on("click","td.product-remove > a",function(b){b.preventDefault();var c=a(b.target);d(c.parent("form")),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(c.parent("form"))}})})}); \ No newline at end of file From a8e51cfb66b582458acd34ff6fb2b5f3efbc969e Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Mon, 15 Feb 2016 08:40:46 -0600 Subject: [PATCH 12/20] Style: Add spaces between closing braces and parens. --- assets/js/frontend/cart.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index ef56b46a6f7..0f6ba972408 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -27,7 +27,7 @@ jQuery( function( $ ) { background: '#fff', opacity: 0.6 } - }); + } ); }; // Unblock a node after processing is complete. @@ -46,12 +46,12 @@ jQuery( function( $ ) { $( document ).on( 'click', '.shipping-calculator-button', function() { $( '.shipping-calculator-form' ).slideToggle( 'slow' ); return false; - }).on( 'change', 'select.shipping_method, input[name^=shipping_method]', function() { + } ).on( 'change', 'select.shipping_method, input[name^=shipping_method]', function() { var shipping_methods = []; $( 'select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]' ).each( function() { shipping_methods[ $( this ).data( 'index' ) ] = $( this ).val(); - }); + } ); block( $( 'div.cart_totals' ) ); @@ -63,8 +63,8 @@ jQuery( function( $ ) { $.post( get_url( 'update_shipping_method' ), data, function( response ) { $( 'div.cart_totals' ).replaceWith( response ); $( document.body ).trigger( 'updated_shipping_method' ); - }); - }); + } ); + } ); $( '.shipping-calculator-form' ).hide(); @@ -78,7 +78,7 @@ jQuery( function( $ ) { success: function( response ) { $( 'div.cart_totals' ).replaceWith( response ); } - }); + } ); }; // clears previous notices and shows new one above form. @@ -122,8 +122,8 @@ jQuery( function( $ ) { $text_field.val( '' ); update_cart_totals(); } - }); - }); + } ); + } ); $( document ).on( 'click', 'a.woocommerce-remove-coupon', function( evt ) { evt.preventDefault(); @@ -150,8 +150,8 @@ jQuery( function( $ ) { complete: function() { update_cart_totals(); } - }); - }); + } ); + } ); // Quantity Update $( document ).on( 'click', '[name=update_cart]', function( evt ) { @@ -177,8 +177,8 @@ jQuery( function( $ ) { complete: function() { unblock( $form ); } - }); - }); + } ); + } ); // Item Remove $( document ).on( 'click', 'td.product-remove > a', function( evt ) { @@ -196,6 +196,6 @@ jQuery( function( $ ) { complete: function() { unblock( $a.parent( 'form' ) ); } - }); - }); -}); + } ); + } ); +} ); From f7d61a7aa1ac1354e1bb1e79bae131dc0ace3b9f Mon Sep 17 00:00:00 2001 From: Ninos Ego Date: Mon, 15 Feb 2016 16:11:04 +0100 Subject: [PATCH 13/20] Fixed: Notice in checkout (order received) with no existing order id -> undefined variable order --- includes/shortcodes/class-wc-shortcode-checkout.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/includes/shortcodes/class-wc-shortcode-checkout.php b/includes/shortcodes/class-wc-shortcode-checkout.php index 1259c8e2d33..ac59a99ee20 100644 --- a/includes/shortcodes/class-wc-shortcode-checkout.php +++ b/includes/shortcodes/class-wc-shortcode-checkout.php @@ -198,8 +198,9 @@ class WC_Shortcode_Checkout { if ( $order_id > 0 ) { $order = wc_get_order( $order_id ); - if ( $order->order_key != $order_key ) - unset( $order ); + if ( $order->order_key != $order_key ) { + $order = false; + } } // Empty awaiting payment session From 62c141ff5db13acb984d181b722f724029a21beb Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Mon, 15 Feb 2016 09:41:58 -0600 Subject: [PATCH 14/20] Cart AJAX: Fix block UI for remove item. The JQuery selector was incorrect and needed to go further up the DOM tree. --- assets/js/frontend/cart.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index 0f6ba972408..aae45ecbd09 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -185,8 +185,9 @@ jQuery( function( $ ) { evt.preventDefault(); var $a = $( evt.target ); + var $form = $a.parents( 'form' ); - block( $a.parent( 'form' ) ); + block( $form ); $.ajax( { type: 'GET', @@ -194,7 +195,7 @@ jQuery( function( $ ) { dataType: 'html', success: update_wc_div, complete: function() { - unblock( $a.parent( 'form' ) ); + unblock( $form ); } } ); } ); From 4b8cf5cd1fb7a9561e22a3ba63411312761f6082 Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Mon, 15 Feb 2016 09:53:11 -0600 Subject: [PATCH 15/20] Cart ajax: Fix html5 validation checks for quantities. The form button click event handling was subverting the validation checks. Moving the event to the actual form submit event fixed it. --- assets/js/frontend/cart.js | 4 ++-- assets/js/frontend/cart.min.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index aae45ecbd09..ae77dfd22e3 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -154,10 +154,10 @@ jQuery( function( $ ) { } ); // Quantity Update - $( document ).on( 'click', '[name=update_cart]', function( evt ) { + $( document ).on( 'submit', 'div.woocommerce > form', function( evt ) { evt.preventDefault(); - var $form = $( 'div.woocommerce > form' ); + var $form = $( evt.target ); // Provide the submit button value because wc-form-handler expects it. $( '' ).attr( 'type', 'hidden' ) diff --git a/assets/js/frontend/cart.min.js b/assets/js/frontend/cart.min.js index 7eb50d3dc0e..8e9c8389fc8 100644 --- a/assets/js/frontend/cart.min.js +++ b/assets/js/frontend/cart.min.js @@ -1 +1 @@ -jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a("div.woocommerce",c);a("div.woocommerce").replaceWith(d)};a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var g=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},h=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(f){f.preventDefault();var i=a("div.woocommerce > form");if(c(i))return!1;d(i);var j=a("#coupon_code"),k=j.val(),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:k};a.ajax({type:"POST",url:b("apply_coupon"),data:l,dataType:"html",success:function(a){h(a)},complete:function(){e(i),j.val(""),g()}})}),a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var f=a(this).parents("tr"),i=a(this).attr("data-coupon");d(f.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){h(a),e(f.parents("table"))},complete:function(){g()}})}),a(document).on("click","[name=update_cart]",function(b){b.preventDefault();var c=a("div.woocommerce > form");a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(c),d(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:f,complete:function(){e(c)}})}),a(document).on("click","td.product-remove > a",function(b){b.preventDefault();var c=a(b.target);d(c.parent("form")),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(c.parent("form"))}})})}); \ No newline at end of file +jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a("div.woocommerce",c);a("div.woocommerce").replaceWith(d)};a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var g=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},h=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(f){f.preventDefault();var i=a("div.woocommerce > form");if(c(i))return!1;d(i);var j=a("#coupon_code"),k=j.val(),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:k};a.ajax({type:"POST",url:b("apply_coupon"),data:l,dataType:"html",success:function(a){h(a)},complete:function(){e(i),j.val(""),g()}})}),a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var f=a(this).parents("tr"),i=a(this).attr("data-coupon");d(f.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){h(a),e(f.parents("table"))},complete:function(){g()}})}),a(document).on("submit","div.woocommerce > form",function(b){b.preventDefault();var c=a(b.target);a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(c),d(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:f,complete:function(){e(c)}})}),a(document).on("click","td.product-remove > a",function(b){b.preventDefault();var c=a(b.target),g=c.parents("form");d(g),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(g)}})})}); \ No newline at end of file From c469ab920bb930a747d1b4926c2805f99fa0d31b Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 15 Feb 2016 15:53:43 +0000 Subject: [PATCH 16/20] Use wpdb query instead of looping over children Closes #10195 cc @claudiosmweb Since this uses `$this->get_children( true );` it will also hide out of stock variation attributes if that setting is enabled. --- includes/class-wc-product-variable.php | 86 +++++++++++--------------- includes/wc-attribute-functions.php | 11 ++++ 2 files changed, 47 insertions(+), 50 deletions(-) diff --git a/includes/class-wc-product-variable.php b/includes/class-wc-product-variable.php index c8c09b7b07d..6fc6a549ae8 100644 --- a/includes/class-wc-product-variable.php +++ b/includes/class-wc-product-variable.php @@ -376,68 +376,54 @@ class WC_Product_Variable extends WC_Product { * @return array of attributes and their available values */ public function get_variation_attributes() { + global $wpdb; + $variation_attributes = array(); + $attributes = $this->get_attributes(); + $child_ids = $this->get_children( true ); - if ( ! $this->has_child() ) { - return $variation_attributes; - } - - $attributes = $this->get_attributes(); - - foreach ( $attributes as $attribute ) { - if ( ! $attribute['is_variation'] ) { - continue; - } - - $values = array(); - $attribute_field_name = 'attribute_' . sanitize_title( $attribute['name'] ); - - // Get used values from children variations - foreach ( $this->get_children() as $child_id ) { - $variation = $this->get_child( $child_id ); - - if ( ! empty( $variation->variation_id ) ) { - if ( ! $variation->variation_is_visible() ) { - continue; // Disabled or hidden - } - - $child_variation_attributes = $variation->get_variation_attributes(); - - if ( isset( $child_variation_attributes[ $attribute_field_name ] ) ) { - $values[] = $child_variation_attributes[ $attribute_field_name ]; - } + if ( ! empty( $child_ids ) ) { + foreach ( $attributes as $attribute ) { + if ( empty( $attribute['is_variation'] ) ) { + continue; } - } - // empty value indicates that all options for given attribute are available - if ( in_array( '', $values ) ) { - $values = $attribute['is_taxonomy'] ? wp_get_post_terms( $this->id, $attribute['name'], array( 'fields' => 'slugs' ) ) : wc_get_text_attributes( $attribute['value'] ); + // Get possible values for this attribute, for only visible variations. + $values = array_unique( $wpdb->get_col( $wpdb->prepare( + "SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s AND post_id IN (" . implode( ',', array_map( 'esc_sql', $child_ids ) ) . ")", + wc_variation_attribute_name( $attribute['name'] ) + ) ) ); - // Get custom attributes (non taxonomy) as defined - } elseif ( ! $attribute['is_taxonomy'] ) { - $text_attributes = wc_get_text_attributes( $attribute['value'] ); - $assigned_text_attributes = $values; - $values = array(); + // empty value indicates that all options for given attribute are available + if ( in_array( '', $values ) ) { + $values = $attribute['is_taxonomy'] ? wp_get_post_terms( $this->id, $attribute['name'], array( 'fields' => 'slugs' ) ) : wc_get_text_attributes( $attribute['value'] ); - // Pre 2.4 handling where 'slugs' were saved instead of the full text attribute - if ( version_compare( get_post_meta( $this->id, '_product_version', true ), '2.4.0', '<' ) ) { - $assigned_text_attributes = array_map( 'sanitize_title', $assigned_text_attributes ); + // Get custom attributes (non taxonomy) as defined + } elseif ( ! $attribute['is_taxonomy'] ) { + $text_attributes = wc_get_text_attributes( $attribute['value'] ); + $assigned_text_attributes = $values; + $values = array(); - foreach ( $text_attributes as $text_attribute ) { - if ( in_array( sanitize_title( $text_attribute ), $assigned_text_attributes ) ) { - $values[] = $text_attribute; + // Pre 2.4 handling where 'slugs' were saved instead of the full text attribute + if ( version_compare( get_post_meta( $this->id, '_product_version', true ), '2.4.0', '<' ) ) { + $assigned_text_attributes = array_map( 'sanitize_title', $assigned_text_attributes ); + + foreach ( $text_attributes as $text_attribute ) { + if ( in_array( sanitize_title( $text_attribute ), $assigned_text_attributes ) ) { + $values[] = $text_attribute; + } } - } - } else { - foreach ( $text_attributes as $text_attribute ) { - if ( in_array( $text_attribute, $assigned_text_attributes ) ) { - $values[] = $text_attribute; + } else { + foreach ( $text_attributes as $text_attribute ) { + if ( in_array( $text_attribute, $assigned_text_attributes ) ) { + $values[] = $text_attribute; + } } } } - } - $variation_attributes[ $attribute['name'] ] = array_unique( $values ); + $variation_attributes[ $attribute['name'] ] = array_unique( $values ); + } } return $variation_attributes; diff --git a/includes/wc-attribute-functions.php b/includes/wc-attribute-functions.php index 8e2b025d157..6fc38fa0b1e 100644 --- a/includes/wc-attribute-functions.php +++ b/includes/wc-attribute-functions.php @@ -49,6 +49,17 @@ function wc_attribute_taxonomy_name( $attribute_name ) { return 'pa_' . wc_sanitize_taxonomy_name( $attribute_name ); } +/** + * Get the attribute name used when storing values in post meta. + * + * @param string $attribute_name Attribute name. + * @since 2.6.0 + * @return string + */ +function wc_variation_attribute_name( $attribute_name ) { + return 'attribute_' . sanitize_title( $attribute_name ); +} + /** * Get a product attribute name by ID. * From b3308133063be629f33e5ad82321a54d30b5a72b Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Mon, 15 Feb 2016 10:27:47 -0600 Subject: [PATCH 17/20] Cart AJAX: Clean up form handling for cart form. The coupon and update cart logic was tripping on each other between the click handling and form submit handling. This commit combines the event handler, then splits off from there. --- assets/js/frontend/cart.js | 30 +++++++++++++++++++++--------- assets/js/frontend/cart.min.js | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index ae77dfd22e3..ab55fb53e44 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -89,16 +89,31 @@ jQuery( function( $ ) { $form.before( html_element ); }; - // Coupon code - $( '[name="apply_coupon"]' ).on( 'click', function( evt ) { + // Handle form submit and route to correct logic. + $( document ).on( 'submit', 'div.woocommerce > form', function( evt ) { evt.preventDefault(); - var $form = $( 'div.woocommerce > form' ); + var $form = $( evt.target ); + var $submit = $( document.activeElement ); + + window.console.log( $submit ); if ( is_blocked( $form ) ) { return false; } + if ( $submit.is( '[name="update_cart"]' ) || $submit.is( 'input.qty' ) ) { + window.console.log( 'update cart' ); + quantity_update( $form ); + + } else if ( $submit.is( '[name="apply_coupon"]' ) || $submit.is( '#coupon_code' ) ) { + window.console.log( 'apply coupon' ); + apply_coupon( $form ); + } + } ); + + // Coupon code + var apply_coupon = function( $form ) { block( $form ); var $text_field = $( '#coupon_code' ); @@ -123,7 +138,7 @@ jQuery( function( $ ) { update_cart_totals(); } } ); - } ); + }; $( document ).on( 'click', 'a.woocommerce-remove-coupon', function( evt ) { evt.preventDefault(); @@ -154,10 +169,7 @@ jQuery( function( $ ) { } ); // Quantity Update - $( document ).on( 'submit', 'div.woocommerce > form', function( evt ) { - evt.preventDefault(); - - var $form = $( evt.target ); + var quantity_update = function( $form ) { // Provide the submit button value because wc-form-handler expects it. $( '' ).attr( 'type', 'hidden' ) @@ -178,7 +190,7 @@ jQuery( function( $ ) { unblock( $form ); } } ); - } ); + }; // Item Remove $( document ).on( 'click', 'td.product-remove > a', function( evt ) { diff --git a/assets/js/frontend/cart.min.js b/assets/js/frontend/cart.min.js index 8e9c8389fc8..3f0635173b2 100644 --- a/assets/js/frontend/cart.min.js +++ b/assets/js/frontend/cart.min.js @@ -1 +1 @@ -jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a("div.woocommerce",c);a("div.woocommerce").replaceWith(d)};a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var g=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},h=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a('[name="apply_coupon"]').on("click",function(f){f.preventDefault();var i=a("div.woocommerce > form");if(c(i))return!1;d(i);var j=a("#coupon_code"),k=j.val(),l={security:wc_cart_params.apply_coupon_nonce,coupon_code:k};a.ajax({type:"POST",url:b("apply_coupon"),data:l,dataType:"html",success:function(a){h(a)},complete:function(){e(i),j.val(""),g()}})}),a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var f=a(this).parents("tr"),i=a(this).attr("data-coupon");d(f.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){h(a),e(f.parents("table"))},complete:function(){g()}})}),a(document).on("submit","div.woocommerce > form",function(b){b.preventDefault();var c=a(b.target);a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(c),d(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:f,complete:function(){e(c)}})}),a(document).on("click","td.product-remove > a",function(b){b.preventDefault();var c=a(b.target),g=c.parents("form");d(g),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(g)}})})}); \ No newline at end of file +jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a("div.woocommerce",c);a("div.woocommerce").replaceWith(d)};a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var g=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},h=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a(document).on("submit","div.woocommerce > form",function(b){b.preventDefault();var d=a(b.target),e=a(document.activeElement);return window.console.log(e),c(d)?!1:void(e.is('[name="update_cart"]')||e.is("input.qty")?(window.console.log("update cart"),j(d)):(e.is('[name="apply_coupon"]')||e.is("#coupon_code"))&&(window.console.log("apply coupon"),i(d)))});var i=function(c){d(c);var f=a("#coupon_code"),i=f.val(),j={security:wc_cart_params.apply_coupon_nonce,coupon_code:i};a.ajax({type:"POST",url:b("apply_coupon"),data:j,dataType:"html",success:function(a){h(a)},complete:function(){e(c),f.val(""),g()}})};a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var f=a(this).parents("tr"),i=a(this).attr("data-coupon");d(f.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){h(a),e(f.parents("table"))},complete:function(){g()}})});var j=function(b){a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(b),d(b),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:f,complete:function(){e(b)}})};a(document).on("click","td.product-remove > a",function(b){b.preventDefault();var c=a(b.target),g=c.parents("form");d(g),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(g)}})})}); \ No newline at end of file From 7e951afbaebae7f36751b6d62d350eb4c63210b0 Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Mon, 15 Feb 2016 10:52:25 -0600 Subject: [PATCH 18/20] Cart AJAX: Add shipping form support. Add support for making an AJAX call for updating the shipping options. --- assets/js/frontend/cart.js | 28 ++++++++++++++++++++++++++++ assets/js/frontend/cart.min.js | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index ab55fb53e44..0ccf9ec6bff 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -66,6 +66,34 @@ jQuery( function( $ ) { } ); } ); + $( document ).on( 'submit', 'form.woocommerce-shipping-calculator', function( evt ) { + evt.preventDefault(); + + var $form = $( evt.target ); + + block( $form ); + + // Provide the submit button value because wc-form-handler expects it. + $( '' ).attr( 'type', 'hidden' ) + .attr( 'name', 'calc_shipping' ) + .attr( 'value', 'x' ) + .appendTo( $form ); + + // Make call to actual form post URL. + $.ajax( { + type: $form.attr( 'method' ), + url: $form.attr( 'action' ), + data: $form.serialize(), + dataType: 'html', + success: function( response ) { + update_wc_div(response ); + }, + complete: function() { + unblock( $form ); + } + } ); + } ); + $( '.shipping-calculator-form' ).hide(); // Update the cart after something has changed. diff --git a/assets/js/frontend/cart.min.js b/assets/js/frontend/cart.min.js index 3f0635173b2..da0aa9928e4 100644 --- a/assets/js/frontend/cart.min.js +++ b/assets/js/frontend/cart.min.js @@ -1 +1 @@ -jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a("div.woocommerce",c);a("div.woocommerce").replaceWith(d)};a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(".shipping-calculator-form").hide();var g=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},h=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a(document).on("submit","div.woocommerce > form",function(b){b.preventDefault();var d=a(b.target),e=a(document.activeElement);return window.console.log(e),c(d)?!1:void(e.is('[name="update_cart"]')||e.is("input.qty")?(window.console.log("update cart"),j(d)):(e.is('[name="apply_coupon"]')||e.is("#coupon_code"))&&(window.console.log("apply coupon"),i(d)))});var i=function(c){d(c);var f=a("#coupon_code"),i=f.val(),j={security:wc_cart_params.apply_coupon_nonce,coupon_code:i};a.ajax({type:"POST",url:b("apply_coupon"),data:j,dataType:"html",success:function(a){h(a)},complete:function(){e(c),f.val(""),g()}})};a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var f=a(this).parents("tr"),i=a(this).attr("data-coupon");d(f.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){h(a),e(f.parents("table"))},complete:function(){g()}})});var j=function(b){a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(b),d(b),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:f,complete:function(){e(b)}})};a(document).on("click","td.product-remove > a",function(b){b.preventDefault();var c=a(b.target),g=c.parents("form");d(g),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(g)}})})}); \ No newline at end of file +jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a("div.woocommerce",c);a("div.woocommerce").replaceWith(d)};a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(document).on("submit","form.woocommerce-shipping-calculator",function(b){b.preventDefault();var c=a(b.target);d(c),a("").attr("type","hidden").attr("name","calc_shipping").attr("value","x").appendTo(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:function(a){f(a)},complete:function(){e(c)}})}),a(".shipping-calculator-form").hide();var g=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},h=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a(document).on("submit","div.woocommerce > form",function(b){b.preventDefault();var d=a(b.target),e=a(document.activeElement);return window.console.log(e),c(d)?!1:void(e.is('[name="update_cart"]')||e.is("input.qty")?(window.console.log("update cart"),j(d)):(e.is('[name="apply_coupon"]')||e.is("#coupon_code"))&&(window.console.log("apply coupon"),i(d)))});var i=function(c){d(c);var f=a("#coupon_code"),i=f.val(),j={security:wc_cart_params.apply_coupon_nonce,coupon_code:i};a.ajax({type:"POST",url:b("apply_coupon"),data:j,dataType:"html",success:function(a){h(a)},complete:function(){e(c),f.val(""),g()}})};a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var f=a(this).parents("tr"),i=a(this).attr("data-coupon");d(f.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){h(a),e(f.parents("table"))},complete:function(){g()}})});var j=function(b){a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(b),d(b),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:f,complete:function(){e(b)}})};a(document).on("click","td.product-remove > a",function(b){b.preventDefault();var c=a(b.target),g=c.parents("form");d(g),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(g)}})})}); \ No newline at end of file From 05b2d4597ca71da7a145a29c230430c5a85c4e6d Mon Sep 17 00:00:00 2001 From: Matty Date: Tue, 16 Feb 2016 09:31:29 +0200 Subject: [PATCH 19/20] Adds a unit test for wc_format_country_state_string(). --- tests/unit-tests/util/core-functions.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/unit-tests/util/core-functions.php b/tests/unit-tests/util/core-functions.php index 00d1c424a0f..0f6c51958de 100644 --- a/tests/unit-tests/util/core-functions.php +++ b/tests/unit-tests/util/core-functions.php @@ -153,5 +153,14 @@ class Core_Functions extends \WC_Unit_Test_Case { $this->assertEquals( '', $default['state'] ); } + /** + * Test wc_format_country_state_string(). + * + * @since 2.6.0 + */ + public function test_wc_format_country_state_string() { + $this->assertEquals( array( 'country' => 'US', 'state' => 'CA' ), wc_format_country_state_string( 'US:CA' ) ); + } + } From 53c0f6c712a08fd4c7d27eccce8bd0fd44709682 Mon Sep 17 00:00:00 2001 From: Matty Date: Tue, 16 Feb 2016 11:05:32 +0200 Subject: [PATCH 20/20] Adds a test with incorrect values, to ensure the wc_format_country_state_string() function handles this as expected. --- tests/unit-tests/util/core-functions.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/unit-tests/util/core-functions.php b/tests/unit-tests/util/core-functions.php index 0f6c51958de..5567014857f 100644 --- a/tests/unit-tests/util/core-functions.php +++ b/tests/unit-tests/util/core-functions.php @@ -159,7 +159,10 @@ class Core_Functions extends \WC_Unit_Test_Case { * @since 2.6.0 */ public function test_wc_format_country_state_string() { + // Test with correct values. $this->assertEquals( array( 'country' => 'US', 'state' => 'CA' ), wc_format_country_state_string( 'US:CA' ) ); + // Test what happens when we pass an incorrect value. + $this->assertEquals( array( 'country' => 'US-CA', 'state' => '' ), wc_format_country_state_string( 'US-CA' ) ); } }