Completed
Push — master ( fc386f...14b40e )
by Mike
08:03
created

WC_Customer::set_billing_city()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
include_once( 'legacy/class-wc-legacy-customer.php' );
3
4
if ( ! defined( 'ABSPATH' ) ) {
5
	exit;
6
}
7
8
/**
9
 * The WooCommerce customer class handles storage of the current customer's data, such as location.
10
 *
11
 * @class    WC_Customer
12
 * @version  2.7.0
13
 * @package  WooCommerce/Classes
14
 * @category Class
15
 * @author   WooThemes
16
 */
17
class WC_Customer extends WC_Legacy_Customer {
18
19
	/**
20
	 * Stores customer data.
21
	 * @var array
22
	 */
23
	protected $_data = array(
24
		'id'				  => 0,
25
		'email'               => '',
26
		'first_name'          => '',
27
		'last_name'           => '',
28
		'role'				  => 'customer',
29
		'last_order_id'       => null, // read only
30
		'last_order_date'     => null, // read only
31
		'orders_count'        => 0, // read only
32
		'total_spent'         => 0, // read only
33
		'username'            => '', // read only on existing users
34
		'password'            => '', // write only
35
		'date_created'        => '', // read only
36
		'date_modified'		  => '', // read only
37
		'billing_first_name'  => '',
38
		'billing_last_name'   => '',
39
		'billing_company'     => '',
40
		'billing_phone'       => '',
41
		'billing_email'       => '',
42
		'billing_address_1'   => '',
43
		'billing_address_2'   => '',
44
		'billing_state'       => '',
45
		'billing_postcode'    => '',
46
		'billing_city'        => '',
47
		'billing_country'     => '',
48
		'shipping_first_name'  => '',
49
		'shipping_last_name'   => '',
50
		'shipping_company'     => '',
51
		'shipping_postcode'   => '',
52
		'shipping_city'       => '',
53
		'shipping_address_1'  => '',
54
		'shipping_address_2'  => '',
55
		'shipping_state'      => '',
56
		'shipping_country'    => '',
57
		'is_paying_customer'  => false,
58
		'is_vat_exempt'       => false, // session only.
59
		'calculated_shipping' => false, // session only
60
	);
61
62
	/**
63
	 * Keys which are also stored in a session (so we can make sure they get updated...)
64
	 * @var array
65
	 */
66
	protected $_session_keys = array(
67
		'billing_postcode', 'billing_city', 'billing_address_1', 'billing_address', 'billing_address_2',
68
		'billing_state', 'billing_country', 'shipping_postcode', 'shipping_city', 'shipping_address_1', 'shipping_address',
69
		'shipping_address_2', 'shipping_state', 'shipping_country', 'is_vat_exempt', 'calculated_shipping',
70
		'billing_first_name', 'billing_last_name', 'billing_company', 'billing_phone', 'billing_email',
71
		'shipping_first_name', 'shipping_last_name', 'shipping_company',
72
	);
73
74
	/**
75
	 * Data stored in meta keys, but not considered "meta"
76
	 * @since 2.7.0
77
	 * @var array
78
	 */
79
	protected $_internal_meta_keys = array(
80
		'billing_postcode', 'billing_city', 'billing_address_1', 'billing_address_2', 'billing_state',
81
		'billing_country', 'shipping_postcode', 'shipping_city', 'shipping_address_1',
82
		'shipping_address_2', 'shipping_state', 'shipping_country', 'paying_customer',
83
		'last_update', 'first_name', 'last_name', 'show_admin_bar_front',
84
		'use_ssl', 'admin_color', 'rich_editing', 'comment_shortcuts', 'dismissed_wp_pointers', 'show_welcome_panel',
85
		'_woocommerce_persistent_cart', 'session_tokens',
86
		'billing_first_name', 'billing_last_name', 'billing_company', 'billing_phone', 'billing_email',
87
		'shipping_first_name', 'shipping_last_name', 'shipping_company',
88
	);
89
90
	/**
91
	 *  Internal meta type used to store user data.
92
	 * @var string
93
	 */
94
	protected $_meta_type = 'user';
95
96
	/**
97
	 * Was data changed in the database for this class?
98
	 * @var boolean
99
	 */
100
	protected $_changed = false;
101
102
	/**
103
	 * If this is the customer session, this is true. When true, guest accounts will not be saved to the DB.
104
	 * @var boolean
105
	 */
106
	protected $_is_session = false;
107
108
	/**
109
	 * Load customer data based on how WC_Customer is called.
110
	 *
111
	 * If $customer is 'new', you can build a new WC_Customer object. If it's empty, some
112
	 * data will be pulled from the session for the current user/customer.
113
	 *
114
	 * @param int $customer_id Customer ID
115
	 * @param bool $is_session True if this is the customer session
116
	 */
117
	public function __construct( $customer_id = 0, $is_session = false ) {
118
		if ( $customer_id > 0 ) {
119
			$this->read( $customer_id );
120
		}
121
		if ( $is_session ) {
122
			$this->_is_session = true;
123
			$this->load_session();
124
			add_action( 'shutdown', array( $this, 'save_session_if_changed' ), 10 );
125
		}
126
	}
127
128
	/**
129
	 * Saves customer information to the current session if any data changed.
130
	 * @since 2.7.0
131
	 */
132
	public function save_session_if_changed() {
133
		if ( $this->_is_session && $this->_changed ) {
134
			$this->save_to_session();
135
		}
136
	}
137
138
	/**
139
	 * Loads a WC session into the customer class.
140
	 */
141
	public function load_session() {
142
		$data = (array) WC()->session->get( 'customer' );
143
		if ( ! empty( $data ) ) {
144
			foreach ( $this->_session_keys as $session_key ) {
145
				$function_key = $session_key;
146
				if ( 'billing_' === substr( $session_key, 0, 8 ) ) {
147
					$session_key = str_replace( 'billing_', '', $session_key );
148
				}
149
				if ( ! empty( $data[ $session_key ] ) && is_callable( array( $this, "set_{$function_key}" ) ) ) {
150
					$this->{"set_{$function_key}"}( $data[ $session_key ] );
151
				}
152
			}
153
		}
154
		$this->load_defaults();
155
	}
156
157
	/**
158
	 * Load default values if props are unset.
159
	 */
160
	protected function load_defaults() {
161
		$default = wc_get_customer_default_location();
162
163
		// Set some defaults if some of our values are still not set.
164
		if ( empty( $this->get_billing_country() ) ) {
165
			$this->set_billing_country( $default['country'] );
166
		}
167
168
		if ( empty( $this->get_shipping_country() ) ) {
169
			$this->set_shipping_country( $this->get_billing_country() );
170
		}
171
172
		if ( empty( $this->get_billing_state() ) ) {
173
			$this->set_billing_state( $default['state'] );
174
		}
175
176
		if ( empty( $this->get_shipping_state() ) ) {
177
			$this->set_shipping_state( $this->get_billing_state() );
178
		}
179
	}
180
181
	/*
182
	 |--------------------------------------------------------------------------
183
	 | Getters
184
	 |--------------------------------------------------------------------------
185
	 | Methods for getting data from the customer object.
186
	 */
187
188
	/**
189
	 * Return a customer's user ID. Logged out users have ID 0.
190
	 * @since 2.7.0
191
	 * @return int
192
	 */
193
	public function get_id() {
194
		return $this->_data['id'];
195
	}
196
197
	/**
198
	 * Return the customer's username.
199
	 * @since 2.7.0
200
	 * @return string
201
	 */
202
	public function get_username() {
203
		return $this->_data['username'];
204
	}
205
206
	/**
207
	 * Return the customer's email.
208
	 * @since 2.7.0
209
	 * @return string
210
	 */
211
	public function get_email() {
212
		return $this->_data['email'];
213
	}
214
215
	/**
216
	 * Return customer's first name.
217
	 * @since 2.7.0
218
	 * @return string
219
	 */
220
	public function get_first_name() {
221
		return $this->_data['first_name'];
222
	}
223
224
	/**
225
	 * Return customer's last name.
226
	 * @since 2.7.0
227
	 * @return string
228
	 */
229
	public function get_last_name() {
230
		return $this->_data['last_name'];
231
	}
232
233
	/**
234
	 * Return customer's user role.
235
	 * @since 2.7.0
236
	 * @return string
237
	 */
238
	public function get_role() {
239
		return $this->_data['role'];
240
	}
241
242
	/**
243
	 * Return customer's last order ID.
244
	 * @since 2.7.0
245
	 * @return integer|null
246
	 */
247
	public function get_last_order_id() {
248
		return ( is_null( $this->_data['last_order_id'] ) ? null : intval( $this->_data['last_order_id'] ) );
249
	}
250
251
	/**
252
	 * Return the date of the customer's last order.
253
	 * @since 2.7.0
254
	 * @return integer|null
255
	 */
256
	public function get_last_order_date() {
257
		return ( is_null( $this->_data['last_order_date'] ) ? null : intval( $this->_data['last_order_date'] ) );
258
	}
259
260
	/**
261
	 * Return the number of orders this customer has.
262
	 * @since 2.7.0
263
	 * @return integer
264
	 */
265
	public function get_orders_count() {
266
		return intval( $this->_data['orders_count'] );
267
	}
268
269
	/**
270
	 * Return how much money this customer has spent.
271
	 * @since 2.7.0
272
	 * @return float
273
	 */
274
	public function get_total_spent() {
275
		return wc_format_decimal( $this->_data['total_spent'] );
276
	}
277
278
	/**
279
	 * Return this customer's avatar.
280
	 * @since 2.7.0
281
	 * @return string
282
	 */
283 View Code Duplication
	public function get_avatar_url() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
284
		$avatar_html = get_avatar( $this->get_email() );
285
286
		// Get the URL of the avatar from the provided HTML
287
		preg_match( '/src=["|\'](.+)[\&|"|\']/U', $avatar_html, $matches );
288
289
		if ( isset( $matches[1] ) && ! empty( $matches[1] ) ) {
290
			return esc_url( $matches[1] );
291
		}
292
293
		return '';
294
	}
