Skip to content

Commit

Permalink
Fix using the PayPal smart button on a variable product page, or a pr…
Browse files Browse the repository at this point in the history
…oduct with Addons (#507)

* Disable the PayPal button in the product page if there are invalid fields in the form

* Send the fields added by Product Addons in the PayPal "add to cart" request

* Simplify the logic for serializing the form before sending it to the AJAX "add to cart" endpoint

* Update changelog
  • Loading branch information
DanReyLop authored Dec 20, 2018
1 parent c7476dd commit 876863b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 36 deletions.
72 changes: 41 additions & 31 deletions assets/js/wc-gateway-ppec-generate-cart.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,52 +30,62 @@
$( '#woo_pp_ec_button_product > *' ).css( 'pointer-events', 'none' );
} );

// True if the product is simple or the user selected a valid variation. False on variable product without a valid variation selected
var variation_valid = true;

// True if all the fields of the product form are valid (such as required fields configured by Product Add-Ons). False otherwise
var fields_valid = true;

var form = $( 'form.cart' );

var update_button = function() {
$( '#woo_pp_ec_button_product' ).trigger( ( variation_valid && fields_valid ) ? 'enable' : 'disable' );
};

var validate_form = function() {
fields_valid = form.get( 0 ).checkValidity();
update_button();
};

// It's a variations form, button availability should depend on its events
if ( $( '.variations_form' ).length ) {
$( '#woo_pp_ec_button_product' ).trigger( 'disable' );
variation_valid = false;

$( '.variations_form' )
.on( 'show_variation', function( event, form, purchasable ) {
$( '#woo_pp_ec_button_product' ).trigger( purchasable ? 'enable' : 'disable' );
variation_valid = purchasable;
update_button();
} )
.on( 'hide_variation', function() {
$( '#woo_pp_ec_button_product' ).trigger( 'disable' );
variation_valid = false;
update_button();
} );
}

var get_attributes = function() {
var select = $( '.variations_form' ).find( '.variations select' ),
data = {},
count = 0,
chosen = 0;

select.each( function() {
var attribute_name = $( this ).data( 'attribute_name' ) || $( this ).attr( 'name' );
var value = $( this ).val() || '';

if ( value.length > 0 ) {
chosen++;
}

count++;
data[ attribute_name ] = value;
} );

return {
'count' : count,
'chosenCount': chosen,
'data' : data
};
};
// Disable the button if there are invalid fields in the product page (like required fields from Product Addons)
form.on( 'change', 'select, input, textarea', function() {
// Hack: IE11 uses the previous field value for the checkValidity() check if it's called in the onChange handler
setTimeout( validate_form, 0 );
} );
validate_form();

var generate_cart = function( callback ) {
var data = {
'nonce': wc_ppec_generate_cart_context.generate_cart_nonce,
'qty': $( '.quantity .qty' ).val(),
'attributes': $( '.variations_form' ).length ? get_attributes().data : [],
'add-to-cart': $( '[name=add-to-cart]' ).val(),
'nonce': wc_ppec_generate_cart_context.generate_cart_nonce,
};

var field_pairs = form.serializeArray();
for ( var i = 0; i < field_pairs.length; i++ ) {
// Prevent the default WooCommerce PHP form handler from recognizing this as an "add to cart" call
if ( 'add-to-cart' === field_pairs[ i ].name ) {
field_pairs[ i ].name = 'ppec-add-to-cart';
}
data[ field_pairs[ i ].name ] = field_pairs[ i ].value;
}

// If this is a simple product, the "Submit" button has the product ID as "value", we need to include it explicitly
data[ 'ppec-add-to-cart' ] = $( '[name=add-to-cart]' ).val();

$.ajax( {
type: 'POST',
data: data,
Expand Down
11 changes: 6 additions & 5 deletions includes/class-wc-gateway-ppec-cart-handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public function before_cart_totals() {

/**
* Generates the cart for PayPal Checkout on a product level.
* TODO: Why not let the default "add-to-cart" PHP form handler insert the product into the cart? Investigate.
*
* @since 1.4.0
*/
Expand All @@ -70,8 +71,8 @@ public function wc_ajax_generate_cart() {
WC()->shipping->reset_shipping();
$product = wc_get_product( $post->ID );

if ( ! empty( $_POST['add-to-cart'] ) ) {
$product = wc_get_product( absint( $_POST['add-to-cart'] ) );
if ( ! empty( $_POST['ppec-add-to-cart'] ) ) {
$product = wc_get_product( absint( $_POST['ppec-add-to-cart'] ) );
}

/**
Expand All @@ -80,11 +81,11 @@ public function wc_ajax_generate_cart() {
* simple or variable product.
*/
if ( $product ) {
$qty = ! isset( $_POST['qty'] ) ? 1 : absint( $_POST['qty'] );
$qty = ! isset( $_POST['quantity'] ) ? 1 : absint( $_POST['quantity'] );
wc_empty_cart();

if ( $product->is_type( 'variable' ) ) {
$attributes = array_map( 'wc_clean', $_POST['attributes'] );
$attributes = array_map( 'wc_clean', $_POST );

if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
$variation_id = $product->get_matching_variation( $attributes );
Expand All @@ -93,7 +94,7 @@ public function wc_ajax_generate_cart() {
$variation_id = $data_store->find_matching_product_variation( $product, $attributes );
}

WC()->cart->add_to_cart( $product->get_id(), $qty, $variation_id, $attributes );
WC()->cart->add_to_cart( $product->get_id(), $qty, $variation_id );
} else {
WC()->cart->add_to_cart( $product->get_id(), $qty );
}
Expand Down
2 changes: 2 additions & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ Please use this to inform us about bugs, or make contributions via PRs.
== Changelog ==

= 1.6.6 - 201x-xx-xx =
* Fix - Unable to buy variation from product page
* Fix - can use PayPal from product page without inputting required fields
* Add - display PayPal fees under the totals on the order admin page

= 1.6.5 - 2018-10-31 =
Expand Down

0 comments on commit 876863b

Please sign in to comment.