Completed
Push — master ( a85a3b...a9e055 )
by Justin
11:13
created

wpsc_checkout::wpsc_checkout()   C

Complexity

Conditions 9
Paths 96

Size

Total Lines 49
Code Lines 35

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 49
rs 5.7446
cc 9
eloc 35
nc 96
nop 1
1
<?php
2
3
/**
4
 * WP eCommerce checkout class
5
 *
6
 * These are the class for the WP eCommerce checkout
7
 * The checkout class handles displaying the checkout form fields
8
 *
9
 * @package wp-e-commerce
10
 * @subpackage wpsc-checkout-classes
11
 */
12
13
/**
14
 * wpsc has regions checks to see whether a country has regions or not
15
 * @access public
16
 *
17
 * @since 3.8
18
 * @param $country (string) ISO code for a country
19
 * @return (boolean) true is country has regions else false
20
 */
21
function wpsc_has_regions( $country ){
22
	return WPSC_Countries::country_has_regions( $country );
23
}
24
25
/**
26
 * wpsc_check_purchase_processed checks the given processed number and checks it against the global wpsc_purchlog_statuses
27
 * @access public
28
 *
29
 * @since 3.8
30
 * @param $processed (int) generally comes from the purchase log table `processed` column
31
 * @return $is_transaction (boolean) true if the process is a completed transaction false otherwise
0 ignored issues
show
Documentation introduced by
The doc-type $is_transaction could not be parsed: Unknown type name "$is_transaction" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
32
 */
33
function wpsc_check_purchase_processed($processed){
34
	global $wpsc_purchlog_statuses;
35
	$is_transaction = false;
36
	foreach($wpsc_purchlog_statuses as $status)
37
		if($status['order'] == $processed && isset($status['is_transaction']) && 1 == $status['is_transaction'] )
38
			$is_transaction = true;
39
40
	return $is_transaction;
41
}
42
43
/**
44
 * get buyers email retrieves the email address associated to the checkout
45
 * @access public
46
 *
47
 * @since 3.8
48
 * @param purchase_id (int) the purchase id
49
 * @return email (strong) email addess
50
 */
51
function wpsc_get_buyers_email($purchase_id){
52
	global $wpdb;
53
	$email_form_field = $wpdb->get_col( "SELECT `id` FROM `" . WPSC_TABLE_CHECKOUT_FORMS . "` WHERE `type` IN ('email') AND `active` = '1' ORDER BY `checkout_order` ASC" );
54
55
	if ( empty( $email_form_field ) )
56
		return '';
57
58
	$email_in = '(' . implode( ',', array_map( 'absint', $email_form_field ) ) . ')';
59
60
	$email = $wpdb->get_var( $wpdb->prepare( "SELECT `value` FROM `" . WPSC_TABLE_SUBMITTED_FORM_DATA . "` WHERE `log_id` = %d AND `form_id` IN {$email_in} LIMIT 1", $purchase_id ) );
61
62
	return $email;
63
}
64
/**
65
 * returns the tax label
66
 * @access public
67
 *
68
 * @since 3.7
69
 * @param $checkout (unused)
70
 * @return string Tax Included or Tax
71
 */
72
function wpsc_display_tax_label( $checkout = false ) {
0 ignored issues
show
Unused Code introduced by
The parameter $checkout is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
73
	global $wpsc_cart;
74
	if ( wpsc_tax_isincluded ( ) ) {
0 ignored issues
show
Coding Style introduced by
Space before opening parenthesis of function call prohibited
Loading history...
75
		return __( 'Tax Included', 'wp-e-commerce' );
76
	} else {
77
		return __( 'Tax', 'wp-e-commerce' );
78
	}
79
}
80
81
 /**
82
 * Cycles through the categories represented by the products in the cart.
83
 * Retrieves their target markets and returns an array of acceptable markets
84
 * We're only listing target markets that are acceptable for ALL categories in the cart
85
 *
86
 * @since 3.8.9
87
 * @return array Countries that can be shipped to.  If empty, sets session variable with appropriate error message
88
 */