295
296
	/**
297
	 * Return the date this customer was created.
298
	 * @since 2.7.0
299
	 * @return integer
300
	 */
301
	public function get_date_created() {
302
		return absint( $this->_data['date_created'] );
303
	}
304
305
	/**
306
	 * Return the date this customer was last updated.
307
	 * @since 2.7.0
308
	 * @return integer
309
	 */
310
	public function get_date_modified() {
311
		return absint( $this->_data['date_modified'] );
312
	}
313
314
	/**
315
	 * Gets billing first name.
316
	 * @return string
317
	 */
318
	public function get_billing_first_name() {
319
		return $this->_data['billing_first_name'];
320
	}
321
322
	/**
323
	 * Gets billing last name.
324
	 * @return string
325
	 */
326
	public function get_billing_last_name() {
327
		return $this->_data['billing_last_name'];
328
	}
329
330
	/**
331
	 * Gets billing company.
332
	 * @return string
333
	 */
334
	public function get_billing_company() {
335
		return $this->_data['billing_company'];
336
	}
337
338
	/**
339
	 * Gets billing phone.
340
	 * @return string
341
	 */
342
	public function get_billing_phone() {
343
		return $this->_data['billing_phone'];
344
	}
345
346
	/**
347
	 * Gets billing email.
348
	 * @return string
349
	 */
