PluginProbe
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 2.31.1
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v2.31.1
4.7.2 4.7.1 4.7.0 4.6.6 4.6.5 4.6.4 4.6.3 4.6.2 4.6.1 4.6.0 4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 All 281 releases
surecart / app / src / Models / User.php
User.php
597 lines 12.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace SureCart\Models;
3
4 use ArrayAccess;
5 use JsonSerializable;
6 use SureCart\Models\Traits\SyncsCustomer;
7
8 /**
9 * User class.
10 */
11 class User implements ArrayAccess, JsonSerializable {
12 use SyncsCustomer;
13 /**
14 * Holds the user.
15 *
16 * @var \WP_User|null;
17 */
18 protected $user;
19
20 /**
21 * Holds the cutomser
22 *
23 * @var \SureCart\Models\Customer;
24 */
25 protected $customer;
26
27 /**
28 * Stores the customer id key.
29 *
30 * @var string
31 */
32 protected $customer_id_key = 'sc_customer_ids';
33
34 /**
35 * Get the customer meta key.
36 *
37 * @return string
38 */
39 protected function getCustomerMetaKey() {
40 return $this->customer_id_key;
41 }
42
43 /**
44 * Get the user's customer id.
45 *
46 * @param string $mode Customer mode.
47 *
48 * @return int|null
49 */
50 protected function customerId( $mode = 'live' ) {
51 if ( empty( $this->user->ID ) ) {
52 return null;
53 }
54 $meta = (array) get_user_meta( $this->user->ID, $this->customer_id_key, true );
55 if ( isset( $meta[ $mode ] ) ) {
56 return $meta[ $mode ];
57 }
58 if ( isset( $meta[0] ) ) {
59 return $meta[0];
60 }
61 return null;
62 }
63
64 /**
65 * Sync the customer ids.
66 *
67 * @return array Array of synced items.
68 */
69 protected function syncCustomerIds() {
70 // syncing disabled.
71 if ( ! $this->shouldSyncCustomer() ) {
72 return false;
73 }
74
75 // get all customers by email address (live and test).
76 $customers = Customer::where(
77 [
78 'email' => strtolower( $this->user->user_email ),
79 ]
80 )->get();
81
82 if ( is_wp_error( $customers ) ) {
83 return $customers;
84 }
85
86 // we have customers.
87 $live_customer = current(
88 array_filter(
89 $customers,
90 function( $customer ) {
91 return $customer->live_mode;
92 }
93 )
94 );
95
96 $test_customer = current(
97 array_filter(
98 $customers,
99 function( $customer ) {
100 return ! $customer->live_mode;
101 }
102 )
103 );
104
105 if ( empty( $live_customer->id ) ) {
106 $live_customer = Customer::create(
107 [
108 'name' => $this->user->display_name,
109 'email' => strtolower( $this->user->user_email ),
110 'live_mode' => true,
111 ],
112 false // don't create a user.
113 );
114 }
115 if ( empty( $test_customer->id ) ) {
116 $test_customer = Customer::create(
117 [
118 'name' => $this->user->display_name,
119 'email' => strtolower( $this->user->user_email ),
120 'live_mode' => false,
121 ],
122 false // don't create a user.
123 );
124 }
125
126 if ( ! empty( $live_customer->id ) ) {
127 $this->setCustomerId( $live_customer->id, 'live' );
128 }
129 if ( ! empty( $test_customer->id ) ) {
130 $this->setCustomerId( $test_customer->id, 'test' );
131 }
132
133 return [
134 'live' => $this->customerId( 'live' ),
135 'test' => $this->customerId( 'test' ),
136 ];
137 }
138
139 /**
140 * List the users customer ids.
141 *
142 * @return array
143 */
144 protected function customerIds() {
145 if ( empty( $this->user->ID ) ) {
146 return [];
147 }
148 return array_filter( (array) get_user_meta( $this->user->ID, $this->customer_id_key, true ) );
149 }
150
151 /**
152 * Is this user a customer?
153 *
154 * @return boolean
155 */
156 protected function isCustomer() {
157 return ! empty( array_filter( (array) $this->customerIds() ) );
158 }
159
160 /**
161 * Does the user have this customer id?
162 *
163 * @param string $id The customer id.
164 *
165 * @return boolean
166 */
167 protected function hasCustomerId( $id ) {
168 foreach ( (array) $this->customerIds() as $saved_id ) {
169 if ( $saved_id === $id ) {
170 return true;
171 }
172 }
173 return false;
174 }
175
176 /**
177 * Set the customer id in the user meta.
178 *
179 * @param string $id Customer id.
180 * @return $this|bool
181 */
182 protected function setCustomerId( $id, $mode = 'live', $force = false ) {
183 $meta = (array) get_user_meta( $this->user->ID, $this->customer_id_key, true );
184
185 // if we are setting something here.
186 if ( ! empty( $id ) ) {
187 // if they already have one set for this mode.
188 if ( ! empty( $meta[ $mode ] ) ) {
189 // if we have not passed force = true.
190 if ( ! $force ) {
191 return new \WP_Error( 'already_linked', __( 'This user is already linked to a customer.', 'surecart' ) );
192 }
193 }
194 }
195
196 // update id.
197 $meta[ $mode ] = $id;
198 // update meta.
199 update_user_meta( $this->user->ID, $this->customer_id_key, $meta );
200 return $this;
201 }
202
203 /**
204 * Remove the the customer id from the user meta.
205 *
206 * @param string $mode Customer mode.
207 * @return $this
208 */
209 protected function removeCustomerId( $mode = 'live' ) {
210 $meta = (array) get_user_meta( $this->user->ID, $this->customer_id_key, true );
211
212 // if we are setting something here.
213 if ( ! empty( $meta[ $mode ] ) ) {
214 // set mode empty.
215 unset( $meta[ $mode ] );
216 }
217
218 // update meta.
219 update_user_meta( $this->user->ID, $this->customer_id_key, $meta );
220
221 // return this.
222 return $this;
223 }
224
225 /**
226 * Disallow overriding the constructor in child classes and make the code safe that way.
227 */
228 final public function __construct() {
229 }
230
231 /**
232 * Get a user's subscriptions
233 *
234 * @return mixed
235 */
236 protected function subscriptions() {
237 return Subscription::where( [ 'customer_ids' => [ $this->customerId() ] ] );
238 }
239
240 /**
241 * Get a users orders
242 *
243 * @param array $query Query args.
244 * @return SureCart\Models\Order[];
245 */
246 protected function orders() {
247 return Order::where( [ 'customer_ids' => [ $this->customerId() ] ] );
248 }
249
250 /**
251 * Login the user.
252 *
253 * @return true|\WP_Error
254 */
255 protected function login() {
256 if ( empty( $this->user->ID ) ) {
257 return new \Error( 'not_found', esc_html__( 'This user could not be found.', 'surecart' ) );
258 }
259
260 clean_user_cache( $this->user->ID );
261 wp_clear_auth_cookie();
262 wp_set_current_user( $this->user->ID );
263 wp_set_auth_cookie( $this->user->ID );
264 update_user_caches( $this->user );
265
266 return true;
267 }
268
269 /**
270 * Create a new user and return this model context
271 * If the user already exists, just set the customer and role in that case.
272 */
273 protected function create( $args ) {
274 $args = wp_parse_args(
275 $args,
276 [
277 'user_name' => '',
278 'user_email' => '',
279 'user_password' => '',
280 'first_name' => '',
281 'last_name' => '',
282 ]
283 );
284
285 // use the username or the email as a fallback.
286 $name = ! empty( sanitize_user( $args['user_name'], true ) ) ? sanitize_user( $args['user_name'], true ) : $args['user_email'];
287 $username = $this->createUniqueUsername( sanitize_user( $name, true ) );
288
289 $user_password = trim( $args['user_password'] );
290 $user_created = false;
291
292 // password is not provided.
293 if ( empty( $user_password ) ) {
294 $user_password = wp_generate_password( 12, false );
295 $user_id = wp_create_user( sanitize_user( $username, true ), $user_password, $args['user_email'] );
296 // turn off this feature with a filter.
297 if ( apply_filters( 'surecart/default_password_nag', true, $user_id ) ) {
298 update_user_meta( $user_id, 'default_password_nag', true );
299 }
300 $user_created = true;
301 } else {
302 // Password has been provided.
303 $user_id = wp_create_user( sanitize_user( $username, true ), $user_password, $args['user_email'] );
304 $user_created = true;
305 }
306
307 if ( is_wp_error( $user_id ) ) {
308 return $user_id;
309 }
310
311 $user = new \WP_User( $user_id );
312 $user->add_role( 'sc_customer' );
313
314 if ( $args['first_name'] ) {
315 $user->first_name = $args['first_name'];
316 }
317 if ( $args['last_name'] ) {
318 $user->last_name = $args['last_name'];
319 }
320
321 if ( $user_created ) {
322 wp_update_user( $user );
323 }
324
325 return $this->find( $user_id );
326 }
327
328 /**
329 * Create a unique username for the user.
330 *
331 * @param string $name The username.
332 *
333 * @return string
334 */
335 protected function createUniqueUsername( $name ) {
336 $base_name = $name;
337 $i = 0;
338 while ( username_exists( $name ) ) {
339 $name = $base_name . ( ++$i );
340 }
341 return $name;
342 }
343
344 /**
345 * Retrieve user info by a given field
346 *
347 * @param string $field The field to retrieve the user with. id | ID | slug | email | login.
348 * @param int|string $value A value for $field. A user ID, slug, email address, or login name.
349 * @return this|false This object on success, false on failure.
350 */
351 protected function getUserBy( $field, $value ) {
352 $this->user = get_user_by( $field, $value ?? '' );
353 return $this->user ? $this : false;
354 }
355
356 /**
357 * Get the customer from the user.
358 *
359 * @return \SureCart\Models\Customer|false
360 */
361 protected function customer( $mode = 'live' ) {
362 $id = $this->customerId( $mode );
363 if ( ! $id ) {
364 return false;
365 }
366 return Customer::find( $this->customerId( $mode ) );
367 }
368
369 /**
370 * Get the current user
371 *
372 * @return $this
373 */
374 protected function current() {
375 $this->user = wp_get_current_user();
376 return $this;
377 }
378
379 /**
380 * Find the user.
381 *
382 * @param integer $id ID of the WordPress user.
383 * @return $this
384 */
385 protected function find( $id ) {
386 $this->user = get_user_by( 'id', $id );
387 return $this;
388 }
389
390 /**
391 * Find the user by customer id.
392 *
393 * @param string $id Customer id string.
394 * @return $this
395 */
396 protected function findByCustomerId( $id ) {
397 if ( ! is_string( $id ) || empty( $id ) ) {
398 return false;
399 }
400
401 $users = new \WP_User_Query(
402 [
403 'meta_query' => [
404 [
405 'key' => $this->customer_id_key,
406 'value' => $id,
407 'compare' => 'LIKE',
408 ],
409 ],
410 ]
411 );
412
413 if ( empty( $users->results ) ) {
414 return false;
415 }
416
417 $this->user = $users->results[0];
418 return $this;
419 }
420
421 /**
422 * Get the WordPress user.
423 *
424 * @return \WP_User|null;
425 */
426 public function getWPUser() {
427 return $this->user;
428 }
429
430 /**
431 * Get a specific attribute
432 *
433 * @param string $key Attribute name.
434 *
435 * @return mixed
436 */
437 public function getAttribute( $key ) {
438 $attribute = null;
439
440 if ( $this->hasAttribute( $key ) ) {
441 $attribute = $this->user->$key;
442 }
443
444 return $attribute;
445 }
446
447 /**
448 * Sets a user attribute
449 * Optionally calls a mutator based on set{Attribute}Attribute
450 *
451 * @param string $key Attribute key.
452 * @param mixed $value Attribute value.
453 *
454 * @return mixed|void
455 */
456 public function setAttribute( $key, $value ) {
457 $this->user->$key = $value;
458 }
459
460 /**
461 * Does it have the attribute
462 *
463 * @param string $key Attribute key.
464 *
465 * @return boolean
466 */
467 public function hasAttribute( $key ) {
468 return $this->user->$key ?? false;
469 }
470
471 /**
472 * Serialize to json.
473 *
474 * @return Array
475 */
476 #[\ReturnTypeWillChange]
477 public function jsonSerialize() {
478 return $this->user->to_array();
479 }
480
481 /**
482 * Get the attribute
483 *
484 * @param string $key Attribute name.
485 *
486 * @return mixed
487 */
488 public function __get( $key ) {
489 return $this->getAttribute( $key );
490 }
491
492 /**
493 * Set the attribute
494 *
495 * @param string $key Attribute name.
496 * @param mixed $value Value of attribute.
497 *
498 * @return void
499 */
500 public function __set( $key, $value ) {
501 $this->setAttribute( $key, $value );
502 }
503
504 /**
505 * Determine if the given attribute exists.
506 *
507 * @param mixed $offset Name.
508 * @return bool
509 */
510 public function offsetExists( $offset ): bool {
511 return ! is_null( $this->getAttribute( $offset ) );
512 }
513
514 /**
515 * Get the value for a given offset.
516 *
517 * @param mixed $offset Name.
518 * @return mixed
519 */
520 #[\ReturnTypeWillChange]
521 public function offsetGet( $offset ) {
522 return $this->getAttribute( $offset );
523 }
524
525 /**
526 * Set the value for a given offset.
527 *
528 * @param mixed $offset Name.
529 * @param mixed $value Value.
530 * @return void
531 */
532 public function offsetSet( $offset, $value ): void {
533 $this->setAttribute( $offset, $value );
534 }
535
536 /**
537 * Unset the value for a given offset.
538 *
539 * @param mixed $offset Name.
540 * @return void
541 */
542 public function offsetUnset( $offset ) : void {
543 $this->user->$offset = null;
544 }
545
546 /**
547 * Get the user object.
548 *
549 * @return \WP_User|null
550 */
551 public function getUser() {
552 return $this->user;
553 }
554
555 /**
556 * Determine if an attribute or relation exists on the model.
557 *
558 * @param string $key Name.
559 * @return bool
560 */
561 public function __isset( $key ) {
562 return $this->offsetExists( $key );
563 }
564
565 /**
566 * Unset an attribute on the model.
567 *
568 * @param string $key Name.
569 * @return void
570 */
571 public function __unset( $key ) {
572 $this->offsetUnset( $key );
573 }
574
575 /**
576 * Forward call to method
577 *
578 * @param string $method Method to call.
579 * @param mixed $params Method params.
580 */
581 public function __call( $method, $params ) {
582 return call_user_func_array( [ $this, $method ], $params );
583 }
584
585 /**
586 * Static Facade Accessor
587 *
588 * @param string $method Method to call.
589 * @param mixed $params Method params.
590 *
591 * @return mixed
592 */
593 public static function __callStatic( $method, $params ) {
594 return call_user_func_array( [ new static(), $method ], $params );
595 }
596 }
597