89
function wpsc_get_acceptable_countries() {
90
	global $wpdb;
91
92
	$cart_category_ids = array_unique( wpsc_cart_item_categories( true ) );
93
94
	$target_market_ids = array();
95
96
	foreach ( $cart_category_ids as $category_id ) {
97
		$target_markets = wpsc_get_meta( $category_id, 'target_market', 'wpsc_category' );
98
		if ( ! empty( $target_markets ) )
99
			$target_market_ids[$category_id] = $target_markets;
100
	}
101
102
	$have_target_market = ! empty( $target_market_ids );
103
104
	//If we're comparing multiple categories
105
	if ( count( $target_market_ids ) > 1 ) {
106
		$target_market_ids = call_user_func_array( 'array_intersect', $target_market_ids );
107
	} elseif ( $have_target_market ) {
108
		$target_market_ids = array_values( $target_market_ids );
109
		$target_market_ids = $target_market_ids[0];
110
	}
111
112
	$country_data = WPSC_Countries::get_countries_array();
113
114
	$have_target_market = $have_target_market && count( $country_data ) != count( $target_market_ids );
115
	$GLOBALS['wpsc_country_data'] = $country_data; // TODO Is this ever used?
116
117
	$conflict_error = wpsc_get_customer_meta( 'category_shipping_conflict' );
118
	$target_conflict = wpsc_get_customer_meta( 'category_shipping_target_market_conflict' );
119
120
	// Return true if there are no restrictions
121
	if ( ! $have_target_market ) {
122
		// clear out the target market messages
123
		if ( ! empty( $target_conflict ) )
124
			wpsc_delete_customer_meta( 'category_shipping_conflict' );
125
126
		wpsc_update_customer_meta( 'category_shipping_target_market_conflict', false );
127
		wpsc_update_customer_meta( 'category_shipping_conflict', false );
128
		return true;
129
	}
130
131
	// temporarily hijack this session variable to display target market restriction warnings
132
	if ( ! empty( $target_conflict ) || ! wpsc_has_category_and_country_conflict() ) {
133
		wpsc_update_customer_meta( 'category_shipping_target_market_conflict', true );
134
		wpsc_update_customer_meta( 'category_shipping_conflict', __( "Some of your cart items are targeted specifically to certain markets. As a result, you can only select those countries as your shipping destination.", 'wp-e-commerce' ) );
135
	}
136
137
	if ( empty( $target_market_ids ) ) {
138
		wpsc_update_customer_meta( 'category_shipping_target_market_conflict', true );
139
		wpsc_update_customer_meta( 'category_shipping_conflict', __( 'It appears that some products in your cart have conflicting target market restrictions. As a result, there is no common destination country where your cart items can be shipped to. Please contact the site administrator for more information.', 'wp-e-commerce' ) );
140
	}
141
142
	return $target_market_ids;
143
144
}
145
146
/**
147
 * The WPSC Checkout class
148
 */