350
	public function get_billing_email() {
351
		return $this->_data['billing_email'];
352
	}
353
354
	/**
355
	 * Gets customer postcode.
356
	 * @return string
357
	 */
358
	public function get_billing_postcode() {
359
		return wc_format_postcode( $this->_data['billing_postcode'], $this->get_billing_country() );
360
	}
361
362
	/**
363
	 * Get customer city.
364
	 * @return string
365
	 */
366
	public function get_billing_city() {
367
		return $this->_data['billing_city'];
368
	}
369
370
	/**
371
	 * Get customer address.
372
	 * @return string
373
	 */
374
	public function get_billing_address() {
375
		return $this->_data['billing_address_1'];
376
	}
377
378
	/**
379
	 * Get customer address.
380
	 * @return string
381
	 */
382
	public function get_billing_address_1() {
383
		return $this->get_billing_address();
384
	}
385
386
	/**
387
	 * Get customer's second address.
388
	 * @return string
389
	 */
390
	public function get_billing_address_2() {
391
		return $this->_data['billing_address_2'];
392
	}
393
394
	/**
395
	 * Get customer state.
396
	 * @return string
397
	 */
398
	public function get_billing_state() {
399
		return $this->_data['billing_state'];
400
	}
401
402
	/**
403
	 * Get customer country.
404
	 * @return string
405
	 */
406
	public function get_billing_country() {
407
		return $this->_data['billing_country'];
408
	}
409
410
	/**
411
	 * Gets shipping first name.
412
	 * @return string
413
	 */
414
	public function get_shipping_first_name() {
415
		return $this->_data['shipping_first_name'];
416
	}
417
418
	/**
419
	 * Gets shipping last name.
420
	 * @return string
421
	 */
422
	public function get_shipping_last_name() {
423
		return $this->_data['shipping_last_name'];
424
	}
425
426
	/**
427
	 * Gets shipping company.
428
	 * @return string
429
	 */
430
	public function get_shipping_company() {
431
		return $this->_data['shipping_company'];
432
	}
433
434
	/**
435
	 * Get customer's shipping state.
436
	 * @return string
437
	 */
438
	public function get_shipping_state() {
439
		return $this->_data['shipping_state'];
440
	}
441
442
	/**
443
	 * Get customer's shipping country.
444
	 * @return string
445
	 */
446
	public function get_shipping_country() {
447
		return $this->_data['shipping_country'];
448
	}
449
450
	/**
451
	 * Get customer's shipping postcode.
452
	 * @return string
453
	 */
454
	public function get_shipping_postcode() {
455
		return wc_format_postcode( $this->_data['shipping_postcode'], $this->get_shipping_country() );
456
	}
457
458
	/**
459
	 * Get customer's shipping city.
460
	 * @return string
461
	 */
462
	public function get_shipping_city() {
463
		return $this->_data['shipping_city'];
464
	}
465
466
	/**
467
	 * Get customer's shipping address.
468
	 * @return string
469
	 */
470
	public function get_shipping_address() {
471
		return $this->_data['shipping_address_1'];
472
	}
473
474
	/**
475
	 * Get customer address.
476
	 * @return string
477
	 */
478
	public function get_shipping_address_1() {
479
		return $this->get_shipping_address();
480
	}
481
482
	/**
483
	 * Get customer's second shipping address.
484
	 * @return string
485
	 */
486
	public function get_shipping_address_2() {
487
		return $this->_data['shipping_address_2'];
488
	}
489
490
	/**
491
	 * Get if customer is VAT exempt?
492
	 * @since 2.7.0
493
	 * @return bool
494
	 */
495
	public function get_is_vat_exempt() {
496
		return ( ! empty( $this->_data['is_vat_exempt'] ) ) ? true : false;
497
	}
498
499
	/**
500
	 * Has customer calculated shipping?
501
	 * @return bool
502
	 */
503
	public function get_calculated_shipping() {
504
		return ! empty( $this->_data['calculated_shipping'] );
505
	}
