1 <?php
  2 
  3 if ( ! defined( 'ABSPATH' ) ) {
  4     exit; // Exit if accessed directly
  5 }
  6 
  7 /**
  8  * Handle frontend forms
  9  *
 10  * @class       WC_Form_Handler
 11  * @version     2.1.0
 12  * @package     WooCommerce/Classes/
 13  * @category    Class
 14  * @author      WooThemes
 15  */
 16 class WC_Form_Handler {
 17 
 18     /**
 19      * Constructor
 20      */
 21     public function __construct() {
 22         add_action( 'template_redirect', array( $this, 'save_address' ) );
 23         add_action( 'template_redirect', array( $this, 'save_account_details' ) );
 24 
 25         add_action( 'init', array( $this, 'checkout_action' ), 20 );
 26         add_action( 'init', array( $this, 'process_login' ) );
 27         add_action( 'init', array( $this, 'process_registration' ) );
 28         add_action( 'init', array( $this, 'process_reset_password' ) );
 29 
 30         add_action( 'init', array( $this, 'cancel_order' ) );
 31         add_action( 'init', array( $this, 'order_again' ) );
 32 
 33         add_action( 'init', array( $this, 'update_cart_action' ) );
 34         add_action( 'init', array( $this, 'add_to_cart_action' ) );
 35 
 36         add_action( 'wp', array( $this, 'pay_action' ), 20 );
 37         add_action( 'wp', array( $this, 'add_payment_method_action' ), 20 );
 38     }
 39 
 40     /**
 41      * Save and and update a billing or shipping address if the
 42      * form was submitted through the user account page.
 43      */
 44     public function save_address() {
 45         global $woocommerce, $wp;
 46 
 47         if ( 'POST' !== strtoupper( $_SERVER[ 'REQUEST_METHOD' ] ) ) {
 48             return;
 49         }
 50 
 51         if ( empty( $_POST[ 'action' ] ) || ( 'edit_address' !== $_POST[ 'action' ] ) || empty( $_POST['_wpnonce'] ) ) {
 52             return;
 53         }
 54 
 55         wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-edit_address' );
 56 
 57         $user_id = get_current_user_id();
 58 
 59         if ( $user_id <= 0 ) {
 60             return;
 61         }
 62 
 63         $load_address = isset( $wp->query_vars['edit-address'] ) ? sanitize_key( $wp->query_vars['edit-address'] ) : 'billing';
 64 
 65         $address = WC()->countries->get_address_fields( esc_attr( $_POST[ $load_address . '_country' ] ), $load_address . '_' );
 66 
 67         foreach ( $address as $key => $field ) {
 68 
 69             if ( ! isset( $field['type'] ) ) {
 70                 $field['type'] = 'text';
 71             }
 72 
 73             // Get Value
 74             switch ( $field['type'] ) {
 75                 case "checkbox" :
 76                     $_POST[ $key ] = isset( $_POST[ $key ] ) ? 1 : 0;
 77                 break;
 78                 default :
 79                     $_POST[ $key ] = isset( $_POST[ $key ] ) ? wc_clean( $_POST[ $key ] ) : '';
 80                 break;
 81             }
 82 
 83             // Hook to allow modification of value
 84             $_POST[ $key ] = apply_filters( 'woocommerce_process_myaccount_field_' . $key, $_POST[ $key ] );
 85 
 86             // Validation: Required fields
 87             if ( ! empty( $field['required'] ) && empty( $_POST[ $key ] ) ) {
 88                 wc_add_notice( $field['label'] . ' ' . __( 'is a required field.', 'woocommerce' ), 'error' );
 89             }
 90 
 91             // Validation rules
 92             if ( ! empty( $field['validate'] ) && is_array( $field['validate'] ) ) {
 93                 foreach ( $field['validate'] as $rule ) {
 94                     switch ( $rule ) {
 95                         case 'postcode' :
 96                             $_POST[ $key ] = strtoupper( str_replace( ' ', '', $_POST[ $key ] ) );
 97 
 98                             if ( ! WC_Validation::is_postcode( $_POST[ $key ], $_POST[ $load_address . '_country' ] ) ) {
 99                                 wc_add_notice( __( 'Please enter a valid postcode/ZIP.', 'woocommerce' ), 'error' );
100                             } else {
101                                 $_POST[ $key ] = wc_format_postcode( $_POST[ $key ], $_POST[ $load_address . '_country' ] );
102                             }
103                         break;
104                         case 'phone' :
105                             $_POST[ $key ] = wc_format_phone_number( $_POST[ $key ] );
106 
107                             if ( ! WC_Validation::is_phone( $_POST[ $key ] ) ) {
108                                 wc_add_notice( '<strong>' . $field['label'] . '</strong> ' . __( 'is not a valid phone number.', 'woocommerce' ), 'error' );
109                             }
110                         break;
111                         case 'email' :
112                             $_POST[ $key ] = strtolower( $_POST[ $key ] );
113 
114                             if ( ! is_email( $_POST[ $key ] ) ) {
115                                 wc_add_notice( '<strong>' . $field['label'] . '</strong> ' . __( 'is not a valid email address.', 'woocommerce' ), 'error' );
116                             }
117                         break;
118                     }
119                 }
120             }
121         }
122 
123         if ( wc_notice_count( 'error' ) == 0 ) {
124 
125             foreach ( $address as $key => $field ) {
126                 update_user_meta( $user_id, $key, $_POST[ $key ] );
127             }
128 
129             wc_add_notice( __( 'Address changed successfully.', 'woocommerce' ) );
130 
131             do_action( 'woocommerce_customer_save_address', $user_id, $load_address );
132 
133             wp_safe_redirect( get_permalink( wc_get_page_id('myaccount') ) );
134             exit;
135         }
136     }
137 
138     /**
139      * Save the password/account details and redirect back to the my account page.
140      */
141     public function save_account_details() {
142 
143         if ( 'POST' !== strtoupper( $_SERVER[ 'REQUEST_METHOD' ] ) ) {
144             return;
145         }
146 
147         if ( empty( $_POST[ 'action' ] ) || ( 'save_account_details' !== $_POST[ 'action' ] ) || empty( $_POST['_wpnonce'] ) ) {
148             return;
149         }
150 
151         wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-save_account_details' );
152 
153         $update       = true;
154         $errors       = new WP_Error();
155         $user         = new stdClass();
156 
157         $user->ID     = (int) get_current_user_id();
158         $current_user = get_user_by( 'id', $user->ID );
159 
160         if ( $user->ID <= 0 ) {
161             return;
162         }
163 
164         $account_first_name = ! empty( $_POST[ 'account_first_name' ] ) ? wc_clean( $_POST[ 'account_first_name' ] ) : '';
165         $account_last_name  = ! empty( $_POST[ 'account_last_name' ] ) ? wc_clean( $_POST[ 'account_last_name' ] ) : '';
166         $account_email      = ! empty( $_POST[ 'account_email' ] ) ? sanitize_email( $_POST[ 'account_email' ] ) : '';
167         $pass1              = ! empty( $_POST[ 'password_1' ] ) ? $_POST[ 'password_1' ] : '';
168         $pass2              = ! empty( $_POST[ 'password_2' ] ) ? $_POST[ 'password_2' ] : '';
169 
170         $user->first_name   = $account_first_name;
171         $user->last_name    = $account_last_name;
172         $user->user_email   = $account_email;
173         $user->display_name = $user->first_name;
174 
175         if ( $pass1 ) {
176             $user->user_pass = $pass1;
177         }
178 
179         if ( empty( $account_first_name ) || empty( $account_last_name ) ) {
180             wc_add_notice( __( 'Please enter your name.', 'woocommerce' ), 'error' );
181         }
182 
183         if ( empty( $account_email ) || ! is_email( $account_email ) ) {
184             wc_add_notice( __( 'Please provide a valid email address.', 'woocommerce' ), 'error' );
185         } elseif ( email_exists( $account_email ) && $account_email !== $current_user->user_email ) {
186             wc_add_notice( __( 'This email address is already registered.', 'woocommerce' ), 'error' );
187         }
188 
189         if ( ! empty( $pass1 ) && empty( $pass2 ) ) {
190             wc_add_notice( __( 'Please re-enter your password.', 'woocommerce' ), 'error' );
191         } elseif ( ! empty( $pass1 ) && $pass1 !== $pass2 ) {
192             wc_add_notice( __( 'Passwords do not match.', 'woocommerce' ), 'error' );
193         }
194 
195         // Allow plugins to return their own errors.
196         do_action_ref_array( 'user_profile_update_errors', array ( &$errors, $update, &$user ) );
197 
198         if ( $errors->get_error_messages() ) {
199             foreach ( $errors->get_error_messages() as $error ) {
200                 wc_add_notice( $error, 'error' );
201             }
202         }
203 
204         if ( wc_notice_count( 'error' ) == 0 ) {
205 
206             wp_update_user( $user ) ;
207 
208             wc_add_notice( __( 'Account details changed successfully.', 'woocommerce' ) );
209 
210             do_action( 'woocommerce_save_account_details', $user->ID );
211 
212             wp_safe_redirect( get_permalink( wc_get_page_id( 'myaccount' ) ) );
213             exit;
214         }
215     }
216 
217     /**
218      * Process the checkout form.
219      */
220     public function checkout_action() {
221         if ( isset( $_POST['woocommerce_checkout_place_order'] ) || isset( $_POST['woocommerce_checkout_update_totals'] ) ) {
222 
223             if ( sizeof( WC()->cart->get_cart() ) == 0 ) {
224                 wp_redirect( get_permalink( wc_get_page_id( 'cart' ) ) );
225                 exit;
226             }
227 
228             if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) {
229                 define( 'WOOCOMMERCE_CHECKOUT', true );
230             }
231 
232             $woocommerce_checkout = WC()->checkout();
233             $woocommerce_checkout->process_checkout();
234         }
235     }
236 
237     /**
238      * Process the pay form.
239      */
240     public function pay_action() {
241         global $wp;
242 
243         if ( isset( $_POST['woocommerce_pay'] ) && isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-pay' ) ) {
244 
245             ob_start();
246 
247             // Pay for existing order
248             $order_key  = $_GET['key'];
249             $order_id   = absint( $wp->query_vars['order-pay'] );
250             $order      = new WC_Order( $order_id );
251 
252             if ( $order->id == $order_id && $order->order_key == $order_key && in_array( $order->status, array( 'pending', 'failed' ) ) ) {
253 
254                 // Set customer location to order location
255                 if ( $order->billing_country ) {
256                     WC()->customer->set_country( $order->billing_country );
257                 }
258                 if ( $order->billing_state ) {
259                     WC()->customer->set_state( $order->billing_state );
260                 }
261                 if ( $order->billing_postcode ) {
262                     WC()->customer->set_postcode( $order->billing_postcode );
263                 }
264                 if ( $order->billing_city ) {
265                     WC()->customer->set_city( $order->billing_city );
266                 }
267 
268                 // Update payment method
269                 if ( $order->needs_payment() ) {
270                     $payment_method = wc_clean( $_POST['payment_method'] );
271 
272                     $available_gateways = WC()->payment_gateways->get_available_payment_gateways();
273 
274                     // Update meta
275                     update_post_meta( $order_id, '_payment_method', $payment_method );
276 
277                     if ( isset( $available_gateways[ $payment_method ] ) ) {
278                         $payment_method_title = $available_gateways[ $payment_method ]->get_title();
279                     }
280 
281                     update_post_meta( $order_id, '_payment_method_title', $payment_method_title);
282 
283                     // Validate
284                     $available_gateways[ $payment_method ]->validate_fields();
285 
286                     // Process
287                     if ( wc_notice_count( 'error' ) == 0 ) {
288 
289                         $result = $available_gateways[ $payment_method ]->process_payment( $order_id );
290 
291                         // Redirect to success/confirmation/payment page
292                         if ( 'success' == $result['result'] ) {
293                             wp_redirect( $result['redirect'] );
294                             exit;
295                         }
296 
297                     }
298 
299                 } else {
300                     // No payment was required for order
301                     $order->payment_complete();
302                     wp_safe_redirect( $order->get_checkout_order_received_url() );
303                     exit;
304                 }
305 
306             }
307 
308         }
309     }
310 
311     /**
312      * Process the add payment method form.
313      */
314     public function add_payment_method_action() {
315         global $wp;
316 
317         if ( isset( $_POST['woocommerce_add_payment_method'] ) && isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-add-payment-method' ) ) {
318 
319             ob_start();
320 
321             $payment_method = wc_clean( $_POST['payment_method'] );
322 
323             $available_gateways = WC()->payment_gateways->get_available_payment_gateways();
324 
325             // Validate
326             $available_gateways[ $payment_method ]->validate_fields();
327 
328             // Process
329             if ( wc_error_count() == 0 ) {
330                 $result = $available_gateways[ $payment_method ]->add_payment_method();
331 
332                 // Redirect to success/confirmation/payment page
333                 if ( $result['result'] == 'success' ) {
334                     wc_add_message( __( 'Payment method added.', 'woocommerce' ) );
335                     wp_redirect( $result['redirect'] );
336                     exit();
337                 }
338 
339             }
340 
341         }
342 
343     }
344 
345     /**
346      * Remove from cart/update.
347      */
348     public function update_cart_action() {
349 
350         // Add Discount
351         if ( ! empty( $_POST['apply_coupon'] ) && ! empty( $_POST['coupon_code'] ) ) {
352             WC()->cart->add_discount( sanitize_text_field( $_POST['coupon_code'] ) );
353         }
354 
355         // Remove Coupon Codes
356         elseif ( isset( $_GET['remove_coupon'] ) ) {
357 
358             WC()->cart->remove_coupon( wc_clean( $_GET['remove_coupon'] ) );
359 
360         }
361 
362         // Remove from cart
363         elseif ( ! empty( $_GET['remove_item'] ) && isset( $_GET['_wpnonce'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'woocommerce-cart' ) ) {
364 
365             WC()->cart->set_quantity( $_GET['remove_item'], 0 );
366 
367             wc_add_notice( __( 'Cart updated.', 'woocommerce' ) );
368 
369             $referer = wp_get_referer() ? wp_get_referer() : WC()->cart->get_cart_url();
370             wp_safe_redirect( $referer );
371             exit;
372 
373         }
374 
375         // Update Cart - checks apply_coupon too because they are in the same form
376         if ( ( ! empty( $_POST['apply_coupon'] ) || ! empty( $_POST['update_cart'] ) || ! empty( $_POST['proceed'] ) ) && isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-cart' ) ) {
377 
378             $cart_updated = false;
379             $cart_totals  = isset( $_POST['cart'] ) ? $_POST['cart'] : '';
380 
381             if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
382                 foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
383 
384                     $_product = $values['data'];
385 
386                     // Skip product if no updated quantity was posted
387                     if ( ! isset( $cart_totals[ $cart_item_key ]['qty'] ) ) {
388                         continue;
389                     }
390 
391                     // Sanitize
392                     $quantity = apply_filters( 'woocommerce_stock_amount_cart_item', apply_filters( 'woocommerce_stock_amount', preg_replace( "/[^0-9\.]/", '', $cart_totals[ $cart_item_key ]['qty'] ) ), $cart_item_key );
393 
394                     if ( '' === $quantity || $quantity == $values['quantity'] )
395                         continue;
396 
397                     // Update cart validation
398                     $passed_validation  = apply_filters( 'woocommerce_update_cart_validation', true, $cart_item_key, $values, $quantity );
399 
400                     // is_sold_individually
401                     if ( $_product->is_sold_individually() && $quantity > 1 ) {
402                         wc_add_notice( sprintf( __( 'You can only have 1 %s in your cart.', 'woocommerce' ), $_product->get_title() ), 'error' );
403                         $passed_validation = false;
404                     }
405 
406                     if ( $passed_validation ) {
407                         WC()->cart->set_quantity( $cart_item_key, $quantity, false );
408                     }
409 
410                     $cart_updated = true;
411                 }
412             }
413 
414             // Trigger action - let 3rd parties update the cart if they need to and update the $cart_updated variable
415             $cart_updated = apply_filters( 'woocommerce_update_cart_action_cart_updated', $cart_updated );
416 
417             if ( $cart_updated ) {
418                 // Recalc our totals
419                 WC()->cart->calculate_totals();
420             }
421 
422             if ( ! empty( $_POST['proceed'] ) ) {
423                 wp_safe_redirect( WC()->cart->get_checkout_url() );
424                 exit;
425             } elseif ( $cart_updated ) {
426                 wc_add_notice( __( 'Cart updated.', 'woocommerce' ) );
427 
428                 $referer = ( wp_get_referer() ) ? wp_get_referer() : WC()->cart->get_cart_url();
429                 $referer = remove_query_arg( 'remove_coupon', $referer );
430                 wp_safe_redirect( $referer );
431                 exit;
432             }
433         }
434     }
435 
436     /**
437      * Place a previous order again.
438      */
439     public function order_again() {
440 
441         // Nothing to do
442         if ( ! isset( $_GET['order_again'] ) || ! is_user_logged_in() || ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'woocommerce-order_again' ) ) {
443             return;
444         }
445 
446         // Clear current cart
447         WC()->cart->empty_cart();
448 
449         // Load the previous order - Stop if the order does not exist
450         $order = new WC_Order( absint( $_GET['order_again'] ) );
451 
452         if ( empty( $order->id ) ) {
453             return;
454         }
455 
456         if ( 'completed' != $order->status ) {
457             return;
458         }
459 
460         // Make sure the user is allowed to order again. By default it check if the
461         // previous order belonged to the current user.
462         if ( ! current_user_can( 'order_again', $order->id ) ) {
463             return;
464         }
465 
466         // Copy products from the order to the cart
467         foreach ( $order->get_items() as $item ) {
468             // Load all product info including variation data
469             $product_id   = (int) apply_filters( 'woocommerce_add_to_cart_product_id', $item['product_id'] );
470             $quantity     = (int) $item['qty'];
471             $variation_id = (int) $item['variation_id'];
472             $variations   = array();
473             $cart_item_data = apply_filters( 'woocommerce_order_again_cart_item_data', array(), $item, $order );
474 
475             foreach ( $item['item_meta'] as $meta_name => $meta_value ) {
476                 if ( taxonomy_is_product_attribute( $meta_name ) ) {
477                     $variations[ $meta_name ] = $meta_value[0];
478                 } elseif ( meta_is_product_attribute( $meta_name, $meta_value, $product_id ) ) {
479                     $variations[ $meta_name ] = $meta_value[0];
480                 }
481             }
482 
483             // Add to cart validation
484             if ( ! apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations, $cart_item_data ) ) {
485                 continue;
486             }
487 
488             WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations, $cart_item_data );
489         }
490 
491         do_action( 'woocommerce_ordered_again', $order->id );
492 
493         // Redirect to cart
494         wc_add_notice( __( 'The cart has been filled with the items from your previous order.', 'woocommerce' ) );
495         wp_safe_redirect( WC()->cart->get_cart_url() );
496         exit;
497     }
498 
499     /**
500      * Cancel a pending order.
501      */
502     public function cancel_order() {
503         if ( isset( $_GET['cancel_order'] ) && isset( $_GET['order'] ) && isset( $_GET['order_id'] ) ) {
504 
505             $order_key        = $_GET['order'];
506             $order_id         = absint( $_GET['order_id'] );
507             $order            = new WC_Order( $order_id );
508             $user_can_cancel  = current_user_can( 'cancel_order', $order_id );
509             $order_can_cancel = in_array( $order->status, apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ) ) );
510             $redirect         = $_GET['redirect'];
511 
512             if ( $order->status == 'cancelled' ) {
513                 // Already cancelled - take no action
514             } elseif ( $user_can_cancel && $order_can_cancel && $order->id == $order_id && $order->order_key == $order_key && isset( $_GET['_wpnonce'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'woocommerce-cancel_order' ) ) {
515 
516                 // Cancel the order + restore stock
517                 $order->cancel_order( __('Order cancelled by customer.', 'woocommerce' ) );
518 
519                 // Message
520                 wc_add_notice( apply_filters( 'woocommerce_order_cancelled_notice', __( 'Your order was cancelled.', 'woocommerce' ) ), apply_filters( 'woocommerce_order_cancelled_notice_type', 'notice' ) );
521 
522                 do_action( 'woocommerce_cancelled_order', $order->id );
523 
524             } elseif ( $user_can_cancel && ! $order_can_cancel ) {
525                 wc_add_notice( __( 'Your order can no longer be cancelled. Please contact us if you need assistance.', 'woocommerce' ), 'error' );
526             } else {
527                 wc_add_notice( __( 'Invalid order.', 'woocommerce' ), 'error' );
528             }
529 
530             if ( $redirect ) {
531                 wp_safe_redirect( $redirect );
532                 exit;
533             }
534         }
535     }
536 
537     /**
538      * Add to cart action
539      *
540      * Checks for a valid request, does validation (via hooks) and then redirects if valid.
541      *
542      * @param bool $url (default: false)
543      */
544     public function add_to_cart_action( $url = false ) {
545         if ( empty( $_REQUEST['add-to-cart'] ) || ! is_numeric( $_REQUEST['add-to-cart'] ) ) {
546             return;
547         }
548 
549         $product_id          = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_REQUEST['add-to-cart'] ) );
550         $was_added_to_cart   = false;
551         $added_to_cart       = array();
552         $adding_to_cart      = get_product( $product_id );
553         $add_to_cart_handler = apply_filters( 'woocommerce_add_to_cart_handler', $adding_to_cart->product_type, $adding_to_cart );
554 
555         // Variable product handling
556         if ( 'variable' === $add_to_cart_handler ) {
557 
558             $variation_id       = empty( $_REQUEST['variation_id'] ) ? '' : absint( $_REQUEST['variation_id'] );
559             $quantity           = empty( $_REQUEST['quantity'] ) ? 1 : apply_filters( 'woocommerce_stock_amount', $_REQUEST['quantity'] );
560             $all_variations_set = true;
561             $variations         = array();
562 
563             // Only allow integer variation ID - if its not set, redirect to the product page
564             if ( empty( $variation_id ) ) {
565                 wc_add_notice( __( 'Please choose product options&hellip;', 'woocommerce' ), 'error' );
566                 return;
567             }
568 
569             $attributes = $adding_to_cart->get_attributes();
570             $variation  = get_product( $variation_id );
571 
572             // Verify all attributes
573             foreach ( $attributes as $attribute ) {
574                 if ( ! $attribute['is_variation'] ) {
575                     continue;
576                 }
577 
578                 $taxonomy = 'attribute_' . sanitize_title( $attribute['name'] );
579 
580                 if ( isset( $_REQUEST[ $taxonomy ] ) ) {
581 
582                     // Get value from post data
583                     // Don't use wc_clean as it destroys sanitized characters
584                     $value = sanitize_title( trim( stripslashes( $_REQUEST[ $taxonomy ] ) ) );
585 
586                     // Get valid value from variation
587                     $valid_value = $variation->variation_data[ $taxonomy ];
588 
589                     // Allow if valid
590                     if ( $valid_value == '' || $valid_value == $value ) {
591                         if ( $attribute['is_taxonomy'] ) {
592                             $variations[ $taxonomy ] = $value;
593                         }
594                         else {
595                             // For custom attributes, get the name from the slug
596                             $options = array_map( 'trim', explode( WC_DELIMITER, $attribute['value'] ) );
597                             foreach ( $options as $option ) {
598                                 if ( sanitize_title( $option ) == $value ) {
599                                     $value = $option;
600                                     break;
601                                 }
602                             }
603                              $variations[ $taxonomy ] = $value;
604                         }
605                         continue;
606                     }
607 
608                 }
609 
610                 $all_variations_set = false;
611             }
612 
613             if ( $all_variations_set ) {
614                 // Add to cart validation
615                 $passed_validation  = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations );
616 
617                 if ( $passed_validation ) {
618                     if ( WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations ) ) {
619                         wc_add_to_cart_message( $product_id );
620                         $was_added_to_cart = true;
621                         $added_to_cart[] = $product_id;
622                     }
623                 }
624             } else {
625                 wc_add_notice( __( 'Please choose product options&hellip;', 'woocommerce' ), 'error' );
626                 return;
627             }
628 
629         // Grouped Products
630         } elseif ( 'grouped' === $add_to_cart_handler ) {
631 
632             if ( ! empty( $_REQUEST['quantity'] ) && is_array( $_REQUEST['quantity'] ) ) {
633 
634                 $quantity_set = false;
635 
636                 foreach ( $_REQUEST['quantity'] as $item => $quantity ) {
637                     if ( $quantity <= 0 ) {
638                         continue;
639                     }
640 
641                     $quantity_set = true;
642 
643                     // Add to cart validation
644                     $passed_validation  = apply_filters( 'woocommerce_add_to_cart_validation', true, $item, $quantity );
645 
646                     if ( $passed_validation ) {
647                         if ( WC()->cart->add_to_cart( $item, $quantity ) ) {
648                             $was_added_to_cart = true;
649                             $added_to_cart[] = $item;
650                         }
651                     }
652                 }
653 
654                 if ( $was_added_to_cart ) {
655                     wc_add_to_cart_message( $added_to_cart );
656                 }
657 
658                 if ( ! $was_added_to_cart && ! $quantity_set ) {
659                     wc_add_notice( __( 'Please choose the quantity of items you wish to add to your cart&hellip;', 'woocommerce' ), 'error' );
660                     return;
661                 }
662 
663             } elseif ( $product_id ) {
664 
665                 /* Link on product archives */
666                 wc_add_notice( __( 'Please choose a product to add to your cart&hellip;', 'woocommerce' ), 'error' );
667                 return;
668 
669             }
670 
671         // Simple Products
672         } else {
673 
674             $quantity           = empty( $_REQUEST['quantity'] ) ? 1 : apply_filters( 'woocommerce_stock_amount', $_REQUEST['quantity'] );
675 
676             // Add to cart validation
677             $passed_validation  = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity );
678 
679             if ( $passed_validation ) {
680                 // Add the product to the cart
681                 if ( WC()->cart->add_to_cart( $product_id, $quantity ) ) {
682                     wc_add_to_cart_message( $product_id );
683                     $was_added_to_cart = true;
684                     $added_to_cart[] = $product_id;
685                 }
686             }
687 
688         }
689 
690         // If we added the product to the cart we can now optionally do a redirect.
691         if ( $was_added_to_cart && wc_notice_count( 'error' ) == 0 ) {
692 
693             $url = apply_filters( 'add_to_cart_redirect', $url );
694 
695             // If has custom URL redirect there
696             if ( $url ) {
697                 wp_safe_redirect( $url );
698                 exit;
699             }
700 
701             // Redirect to cart option
702             elseif ( get_option('woocommerce_cart_redirect_after_add') == 'yes' ) {
703                 wp_safe_redirect( WC()->cart->get_cart_url() );
704                 exit;
705             }
706 
707         }
708 
709     }
710 
711     /**
712      * Process the login form.
713      */
714     public function process_login() {
715         if ( ! empty( $_POST['login'] ) && ! empty( $_POST['_wpnonce'] ) ) {
716 
717             wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-login' );
718 
719             try {
720                 $creds  = array();
721 
722                 $validation_error = new WP_Error();
723                 $validation_error = apply_filters( 'woocommerce_process_login_errors', $validation_error, $_POST['username'], $_POST['password'] );
724 
725                 if ( $validation_error->get_error_code() ) {
726                     throw new Exception( '<strong>' . __( 'Error', 'woocommerce' ) . ':</strong> ' . $validation_error->get_error_message() );
727                 }
728 
729                 if ( empty( $_POST['username'] ) ) {
730                     throw new Exception( '<strong>' . __( 'Error', 'woocommerce' ) . ':</strong> ' . __( 'Username is required.', 'woocommerce' ) );
731                 }
732 
733                 if ( empty( $_POST['password'] ) ) {
734                     throw new Exception( '<strong>' . __( 'Error', 'woocommerce' ) . ':</strong> ' . __( 'Password is required.', 'woocommerce' ) );
735                 }
736 
737                 if ( is_email( $_POST['username'] ) && apply_filters( 'woocommerce_get_username_from_email', true ) ) {
738                     $user = get_user_by( 'email', $_POST['username'] );
739 
740                     if ( isset( $user->user_login ) ) {
741                         $creds['user_login']    = $user->user_login;
742                     } else {
743                         throw new Exception( '<strong>' . __( 'Error', 'woocommerce' ) . ':</strong> ' . __( 'A user could not be found with this email address.', 'woocommerce' ) );
744                     }
745 
746                 } else {
747                     $creds['user_login']    = $_POST['username'];
748                 }
749 
750                 $creds['user_password'] = $_POST['password'];
751                 $creds['remember']      = isset( $_POST['rememberme'] );
752                 $secure_cookie          = is_ssl() ? true : false;
753                 $user                   = wp_signon( apply_filters( 'woocommerce_login_credentials', $creds ), $secure_cookie );
754 
755                 if ( is_wp_error( $user ) ) {
756                     throw new Exception( $user->get_error_message() );
757                 } else {
758 
759                     if ( ! empty( $_POST['redirect'] ) ) {
760                         $redirect = esc_url( $_POST['redirect'] );
761                     } elseif ( wp_get_referer() ) {
762                         $redirect = esc_url( wp_get_referer() );
763                     } else {
764                         $redirect = esc_url( get_permalink( wc_get_page_id( 'myaccount' ) ) );
765                     }
766 
767                     // Feedback
768                     wc_add_notice( sprintf( __( 'You are now logged in as <strong>%s</strong>', 'woocommerce' ), $user->display_name ) );
769 
770                     wp_redirect( apply_filters( 'woocommerce_login_redirect', $redirect, $user ) );
771                     exit;
772                 }
773 
774             } catch (Exception $e) {
775 
776                 wc_add_notice( apply_filters('login_errors', $e->getMessage() ), 'error' );
777 
778             }
779         }
780     }
781 
782     /**
783      * Handle reset password form
784      */
785     public function process_reset_password() {
786         if ( ! isset( $_POST['wc_reset_password'] ) ) {
787             return;
788         }
789 
790         // process lost password form
791         if ( isset( $_POST['user_login'] ) && isset( $_POST['_wpnonce'] ) ) {
792             wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-lost_password' );
793 
794             WC_Shortcode_My_Account::retrieve_password();
795         }
796 
797         // process reset password form
798         if ( isset( $_POST['password_1'] ) && isset( $_POST['password_2'] ) && isset( $_POST['reset_key'] ) && isset( $_POST['reset_login'] ) && isset( $_POST['_wpnonce'] ) ) {
799 
800             // verify reset key again
801             $user = WC_Shortcode_My_Account::check_password_reset_key( $_POST['reset_key'], $_POST['reset_login'] );
802 
803             if ( is_object( $user ) ) {
804 
805                 // save these values into the form again in case of errors
806                 $args['key']   = wc_clean( $_POST['reset_key'] );
807                 $args['login'] = wc_clean( $_POST['reset_login'] );
808 
809                 wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-reset_password' );
810 
811                 if ( empty( $_POST['password_1'] ) || empty( $_POST['password_2'] ) ) {
812                     wc_add_notice( __( 'Please enter your password.', 'woocommerce' ), 'error' );
813                     $args['form'] = 'reset_password';
814                 }
815 
816                 if ( $_POST[ 'password_1' ] !== $_POST[ 'password_2' ] ) {
817                     wc_add_notice( __( 'Passwords do not match.', 'woocommerce' ), 'error' );
818                     $args['form'] = 'reset_password';
819                 }
820 
821                 $errors = new WP_Error();
822                 do_action( 'validate_password_reset', $errors, $user );
823                 if ( $errors->get_error_messages() ) {
824                     foreach ( $errors->get_error_messages() as $error ) {
825                         wc_add_notice( $error, 'error');
826                     }
827                 }
828 
829                 if ( 0 == wc_notice_count( 'error' ) ) {
830 
831                     WC_Shortcode_My_Account::reset_password( $user, $_POST['password_1'] );
832 
833                     do_action( 'woocommerce_customer_reset_password', $user );
834 
835                     wp_redirect( add_query_arg( 'reset', 'true', remove_query_arg( array( 'key', 'login' ) ) ) );
836                     exit;
837                 }
838             }
839 
840         }
841     }
842 
843     /**
844      * Process the registration form.
845      */
846     public function process_registration() {
847         if ( ! empty( $_POST['register'] ) ) {
848 
849             wp_verify_nonce( $_POST['register'], 'woocommerce-register' );
850 
851             if ( 'no' === get_option( 'woocommerce_registration_generate_username' ) ) {
852                 $_username = $_POST['username'];
853             } else {
854                 $_username = '';
855             }
856 
857             if ( 'no' === get_option( 'woocommerce_registration_generate_password' ) ) {
858                 $_password = $_POST['password'];
859             } else {
860                 $_password = '';
861             }
862 
863             try {
864 
865                 $validation_error = new WP_Error();
866                 $validation_error = apply_filters( 'woocommerce_process_registration_errors', $validation_error, $_username, $_password, $_POST['email'] );
867 
868                 if ( $validation_error->get_error_code() ) {
869                     throw new Exception( '<strong>' . __( 'Error', 'woocommerce' ) . ':</strong> ' . $validation_error->get_error_message() );
870                 }
871 
872             } catch ( Exception $e ) {
873 
874                 wc_add_notice( $e->getMessage(), 'error' );
875                 return;
876 
877             }
878 
879             $username   = ! empty( $_username ) ? wc_clean( $_username ) : '';
880             $email      = ! empty( $_POST['email'] ) ? sanitize_email( $_POST['email'] ) : '';
881             $password   = $_password;
882 
883             // Anti-spam trap
884             if ( ! empty( $_POST['email_2'] ) ) {
885                 wc_add_notice( '<strong>' . __( 'ERROR', 'woocommerce' ) . '</strong>: ' . __( 'Anti-spam field was filled in.', 'woocommerce' ), 'error' );
886                 return;
887             }
888 
889             $new_customer = wc_create_new_customer( $email, $username, $password );
890 
891             if ( is_wp_error( $new_customer ) ) {
892                 wc_add_notice( $new_customer->get_error_message(), 'error' );
893                 return;
894             }
895 
896             wc_set_customer_auth_cookie( $new_customer );
897 
898             // Redirect
899             if ( wp_get_referer() ) {
900                 $redirect = esc_url( wp_get_referer() );
901             } else {
902                 $redirect = esc_url( get_permalink( wc_get_page_id( 'myaccount' ) ) );
903             }
904 
905             wp_redirect( apply_filters( 'woocommerce_registration_redirect', $redirect ) );
906             exit;
907         }
908     }
909 }
910 
911 new WC_Form_Handler();
912 
WooCommerce API documentation generated by ApiGen 2.8.0