Completed
Branch FET-8385-datetime-ticket-selec... (304b56)
by
unknown
51:42 queued 39:36
created

EE_Checkout::__sleep()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 6
nc 4
nop 0
dl 0
loc 10
rs 8.8571
c 0
b 0
f 0
1
<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) { exit('No direct script access allowed'); }
2
 /**
3
 *
4
 * Class EE_Checkout
5
 *
6
 * Description
7
 *
8
 * @package 			Event Espresso
9
 * @subpackage    core
10
 * @author				Brent Christensen
11
 * @since 				4.5.0
12
 *
13
 */
14
class EE_Checkout {
15
16
	/**
17
	 * 	whether current request originated from the EE admin
18
	 * @type bool
19
	 */
20
	public $admin_request = FALSE;
21
22
	/**
23
	 * whether returning to edit attendee information or to retry a payment
24
	 * @type bool
25
	 */
26
	public $revisit = FALSE;
27
28
	/**
29
	 * whether the primary registrant is returning to edit attendee information or to retry a payment
30
	 * @type bool
31
	 */
32
	public $primary_revisit = FALSE;
33
34
	/**
35
	 * is registration allowed to progress or halted for some reason such as failing to pass recaptcha?
36
	 * @type bool
37
	 */
38
	public $continue_reg = TRUE;
39
40
	/**
41
	 * redirect to thank you page ?
42
	 * @type bool
43
	 */
44
	public $redirect = FALSE;
45
46
	/**
47
	 * generate the reg form or not ?
48
	 * @type bool
49
	 */
50
	public $generate_reg_form = TRUE;
51
52
	/**
53
	 * process a reg form submission or not ?
54
	 * @type bool
55
	 */
56
	public $process_form_submission = FALSE;
57
58
	/**
59
	 * tracks whether the TXN status modified during this checkout
60
	 *
61
	 * @type bool
62
	 */
63
	public $txn_status_updated = FALSE;
64
65
	/**
66
	 * only triggered to true after absolutely everything has finished.
67
	 *
68
	 * @type bool
69
	 */
70
	protected $exit_spco = FALSE;
71
72
	/**
73
	 * tracks whether any of the TXN's Registrations statuses modified during this checkout
74
	 * indexed by registration ID
75
	 *
76
	 * @type array
77
	 */
78
	protected $reg_status_updated = array();
79
80
	/**
81
	 * timestamp when redirected from Ticket Selector to the checkout
82
	 * @type int
83
	 */
84
	public $uts = 0;
85
86
	/**
87
	 * total number of tickets that were in the cart
88
	 * @type int
89
	 */
90
	public $total_ticket_count = 0;
91
92
	/**
93
	 * corresponds loosely to EE_Transaction::remaining()
94
	 * but can be modified by SPCO
95
	 *
96
	 * @type float
97
	 */
98
	public $amount_owing = 0;
99
100
	/**
101
	 * the reg step slug from the incoming request
102
	 * @type string
103
	 */
104
	public $step = '';
105
106
	/**
107
	 * the reg step slug for a step being edited
108
	 * @type string
109
	 */
110
	public $edit_step = '';
111
112
	/**
113
	 * the action being performed on the current step
114
	 * @type string
115
	 */
116
	public $action = '';
117
118
	/**
119
	 * reg_url_link for a previously saved registration
120
	 * @type string
121
	 */
122
	public $reg_url_link = '';
123
124
	/**
125
	 * string slug for the payment method that was selected during the payment options step
126
	 * @type string
127
	 */
128
	public $selected_method_of_payment = '';
129
130
	/**
131
	 * base url for the site's registration checkout page - additional url params will be added to this
132
	 * @type string
133
	 */
134
	public $reg_page_base_url = '';
135
136
	/**
137
	 * base url for the site's registration cancelled page - additional url params will be added to this
138
	 * @type string
139
	 */
140
	public $cancel_page_url = '';
141
142
	/**
143
	 * base url for the site's thank you page - additional url params will be added to this
144
	 * @type string
145
	 */
146
	public $thank_you_page_url = '';
147
148
	/**
149
	 * base url for any redirects - additional url params will be added to this
150
	 * @type string
151
	 */
152
	public $redirect_url = '';
153
154
	/**
155
	 * form of POST data for use with off-site gateways
156
	 * @type string
157
	 */
158
	public $redirect_form = '';
159
160
	/**
161
	 * array of query where params to use when retrieving cached registrations from $this->checkout->transaction
162
	 * @type array
163
	 */
164
	public $reg_cache_where_params = array();
165
166
	/**
167
	 * a class for managing and creating the JSON encoded array of data that gets passed back to the client during AJAX requests
168
	 * @type EE_SPCO_JSON_Response
169
	 */
170
	public $json_response;
171
172
	/**
173
	 * where we are going next in the reg process
174
	 * @type EE_SPCO_Reg_Step
175
	 */
176
	public $next_step;
177
178
	/**
179
	 * where we are in the reg process
180
	 * @type EE_SPCO_Reg_Step
181
	 */
182
	public $current_step;
183
184
	/**
185
	 * 	$_cart - the current cart object
186
	 *	@var EE_CART
187
	 */
188
	public $cart;
189
190
	/**
191
	 * 	$_transaction - the current transaction object
192
	 *	@var EE_Transaction
193
	 */
194
	public $transaction;
195
196
	/**
197
	 * 	the related attendee object for the primary registrant
198
	 * @type EE_Attendee
199
	 */
200
	public $primary_attendee_obj;
201
202
	/**
203
	 *	$payment_method - the payment method object for the selected method of payment
204
	 *	@type EE_Payment_Method
205
	 */
206
	public $payment_method;
207
208
	/**
209
	 * 	$payment - if a payment was successfully made during the reg process,
210
	 * 	then here it is !!!
211
	 *	@type EE_Payment
212
	 */
213
	public $payment;
214
215
	/**
216
	 * 	if a payment method was selected that uses an on-site gateway, then this is the billing form
217
	 * @type EE_Billing_Info_Form | EE_Billing_Attendee_Info_Form
218
	 */
219
	public $billing_form;
220
221
	/**
222
	 * 	the entire registration form composed of ALL of the subsections generated by the various reg steps
223
	 * @type EE_Form_Section_Proper
224
	 */
225
	public $registration_form;
226
227
	/**
228
	 * array of EE_SPCO_Reg_Step objects
229
	 * @type EE_SPCO_Reg_Step[]
230
	 */
231
	public $reg_steps = array();
232
233
	/**
234
	 * array of EE_Payment_Method objects
235
	 * @type EE_Payment_Method[]
236
	 */
237
	public $available_payment_methods = array();
238
239
240
241
	/**
242
	 *    class constructor
243
	 *
244
	 * @access    public
245
	 */
246
	public function __construct(  ) {
247
		$this->reg_page_base_url = EE_Registry::instance()->CFG->core->reg_page_url();
0 ignored issues
show
Documentation Bug introduced by
It seems like \EE_Registry::instance()...G->core->reg_page_url() can also be of type integer. However, the property $reg_page_base_url is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
248
		$this->thank_you_page_url = EE_Registry::instance()->CFG->core->thank_you_page_url();
249
		$this->cancel_page_url = EE_Registry::instance()->CFG->core->cancel_page_url();
250
		$this->continue_reg = apply_filters( 'FHEE__EE_Checkout___construct___continue_reg', TRUE );
251
		$this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->ajax;
252
		$this->reg_cache_where_params = array( 'order_by' => array( 'REG_count' => 'ASC' ));
253
	}
254
255
256
257
	/**
258
	 * returns true if ANY reg status was updated during checkout
259
	 *
260
	 * @return boolean
261
	 */
262
	public function any_reg_status_updated() {
263
		foreach ( $this->reg_status_updated as $reg_status ) {
264
			if ( $reg_status ) {
265
				return true;
266
			}
267
		}
268
		return false;
269
	}
270
271
272
273
	/**
274
	 * @param $REG_ID
275
	 * @return boolean
276
	 */
277
	public function reg_status_updated( $REG_ID ) {
278
		return isset( $this->reg_status_updated[ $REG_ID ] ) ? $this->reg_status_updated[ $REG_ID ] : false;
279
	}
280
281
282
283
	/**
284
	 * @param $REG_ID
285
	 * @param $reg_status
286
	 */
287
	public function set_reg_status_updated( $REG_ID, $reg_status ) {
288
		$this->reg_status_updated[ $REG_ID ] = filter_var( $reg_status, FILTER_VALIDATE_BOOLEAN );
289
	}
290
291
292
293
	/**
294
	 * exit_spco
295
	 *
296
	 * @return bool
297
	 */
298
	public function exit_spco() {
299
		return $this->exit_spco;
300
	}
301
302
303
304
	/**
305
	 * set_exit_spco
306
	 * can ONLY be set by the  Finalize_Registration reg step
307
	 */
308
	public function set_exit_spco() {
309
		if ( $this->current_step instanceof EE_SPCO_Reg_Step_Finalize_Registration ) {
310
			$this->exit_spco = true;
311
		}
312
	}
313
314
315
316
317
318
	/**
319
	 *    reset_for_current_request
320
	 *
321
	 * @access    public
322
	 * @return    void
323
	 */
324
	public function reset_for_current_request() {
325
		$this->process_form_submission = FALSE;
326
		$this->continue_reg = apply_filters( 'FHEE__EE_Checkout___construct___continue_reg', true );
327
		$this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->front_ajax;
328
		$this->continue_reg = true;
329
		$this->redirect = false;
330
		// don't reset the cached redirect form if we're about to be asked to display it !!!
331
		if ( EE_Registry::instance()->REQ->get( 'action', 'display_spco_reg_step' ) !== 'redirect_form' ) {
332
			$this->redirect_form = '';
333
		}
334
		$this->redirect_url = '';
335
		$this->json_response = new EE_SPCO_JSON_Response();
336
		EE_Form_Section_Proper::reset_js_localization();
337
	}
338
339
340
341
	/**
342
	 *    add_reg_step
343
	 *
344
	 * @access    public
345
	 * @param EE_SPCO_Reg_Step $reg_step_obj
346
	 * @return    void
347
	 */
348
	public function add_reg_step( EE_SPCO_Reg_Step $reg_step_obj ) {
349
		$this->reg_steps[ $reg_step_obj->slug()  ] = $reg_step_obj;
350
	}
351
352
353
354
	/**
355
	 * skip_reg_step
356
	 * if the current reg step does not need to run for some reason,
357
	 * then this will advance SPCO to the next reg step,
358
	 * and mark the skipped step as completed
359
	 *
360
	 * @access    public
361
	 * @param string $reg_step_slug
362
	 * @return    void
363
	 * @throws \EE_Error
364
	 */
365
	public function skip_reg_step( $reg_step_slug = '' ) {
366
		$step_to_skip = $this->find_reg_step( $reg_step_slug );
367
		if ( $step_to_skip instanceof EE_SPCO_Reg_Step && $step_to_skip->is_current_step() ) {
368
			$step_to_skip->set_is_current_step( false );
369
			$step_to_skip->set_completed();
370
			// advance to the next step
371
			$this->set_current_step( $this->next_step->slug() );
372
			// also reset the step param in the request in case any other code references that directly
373
			EE_Registry::instance()->REQ->set( 'step', $this->current_step->slug() );
374
			// since we are skipping a step and setting the current step to be what was previously the next step,
375
			// we need to check that the next step is now correct, and not still set to the current step.
376
			if ( $this->current_step->slug() === $this->next_step->slug() ) {
377
				// correctly setup the next step
378
				$this->set_next_step();
379
			}
380
			$this->set_reg_step_initiated( $this->current_step );
381
		}
382
	}
383
384
385
386
	/**
387
	 *    remove_reg_step
388
	 *
389
	 * @access    public
390
	 * @param string $reg_step_slug
391
	 * @param bool   $reset whether to reset reg steps after removal
392
	 * @throws EE_Error
393
	 */
394
	public function remove_reg_step( $reg_step_slug = '', $reset = true ) {
395
		unset( $this->reg_steps[ $reg_step_slug  ] );
396
		if ( $this->transaction instanceof EE_Transaction ) {
397
			// now remove reg step from TXN and save
398
			$this->transaction->remove_reg_step( $reg_step_slug );
399
			$this->transaction->save();
400
		}
401
		if ( $reset ) {
402
			$this->reset_reg_steps();
403
		}
404
	}
405
406
407
408
	/**
409
	 *    set_reg_step_order
410
	 *
411
	 * @access    public
412
	 * @param string $reg_step_slug
413
	 * @param int    $order
414
	 * @return    void
415
	 */
416
	public function set_reg_step_order( $reg_step_slug = '', $order = 100 ) {
417
		if ( isset( $this->reg_steps[ $reg_step_slug  ] )) {
418
			$this->reg_steps[ $reg_step_slug ]->set_order( $order );
419
		}
420
	}
421
422
423
424
	/**
425
	 *    set_current_step
426
	 *
427
	 * @access    public
428
	 * @param string $current_step
429
	 * @return    void
430
	 */
431
	public function set_current_step( $current_step ) {
432
		// grab what step we're on
433
		$this->current_step = isset( $this->reg_steps[ $current_step ] ) ? $this->reg_steps[ $current_step ] : reset( $this->reg_steps );
0 ignored issues
show
Documentation Bug introduced by
It seems like isset($this->reg_steps[$...reset($this->reg_steps) can also be of type false. However, the property $current_step is declared as type object<EE_SPCO_Reg_Step>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
434
		// verify instance
435
		if ( $this->current_step instanceof EE_SPCO_Reg_Step ) {
436
			// we don't want to repeat completed steps if this is the first time through SPCO
437
			if ( $this->continue_reg && ! $this->revisit && $this->current_step->completed() ) {
438
				// so advance to the next step
439
				$this->set_next_step();
440
				if ( $this->next_step instanceof EE_SPCO_Reg_Step ) {
441
					// and attempt to set it as the current step
442
					$this->set_current_step( $this->next_step->slug() );
443
				}
444
				return;
445
			}
446
			$this->current_step->set_is_current_step( TRUE );
447
		} else {
448
			EE_Error::add_error(
449
				__( 'The current step could not be set.', 'event_espresso' ),
450
				__FILE__, __FUNCTION__, __LINE__
451
			);
452
		}
453
	}
454
455
456
457
	/**
458
	 * 	set_next_step
459
	 * advances the reg_steps array pointer and sets the next step, then reverses pointer back to the current step
460
	 *
461
	 *  @access 	public
462
	 *  @return 	void
463
	 */
464
	public function set_next_step() {
465
		// set pointer to start of array
466
		reset( $this->reg_steps );
467
		// if there is more than one step
468
		if ( count( $this->reg_steps ) > 1 ) {
469
			// advance to the current step and set pointer
470
			while ( key( $this->reg_steps ) !== $this->current_step->slug() && key( $this->reg_steps ) !== '' ) {
471
				next( $this->reg_steps );
472
			}
473
		}
474
		// advance one more spot ( if it exists )
475
		$this->next_step = next( $this->reg_steps );
476
		// verify instance
477
		$this->next_step = $this->next_step instanceof EE_SPCO_Reg_Step ? $this->next_step  : NULL;
478
		// then back to current step to reset
479
		prev( $this->reg_steps );
480
	}
481
482
483
484
485
	/**
486
	 * 	get_next_reg_step
487
	 * 	this simply returns the next step from reg_steps array
488
	 *
489
	 *  @access 	public
490
	 *  @return 	EE_SPCO_Reg_Step | null
491
	 */
492
	public function get_next_reg_step() {
493
		$next = next( $this->reg_steps );
494
		prev( $this->reg_steps );
495
		return $next instanceof EE_SPCO_Reg_Step ? $next : null;
496
	}
497
498
499
500
501
	/**
502
	 * get_prev_reg_step
503
	 * 	this simply returns the previous step from reg_steps array
504
	 *
505
	 *  @access 	public
506
	 *  @return 	EE_SPCO_Reg_Step | null
507
	 */
508
	public function get_prev_reg_step() {
509
		$prev = prev( $this->reg_steps );
510
		next( $this->reg_steps );
511
		return $prev instanceof EE_SPCO_Reg_Step ? $prev : null;
512
	}
513
514
515
516
	/**
517
	 * sort_reg_steps
518
	 *
519
	 * @access public
520
	 * @return void
521
	 */
522
	public function sort_reg_steps() {
523
		$reg_step_sorting_callback = apply_filters( 'FHEE__EE_Checkout__sort_reg_steps__reg_step_sorting_callback', 'reg_step_sorting_callback' );
524
		uasort( $this->reg_steps, array( $this, $reg_step_sorting_callback ));
525
	}
526
527
528
529
	/**
530
	 * find_reg_step
531
	 * finds a reg step by the given slug
532
	 *
533
	 * @access    public
534
	 * @param string $reg_step_slug
535
	 * @return EE_SPCO_Reg_Step|null
536
	 */
537
	public function find_reg_step( $reg_step_slug = '' ) {
538
		if ( ! empty( $reg_step_slug ) ) {
539
			// copy reg step array
540
			$reg_steps = $this->reg_steps;
541
			// set pointer to start of array
542
			reset( $reg_steps );
543
			// if there is more than one step
544
			if ( count( $reg_steps ) > 1 ) {
545
				// advance to the current step and set pointer
546
				while ( key( $reg_steps ) !== $reg_step_slug && key( $reg_steps ) !== '' ) {
547
					next( $reg_steps );
548
				}
549
				return current( $reg_steps );
550
			}
551
		}
552
		return null;
553
	}
554
555
556
557
	/**
558
	 * reg_step_sorting_callback
559
	 *
560
	 * @access public
561
	 * @param EE_SPCO_Reg_Step $reg_step_A
562
	 * @param EE_SPCO_Reg_Step $reg_step_B
563
	 * @return int
564
	 */
565
	public function reg_step_sorting_callback( EE_SPCO_Reg_Step $reg_step_A, EE_SPCO_Reg_Step $reg_step_B ) {
566
		// send finalize_registration step to the end of the array
567
		if ( $reg_step_A->slug() === 'finalize_registration' ) {
568
			return 1;
569
		} else if ( $reg_step_B->slug() === 'finalize_registration' ) {
570
			return -1;
571
		}
572
		if ( $reg_step_A->order() === $reg_step_B->order() ) {
573
			return 0;
574
		}
575
		return ( $reg_step_A->order() > $reg_step_B->order() ) ? 1 : -1;
576
	}
577
578
579
580
	/**
581
	 * set_reg_step_initiated
582
	 *
583
	 * @access    public
584
	 * @param    EE_SPCO_Reg_Step $reg_step
585
	 * @throws \EE_Error
586
	 */
587
	public function set_reg_step_initiated( EE_SPCO_Reg_Step $reg_step ) {
588
		// call set_reg_step_initiated ???
589
		if (
590
			// first time visiting SPCO ?
591
			! $this->revisit
592
			&& (
593
				// and displaying the reg step form for the first time ?
594
				$this->action === 'display_spco_reg_step'
595
				// or initializing the final step
596
				|| $reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration
597
			)
598
		) {
599
			// set the start time for this reg step
600
			if ( ! $this->transaction->set_reg_step_initiated( $reg_step->slug() ) ) {
601 View Code Duplication
				if ( WP_DEBUG ) {
602
					EE_Error::add_error(
603
						sprintf(
604
							__( 'The "%1$s" registration step was not initialized properly.', 'event_espresso' ),
605
							$reg_step->name()
606
						),
607
						__FILE__, __FUNCTION__, __LINE__
608
					);
609
				}
610
			}
611
		}
612
	}
613
614
615
616
	/**
617
	 * 	set_reg_step_JSON_info
618
	 *
619
	 * 	@access public
620
	 * 	@return 	void
621
	 */
622
	public function set_reg_step_JSON_info() {
623
		EE_Registry::$i18n_js_strings[ 'reg_steps' ] = array();
624
		// pass basic reg step data to JS
625
		foreach ( $this->reg_steps as $reg_step ) {
626
			EE_Registry::$i18n_js_strings[ 'reg_steps' ][] = $reg_step->slug();
627
		}
628
		// reset reg step html
629
//		$this->json_response->set_reg_step_html( '' );
630
	}
631
632
633
634
	/**
635
	 * 	reset_reg_steps
636
	 *
637
	 * 	@access public
638
	 * 	@return void
639
	 */
640
	public function reset_reg_steps() {
641
		$this->sort_reg_steps();
642
		$this->set_current_step( EE_Registry::instance()->REQ->get( 'step' ));
643
		$this->set_next_step();
644
		// the text that appears on the reg step form submit button
645
		$this->current_step->set_submit_button_text();
646
		$this->set_reg_step_JSON_info();
647
	}
648
649
650
651
	/**
652
	 *    get_registration_time_limit
653
	 *
654
	 * @access    public
655
	 * @return        string
656
	 */
657
	public function get_registration_time_limit() {
658
659
		$registration_time_limit = (float)( EE_Registry::instance()	->SSN->expiration() - time() );
660
		$time_limit_format = $registration_time_limit > 60 * MINUTE_IN_SECONDS ? 'H:i:s' : 'i:s';
661
		$registration_time_limit = date( $time_limit_format, $registration_time_limit );
662
		return apply_filters(
663
			'FHEE__EE_Checkout__get_registration_time_limit__registration_time_limit',
664
			$registration_time_limit
665
		);
666
	}
667
668
669
670
	/**
671
	 * payment_required
672
	 * @return boolean
673
	 */
674
	public function payment_required() {
675
		// if NOT:
676
		//		registration via admin
677
		//		completed TXN
678
		//		overpaid TXN
679
		//		free TXN ( total = 0.00 )
680
		// then payment required is TRUE
681
		return ! ( $this->admin_request || $this->transaction->is_completed() || $this->transaction->is_overpaid() || $this->transaction->is_free() ) ? TRUE : FALSE;
682
	}
683
684
685
686
	/**
687
	 * get_cart_for_transaction
688
	 *
689
	 * @access public
690
	 * @param EE_Transaction $transaction
691
	 * @return EE_Cart
692
	 */
693
	public function get_cart_for_transaction( $transaction ) {
694
		$session = EE_Registry::instance()->load_core( 'Session' );
695
		$cart = $transaction instanceof EE_Transaction ? EE_Cart::get_cart_from_txn( $transaction, $session ) : null;
0 ignored issues
show
Bug introduced by
It seems like $session defined by \EE_Registry::instance()->load_core('Session') on line 694 can also be of type boolean or object; however, EE_Cart::get_cart_from_txn() does only seem to accept null|object<EE_Session>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
696
		// verify cart
697
		if ( ! $cart instanceof EE_Cart ) {
698
			$cart = EE_Registry::instance()->load_core( 'Cart' );
0 ignored issues
show
Bug Compatibility introduced by
The expression \EE_Registry::instance()->load_core('Cart'); of type null|object|boolean adds the type boolean to the return on line 701 which is incompatible with the return type documented by EE_Checkout::get_cart_for_transaction of type EE_Cart|null.
Loading history...
699
		}
700
701
		return $cart;
702
	}
703
704
705
706
	/**
707
	 * 	initialize_txn_reg_steps_array
708
	 *
709
	 * 	@access public
710
	 * 	@return 	array
711
	 */
712
	public function initialize_txn_reg_steps_array() {
713
		$txn_reg_steps_array = array();
714
		foreach ( $this->reg_steps as $reg_step ) {
715
			$txn_reg_steps_array[ $reg_step->slug() ] = FALSE;
716
		}
717
		return $txn_reg_steps_array;
718
	}
719
720
721
722
	/**
723
	 *    update_txn_reg_steps_array
724
	 *
725
	 * @access public
726
	 * @return    bool
727
	 * @throws \EE_Error
728
	 */
729
	public function update_txn_reg_steps_array() {
730
		$updated = false;
731
		foreach ( $this->reg_steps as $reg_step ) {
732
			if ( $reg_step->completed() ) {
733
				$updated = $this->transaction->set_reg_step_completed( $reg_step->slug() )
734
					? true
735
					: $updated;
736
			}
737
		}
738
		if ( $updated ) {
739
			$this->transaction->save();
740
		}
741
		return $updated;
742
	}
743
744
745
746
	/**
747
	 *    stash_transaction_and_checkout
748
	 *
749
	 * @access public
750
	 * @return    void
751
	 * @throws \EE_Error
752
	 */
753
	public function stash_transaction_and_checkout() {
754
		if ( ! $this->revisit ) {
755
			$this->update_txn_reg_steps_array();
756
		}
757
		$this->track_transaction_and_registration_status_updates();
758
		// save all data to the db, but suppress errors
759
		//$this->save_all_data( FALSE );
760
		// cache the checkout in the session
761
		EE_Registry::instance()->SSN->set_checkout( $this );
762
	}
763
764
765
766
	/**
767
	 *    track_transaction_and_registration_status_updates
768
	 *    stores whether any updates were made to the TXN or it's related registrations
769
	 *
770
	 * @access public
771
	 * @return void
772
	 * @throws \EE_Error
773
	 */
774
	public function track_transaction_and_registration_status_updates() {
775
		// verify the transaction
776
		if ( $this->transaction instanceof EE_Transaction ) {
777
			// has there been a TXN status change during this checkout?
778
			$this->txn_status_updated = $this->transaction->txn_status_updated();
779
			/** @type EE_Registration_Processor $registration_processor */
780
			$registration_processor = EE_Registry::instance()->load_class( 'Registration_Processor' );
781
			// grab the saved registrations from the transaction
782
			foreach ( $this->transaction->registrations( $this->reg_cache_where_params ) as $registration ) {
783
				if ( $registration_processor->reg_status_updated( $registration->ID() ) ) {
784
					$this->set_reg_status_updated( $registration->ID(), true );
785
				}
786
			}
787
		}
788
	}
789
790
791
792
	/**
793
	 *    visit_allows_processing_of_this_registration
794
	 *    determines if the current SPCO visit should allow the passed EE_Registration to be used in processing.
795
	 *    one of the following conditions must be met:
796
	 *        EITHER:    A) first time thru SPCO -> process ALL registrations ( NOT a revisit )
797
	 *        OR :        B) primary registrant is editing info -> process ALL registrations ( primary_revisit )
798
	 *        OR :        C) another registrant is editing info -> ONLY process their registration ( revisit AND their reg_url_link matches )
799
	 *
800
	 * @access public
801
	 * @param    EE_Registration $registration
802
	 * @return    bool
803
	 * @throws \EE_Error
804
	 */
805
	public function visit_allows_processing_of_this_registration( EE_Registration $registration ) {
806
		return ! $this->revisit
807
		       || $this->primary_revisit
808
		       || (
809
			       $this->revisit && $this->reg_url_link === $registration->reg_url_link()
810
		       )
811
			? true
812
			: false;
813
	}
814
815
816
817
	/**
818
	 * 	_transaction_has_primary_registration
819
	 *
820
	 * 	@access 		private
821
	 * 	@return 		bool
822
	 */
823
	public function transaction_has_primary_registrant() {
824
		return $this->primary_attendee_obj instanceof EE_Attendee ? TRUE : FALSE;
825
	}
826
827
828
829
	/**
830
	 *    save_all_data
831
	 *    simply loops through the current transaction and saves all data for each registration
832
	 *
833
	 * @access public
834
	 * @param bool $show_errors
835
	 * @return bool
836
	 * @throws \EE_Error
837
	 */
838
	public function save_all_data( $show_errors = TRUE ) {
839
		// verify the transaction
840
		if ( $this->transaction instanceof EE_Transaction ) {
841
			// save to ensure that TXN has ID
842
			$this->transaction->save();
843
			// grab the saved registrations from the transaction
844
			foreach ( $this->transaction->registrations( $this->reg_cache_where_params ) as  $registration ) {
845
				$this->_save_registration( $registration, $show_errors );
0 ignored issues
show
Compatibility introduced by
$registration of type object<EE_Base_Class> is not a sub-type of object<EE_Registration>. It seems like you assume a child class of the class EE_Base_Class to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
846
			}
847
		} else {
848
			if ( $show_errors ) {
849
				EE_Error::add_error( __( 'A valid Transaction was not found when attempting to save your registration information.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
850
			}
851
			return FALSE;
852
		}
853
		return TRUE;
854
	}
855
856
857
858
	/**
859
	 * _save_registration_attendee
860
	 *
861
	 * @param    EE_Registration $registration
862
	 * @param bool               $show_errors
863
	 * @return void
864
	 * @throws \EE_Error
865
	 */
866
	private function _save_registration( $registration, $show_errors = TRUE  ) {
867
		// verify object
868
		if ( $registration instanceof EE_Registration ) {
869
			// should this registration be processed during this visit ?
870
			if ( $this->visit_allows_processing_of_this_registration( $registration ) ) {
871
				//set TXN ID
872
				if ( ! $registration->transaction_ID() ) {
873
					$registration->set_transaction_id( $this->transaction->ID() );
874
				}
875
				// verify and save the attendee
876
				$this->_save_registration_attendee( $registration, $show_errors );
877
				// save answers to reg form questions
878
				$this->_save_registration_answers( $registration, $show_errors );
879
				// save changes
880
				$registration->save();
881
				// update txn cache
882 View Code Duplication
				if ( ! $this->transaction->update_cache_after_object_save( 'Registration', $registration )) {
883
					if ( $show_errors ) {
884
						EE_Error::add_error( __( 'The newly saved Registration object could not be cached on the Transaction.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
885
					}
886
				}
887
			}
888
		} else {
889
			if ( $show_errors ) {
890
				EE_Error::add_error(
891
					__( 'An invalid Registration object was discovered when attempting to save your registration information.', 'event_espresso' ),
892
					__FILE__, __FUNCTION__, __LINE__
893
				);
894
			}
895
		}
896
	}
897
898
899
900
	/**
901
	 * _save_registration_attendee
902
	 *
903
	 * @param    EE_Registration $registration
904
	 * @param bool               $show_errors
905
	 * @return void
906
	 * @throws \EE_Error
907
	 */
908
	private function _save_registration_attendee( $registration, $show_errors = TRUE ) {
909
		if ( $registration->attendee() instanceof EE_Attendee ) {
910
			// save so that ATT has ID
911
			$registration->attendee()->save();
912 View Code Duplication
			if ( ! $registration->update_cache_after_object_save( 'Attendee', $registration->attendee() ) ) {
913
				if ( $show_errors ) {
914
					EE_Error::add_error(
915
						__( 'The newly saved Attendee object could not be cached on the registration.', 'event_espresso' ),
916
						__FILE__, __FUNCTION__, __LINE__
917
					);
918
				}
919
			}
920 View Code Duplication
		} else {
921
			if ( $show_errors ) {
922
				EE_Error::add_error(
923
					sprintf(
924
						'%1$s||%1$s $attendee = %2$s',
925
						__( 'Either no Attendee information was found, or an invalid Attendee object was discovered when attempting to save your registration information.', 'event_espresso' ),
926
						var_export( $registration->attendee(), true )
927
					),
928
					__FILE__, __FUNCTION__, __LINE__
929
				);
930
			}
931
		}
932
	}
933
934
935
936
	/**
937
	 * _save_question_answers
938
	 *
939
	 * @param    EE_Registration $registration
940
	 * @param bool               $show_errors
941
	 * @return void
942
	 * @throws \EE_Error
943
	 */
944
	private function _save_registration_answers( $registration, $show_errors = TRUE ) {
945
		// now save the answers
946
		foreach ( $registration->answers() as $cache_key => $answer ) {
947
			// verify object
948
			if ( $answer instanceof EE_Answer ) {
949
				$answer->set_registration( $registration->ID() );
950
				$answer->save();
951
				if ( ! $registration->update_cache_after_object_save( 'Answer', $answer, $cache_key )) {
952
					if ( $show_errors ) {
953
						EE_Error::add_error(
954
							__( 'The newly saved Answer object could not be cached on the registration.', 'event_espresso' ),
955
							__FILE__, __FUNCTION__, __LINE__
956
						);
957
					}
958
				}
959
			} else {
960
				if ( $show_errors ) {
961
					EE_Error::add_error(
962
						__( 'An invalid Answer object was discovered when attempting to save your registration information.', 'event_espresso' ),
963
						__FILE__, __FUNCTION__, __LINE__
964
					);
965
				}
966
			}
967
		}
968
	}
969
970
971
972
	/**
973
	 *    refresh_all_entities
974
	 *   will either refresh the entity map with objects form the db or from the checkout cache
975
	 *
976
	 * @access public
977
	 * @param bool $from_db
978
	 * @return bool
979
	 * @throws \EE_Error
980
	 */
981
	public function refresh_all_entities( $from_db = false ) {
982
		$from_db = $this->current_step->is_final_step() || $this->action === 'process_gateway_response'
983
			? true
984
			: $from_db;
985
		//$this->log(
986
		//	__CLASS__, __FUNCTION__, __LINE__,
987
		//	array( 'from_db' =>$from_db )
988
		//);
989
		return $from_db ? $this->refresh_from_db() : $this->refresh_entity_map();
990
	}
991
992
993
994
	/**
995
	 *  refresh_entity_map
996
	 *  simply loops through the current transaction and updates each
997
	 *  model's entity map using EEM_Base::refresh_entity_map_from_db()
998
	 *
999
	 * @access public
1000
	 * @return bool
1001
	 * @throws \EE_Error
1002
	 */
1003
	protected function refresh_from_db() {
1004
		// verify the transaction
1005
		if ( $this->transaction instanceof EE_Transaction && $this->transaction->ID() ) {
1006
			// pull fresh TXN data from the db
1007
			$this->transaction = $this->transaction->get_model()->refresh_entity_map_from_db( $this->transaction->ID() );
1008
			// update EE_Checkout's cached primary_attendee object
1009
			$this->primary_attendee_obj = $this->_refresh_primary_attendee_obj_from_db( $this->transaction );
1010
			// update EE_Checkout's cached payment object
1011
			$payment = $this->transaction->last_payment();
1012
			$this->payment = $payment instanceof EE_Payment ? $payment : $this->payment;
1013
			// update EE_Checkout's cached payment_method object
1014
			$payment_method = $this->payment instanceof EE_Payment ? $this->payment->payment_method() : null;
1015
			$this->payment_method = $payment_method instanceof EE_Payment_Method ? $payment_method : $this->payment_method;
1016
			//now refresh the cart, based on the TXN
1017
			$this->cart = $this->get_cart_for_transaction( $this->transaction );
1018
		} else {
1019
			EE_Error::add_error( __( 'A valid Transaction was not found when attempting to update the model entity mapper.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
1020
			return FALSE;
1021
		}
1022
		return TRUE;
1023
	}
1024
1025
1026
1027
	/**
1028
	 * _refresh_primary_attendee_obj_from_db
1029
	 *
1030
	 * @param   EE_Transaction $transaction
1031
	 * @return  EE_Attendee | null
1032
	 * @throws \EE_Error
1033
	 */
1034
	protected function _refresh_primary_attendee_obj_from_db( EE_Transaction $transaction ) {
1035
1036
		$primary_attendee_obj = null;
1037
		// grab the saved registrations from the transaction
1038
		foreach ( $transaction->registrations( $this->reg_cache_where_params, true ) as $registration ) {
1039
			// verify object
1040
			if ( $registration instanceof EE_Registration ) {
1041
				$attendee = $registration->attendee();
1042
				// verify object && maybe cache primary_attendee_obj ?
1043
				if ( $attendee instanceof EE_Attendee&& $registration->is_primary_registrant() ) {
1044
					$primary_attendee_obj = $attendee;
1045
				}
1046
			} else {
1047
				EE_Error::add_error(
1048
						__( 'An invalid Registration object was discovered when attempting to update the model entity mapper.', 'event_espresso' ),
1049
						__FILE__, __FUNCTION__, __LINE__
1050
				);
1051
			}
1052
		}
1053
		return $primary_attendee_obj;
1054
	}
1055
1056
1057
1058
	/**
1059
	 *  refresh_entity_map
1060
	 *  simply loops through the current transaction and updates
1061
	 *  each model's entity map using EEM_Base::refresh_entity_map_with()
1062
	 *
1063
	 * @access public
1064
	 * @return bool
1065
	 * @throws \EE_Error
1066
	 */
1067
	protected function refresh_entity_map() {
1068
		// verify the transaction
1069
		if ( $this->transaction instanceof EE_Transaction && $this->transaction->ID() ) {
1070
			// never cache payment info
1071
			$this->transaction->clear_cache( 'Payment' );
1072
			// is the Payment Options Reg Step completed ?
1073
			if ( $this->transaction->reg_step_completed( 'payment_options' ) ) {
1074
				// then check for payments and update TXN accordingly
1075
				/** @type EE_Transaction_Payments $transaction_payments */
1076
				$transaction_payments = EE_Registry::instance()->load_class( 'Transaction_Payments' );
1077
				$transaction_payments->calculate_total_payments_and_update_status( $this->transaction );
1078
			}
1079
			// grab the saved registrations from the transaction
1080
			foreach (
1081
				$this->transaction->registrations( $this->reg_cache_where_params ) as $reg_cache_ID => $registration
1082
			) {
1083
				$this->_refresh_registration( $reg_cache_ID, $registration );
0 ignored issues
show
Compatibility introduced by
$registration of type object<EE_Base_Class> is not a sub-type of object<EE_Registration>. It seems like you assume a child class of the class EE_Base_Class to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
1084
			}
1085
			// make sure our cached TXN is added to the model entity mapper
1086
			$this->transaction = $this->transaction->get_model()->refresh_entity_map_with( $this->transaction->ID(), $this->transaction );
1087
1088
		} else {
1089
			EE_Error::add_error( __( 'A valid Transaction was not found when attempting to update the model entity mapper.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
1090
			return FALSE;
1091
		}
1092
		// verify and update the cart because inaccurate totals are not so much fun
1093
		if ( $this->cart instanceof EE_Cart ) {
1094
			$grand_total = $this->cart->get_grand_total();
1095
			if ( $grand_total instanceof EE_Line_Item && $grand_total->ID() ) {
1096
				$grand_total->recalculate_total_including_taxes();
1097
				$grand_total = $grand_total->get_model()->refresh_entity_map_with(
1098
					$this->cart->get_grand_total()->ID(),
1099
					$this->cart->get_grand_total()
1100
				);
1101
			}
1102
			if ( $grand_total instanceof EE_Line_Item ) {
1103
				$this->cart = EE_Cart::instance( $grand_total );
1104
			} else {
1105
				EE_Error::add_error( __( 'A valid Cart was not found when attempting to update the model entity mapper.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__ );
1106
				return false;
1107
			}
1108
		}
1109
		return TRUE;
1110
	}
1111
1112
1113
1114
	/**
1115
	 * _refresh_registration
1116
	 *
1117
	 * @param    string | int    $reg_cache_ID
1118
	 * @param    EE_Registration $registration
1119
	 * @return void
1120
	 * @throws \EE_Error
1121
	 */
1122
	protected function _refresh_registration( $reg_cache_ID, $registration ) {
1123
1124
		// verify object
1125 View Code Duplication
		if ( $registration instanceof EE_Registration ) {
1126
			// update the entity mapper attendee
1127
			$this->_refresh_registration_attendee( $registration );
1128
			// update the entity mapper answers for reg form questions
1129
			$this->_refresh_registration_answers( $registration );
1130
			// make sure the cached registration is added to the model entity mapper
1131
			$registration->get_model()->refresh_entity_map_with( $reg_cache_ID, $registration );
1132
		} else {
1133
			EE_Error::add_error(
1134
				__( 'An invalid Registration object was discovered when attempting to update the model entity mapper.', 'event_espresso' ),
1135
				__FILE__, __FUNCTION__, __LINE__
1136
			);
1137
		}
1138
	}
1139
1140
1141
1142
	/**
1143
	 * _save_registration_attendee
1144
	 *
1145
	 * @param    EE_Registration $registration
1146
	 * @return void
1147
	 * @throws \EE_Error
1148
	 */
1149
	protected function _refresh_registration_attendee( $registration ) {
1150
1151
		$attendee = $registration->attendee();
1152
		// verify object
1153
		if ( $attendee instanceof EE_Attendee && $attendee->ID() ) {
1154
			// make sure the cached attendee is added to the model entity mapper
1155
			$registration->attendee()->get_model()->refresh_entity_map_with( $attendee->ID(), $attendee );
1156
			// maybe cache primary_attendee_obj ?
1157
			if ( $registration->is_primary_registrant() ) {
1158
				$this->primary_attendee_obj = $attendee;
1159
			}
1160
		}
1161
	}
1162
1163
1164
1165
	/**
1166
	 * _refresh_registration_answers
1167
	 *
1168
	 * @param    EE_Registration $registration
1169
	 * @return void
1170
	 * @throws \EE_Error
1171
	 */
1172
	protected function _refresh_registration_answers( $registration ) {
1173
1174
		// now update the answers
1175
		foreach ( $registration->answers() as $cache_key => $answer ) {
1176
			// verify object
1177 View Code Duplication
			if ( $answer instanceof EE_Answer ) {
1178
				if ( $answer->ID() ) {
1179
					// make sure the cached answer is added to the model entity mapper
1180
					$answer->get_model()->refresh_entity_map_with( $answer->ID(), $answer );
1181
				}
1182
			} else {
1183
				EE_Error::add_error(
1184
					__( 'An invalid Answer object was discovered when attempting to update the model entity mapper.', 'event_espresso' ),
1185
					__FILE__, __FUNCTION__, __LINE__
1186
				);
1187
			}
1188
		}
1189
	}
1190
1191
1192
1193
	/**
1194
	 *    __sleep
1195
	 * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon serialization
1196
	 * EE_Checkout will handle the reimplementation of itself upon waking,
1197
	 * but we won't bother with the reg form, because if needed, it will be regenerated anyways
1198
	 *
1199
	 * @return array
1200
	 * @throws \EE_Error
1201
	 */
1202
    public function __sleep()
1203
    {
1204
	    if ( $this->primary_attendee_obj instanceof EE_Attendee && $this->primary_attendee_obj->ID() ) {
1205
		    $this->primary_attendee_obj = $this->primary_attendee_obj->ID();
1206
	    }        // remove the reg form and the checkout
1207
	    if ( $this->transaction instanceof EE_Transaction && $this->transaction->ID() ) {
1208
		    $this->transaction = $this->transaction->ID();
1209
	    }        // remove the reg form and the checkout
1210
        return array_diff( array_keys( get_object_vars( $this ) ), array( 'billing_form', 'registration_form' ) );
1211
    }
1212
1213
1214
	/**
1215
	 * 	__wakeup
1216
	 * to conserve db space, we are removing the EE_Checkout object from EE_SPCO_Reg_Step objects upon serialization
1217
	 * this will reinstate the EE_Checkout object on each EE_SPCO_Reg_Step object
1218
	 */
1219
	public function __wakeup() {
1220
		if ( ! $this->primary_attendee_obj instanceof EE_Attendee && absint( $this->primary_attendee_obj ) !== 0 ) {
1221
			// $this->primary_attendee_obj is actually just an ID, so use it to get the object from the db
1222
			$this->primary_attendee_obj = EEM_Attendee::instance()->get_one_by_ID( $this->primary_attendee_obj );
0 ignored issues
show
Documentation Bug introduced by
It seems like \EEM_Attendee::instance(...->primary_attendee_obj) can also be of type object<EE_Base_Class>. However, the property $primary_attendee_obj is declared as type object<EE_Attendee>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1223
		}
1224
		if ( ! $this->transaction instanceof EE_Transaction && absint( $this->transaction ) !== 0 ) {
1225
			// $this->transaction is actually just an ID, so use it to get the object from the db
1226
			$this->transaction = EEM_Transaction::instance()->get_one_by_ID( $this->transaction );
0 ignored issues
show
Documentation Bug introduced by
It seems like \EEM_Transaction::instan..._ID($this->transaction) can also be of type object<EE_Base_Class>. However, the property $transaction is declared as type object<EE_Transaction>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1227
		}
1228
		foreach ( $this->reg_steps as $reg_step ) {
1229
			$reg_step->checkout = $this;
1230
		}
1231
	}
1232
1233
1234
1235
	/**
1236
	 * debug
1237
	 *
1238
	 * @param string $class
1239
	 * @param string $func
1240
	 * @param string $line
1241
	 * @param array  $info
1242
	 * @param bool   $display_request
1243
	 * @throws \EE_Error
1244
	 */
1245
	public function log( $class = '', $func = '', $line = '', $info = array(), $display_request = false ) {
1246
		$disabled = true;
1247
		if ( WP_DEBUG && ! $disabled ) {
1248
			$debug_data = get_option( 'EE_DEBUG_SPCO_' . EE_Session::instance()->id(), array() );
1249
			$default_data = array(
1250
				$class 		=> $func . '() : ' . $line,
1251
				'request->step' 		=> $this->step,
1252
				'request->action' 	=> $this->action,
1253
				'current_step->slug' => $this->current_step instanceof EE_SPCO_Reg_Step ?
1254
					$this->current_step->slug() : '',
1255
				'current_step->completed' => $this->current_step instanceof EE_SPCO_Reg_Step ?
1256
					$this->current_step->completed() : '',
1257
				'txn_status_updated' => $this->transaction->txn_status_updated(),
1258
				'reg_status_updated' => $this->reg_status_updated,
1259
				'reg_url_link' => $this->reg_url_link,
1260
				'REQ' => $display_request ? $_REQUEST : '',
1261
			);
1262
			if ( $this->transaction instanceof EE_Transaction ) {
1263
				$default_data[ 'TXN_status' ] 		= $this->transaction->status_ID();
1264
				$default_data[ 'TXN_reg_steps' ] 	= $this->transaction->reg_steps();
1265
				foreach ( $this->transaction->registrations( $this->reg_cache_where_params ) as $REG_ID => $registration ) {
1266
					$default_data[ 'registrations' ][ $REG_ID ] = $registration->status_ID();
0 ignored issues
show
Documentation Bug introduced by
The method status_ID does not exist on object<EE_Base_Class>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
1267
				}
1268
				if ( $this->transaction->ID() ) {
1269
					$TXN_ID = 'EE_Transaction: ' . $this->transaction->ID();
1270
					// don't serialize objects
1271
					$info = $this->_strip_objects( $info );
1272
					if ( ! isset( $debug_data[ $TXN_ID ] ) ) {
1273
						$debug_data[ $TXN_ID ] = array();
1274
					}
1275
					$debug_data[ $TXN_ID ][ microtime() ] = array_merge(
1276
						$default_data,
1277
						$info
1278
					);
1279
					update_option( 'EE_DEBUG_SPCO_' . EE_Session::instance()->id(), $debug_data );
1280
				}
1281
			}
1282
		}
1283
	}
1284
1285
1286
	/**
1287
	 * _strip_objects
1288
	 *
1289
	 * @param array $info
1290
	 * @return array
1291
	 */
1292
	public function _strip_objects( $info = array() ) {
1293
		foreach ( (array)$info as $key => $value ) {
1294 View Code Duplication
			if ( is_array( $value )) {
1295
				$info[ $key ] = $this->_strip_objects( $value );
1296
			} else if ( is_object( $value ) ) {
1297
				$object_class = get_class( $value );
1298
				$info[ $object_class ] = array();
1299
				$info[ $object_class ][ 'ID' ] = method_exists( $value, 'ID' ) ? $value->ID() : 0;
1300
				if ( method_exists( $value, 'status' ) ) {
1301
					$info[ $object_class ][ 'status' ] = $value->status();
1302
				} else if ( method_exists( $value, 'status_ID' ) ) {
1303
					$info[ $object_class ][ 'status' ] = $value->status_ID();
1304
				}
1305
				unset( $info[ $key ] );
1306
			}
1307
		}
1308
		return (array)$info;
1309
	}
1310
1311
1312
1313
1314
}
1315
// End of file EE_Checkout.class.php
1316
// Location: /EE_Checkout.class.php