506
507
	/**
508
	 * Get taxable address.
509
	 * @return array
510
	 */
511
	public function get_taxable_address() {
512
		$tax_based_on = get_option( 'woocommerce_tax_based_on' );
513
514
		// Check shipping method at this point to see if we need special handling
515
		if ( true === apply_filters( 'woocommerce_apply_base_tax_for_local_pickup', true ) && sizeof( array_intersect( wc_get_chosen_shipping_method_ids(), apply_filters( 'woocommerce_local_pickup_methods', array( 'legacy_local_pickup', 'local_pickup' ) ) ) ) > 0 ) {
516
			$tax_based_on = 'base';
517
		}
518
519
		if ( 'base' === $tax_based_on ) {
520
			$country  = WC()->countries->get_base_country();
521
			$state    = WC()->countries->get_base_state();
522
			$postcode = WC()->countries->get_base_postcode();
523
			$city     = WC()->countries->get_base_city();
524
		} elseif ( 'billing' === $tax_based_on ) {
525
			$country  = $this->get_billing_country();
526
			$state    = $this->get_billing_state();
527
			$postcode = $this->get_billing_postcode();
528
			$city     = $this->get_billing_city();
529
		} else {
530
			$country  = $this->get_shipping_country();
531
			$state    = $this->get_shipping_state();
532
			$postcode = $this->get_shipping_postcode();
533
			$city     = $this->get_shipping_city();
534
		}
535
536
		return apply_filters( 'woocommerce_customer_taxable_address', array( $country, $state, $postcode, $city ) );
537
	}
538
539
	/**
540
	 * Gets a customer's downloadable products.
541
	 * @return array Array of downloadable products
542
	 */
543
	public function get_downloadable_products() {
544
		$downloads = array();
545
		if ( $this->get_id() ) {
546
			$downloads = wc_get_customer_available_downloads( $this->get_id() );
547
		}
548
		return apply_filters( 'woocommerce_customer_get_downloadable_products', $downloads );
549
	}
550
551
	/**
552
	 * Is the user a paying customer?
553
	 * @since 2.7.0
554
	 * @return bool
555
	 */
556
	function get_is_paying_customer() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
557
		return (bool) $this->_data['is_paying_customer'];
558
	}
559
560
	/*
561
	|--------------------------------------------------------------------------
562
	| Setters
563
	|--------------------------------------------------------------------------
564
	| Functions for setting customer data. These should not update anything in the
565
	| database itself and should only change what is stored in the class
566
	| object.
567
	*/
568
569
	/**
570
	 * Set customer's username.
571
	 * @since 2.7.0
572
	 * @param string $username
573
	 */
574
	public function set_username( $username ) {
575
		$this->_data['username'] = $username;
576
	}
577
578
	/**
579
	 * Set customer's email.
580
	 * @since 2.7.0
581
	 * @param string $email
582
	 */
583
	public function set_email( $email ) {
584
		$this->_data['email'] = sanitize_email( $email );
585
	}
586
587
	/**
588
	 * Set customer's first name.
589
	 * @since 2.7.0
590
	 * @param string $first_name
591
	 */
592
	public function set_first_name( $first_name ) {
593
		$this->_data['first_name'] = $first_name;
594
	}
595
596
	/**
597
	 * Set customer's last name.
598
	 * @since 2.7.0
599
	 * @param string $last_name
600
	 */
601
	public function set_last_name( $last_name ) {
602
		$this->_data['last_name'] = $last_name;
603
	}
604
605
	/**
606
	 * Set customer's user role(s).
607
	 * @since 2.7.0
608
	 * @param mixed $role
609
	 */
610
	public function set_role( $role ) {
611
		$this->_data['role'] = $role;
612
	}
613
614
	/**
615
	 * Set customer's last order ID.
616
	 * @since 2.7.0
617
	 * @param integer|null $last_order_id
618
	 */
619
	public function set_last_order_id( $last_order_id ) {
620
		$this->_data['last_order_id'] = $last_order_id;
621
	}
622
623
	/**
624
	 * Set the date of the customer's last order.
625
	 * @since 2.7.0
626
	 * @param string|null $last_order_date
627
	 */
628
	public function set_last_order_date( $last_order_date ) {
629
		$this->_data['last_order_date'] = $last_order_date;
630
 	}
631
632
	/**
633
	 * Set the number of orders this customer has.
634
	 * @since 2.7.0
635
	 * @param integer $order_count
0 ignored issues
show
Documentation introduced by
There is no parameter named $order_count. Did you maybe mean $orders_count?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
636
	 */
637
	public function set_orders_count( $orders_count ) {
638
		$this->_data['orders_count'] = $orders_count;
639
	}
640
641
	/**
642
	 * Return how much money this customer has spent.
643
	 * @since 2.7.0
644
	 * @param float $total_spent
645
	 */
646
	public function set_total_spent( $total_spent ) {
647
		$this->_data['total_spent'] = $total_spent;
648
	}
649
650
	/**
651
	 * Set customer's password.
652
	 * @since 2.7.0
653
	 * @param string $password
654
	 */
655
	public function set_password( $password ) {
656
		$this->_data['password'] = wc_clean( $password );
657
	}