149
class wpsc_checkout {
0 ignored issues
show
Coding Style introduced by
Class name "wpsc_checkout" is not in camel caps format
Loading history...
150
151
	// The checkout loop variables
152
	var $checkout_items = array( );
0 ignored issues
show
introduced by
Empty array declaration must have no space between the parentheses
Loading history...
153
	var $checkout_item;
154
	var $checkout_item_count = 0;
155
	var $current_checkout_item = -1;
156
	var $in_the_loop = false;
157
	//the ticket additions
158
	var $additional_fields = array();
159
	var $formfield_count = 0;
160
161
	/**
162
	 * wpsc_checkout method, gets the tax rate as a percentage, based on the selected country and region
163
	 * @access public
164
	 */
165
	public function __construct( $checkout_set = 0 ) {
166
		global $wpdb;
167
		$this->checkout_items = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `" . WPSC_TABLE_CHECKOUT_FORMS . "` WHERE `active` = '1'  AND `checkout_set`= %s ORDER BY `checkout_order`;", $checkout_set ) );
168
169
		$GLOBALS['wpsc_checkout_error_messages'    ] = wpsc_get_customer_meta( 'checkout_error_messages'     );
170
		$GLOBALS['wpsc_gateway_error_messages'     ] = wpsc_get_customer_meta( 'gateway_error_messages'      );
171
		$GLOBALS['wpsc_registration_error_messages'] = wpsc_get_customer_meta( 'registration_error_messages' );
172
		$GLOBALS['wpsc_customer_checkout_details'  ] = apply_filters( 'wpsc_get_customer_checkout_details', wpsc_get_customer_meta( 'checkout_details' ) );
173
174
		// legacy filter
175
		if ( is_user_logged_in() )
176
			$GLOBALS['wpsc_customer_checkout_details'] = apply_filters( 'wpsc_checkout_user_profile_get', $GLOBALS['wpsc_customer_checkout_details'], get_current_user_id() );
177
178
		if ( ! is_array( $GLOBALS['wpsc_customer_checkout_details'] ) )
179
			$GLOBALS['wpsc_customer_checkout_details'] = array();
180
181
		$category_list = wpsc_cart_item_categories( true );
182
		$additional_form_list = array( );
0 ignored issues
show
introduced by
Empty array declaration must have no space between the parentheses
Loading history...
183
		foreach ( $category_list as $category_id ) {
184
			$additional_form_list[] = wpsc_get_categorymeta( $category_id, 'use_additional_form_set' );
185
		}
186
		if ( function_exists( 'wpsc_get_ticket_checkout_set' ) ) {
187
			$checkout_form_fields_id = array_search( wpsc_get_ticket_checkout_set(), $additional_form_list );
188
			unset( $additional_form_list[$checkout_form_fields_id] );
189
		}
190
		if ( count( $additional_form_list ) > 0 ) {
191
			$this->category_checkout_items = $wpdb->get_results( "SELECT * FROM `" . WPSC_TABLE_CHECKOUT_FORMS . "` WHERE `active` = '1'  AND `checkout_set` IN ('" . implode( "','", $additional_form_list ) . "') ORDER BY `checkout_set`, `checkout_order`;" );
0 ignored issues
show
Bug introduced by
The property category_checkout_items does not seem to exist. Did you mean checkout_items?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
192
			$this->checkout_items = array_merge( (array)$this->checkout_items, (array)$this->category_checkout_items );
193
		}
194
		if ( function_exists( 'wpsc_get_ticket_checkout_set' ) ) {
195
			$sql = "SELECT * FROM `" . WPSC_TABLE_CHECKOUT_FORMS . "` WHERE `active` = '1'  AND `checkout_set`='" . wpsc_get_ticket_checkout_set() . "' ORDER BY `checkout_order`;";
196
			$this->additional_fields = $wpdb->get_results( $sql );
197
			$count = wpsc_ticket_checkoutfields();
198
			$j = 1;
199
			$fields = $this->additional_fields;
200
			$this->formfield_count = count( $fields ) + $this->checkout_item_count;
201
			while ( $j < $count ) {
202
				$this->additional_fields = array_merge( (array)$this->additional_fields, (array)$fields );
203
				$j++;
204
			}
205
			if ( wpsc_ticket_checkoutfields() > 0 ) {
206
				$this->checkout_items = array_merge( (array)$this->checkout_items, (array)$this->additional_fields );
207
			}
208
		}
209
210
		$this->checkout_items = apply_filters( 'wpsc_checkout_fields', $this->checkout_items, $this );
211
212
		$this->checkout_item_count = count( $this->checkout_items );
213
	}
214
215
	function form_name() {
216
		if ( $this->form_name_is_required() && ($this->checkout_item->type != 'heading') )
217
			return esc_html( apply_filters( 'wpsc_checkout_field_name', $this->checkout_item->name ) ) . ' <span class="asterix">*</span> ';
218
		else
219
			return esc_html( apply_filters( 'wpsc_checkout_field_name', $this->checkout_item->name ) );
220
	}
221
222
	function form_name_is_required() {
223
		return ! $this->checkout_item->mandatory == 0;
224
	}
225
226
	function form_element_active() {
227
		return $this->checkout_item->active != 0;
228
	}
229
230
	/**
231
	 * form_element_id method, returns the form html ID
232
	 * @access public
233
	 */
234
	function form_element_id() {
235
		return 'wpsc_checkout_form_' . $this->checkout_item->id;
236
	}
237
238
	/**
239
	 * form_item_id method, returns the form html ID
240
	 * @access public
241
	 */
242
	function form_item_id() {
243
		return $this->checkout_item->id;
244
	}
245
246
	/**
247
	 * returns the unqiue name for the current checkout item
248
	 *
249
	 * @since 3.8.14
250
	 *
251
	 * @access public
252
	 *
253
	 * @return string	unqiue name associated with the current checkout item
254
	 */
255
	function form_item_unique_name() {
256
		return $this->checkout_item->unique_name;
257
	}
258
259
	/**
260
	 * get_checkout_options, returns the form field options
261
	 * @access public
262
	 */
263
	function get_checkout_options( $id ) {
264
		global $wpdb;
265
		$sql = $wpdb->prepare( 'SELECT `options` FROM `' . WPSC_TABLE_CHECKOUT_FORMS . '` WHERE `id` = %d', $id );
266
		$options = $wpdb->get_var( $sql );
267
		$options = unserialize( $options );
268
		return $options;
269
	}
270
271
	/**
272
	 * form_field method, returns the form html
273
	 * @access public
274
	 */
275
	function form_field() {
276
277
		global $wpdb, $user_ID, $wpsc_customer_checkout_details;
278
279
		$saved_form_data = empty( $wpsc_customer_checkout_details[$this->checkout_item->id] ) ? null : $wpsc_customer_checkout_details[$this->checkout_item->id];
280
		$an_array = '';
281
		if ( function_exists( 'wpsc_get_ticket_checkout_set' ) ) {
282
			if ( $this->checkout_item->checkout_set == wpsc_get_ticket_checkout_set() )
283
				$an_array = '[]';
284
		}
285
286
		$output = '';
287
		$delivery_country = wpsc_get_customer_meta( 'shippingcountry' );
288
		$billing_country  = wpsc_get_customer_meta( 'billingcountry'  );
289
		$delivery_region  = wpsc_get_customer_meta( 'shippingregion'  );
290
		$billing_region   = wpsc_get_customer_meta( 'billingregion'   );
291
292
		$meta_key = ! empty( $this->checkout_item->unique_name ) ? $this->checkout_item->unique_name : sanitize_title( $this->checkout_item->name ) . '_' . $this->checkout_item->id;
293
294
		switch ( $this->checkout_item->type ) {
295
296
			case "address":
297
			case "delivery_address":
298
			case "textarea":
299
				$placeholder = apply_filters( 'wpsc_checkout_field_placeholder', apply_filters( 'wpsc_checkout_field_name', $this->checkout_item->name ), $this->checkout_item );
300
				$output .= '<textarea data-wpsc-meta-key="' . $meta_key . '" title="' . $this->checkout_item->unique_name
301
							. '" class="text wpsc-visitor-meta" id="' . $this->form_element_id()
302
								. '" name="collected_data[' . $this->checkout_item->id . ']' . $an_array . '" placeholder="'
303
										. esc_attr( $placeholder ) . '" rows="3" cols="40" >'
304
												. esc_textarea( (string) $saved_form_data ) . '</textarea>';
305
				break;
306
307
			case "checkbox":
308
				$options = $this->get_checkout_options( $this->checkout_item->id );
309
				if ( $options != '' ) {
310
					$i = mt_rand();
311
					foreach ( $options as $label => $value ) {
312
						?>
313
							<label>
314
								<input class="wpsc-visitor-meta" data-wpsc-meta-key="<?php echo $meta_key; ?>" <?php checked( in_array( $value, (array) $saved_form_data ) ); ?> type="checkbox" name="collected_data[<?php echo esc_attr( $this->checkout_item->id ); ?>]<?php echo $an_array; ?>[]" value="<?php echo esc_attr( $value ); ?>"  />
315
								<?php echo esc_html( $label ); ?>
316
							</label>
317
						<?php
318
					}
319
				}
320
				break;
321
322
			case "country":
323
				$output = wpsc_country_list( $this->checkout_item->id, null, $billing_country, $billing_region, $this->form_element_id() );
324
				break;
325
326
			case "delivery_country":
327
				$checkoutfields = true;
328
				$output = wpsc_country_list( $this->checkout_item->id, null, $delivery_country, $delivery_region, $this->form_element_id(), $checkoutfields );
329
				break;
330
331
			case "select":
332
				$options = $this->get_checkout_options( $this->checkout_item->id );
333
				if ( $options != '' ) {
334
					$output = '<select class="wpsc-visitor-meta" data-wpsc-meta-key="' . $meta_key . '" name="collected_data[' . $this->checkout_item->id . ']"' . $an_array . '">';
335
					$output .= "<option value='-1'>" . _x( 'Select an Option', 'Dropdown default when called within checkout class' , 'wp-e-commerce' ) . "</option>";
336
					foreach ( (array)$options as $label => $value ) {
337
						$value = esc_attr(str_replace( ' ', '', $value ) );
338
						$output .="<option " . selected( $value, $saved_form_data, false ) . " value='" . esc_attr( $value ) . "'>" . esc_html( $label ) . "</option>\n\r";
339
					}
340
					$output .="</select>";
341
				}
342
				break;
343
			case "radio":
344
				$options = $this->get_checkout_options( $this->checkout_item->id );
345
				if ( $options != '' ) {
346
					foreach ( (array)$options as $label => $value ) {
347
						?>
348
							<label>
349
								<input class="wpsc-visitor-meta" data-wpsc-meta-key="<?php echo $meta_key; ?>" type="radio" <?php checked( $value, $saved_form_data ); ?> name="collected_data[<?php echo esc_attr( $this->checkout_item->id ); ?>]<?php echo $an_array; ?>" value="<?php echo esc_attr( $value ); ?>"  />
350
								<?php echo esc_html( $label ); ?>
351
							</label>
352
						<?php
353
					}
354
				}
355
				break;
356
357
			case "text":
358
			case "city":
359
			case "delivery_city":
360
			case "email":
361
			case "coupon":
362
			default:
363
				if ( $this->checkout_item->unique_name == 'shippingstate' ) {
364
					$output .= wpsc_checkout_shipping_state_and_region( $this );
365
				} elseif ( $this->checkout_item->unique_name == 'billingstate' ) {
366
					$output .= wpsc_checkout_billing_state_and_region( $this );
367
				} else {
368
					$placeholder = apply_filters( 'wpsc_checkout_field_placeholder', apply_filters( 'wpsc_checkout_field_name', $this->checkout_item->name ), $this->checkout_item );
369
					$output = '<input data-wpsc-meta-key="' . $meta_key . '" title="' . $meta_key . '" type="text" id="' . $this->form_element_id() . '" class="text wpsc-visitor-meta" placeholder="' . esc_attr( $placeholder ) . '" value="' . esc_attr( $saved_form_data ) . '" name="collected_data[' . $this->checkout_item->id . ']' . $an_array . '" />';
370
				}
371
372
				break;
373
		}
374
		return $output;
375
	}
376
377
	/**
378
	 * validate_forms method, validates the input from the checkout page
379
	 * @access public
380
	 */
381
	function validate_forms() {
382
		global $wpsc_cart, $wpdb, $current_user, $user_ID, $wpsc_gateway_error_messages, $wpsc_checkout_error_messages, $wpsc_customer_checkout_details, $wpsc_registration_error_messages;
383
		$any_bad_inputs = false;
384
		$bad_input_message = '';
385
		$wpsc_gateway_error_messages      = array();
386
		$wpsc_checkout_error_messages     = array();
387
		$wpsc_registration_error_messages = array();
388
		// Credit Card Number Validation for PayPal Pro and maybe others soon
389
		if ( isset( $_POST['card_number'] ) ) {
390
			//should do some php CC validation here~
391
		} else {
392
			$wpsc_gateway_error_messages['card_number'] = '';
393
		}
394
		if ( isset( $_POST['card_number1'] ) && isset( $_POST['card_number2'] ) && isset( $_POST['card_number3'] ) && isset( $_POST['card_number4'] ) ) {
395
			if ( $_POST['card_number1'] != '' && $_POST['card_number2'] != '' && $_POST['card_number3'] != '' && $_POST['card_number4'] != '' && is_numeric( $_POST['card_number1'] ) && is_numeric( $_POST['card_number2'] ) && is_numeric( $_POST['card_number3'] ) && is_numeric( $_POST['card_number4'] ) ) {
396
				$wpsc_gateway_error_messages['card_number'] = '';
397
			} else {
398
399
				$any_bad_inputs = true;
400
				$bad_input = true;
401
				$wpsc_gateway_error_messages['card_number'] = __( 'Please enter a valid credit card number.', 'wp-e-commerce' );
402
				$wpsc_customer_checkout_details['card_number'] = '';
403
			}
404
		}
405
		if ( isset( $_POST['expiry'] ) ) {
406
			if ( !empty($_POST['expiry']['month']) && !empty($_POST['expiry']['month']) && is_numeric( $_POST['expiry']['month'] ) && is_numeric( $_POST['expiry']['year'] ) ) {
407
				$wpsc_gateway_error_messages['expdate'] = '';
408
			} else {
409
				$any_bad_inputs = true;
410
				$bad_input = true;
411
				$wpsc_gateway_error_messages['expdate'] = __( 'Please enter a valid expiry date.', 'wp-e-commerce' );
412
				$wpsc_customer_checkout_details['expdate'] = '';
413
			}
414
		}
415
		if ( isset( $_POST['card_code'] ) ) {
416
			if ( empty($_POST['card_code']) || (!is_numeric( $_POST['card_code'] )) ) {
417
				$any_bad_inputs = true;
418
				$bad_input = true;
419
				$wpsc_gateway_error_messages['card_code'] = __( 'Please enter a valid CVV.', 'wp-e-commerce' );
420
				$wpsc_customer_checkout_details['card_code'] = '';
421
			} else {
422
				$wpsc_gateway_error_messages['card_code'] = '';
423
			}
424
		}
425
		if ( isset( $_POST['cctype'] ) ) {
426
			if ( $_POST['cctype'] == '' ) {
427
				$any_bad_inputs = true;
428
				$bad_input = true;
429
				$wpsc_gateway_error_messages['cctype'] = __( 'Please enter a valid CVV.', 'wp-e-commerce' );
430
				$wpsc_customer_checkout_details['cctype'] = '';
431
			} else {
432
				$wpsc_gateway_error_messages['cctype'] = '';
433
			}
434
		}
435
		if ( isset( $_POST['log'] ) || isset( $_POST['pwd'] ) || isset( $_POST['user_email'] ) ) {
436
			$results = wpsc_add_new_user( $_POST['log'], $_POST['pwd'], $_POST['user_email'] );
437
			if ( is_callable( array( $results, 'get_error_code' ) ) && $results->get_error_code() ) {
0 ignored issues
show
Bug introduced by
The method get_error_code cannot be called on $results (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
438
				foreach ( $results->get_error_codes() as $code ) {
0 ignored issues
show
Bug introduced by
The method get_error_codes cannot be called on $results (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
439
					foreach ( $results->get_error_messages( $code ) as $error ) {
0 ignored issues
show
Bug introduced by
The method get_error_messages cannot be called on $results (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
440
						$wpsc_registration_error_messages[] = $error;
441
					}
442
443
					$any_bad_inputs = true;
444
				}
445
			}
446
			if ( property_exists( $results, 'ID' ) && ( $results->ID > 0 ) ) {
447
				$our_user_id = $results->ID;
448
			} else {
449
				$any_bad_inputs = true;
450
				$our_user_id = '';
451
			}
452
		}
453
		if ( isset( $our_user_id ) && $our_user_id < 1 ) {
454
			$our_user_id = $user_ID;
455
		}
456
		// check we have a user id
457
		if ( isset( $our_user_id ) && $our_user_id > 0 ) {
458
			$user_ID = $our_user_id;
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
459
		}
460
461
		//Basic Form field validation for billing and shipping details
462
		foreach ( $this->checkout_items as $form_data ) {
463
464
			$value = wpsc_get_customer_meta( $form_data->unique_name );
465
466
			$wpsc_customer_checkout_details[$form_data->id] = $value;
467
468
			$bad_input = false;
469
			if ( ( $form_data->mandatory == 1 ) || ( $form_data->type == 'coupon' ) ) {
470
471
				if ( $form_data->unique_name == 'billingstate' && empty( $value ) ) {
472
473
					$value = wpsc_get_customer_meta( 'billingregion' );
474
					if ( empty( $value ) ) {
475
						$any_bad_inputs = true;
476
						$bad_input      = true;
477
						$country = new WPSC_Country( wpsc_get_customer_meta( 'billingcountry' ) );
478
						$name    = $country->get( 'region_label' );
479
					}
480
				} else if ( $form_data->unique_name == 'shippingstate' && empty( $value ) ) {
481
482
					$value = wpsc_get_customer_meta( 'shippingregion' );
483
					if ( empty( $value ) ) {
484
						$any_bad_inputs = true;
485
						$bad_input      = true;
486
						$country = new WPSC_Country( wpsc_get_customer_meta( 'shippingcountry' ) );
487
						$name    = $country->get( 'region_label' );
488
					}
489
				} else {
490
491
					$name = $form_data->name;
492
493
					switch ( $form_data->type ) {
494
						case 'email':
495
496
							if ( ! is_email( $value ) ) {
497
								$any_bad_inputs = true;
498
								$bad_input = true;
499
							}
500
							break;
501
502
						case 'delivery_country':
503
						case 'country':
504
							if ( empty( $value ) ) {
505
								$any_bad_inputs = true;
506
								$bad_input      = true;
507
							}
508
							break;
509
510
						case 'heading':
511
							break;
512
513
						case 'select':
514
							if ( $value == '-1' ) {
515
								$any_bad_inputs = true;
516
								$bad_input = true;
517
							}
518
							break;
519
520
						default:
521
							if ( empty( $value ) ) {
522
								$any_bad_inputs = true;
523
								$bad_input = true;
524
							}
525
526
							break;
527
					}
528
				}
529
530
				if ( $bad_input === true ) {
531
					$wpsc_checkout_error_messages[$form_data->id] = sprintf( __( 'Please enter a valid <span class="wpsc_error_msg_field_name">%s</span>.', 'wp-e-commerce' ), strtolower( esc_attr( $name ) ) );
0 ignored issues
show
Bug introduced by
The variable $name does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
532
					$wpsc_customer_checkout_details[$form_data->id] = '';
533
				}
534
			}
535
		}
536
537
		wpsc_update_customer_meta( 'checkout_error_messages'    , $wpsc_checkout_error_messages     );
538
		wpsc_update_customer_meta( 'gateway_error_messages'     , $wpsc_gateway_error_messages      );
539
		wpsc_update_customer_meta( 'registration_error_messages', $wpsc_registration_error_messages );
540
541
		$filtered_checkout_details = apply_filters( 'wpsc_update_customer_checkout_details', $wpsc_customer_checkout_details );
542
543
		// legacy filter
544
		if ( is_user_logged_in() ) {
545
			$filtered_checkout_details = apply_filters( 'wpsc_checkout_user_profile_update', $wpsc_customer_checkout_details, get_current_user_id() );
546
		}
547
548
		// Check if the shoppers location has changed
549
		_wpsc_has_visitor_location_changed();
550
551
		$states = array( 'is_valid' => ! $any_bad_inputs, 'error_messages' => $bad_input_message );
552
		$states = apply_filters( 'wpsc_checkout_form_validation', $states );
553
		return $states;
554
	}
555
556
	/**
557
	 * validate_forms method, validates the input from the checkout page
558
	 * @access public
559
	 */
560
	function save_forms_to_db( $purchase_id ) {
561
562
		foreach ( $this->checkout_items as $form_data ) {
563
564
			if ( $form_data->type == 'heading' ) {
565
				continue;
566
			}
567
568
			$customer_meta_key    = ! empty( $form_data->unique_name ) ? $form_data->unique_name : sanitize_title( $form_data->name ) . '_' . $form_data->id;
569
			$checkout_item_values = wpsc_get_customer_meta( $customer_meta_key );
570
571
			// Prior to release 3.8.14 the billingstate and shippingstate checkout items were used
572
			// differently depending on if the billingcountry and shippingcountry values contained countries
573
			// that used regions.  When countries with regions were present, the billing state field was
574
			// set to the numeric region id, rather than the string name of the region.  A better long term
575
			// solution may be to have a distinct checkout item to hold the billingregion or shippingregion
576
			// code when available.
577
			if ( $customer_meta_key == 'billingstate' ) {
578
				$current_country = wpsc_get_customer_meta( 'billingcountry' );
579
				if ( ! empty( $current_country) ) {
580
					$wpsc_country = new WPSC_Country( $current_country );
581
					if ( $wpsc_country->has_regions() ) {
582
						$region = wpsc_get_customer_meta( 'billingregion' );
583
						if ( ! empty( $region ) ) {
584
							$wpsc_region = $wpsc_country->get_region( $region );
585
							$checkout_item_values = $wpsc_region->get_name();
0 ignored issues
show
Bug introduced by
The method get_name cannot be called on $wpsc_region (of type string|false).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
586
						}
587
					}
588
				}
589
			} elseif (  $customer_meta_key == 'shippingstate' ) {
590
				$current_country = wpsc_get_customer_meta( 'shippingcountry' );
591
				if ( ! empty( $current_country) ) {
592
					$wpsc_country = new WPSC_Country( $current_country );
593
					if ( $wpsc_country->has_regions() ) {
594
						$region = wpsc_get_customer_meta( 'shippingregion' );
595
						if ( ! empty( $region ) ) {
596
							$wpsc_region = $wpsc_country->get_region( $region );
597
							$checkout_item_values = $wpsc_region->get_name();
0 ignored issues
show
Bug introduced by
The method get_name cannot be called on $wpsc_region (of type string|false).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
598
						}
599
					}
600
				}
601
			}
602
603
			if ( ! is_array( $checkout_item_values ) ) {
604
				$checkout_item_values = array( $checkout_item_values );
605
			}
606
607
			global $wpdb;
608
609
			foreach ( $checkout_item_values as $checkout_item_value ) {
610
				$prepared_query = $wpdb->insert(
611
						WPSC_TABLE_SUBMITTED_FORM_DATA,
612
						array(
613
								'log_id'  => $purchase_id,
614
								'form_id' => $form_data->id,
615
								'value'   => $checkout_item_value,
616
						),
617
						array(
618
								'%d',
619
								'%d',
620
								'%s',
621
						)
622
				);
623
			}
624
		}
625
	}
626
627
	/**
628
	 * Function that checks how many checkout fields are stored in checkout form fields table
629
	 */
630
	function get_count_checkout_fields() {
631
		$checkout = new WPSC_Checkout_Form();
632
		$count    = $checkout->get_field_count();
633
		return $count;
634
	}
635
636
	/**
637
	 * checkout loop methods
638
	 */
639
	function next_checkout_item() {
640
		$this->current_checkout_item++;
641
		$this->checkout_item = $this->checkout_items[$this->current_checkout_item];
642
		return $this->checkout_item;
643
	}
644
645
	function the_checkout_item() {
646
		$this->in_the_loop = true;
647
		$this->checkout_item = $this->next_checkout_item();
648
		if ( $this->current_checkout_item == 0 ) {
649
			// loop has just started
650
			do_action( 'wpsc_checkout_loop_start', $this );
651
		}
652
		return $this->checkout_item;
653
	}
654
655
	function have_checkout_items() {
656
		if ( $this->current_checkout_item + 1 < $this->checkout_item_count ) {
657
			return true;
658
		} else if ( $this->current_checkout_item + 1 == $this->checkout_item_count && $this->checkout_item_count > 0 ) {
659
			do_action( 'wpsc_checkout_loop_end', $this );
660
			// Do some cleaning up after the loop,
661
			$this->rewind_checkout_items();
662
		}
663
664
		$this->in_the_loop = false;
665
		return false;
666
	}
667
668
	function rewind_checkout_items() {
669
		global $wpsc_checkout_error_messages;
670
		$wpsc_checkout_error_messages = array();
671
		wpsc_delete_customer_meta( 'checkout_error_messages' );
672
		$this->current_checkout_item = -1;
673
		if ( $this->checkout_item_count > 0 ) {
674
			$this->checkout_item = $this->checkout_items[0];
675
		}
676
	}
677
678
	/**
679
	 * find the checkout item that corresponsds to the identifier
680
	 *
681
	 * @param int|string $id  the checkout item identifier, if a numeric the checkout item id, if a string the checkout item unique name
682
	 *
683
	 * @return cehckout item found, or false if not found
684
	 */
685
	function get_checkout_item( $id ) {
686
		$result = false;
687
		if ( is_numeric( $id ) ) {
688
			$result = $this->checkout_items[$id];
689
		} else {
690
			foreach ( $this->checkout_items as $checkout_item_id => $checkout_item ) {
691
				if ( ! empty( $checkout_item->unique_name ) && $checkout_item->unique_name == $id ) {
692
					$result = $checkout_item;
693
					break;
694
				}
695
			}
696
		}
697
698
		return $result;
699
	}
700
701
702
703
704
}
705