Completed
Pull Request — master (#2165)
by Justin
05:25
created

WPSC_Checkout_Form_Data   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 358
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 0
loc 358
rs 8.6
c 0
b 0
f 0
wmc 37
lcom 1
cbo 3

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B fetch() 0 52 6
A get_indexed_raw_data() 0 10 2
B shipping_matches_billing() 0 25 4
A get_billing_data() 0 5 1
A get_shipping_data() 0 5 1
A get_raw_data() 0 5 1
A prepare_get() 0 3 1
A prepare_get_data() 0 3 1
D get_gateway_data() 0 44 9
A set() 0 11 2
A save() 0 12 1
B save_form() 0 46 6
A get_log_id() 0 3 1
1
<?php
2
/**
3
 * The WP eCommerce Checkout form data Class
4
 *
5
 * @package wp-e-commerce
6
 * @since 3.8
7
 */
8
9
class WPSC_Checkout_Form_Data extends WPSC_Query_Base {
10
	protected $raw_data       = array();
11
	protected $segmented_data = array();
12
	protected $gateway_data   = array();
13
	protected $submitted_data = array();
14
	protected $log_id = 0;
15
16
	/**
17
	 * An array of arrays of cache keys. Allows versioning the cached values,
18
	 * and busting cache for a group if needed (by incrementing the version).
19
	 *
20
	 * @var array
21
	 */
22
	protected $group_ids = array(
23
		'raw_data' => array(
24
			'group'     => 'wpsc_checkout_form_raw_data',
25
			'version' => 1,
26
		),
27
		'gateway_data' => array(
28
			'group'     => 'wpsc_checkout_form_gateway_data',
29
			'version' => 0,
30
		),
31
	);
32
33
	public function __construct( $log_id ) {
34
		$this->log_id = absint( $log_id );
35
		$this->fetch();
36
	}
37
38
	/**
39
	 * Fetches the actual $data array.
40
	 *
41
	 * @access protected
42
	 * @since 4.0
43
	 *
44
	 * @return WPSC_Query_Base
45
	 */
46
	protected function fetch() {
47
		if ( $this->fetched ) {
48
			return;
49
		}
50
51
		global $wpdb;
52
53
		if ( ! $this->raw_data = $this->cache_get( $this->log_id, 'raw_data' ) ) {
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->cache_get($this->log_id, 'raw_data') of type * is incompatible with the declared type array of property $raw_data.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
54
			$sql = "
55
				SELECT c.id, c.name, c.type, c.mandatory, c.unique_name, c.checkout_set as form_group, s.id as data_id, s.value
56
				FROM " . WPSC_TABLE_SUBMITTED_FORM_DATA . " AS s
57
				INNER JOIN " . WPSC_TABLE_CHECKOUT_FORMS . " AS c
58
					ON c.id = s.form_id
59
				WHERE s.log_id = %d AND active = '1'
60
			";
61
62
			$sql = $wpdb->prepare( $sql, $this->log_id );
63
			$this->raw_data = $wpdb->get_results( $sql );
64
65
			// Set the cache for raw checkout for data
66
			$this->cache_set( $this->log_id, $this->raw_data, 'raw_data' );
67
		}
68
69
		$this->exists = ! empty( $this->raw_data );
70
		$this->segmented_data = array(
71
			'shipping' => array(),
72
			'billing'  => array(),
73
		);
74
75
		// At the moment, only core fields have unique_name. In the future,
76
		// all fields will have a unique name rather than just IDs.
77
		foreach ( $this->raw_data as $index => $field ) {
78
			if ( ! empty( $field->unique_name ) ) {
79
80
				$is_shipping = false !== strpos( $field->unique_name, 'shipping' );
81
82
				if ( $is_shipping ) {
83
					$this->segmented_data['shipping'][ str_replace( 'shipping', '', $field->unique_name ) ] = $index;
84
				} else {
85
					$this->segmented_data['billing'][ str_replace( 'billing', '', $field->unique_name ) ] = $index;
86
				}
87
88
				$this->data[ $field->unique_name ] = $field->value;
89
			}
90
		}
91
92
		do_action( 'wpsc_checkout_form_data_fetched', $this );
93
94
		$this->fetched = true;
95
96
		return $this;
97
	}
98
99
	/**
100
	 * Get the raw data indexed by the 'id' column.
101
	 *
102
	 * @since  4.0
103
	 *
104
	 * @return array
105
	 */
106
	public function get_indexed_raw_data() {
107
		$this->fetch();
108
109
		$data = array();
110
		foreach ( $this->raw_data as $field ) {
111
			$data[ $field->id ] = $field;
112
		}
113
114
		return $data;
115
	}
116
117
	/**
118
	 * Determines if values in shipping fields matches values in billing fields.
119
	 *
120
	 * @since  4.0
121
	 *
122
	 * @return bool  Whether shipping values match billing values.
123
	 */
124
	public function shipping_matches_billing() {
125
		$this->fetch();
126
127
		foreach ( $this->segmented_data['shipping'] as $id => $index ) {
128
			// If we're missing data from any of these arrays, something's wrong (and they don't match).
129
			if ( ! isset(
130
				$this->raw_data[ $index ],
131
				$this->segmented_data['billing'][ $id ],
132
				$this->raw_data[ $this->segmented_data['billing'][ $id ] ]
133
			) ) {
134
				return false;
135
			}
136
137
			// Now we can get the values for the fields.
138
			$ship_val    = $this->raw_data[ $index ]->value;
139
			$billing_val = $this->raw_data[ $this->segmented_data['billing'][ $id ] ]->value;
140
141
			// Do they match?
142
			if ( $ship_val !== $billing_val ) {
143
				return false;
144
			}
145
		}
146
147
		return true;
148
	}
149
150
	/**
151
	 * Get the segmented billing info.
152
	 *
153
	 * @since  4.0
154
	 *
155
	 * @return array
156
	 */
157
	public function get_billing_data() {
158
		$this->fetch();
159
160
		return $this->segmented_data['billing'];
161
	}
162
163
	/**
164
	 * Get the segmented shipping info.
165
	 *
166
	 * @since  4.0
167
	 *
168
	 * @return array
169
	 */
170
	public function get_shipping_data() {
171
		$this->fetch();
172
173
		return $this->segmented_data['shipping'];
174
	}
175
176
	/**
177
	 * Gets the raw data array.
178
	 *
179
	 * @since  4.0
180
	 *
181
	 * @return array
182
	 */
183
	public function get_raw_data() {
184
		$this->fetch();
185
186
		return $this->raw_data;
187
	}
188
189
	/**
190
	 * Prepares the return value for get() (apply_filters, etc).
191
	 *
192
	 * @access protected
193
	 * @since  4.0
194
	 *
195
	 * @param  mixed  $value Value fetched
196
	 * @param  string $key   Key for $data.
197
	 *
198
	 * @return mixed
199
	 */
200
	protected function prepare_get( $value, $key ) {
201
		return apply_filters( 'wpsc_checkout_form_data_get_property', $value, $key, $this );
202
	}
203
204
	/**
205
	 * Prepares the return value for get_data() (apply_filters, etc).
206
	 *
207
	 * @access protected
208
	 * @since  4.0
209
	 *
210
	 * @return mixed
211
	 */
212
	protected function prepare_get_data() {
213
		return apply_filters( 'wpsc_checkout_form_get_data', $this->data, $this->log_id, $this );
214
	}
215
216
	public function get_gateway_data() {
217
		if ( ! $this->gateway_data = $this->cache_get( $this->log_id, 'gateway_data' ) ) {
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->cache_get($this->log_id, 'gateway_data') of type * is incompatible with the declared type array of property $gateway_data.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
218
			$map = array(
219
				'firstname' => 'first_name',
220
				'lastname'  => 'last_name',
221
				'address'   => 'street',
222
				'city'      => 'city',
223
				'state'     => 'state',
224
				'country'   => 'country',
225
				'postcode'  => 'zip',
226
				'phone'     => 'phone',
227
			);
228
229
			foreach ( array( 'shipping', 'billing' ) as $type ) {
230
231
				$data_key = "{$type}_address";
232
				$this->gateway_data[ $data_key ] = array();
233
234
				foreach ( $map as $key => $new_key ) {
235
					$key = $type . $key;
236
237
					if ( isset( $this->data[ $key ] ) ) {
238
						$value = $this->data [$key ];
239
240
						if ( $new_key == 'state' && is_numeric( $value ) ) {
241
							$value = wpsc_get_state_by_id( $value, 'code' );
242
						}
243
244
						$this->gateway_data[ $data_key ][ $new_key ] = $value;
245
					}
246
				}
247
248
				$name  = isset( $this->gateway_data[ $data_key ]['first_name'] ) ? $this->gateway_data[ $data_key ]['first_name'] . ' ' : '';
249
				$name .= isset( $this->gateway_data[ $data_key ]['last_name']  ) ? $this->gateway_data[ $data_key ]['last_name']        : '';
250
251
				$this->gateway_data[ $data_key ]['name'] = trim( $name );
252
			}
253
254
			// Sets the cache for checkout form gateway data
255
			$this->cache_set( $this->log_id, $this->gateway_data, 'gateway_data' );
256
		}
257
258
		return apply_filters( 'wpsc_checkout_form_gateway_data', $this->gateway_data, $this->log_id );
259
	}
260
261
	/**
262
	 * Set specific database fields.
263
	 *
264
	 * @param string|int $key   Expects either form ID or unique name.
265
	 * @param string     $value Value to be set for field.
266
	 *
267
	 * @since  4.0
268
	 * @return WPSC_Checkout_Form_Data Current instance of form data.
269
	 */
270
	public function set( $key, $value = '' ) {
271
272
		if ( ! is_numeric( $key ) ) {
273
			$checkout_form = WPSC_Checkout_Form::get();
274
			$key = $checkout_form->get_field_id_by_unique_name( $key );
275
		}
276
277
		$this->submitted_data[ $key ] = $value;
278
279
		return $this;
280
	}
281
282
	/**
283
	 * Used in conjunction with set() method, saves individual checkout form fields to database.
284
	 *
285
	 * @since  4.0
286
	 * @return void
287
	 */
288
	public function save() {
289
290
		$log    = new WPSC_Purchase_Log( $this->log_id );
291
		$form   = WPSC_Checkout_Form::get();
292
		$fields = $form->get_fields();
293
294
		$original_data = wp_list_pluck( $this->get_raw_data(), 'value', 'id' );
295
296
		$this->submitted_data = array_replace( $original_data, $this->submitted_data );
297
298
		return self::save_form( $log, $fields, $this->submitted_data );
299
	}
300
301
	/**
302
	 * Save Submitted Form Fields to the wpsc_submited_form_data table.
303
	 *
304
	 * @param WPSC_Purchase_Log $purchase_log
305
	 * @param array $fields
306
	 * @return void
307
	 */
308
	public static function save_form( $purchase_log, $fields, $data = array() ) {
309
		global $wpdb;
310
311
		$log_id = $purchase_log->get( 'id' );
312
313
		// delete previous field values
314
		$sql = $wpdb->prepare( "DELETE FROM " . WPSC_TABLE_SUBMITTED_FORM_DATA . " WHERE log_id = %d", $log_id );
315
		$wpdb->query( $sql );
316
317
		if ( empty( $data ) && isset( $_POST['wpsc_checkout_details'] ) ) {
318
			$data = $_POST['wpsc_checkout_details'];
319
		}
320
321
		$customer_details = array();
322
323
		foreach ( $fields as $field ) {
324
325
			if ( $field->type == 'heading' ) {
326
				continue;
327
			}
328
329
			$value = '';
330
331
			if ( isset( $data[ $field->id ] ) ) {
332
				$value = wp_unslash( $data[ $field->id ] );
333
			}
334
335
			$customer_details[ $field->id ] = $value;
336
337
			$wpdb->insert(
338
				WPSC_TABLE_SUBMITTED_FORM_DATA,
339
				array(
340
					'log_id'  => $log_id,
341
					'form_id' => $field->id,
342
					'value'   => $value,
343
				),
344
				array(
345
					'%d',
346
					'%d',
347
					'%s',
348
				)
349
			);
350
		}
351
352
		wpsc_save_customer_details( $customer_details );
353
	}
354
355
	/**
356
	 * Returns the log id property.
357
	 *
358
	 * @since  4.0
359
	 *
360
	 * @return int  The log id.
361
	 */
362
	public function get_log_id() {
363
		return $this->log_id;
364
	}
365
366
}
367