658
659
	/**
660
	 * Set the date this customer was last updated.
661
	 * @since 2.7.0
662
	 * @param integer $timestamp
663
	 */
664
	public function set_date_modified( $timestamp ) {
665
		$this->_data['date_modified'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp );
666
	}
667
668
	/**
669
	 * Set the date this customer was last updated.
670
	 * @since 2.7.0
671
	 * @param integer $timestamp
672
	 */
673
	public function set_date_created( $timestamp ) {
674
		$this->_data['date_created'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp );
675
	}
676
677
	/**
678
	 * Set customer address to match shop base address.
679
	 * @since 2.7.0
680
	 */
681 View Code Duplication
	public function set_billing_address_to_base() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
682
		$base = wc_get_customer_default_location();
683
		$this->_data['billing_country']  = $base['country'];
684
		$this->_data['billing_state']    = $base['state'];
685
		$this->_data['billing_postcode'] = '';
686
		$this->_data['billing_city']     = '';
687
	}
688
689
	/**
690
	 * Set customer shipping address to base address.
691
	 * @since 2.7.0
692
	 */
693 View Code Duplication
	public function set_shipping_address_to_base() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
694
		$base = wc_get_customer_default_location();
695
		$this->_data['shipping_country']  = $base['country'];
696
		$this->_data['shipping_state']    = $base['state'];
697
		$this->_data['shipping_postcode'] = '';
698
		$this->_data['shipping_city']     = '';
699
	}
700
701
	/**
702
	 * Sets all shipping info at once.
703
	 * @param string $country
704
	 * @param string $state
705
	 * @param string $postcode
706
	 * @param string $city
707
	 */
708
	public function set_shipping_location( $country, $state = '', $postcode = '', $city = '' ) {
709
		$this->_data['shipping_country']  = $country;
710
		$this->_data['shipping_state']    = $state;
711
		$this->_data['shipping_postcode'] = $postcode;
712
		$this->_data['shipping_city']     = $city;
713
	}
714
715
	/**
716
	 * Sets all address info at once.
717
	 * @param string $country
718
	 * @param string $state
719
	 * @param string $postcode
720
	 * @param string $city
721
	 */
722
	public function set_billing_location( $country, $state, $postcode = '', $city = '' ) {
723
		$this->_data['billing_country']  = $country;
724
		$this->_data['billing_state']    = $state;
725
		$this->_data['billing_postcode'] = $postcode;
726
		$this->_data['billing_city']     = $city;
727
	}
728
729
	/**
730
	 * Set billing first name.
731
	 * @return string
732
	 */
733
	public function set_billing_first_name( $value ) {
734
		$this->_data['billing_first_name'] = $value;
735
	}
736
737
	/**
738
	 * Set billing last name.
739
	 * @return string
740
	 */
741
	public function set_billing_last_name( $value ) {
742
		$this->_data['billing_last_name'] = $value;
743
	}
744
745
	/**
746
	 * Set billing company.
747
	 * @return string
748
	 */
749
	public function set_billing_company( $value ) {
750
		$this->_data['billing_company'] = $value;
751
	}
752
753
	/**
754
	 * Set billing phone.
755
	 * @return string
756
	 */
757
	public function set_billing_phone( $value ) {
758
		$this->_data['billing_phone'] = $value;
759
	}
760
761
	/**
762
	 * Set billing email.
763
	 * @return string
764
	 */
765
	public function set_billing_email( $email ) {
766
		$this->_data['billing_email'] = sanitize_email( $email );
767
	}
768
769
	/**
770
	 * Set customer country.
771
	 * @param mixed $country
772
	 */
773
	public function set_billing_country( $country ) {
774
		$this->_data['billing_country'] = $country;
775
	}
776
777
	/**
778
	 * Set customer state.
779
	 * @param mixed $state
780
	 */
781
	public function set_billing_state( $state ) {
782
		$this->_data['billing_state'] = $state;
783
	}
784
785
	/**
786
	 * Sets customer postcode.
787
	 * @param mixed $postcode
788
	 */
789
	public function set_billing_postcode( $postcode ) {
790
		$this->_data['billing_postcode'] = $postcode;
791
	}
792
793
	/**
794
	 * Sets customer city.
795
	 * @param mixed $city
796
	 */
797
	public function set_billing_city( $city ) {
798
		$this->_data['billing_city'] = $city;
799
	}
800
801
	/**
802
	 * Set customer address.
803
	 * @param mixed $address
804
	 */
805
	public function set_billing_address( $address ) {
806
		$this->_data['billing_address_1'] = $address;
807
	}
808
809
	/**
810
	 * Set customer address.
811
	 * @param mixed $address
812
	 */
813
	public function set_billing_address_1( $address ) {
814
		$this->set_billing_address( $address );
815
	}
816
817
	/**
818
	 * Set customer's second address.
819
	 * @param mixed $address
820
	 */
821
	public function set_billing_address_2( $address ) {
822
		$this->_data['billing_address_2'] = $address;
823
	}
824
825
	/**
826
	 * Set shipping first name.
827
	 * @return string
828
	 */
829
	public function set_shipping_first_name( $value ) {
830
		$this->_data['shipping_first_name'] = $value;
831
	}
832
833
	/**
834
	 * Set shipping last name.
835
	 * @return string
836
	 */
837
	public function set_shipping_last_name( $value ) {
838
		$this->_data['shipping_last_name'] = $value;
839
	}
840
841
	/**
842
	 * Set shipping company.
843
	 * @return string
844
	 */
845
	public function set_shipping_company( $value ) {
846
		$this->_data['shipping_company'] = $value;
847
	}
848
849
	/**
850
	 * Set shipping country.
851
	 * @param string $country
852
	 */
853
	public function set_shipping_country( $country ) {
854
		$this->_data['shipping_country'] = $country;
855
	}
856
857
	/**
858
	 * Set shipping state.
859
	 * @param string $state
860
	 */
861
	public function set_shipping_state( $state ) {
862
		$this->_data['shipping_state'] = $state;
863
	}
864
865
	/**
866
	 * Set shipping postcode.
867
	 * @param string $postcode
868
	 */
869
	public function set_shipping_postcode( $postcode ) {
870
		$this->_data['shipping_postcode'] = $postcode;
871
	}
872
873
	/**
874
	 * Sets shipping city.
875
	 * @param string $city
876
	 */
877
	public function set_shipping_city( $city ) {
878
		$this->_data['shipping_city'] = $city;
879
	}
880
881
	/**
882
	 * Set shipping address.
883
	 * @param string $address
884
	 */
885
	public function set_shipping_address( $address ) {
886
		$this->_data['shipping_address_1'] = $address;
887
	}
888
889
	/**
890
	 * Set customer shipping address.
891
	 * @param mixed $address
892
	 */
893
	public function set_shipping_address_1( $address ) {
894
		$this->set_shipping_address( $address );
895
	}
896
897
	/**
898
	 * Set second shipping address.
899
	 * @param string $address
900
	 */
901
	public function set_shipping_address_2( $address ) {
902
		$this->_data['shipping_address_2'] = $address;
903
	}
904
905
	/**
906
	 * Set if customer has tax exemption.
907
	 * @param bool $is_vat_exempt
908
	 */
909
	public function set_is_vat_exempt( $is_vat_exempt ) {
910
		$this->_data['is_vat_exempt'] = $is_vat_exempt;
911
	}
912
913
	/**
914
	 * Calculated shipping?
915
	 * @param boolean $calculated
916
	 */
917
	public function set_calculated_shipping( $calculated = true ) {
918
		$this->_data['calculated_shipping'] = $calculated;
919
	}
920
921
	/**
922
	 * Set if the user a paying customer.
923
	 * @since 2.7.0
924
	 * @param boolean $is_paying_customer
925
	 */
926
	function set_is_paying_customer( $is_paying_customer ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
927
		$this->_data['is_paying_customer'] = (bool) $is_paying_customer;
928
	}
929
930
	/*
931
	|--------------------------------------------------------------------------
932
	| Other methods
933
	|--------------------------------------------------------------------------
934
	| Other functions for interacting with customers.
935
	*/
936
937
	/**
938
	 * Is customer outside base country (for tax purposes)?
939
	 * @return bool
940
	 */
941
	public function is_customer_outside_base() {
942
		list( $country, $state ) = $this->get_taxable_address();
943
		if ( $country ) {
944
			$default = wc_get_base_location();
945
			if ( $default['country'] !== $country ) {
946
				return true;
947
			}
948
			if ( $default['state'] && $default['state'] !== $state ) {
949
				return true;
950
			}
951
		}
952
		return false;
953
	}
954
955
	/*
956
	 |--------------------------------------------------------------------------
957
	 | CRUD methods
958
	 |--------------------------------------------------------------------------
959
	 | Methods which create, read, update and delete from the database.
960
	 |
961
	 | A save method is included for convenience (chooses update or create based
962
	 | on if the order exists yet).
963
	 */
964
965
	 /**
966
	  * Create a customer.
967
	  * @since 2.7.0.
968
	  */
969
	public function create() {
970
		$customer_id = wc_create_new_customer( $this->get_email(), $this->get_username(), $this->_data['password'] );
971
		unset( $this->_data['password'] );
972
		if ( $customer_id ) {
973
			$this->_data['id'] = $customer_id;
974
			update_user_meta( $this->get_id(), 'billing_first_name', $this->get_billing_first_name() );
975
			update_user_meta( $this->get_id(), 'billing_last_name', $this->get_billing_last_name() );
976
			update_user_meta( $this->get_id(), 'billing_company', $this->get_billing_company() );
977
			update_user_meta( $this->get_id(), 'billing_phone', $this->get_billing_phone() );
978
			update_user_meta( $this->get_id(), 'billing_email', $this->get_billing_email() );
979
			update_user_meta( $this->get_id(), 'billing_postcode', $this->get_billing_postcode() );
980
			update_user_meta( $this->get_id(), 'billing_city', $this->get_billing_city() );
981
			update_user_meta( $this->get_id(), 'billing_address_1', $this->get_billing_address() );
982
			update_user_meta( $this->get_id(), 'billing_address_2', $this->get_billing_address_2() );
983
			update_user_meta( $this->get_id(), 'billing_state', $this->get_billing_state() );
984
			update_user_meta( $this->get_id(), 'billing_country', $this->get_billing_country() );
985
			update_user_meta( $this->get_id(), 'shipping_first_name', $this->get_shipping_first_name() );
986
			update_user_meta( $this->get_id(), 'shipping_last_name', $this->get_shipping_last_name() );
987
			update_user_meta( $this->get_id(), 'shipping_company', $this->get_shipping_company() );
988
			update_user_meta( $this->get_id(), 'shipping_postcode', $this->get_shipping_postcode() );
989
			update_user_meta( $this->get_id(), 'shipping_city', $this->get_shipping_city() );
990
			update_user_meta( $this->get_id(), 'shipping_address_1', $this->get_shipping_address() );
991
			update_user_meta( $this->get_id(), 'shipping_address_2', $this->get_shipping_address_2() );
992
			update_user_meta( $this->get_id(), 'shipping_state', $this->get_shipping_state() );
993
			update_user_meta( $this->get_id(), 'shipping_country', $this->get_shipping_country() );
994
			update_user_meta( $this->get_id(), 'paying_customer', $this->get_is_paying_customer() );
995
			update_user_meta( $this->get_id(), 'last_update',  $this->get_date_modified() );
996
			update_user_meta( $this->get_id(), 'first_name', $this->get_first_name() );
997
			update_user_meta( $this->get_id(), 'last_name', $this->get_last_name() );
998
			$this->set_date_modified( time() );
999
			wp_update_user( array( 'ID' => $this->get_id(), 'role' => $this->get_role() ) );
1000
			$wp_user = new WP_User( $this->get_id() );
1001
			$this->set_date_created( strtotime( $wp_user->user_registered ) );
1002
			$this->read_meta_data();
1003
		}
1004
	}
1005
1006
	/**
1007
	 * Read a customer from the database.
1008
	 * @since 2.7.0
1009
	 * @param integer $id
1010
	 */
1011
	public function read( $id ) {
1012
		global $wpdb;
1013
1014
		if ( $id ) {
1015
			// Only continue reading if the customer exists.
1016
			$user_object = get_userdata( $id );
1017
1018
			if ( empty( $user_object ) || empty( $user_object->ID ) ) {
1019
				$this->_data['id'] = 0;
1020
				return;
1021
			}
1022
1023
			$this->_data['id'] = $id;
1024
1025
			foreach ( array_keys( $this->_data ) as $key ) {
1026
				$meta_value = get_user_meta( $id, $key, true );
1027
				if ( $meta_value && is_callable( array( $this, "set_{$key}" ) ) ) {
1028
					$this->{"set_{$key}"}( $meta_value );
1029
				}
1030
			}
1031
1032
			$this->set_is_paying_customer( get_user_meta( $id, 'paying_customer', true ) );
1033
			$wp_user = new WP_User( $id );
1034
			$this->set_email( $wp_user->user_email );
1035
			$this->set_username( $wp_user->user_login );
1036
			$this->set_date_created( strtotime( $wp_user->user_registered ) );
1037
			$this->set_date_modified( get_user_meta( $id, 'last_update', true ) );
1038
			$this->set_role( ( ! empty ( $wp_user->roles[0] ) ? $wp_user->roles[0] : 'customer' ) );
1039
1040
			// Get info about user's last order
1041
			$last_order = $wpdb->get_row( "SELECT id, post_date_gmt
1042
				FROM $wpdb->posts AS posts
1043
				LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id
1044
				WHERE meta.meta_key = '_customer_user'
1045
				AND   meta.meta_value = {$id}
1046
				AND   posts.post_type = 'shop_order'
1047
				AND   posts.post_status IN ( '" . implode( "','", array_keys( wc_get_order_statuses() ) ) . "' )
1048
				ORDER BY posts.ID DESC
1049
			" );
1050
1051
			$this->set_last_order_id( is_object( $last_order ) ? $last_order->id : null );
1052
			$this->set_last_order_date( is_object( $last_order ) ? strtotime( $last_order->post_date_gmt ) : null );
1053
1054
			// WC_Customer can't use wc_get_customer_order_count because get_order_types might not be loaded by the time a customer/session is
1055
1056
			$count = $wpdb->get_var( "SELECT COUNT(*)
1057
				FROM $wpdb->posts as posts
1058
1059
				LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id
1060
1061
				WHERE   meta.meta_key       = '_customer_user'
1062
				AND     posts.post_type = 'shop_order'
1063
				AND     posts.post_status   IN ('" . implode( "','", array_keys( wc_get_order_statuses() ) )  . "')
1064
				AND     meta_value          = $id
1065
			" );
1066
1067
			$spent = $wpdb->get_var( "SELECT SUM(meta2.meta_value)
1068
				FROM $wpdb->posts as posts
1069
1070
				LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id
1071
				LEFT JOIN {$wpdb->postmeta} AS meta2 ON posts.ID = meta2.post_id
1072
1073
				WHERE   meta.meta_key       = '_customer_user'
1074
				AND     meta.meta_value     = $id
1075
				AND     posts.post_type     = 'shop_order'
1076
				AND     posts.post_status   IN ( 'wc-completed', 'wc-processing' )
1077
				AND     meta2.meta_key      = '_order_total'
1078
			" );
1079
			if ( ! $spent ) {
1080
				$spent = 0;
1081
			}
1082
1083
			$this->set_orders_count( $count );
1084
			$this->set_total_spent( $spent );
1085
			$this->read_meta_data();
1086
		}
1087
1088
		unset( $this->_data['password'] ); // password is write only, never ever read it
1089
	}
1090
1091
	/**
1092
	 * Update a customer.
1093
	 * @since 2.7.0
1094
	 */
1095
	public function update() {
1096
		$customer_ID = $this->get_id();
1097
1098
		wp_update_user( array( 'ID' => $customer_ID, 'user_email' => $this->get_email() ) );
1099
		// Only update password if a new one was set with set_password
1100
		if ( isset( $this->_data['password'] ) ) {
1101
			wp_update_user( array( 'ID' => $customer_ID, 'user_pass' => $this->_data['password'] ) );
1102
			unset( $this->_data['password'] );
1103
		}
1104
1105
		update_user_meta( $this->get_id(), 'billing_first_name', $this->get_billing_first_name() );
1106
		update_user_meta( $this->get_id(), 'billing_last_name', $this->get_billing_last_name() );
1107
		update_user_meta( $this->get_id(), 'billing_company', $this->get_billing_company() );
1108
		update_user_meta( $this->get_id(), 'billing_phone', $this->get_billing_phone() );
1109
		update_user_meta( $this->get_id(), 'billing_email', $this->get_billing_email() );
1110
		update_user_meta( $this->get_id(), 'billing_postcode', $this->get_billing_postcode() );
1111
		update_user_meta( $this->get_id(), 'billing_city', $this->get_billing_city() );
1112
		update_user_meta( $this->get_id(), 'billing_address_1', $this->get_billing_address() );
1113
		update_user_meta( $this->get_id(), 'billing_address_2', $this->get_billing_address_2() );
1114
		update_user_meta( $this->get_id(), 'billing_state', $this->get_billing_state() );
1115
		update_user_meta( $this->get_id(), 'shipping_first_name', $this->get_shipping_first_name() );
1116
		update_user_meta( $this->get_id(), 'shipping_last_name', $this->get_shipping_last_name() );
1117
		update_user_meta( $this->get_id(), 'shipping_company', $this->get_shipping_company() );
1118
		update_user_meta( $this->get_id(), 'billing_country', $this->get_billing_country() );
1119
		update_user_meta( $this->get_id(), 'shipping_postcode', $this->get_shipping_postcode() );
1120
		update_user_meta( $this->get_id(), 'shipping_city', $this->get_shipping_city() );
1121
		update_user_meta( $this->get_id(), 'shipping_address_1', $this->get_shipping_address() );
1122
		update_user_meta( $this->get_id(), 'shipping_address_2', $this->get_shipping_address_2() );
1123
		update_user_meta( $this->get_id(), 'shipping_state', $this->get_shipping_state() );
1124
		update_user_meta( $this->get_id(), 'shipping_country', $this->get_shipping_country() );
1125
		update_user_meta( $this->get_id(), 'paying_customer', $this->get_is_paying_customer() );
1126
		$this->set_date_modified( time() );
1127
		update_user_meta( $this->get_id(), 'last_update',  $this->get_date_modified() );
1128
		update_user_meta( $this->get_id(), 'first_name', $this->get_first_name() );
1129
		update_user_meta( $this->get_id(), 'last_name', $this->get_last_name() );
1130
		wp_update_user( array( 'ID' => $this->get_id(), 'role' => $this->get_role() ) );
1131
		$this->save_meta_data();
1132
	}
1133
1134
	/**
1135
	 * Delete a customer.
1136
	 * @since 2.7.0
1137
	 */
1138
	public function delete() {
1139
		if ( ! $this->get_id() ) {
1140
			return;
1141
		}
1142
		wp_delete_user( $this->get_id() );
1143
	}
1144
1145
	/**
1146
	 * Save data. Create when creating a new user/class, update when editing
1147
	 * an existing user, and save session when working on a logged out guest
1148
	 * session.
1149
	 * @since 2.7.0
1150
	 */
1151
	public function save() {
1152
		if ( $this->_is_session ) {
1153
			$this->save_session_if_changed();
1154
		} elseif ( ! $this->get_id() ) {
1155
			$this->create();
1156
		} else {
1157
			$this->update();
1158
		}
1159
	}
1160
1161
	/**
1162
	 * Saves data to the session only (does not overwrite DB values).
1163
	 * @since 2.7.0
1164
	 */
1165
	public function save_to_session() {
1166
		if ( ! $this->_is_session ) {
1167
			return;
1168
		}
1169
		$data = array();
1170
		foreach ( $this->_session_keys as $session_key ) {
1171
			$function_key = $session_key;
1172
			if ( 'billing_' === substr( $session_key, 0, 8 ) ) {
1173
				$session_key = str_replace( 'billing_', '', $session_key );
1174
			}
1175
			$data[ $session_key ] = $this->{"get_$function_key"}();
1176
		}
1177
		WC()->session->set( 'customer', $data );
1178
	}
1179
1180
}
1181