Completed
Branch FET-8284-automagic-dependency-... (a299cf)
by
unknown
1189:26 queued 1175:37
created

EE_Checkout   F

Complexity

Total Complexity 165

Size/Duplication

Total Lines 1246
Duplicated Lines 4.49 %

Coupling/Cohesion

Components 1
Dependencies 20

Importance

Changes 0
Metric Value
dl 56
loc 1246
rs 0.6314
c 0
b 0
f 0
wmc 165
lcom 1
cbo 20

44 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
A reg_status_updated() 0 3 2
A set_reg_status_updated() 0 3 1
A exit_spco() 0 3 1
A set_exit_spco() 0 5 2
A reset_for_current_request() 0 14 3
A add_reg_step() 0 3 1
A set_reg_step_order() 0 5 2
C set_current_step() 0 23 7
B set_next_step() 0 17 5
A get_next_reg_step() 0 5 2
A get_prev_reg_step() 0 5 2
A sort_reg_steps() 0 4 1
B reg_step_sorting_callback() 0 12 5
A set_reg_step_JSON_info() 0 9 2
A reset_reg_steps() 0 8 1
A get_registration_time_limit() 0 10 2
B payment_required() 0 9 5
A any_reg_status_updated() 0 8 3
A skip_reg_step() 0 10 3
A remove_reg_step() 0 13 3
B find_reg_step() 0 17 5
B set_reg_step_initiated() 0 24 5
A get_cart_for_transaction() 0 10 3
A initialize_txn_reg_steps_array() 0 7 2
B update_txn_reg_steps_array() 0 14 5
A stash_transaction_and_checkout() 0 10 2
B track_transaction_and_registration_status_updates() 0 21 6
B visit_allows_processing_of_this_registration() 0 3 5
A transaction_has_primary_registrant() 0 3 2
A save_all_data() 0 17 4
C _save_registration() 5 31 7
B _save_registration_attendee() 8 27 5
B _save_registration_answers() 0 25 6
A refresh_all_entities() 0 8 4
B refresh_from_db() 0 21 6
B _refresh_primary_attendee_obj_from_db() 0 24 5
D refresh_entity_map() 6 44 9
A _refresh_registration() 13 17 2
A _refresh_registration_attendee() 0 13 4
A _refresh_registration_answers() 11 18 4
A __wakeup() 0 5 2
D log() 0 38 10
B _strip_objects() 13 18 7

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like EE_Checkout often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EE_Checkout, and based on these observations, apply Extract Interface, too.

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
	 * total number of tickets that were in the cart
82
	 * @type int
83
	 */
84
	public $total_ticket_count = 0;
85
86
	/**
87
	 * corresponds loosely to EE_Transaction::remaining()
88
	 * but can be modified by SPCO
89
	 *
90
	 * @type float
91
	 */
92
	public $amount_owing = 0;
93
94
	/**
95
	 * the reg step slug from the incoming request
96
	 * @type string
97
	 */
98
	public $step = '';
99
100
	/**
101
	 * the reg step slug for a step being edited
102
	 * @type string
103
	 */
104
	public $edit_step = '';
105
106
	/**
107
	 * the action being performed on the current step
108
	 * @type string
109
	 */
110
	public $action = '';
111
112
	/**
113
	 * reg_url_link for a previously saved registration
114
	 * @type string
115
	 */
116
	public $reg_url_link = '';
117
118
	/**
119
	 * string slug for the payment method that was selected during the payment options step
120
	 * @type string
121
	 */
122
	public $selected_method_of_payment = '';
123
124
	/**
125
	 * base url for the site's registration checkout page - additional url params will be added to this
126
	 * @type string
127
	 */
128
	public $reg_page_base_url = '';
129
130
	/**
131
	 * base url for the site's registration cancelled page - additional url params will be added to this
132
	 * @type string
133
	 */
134
	public $cancel_page_url = '';
135
136
	/**
137
	 * base url for the site's thank you page - additional url params will be added to this
138
	 * @type string
139
	 */
140
	public $thank_you_page_url = '';
141
142
	/**
143
	 * base url for any redirects - additional url params will be added to this
144
	 * @type string
145
	 */
146
	public $redirect_url = '';
147
148
	/**
149
	 * form of POST data for use with off-site gateways
150
	 * @type string
151
	 */
152
	public $redirect_form = '';
153
154
	/**
155
	 * array of query where params to use when retrieving cached registrations from $this->checkout->transaction
156
	 * @type array
157
	 */
158
	public $reg_cache_where_params = array();
159
160
	/**
161
	 * a class for managing and creating the JSON encoded array of data that gets passed back to the client during AJAX requests
162
	 * @type EE_SPCO_JSON_Response
163
	 */
164
	public $json_response = NULL;
165
166
	/**
167
	 * where we are going next in the reg process
168
	 * @type EE_SPCO_Reg_Step
169
	 */
170
	public $next_step = NULL;
171
172
	/**
173
	 * where we are in the reg process
174
	 * @type EE_SPCO_Reg_Step
175
	 */
176
	public $current_step = NULL;
177
178
	/**
179
	 * 	$_cart - the current cart object
180
	 *	@var EE_CART
181
	 */
182
	public $cart = NULL;
183
184
	/**
185
	 * 	$_transaction - the current transaction object
186
	 *	@var EE_Transaction
187
	 */
188
	public $transaction = NULL;
189
190
	/**
191
	 * 	the related attendee object for the primary registrant
192
	 * @type EE_Attendee
193
	 */
194
	public $primary_attendee_obj = NULL;
195
196
	/**
197
	 *	$payment_method - the payment method object for the selected method of payment
198
	 *	@type EE_Payment_Method
199
	 */
200
	public $payment_method = NULL;
201
202
	/**
203
	 * 	$payment - if a payment was successfully made during the reg process,
204
	 * 	then here it is !!!
205
	 *	@type EE_Payment
206
	 */
207
	public $payment = NULL;
208
209
	/**
210
	 * 	if a payment method was selected that uses an on-site gateway, then this is the billing form
211
	 * @type EE_Billing_Info_Form | EE_Billing_Attendee_Info_Form
212
	 */
213
	public $billing_form = NULL;
214
215
	/**
216
	 * 	the entire registration form composed of ALL of the subsections generated by the various reg steps
217
	 * @type EE_Form_Section_Proper
218
	 */
219
	public $registration_form = NULL;
220
221
	/**
222
	 * array of EE_SPCO_Reg_Step objects
223
	 * @type EE_SPCO_Reg_Step[]
224
	 */
225
	public $reg_steps = array();
226
227
	/**
228
	 * array of EE_Payment_Method objects
229
	 * @type EE_Payment_Method[]
230
	 */
231
	public $available_payment_methods = array();
232
233
234
235
	/**
236
	 *    class constructor
237
	 *
238
	 * @access    public
239
	 * @return    \EE_Checkout
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
240
	 */
241
	public function __construct(  ) {
242
		$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...
243
		$this->thank_you_page_url = EE_Registry::instance()->CFG->core->thank_you_page_url();
244
		$this->cancel_page_url = EE_Registry::instance()->CFG->core->cancel_page_url();
245
		$this->continue_reg = apply_filters( 'FHEE__EE_Checkout___construct___continue_reg', TRUE );
246
		$this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->ajax;
247
		$this->reg_cache_where_params = array( 'order_by' => array( 'REG_count' => 'ASC' ));
248
	}
249
250
251
252
	/**
253
	 * returns true if ANY reg status was updated during checkout
254
	 * @return array
255
	 */
256
	public function any_reg_status_updated() {
257
		foreach ( $this->reg_status_updated as $reg_status ) {
258
			if ( $reg_status ) {
259
				return true;
260
			}
261
		}
262
		return false;
263
	}
264
265
266
267
	/**
268
	 * @param $REG_ID
269
	 * @return array
270
	 */
271
	public function reg_status_updated( $REG_ID ) {
272
		return isset( $this->reg_status_updated[ $REG_ID ] ) ? $this->reg_status_updated[ $REG_ID ] : false;
273
	}
274
275
276
277
	/**
278
	 * @param $REG_ID
279
	 * @param $reg_status
280
	 */
281
	public function set_reg_status_updated( $REG_ID, $reg_status ) {
282
		$this->reg_status_updated[ $REG_ID ] = filter_var( $reg_status, FILTER_VALIDATE_BOOLEAN );
283
	}
284
285
286
287
	/**
288
	 * exit_spco
289
	 *
290
	 * @return bool
291
	 */
292
	public function exit_spco() {
293
		return $this->exit_spco;
294
	}
295
296
297
298
	/**
299
	 * set_exit_spco
300
	 * can ONLY be set by the  Finalize_Registration reg step
301
	 */
302
	public function set_exit_spco() {
303
		if ( $this->current_step instanceof EE_SPCO_Reg_Step_Finalize_Registration ) {
304
			$this->exit_spco = true;
305
		}
306
	}
307
308
309
310
311
312
	/**
313
	 *    reset_for_current_request
314
	 *
315
	 * @access    public
316
	 * @return    void
317
	 */
318
	public function reset_for_current_request() {
319
		$this->process_form_submission = FALSE;
320
		$this->continue_reg = apply_filters( 'FHEE__EE_Checkout___construct___continue_reg', true );
321
		$this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->front_ajax;
322
		$this->continue_reg = true;
323
		$this->redirect = false;
324
		// don't reset the cached redirect form if we're about to be asked to display it !!!
325
		if ( EE_Registry::instance()->REQ->get( 'action', 'display_spco_reg_step' ) !== 'redirect_form' ) {
326
			$this->redirect_form = '';
327
		}
328
		$this->redirect_url = '';
329
		$this->json_response = new EE_SPCO_JSON_Response();
330
		EE_Form_Section_Proper::reset_js_localization();
331
	}
332
333
334
335
	/**
336
	 *    add_reg_step
337
	 *
338
	 * @access    public
339
	 * @param EE_SPCO_Reg_Step $reg_step_obj
340
	 * @return    void
341
	 */
342
	public function add_reg_step( EE_SPCO_Reg_Step $reg_step_obj ) {
343
		$this->reg_steps[ $reg_step_obj->slug()  ] = $reg_step_obj;
344
	}
345
346
347
348
	/**
349
	 * skip_reg_step
350
	 *
351
	 * if the current reg step does not need to run for some reason,
352
	 * then this will advance SPCO to the next reg step,
353
	 * and mark the skipped step as completed
354
	 *
355
	 * @access    public
356
	 * @param string $reg_step_slug
357
	 * @return    void
358
	 */
359
	public function skip_reg_step( $reg_step_slug = '' ) {
360
		$step_to_skip = $this->find_reg_step( $reg_step_slug );
361
		if ( $step_to_skip instanceof EE_SPCO_Reg_Step && $step_to_skip->is_current_step() ) {
362
			// advance to the next step
363
			$this->set_current_step( $this->next_step->slug() );
364
			$step_to_skip->set_is_current_step( false );
365
			$step_to_skip->set_completed();
366
			$this->set_reg_step_initiated( $this->current_step );
367
		}
368
	}
369
370
371
372
	/**
373
	 *    remove_reg_step
374
	 *
375
	 * @access    public
376
	 * @param string $reg_step_slug
377
	 * @param bool   $reset whether to reset reg steps after removal
378
	 * @throws EE_Error
379
	 */
380
	public function remove_reg_step( $reg_step_slug = '', $reset = true ) {
381
		unset( $this->reg_steps[ $reg_step_slug  ] );
382
		if ( $this->transaction instanceof EE_Transaction ) {
383
			/** @type EE_Transaction_Processor $transaction_processor */
384
			$transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' );
385
			// now remove reg step from TXN and save
386
			$transaction_processor->remove_reg_step( $this->transaction, $reg_step_slug );
387
			$this->transaction->save();
388
		}
389
		if ( $reset ) {
390
			$this->reset_reg_steps();
391
		}
392
	}
393
394
395
396
	/**
397
	 *    set_reg_step_order
398
	 *
399
	 * @access    public
400
	 * @param string $reg_step_slug
401
	 * @param int    $order
402
	 * @return    void
403
	 */
404
	public function set_reg_step_order( $reg_step_slug = '', $order = 100 ) {
405
		if ( isset( $this->reg_steps[ $reg_step_slug  ] )) {
406
			$this->reg_steps[ $reg_step_slug ]->set_order( $order );
407
		}
408
	}
409
410
411
412
	/**
413
	 *    set_current_step
414
	 *
415
	 * @access    public
416
	 * @param string $current_step
417
	 * @return    void
418
	 */
419
	public function set_current_step( $current_step ) {
420
		// grab what step we're on
421
		$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...
422
		// verify instance
423
		if ( $this->current_step instanceof EE_SPCO_Reg_Step ) {
424
			// we don't want to repeat completed steps if this is the first time through SPCO
425
			if ( $this->continue_reg && $this->current_step->completed() && ! $this->revisit ) {
426
				// so advance to the next step
427
				$this->set_next_step();
428
				if ( $this->next_step instanceof EE_SPCO_Reg_Step ) {
429
					// and attempt to set it as the current step
430
					$this->set_current_step( $this->next_step->slug() );
431
				}
432
				return;
433
			}
434
			$this->current_step->set_is_current_step( TRUE );
435
		} else {
436
			EE_Error::add_error(
437
				__( 'The current step could not be set.', 'event_espresso' ),
438
				__FILE__, __FUNCTION__, __LINE__
439
			);
440
		}
441
	}
442
443
444
445
	/**
446
	 * 	set_next_step
447
	 * advances the reg_steps array pointer and sets the next step, then reverses pointer back to the current step
448
	 *
449
	 *  @access 	public
450
	 *  @return 	void
451
	 */
452
	public function set_next_step() {
453
		// set pointer to start of array
454
		reset( $this->reg_steps );
455
		// if there is more than one step
456
		if ( count( $this->reg_steps ) > 1 ) {
457
			// advance to the current step and set pointer
458
			while ( key( $this->reg_steps ) != $this->current_step->slug() && key( $this->reg_steps ) != '' ) {
459
				next( $this->reg_steps );
460
			}
461
		}
462
		// advance one more spot ( if it exists )
463
		$this->next_step = next( $this->reg_steps );
464
		// verify instance
465
		$this->next_step = $this->next_step instanceof EE_SPCO_Reg_Step ? $this->next_step  : NULL;
466
		// then back to current step to reset
467
		prev( $this->reg_steps );
468
	}
469
470
471
472
473
	/**
474
	 * 	get_next_reg_step
475
	 * 	this simply returns the next step from reg_steps array
476
	 *
477
	 *  @access 	public
478
	 *  @return 	EE_SPCO_Reg_Step | null
479
	 */
480
	public function get_next_reg_step() {
481
		$next = next( $this->reg_steps );
482
		prev( $this->reg_steps );
483
		return $next instanceof EE_SPCO_Reg_Step ? $next : null;
484
	}
485
486
487
488
489
	/**
490
	 * get_prev_reg_step
491
	 * 	this simply returns the previous step from reg_steps array
492
	 *
493
	 *  @access 	public
494
	 *  @return 	EE_SPCO_Reg_Step | null
495
	 */
496
	public function get_prev_reg_step() {
497
		$prev = prev( $this->reg_steps );
498
		next( $this->reg_steps );
499
		return $prev instanceof EE_SPCO_Reg_Step ? $prev : null;
500
	}
501
502
503
504
	/**
505
	 * sort_reg_steps
506
	 *
507
	 * @access public
508
	 * @return void
509
	 */
510
	public function sort_reg_steps() {
511
		$reg_step_sorting_callback = apply_filters( 'FHEE__EE_Checkout__sort_reg_steps__reg_step_sorting_callback', 'reg_step_sorting_callback' );
512
		uasort( $this->reg_steps, array( $this, $reg_step_sorting_callback ));
513
	}
514
515
516
517
	/**
518
	 * find_reg_step
519
	 * finds a reg step by the given slug
520
	 *
521
	 * @access    public
522
	 * @param string $reg_step_slug
523
	 * @return EE_SPCO_Reg_Step|null
524
	 */
525
	public function find_reg_step( $reg_step_slug = '' ) {
526
		if ( ! empty( $reg_step_slug ) ) {
527
			// copy reg step array
528
			$reg_steps = $this->reg_steps;
529
			// set pointer to start of array
530
			reset( $reg_steps );
531
			// if there is more than one step
532
			if ( count( $reg_steps ) > 1 ) {
533
				// advance to the current step and set pointer
534
				while ( key( $reg_steps ) != $reg_step_slug && key( $reg_steps ) != '' ) {
535
					next( $reg_steps );
536
				}
537
				return current( $reg_steps );
538
			}
539
		}
540
		return null;
541
	}
542
543
544
545
	/**
546
	 * reg_step_sorting_callback
547
	 *
548
	 * @access public
549
	 * @param EE_SPCO_Reg_Step $reg_step_A
550
	 * @param EE_SPCO_Reg_Step $reg_step_B
551
	 * @return array()
0 ignored issues
show
Documentation introduced by
The doc-type array() could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

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

Loading history...
552
	 */
553
	public function reg_step_sorting_callback( EE_SPCO_Reg_Step $reg_step_A, EE_SPCO_Reg_Step $reg_step_B ) {
554
		// send finalize_registration step to the end of the array
555
		if ( $reg_step_A->slug() == 'finalize_registration' ) {
556
			return 1;
557
		} else if ( $reg_step_B->slug() == 'finalize_registration' ) {
558
			return -1;
559
		}
560
		if ( $reg_step_A->order() == $reg_step_B->order() ) {
561
			return 0;
562
		}
563
		return ( $reg_step_A->order() > $reg_step_B->order() ) ? 1 : -1;
564
	}
565
566
567
568
	/**
569
	 * set_reg_step_initiated
570
	 *
571
	 * @access 	public
572
	 * @param 	EE_SPCO_Reg_Step $reg_step
573
	 */
574
	public function set_reg_step_initiated( EE_SPCO_Reg_Step $reg_step ) {
575
		// call set_reg_step_initiated ???
576
		if (
577
			// first time visiting SPCO ?
578
			! $this->revisit
579
			// and displaying the reg step form for the first time ?
580
			&& $this->action === 'display_spco_reg_step'
581
		) {
582
			/** @type EE_Transaction_Processor $transaction_processor */
583
			$transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' );
584
			// set the start time for this reg step
585
			if ( ! $transaction_processor->set_reg_step_initiated( $this->transaction, $reg_step->slug() ) ) {
586
				if ( WP_DEBUG ) {
587
					EE_Error::add_error(
588
						sprintf(
589
							__( 'The "%1$s" registration step was not initialized properly.', 'event_espresso' ),
590
							$reg_step->name()
591
						),
592
						__FILE__, __FUNCTION__, __LINE__
593
					);
594
				}
595
			};
596
		}
597
	}
598
599
600
601
	/**
602
	 * 	set_reg_step_JSON_info
603
	 *
604
	 * 	@access public
605
	 * 	@return 	void
606
	 */
607
	public function set_reg_step_JSON_info() {
608
		EE_Registry::$i18n_js_strings[ 'reg_steps' ] = array();
609
		// pass basic reg step data to JS
610
		foreach ( $this->reg_steps as $reg_step ) {
611
			EE_Registry::$i18n_js_strings[ 'reg_steps' ][] = $reg_step->slug();
612
		}
613
		// reset reg step html
614
//		$this->json_response->set_reg_step_html( '' );
615
	}
616
617
618
619
	/**
620
	 * 	reset_reg_steps
621
	 *
622
	 * 	@access public
623
	 * 	@return 	bool
624
	 */
625
	public function reset_reg_steps() {
626
		$this->sort_reg_steps();
627
		$this->set_current_step( EE_Registry::instance()->REQ->get( 'step' ));
628
		$this->set_next_step();
629
		// the text that appears on the reg step form submit button
630
		$this->current_step->set_submit_button_text();
631
		$this->set_reg_step_JSON_info();
632
	}
633
634
635
636
	/**
637
	 *    get_registration_time_limit
638
	 *
639
	 * @access    public
640
	 * @return        string
641
	 */
642
	public function get_registration_time_limit() {
643
644
		$registration_time_limit = (float)( EE_Registry::instance()	->SSN->expiration() - time() );
645
		$time_limit_format = $registration_time_limit > 60 * MINUTE_IN_SECONDS ? 'H:i:s' : 'i:s';
646
		$registration_time_limit = gmdate( $time_limit_format, $registration_time_limit );
647
		return apply_filters(
648
			'FHEE__EE_Checkout__get_registration_time_limit__registration_time_limit',
649
			$registration_time_limit
650
		);
651
	}
652
653
654
655
	/**
656
	 * payment_required
657
	 * @return boolean
658
	 */
659
	public function payment_required() {
660
		// if NOT:
661
		//		registration via admin
662
		//		completed TXN
663
		//		overpaid TXN
664
		//		free TXN ( total = 0.00 )
665
		// then payment required is TRUE
666
		return ! ( $this->admin_request || $this->transaction->is_completed() || $this->transaction->is_overpaid() || $this->transaction->is_free() ) ? TRUE : FALSE;
667
	}
668
669
670
671
	/**
672
	 * get_cart_for_transaction
673
	 *
674
	 * @access public
675
	 * @param EE_Transaction $transaction
676
	 * @return EE_Cart
677
	 */
678
	public function get_cart_for_transaction( $transaction ) {
679
		$session = EE_Registry::instance()->load_core( 'Session' );
680
		$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 679 can also be of type 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...
681
		// verify cart
682
		if ( ! $cart instanceof EE_Cart ) {
683
			$cart = EE_Registry::instance()->load_core( 'Cart' );
684
		}
685
686
		return $cart;
687
	}
688
689
690
691
	/**
692
	 * 	initialize_txn_reg_steps_array
693
	 *
694
	 * 	@access public
695
	 * 	@return 	array
696
	 */
697
	public function initialize_txn_reg_steps_array() {
698
		$txn_reg_steps_array = array();
699
		foreach ( $this->reg_steps as $reg_step ) {
700
			$txn_reg_steps_array[ $reg_step->slug() ] = FALSE;
701
		}
702
		return $txn_reg_steps_array;
703
	}
704
705
706
707
	/**
708
	 * 	update_txn_reg_steps_array
709
	 *
710
	 * 	@access public
711
	 * 	@return 	bool
712
	 */
713
	public function update_txn_reg_steps_array() {
714
		$updated = FALSE;
715
		/** @type EE_Transaction_Processor $transaction_processor */
716
		$transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' );
717
		foreach ( $this->reg_steps as $reg_step ) {
718
			if ( $reg_step->completed() ) {
719
				$updated = $transaction_processor->set_reg_step_completed( $this->transaction, $reg_step->slug() ) ? TRUE : $updated;
720
			}
721
		}
722
		if ( $updated ) {
723
			$this->transaction->save();
724
		}
725
		return $updated;
726
	}
727
728
729
730
	/**
731
	 * 	stash_transaction_and_checkout
732
	 *
733
	 * 	@access public
734
	 * 	@return 	void
735
	 */
736
	public function stash_transaction_and_checkout() {
737
		if ( ! $this->revisit ) {
738
			$this->update_txn_reg_steps_array();
739
		}
740
		$this->track_transaction_and_registration_status_updates();
741
		// save all data to the db, but suppress errors
742
		//$this->save_all_data( FALSE );
743
		// cache the checkout in the session
744
		EE_Registry::instance()->SSN->set_checkout( $this );
745
	}
746
747
748
749
750
	/**
751
	 *    track_transaction_and_registration_status_updates
752
	 *
753
	 * 	stores whether any updates were made to the TXN or it's related registrations
754
	 *
755
	 * 	@access public
756
	 * 	@return 	bool
757
	 */
758
	public function track_transaction_and_registration_status_updates() {
759
		// verify the transaction
760
		if ( $this->transaction instanceof EE_Transaction ) {
761
			/** @type EE_Transaction_Payments $transaction_payments */
762
			$transaction_payments = EE_Registry::instance()->load_class( 'Transaction_Payments' );
763
			/** @type EE_Transaction_Processor $transaction_processor */
764
			$transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' );
765
			// has there been a TXN status change during this checkout?
766
			if ( $transaction_payments->txn_status_updated() || $transaction_processor->txn_status_updated() ) {
767
				$this->txn_status_updated = true;
768
			}
769
			/** @type EE_Registration_Processor $registration_processor */
770
			$registration_processor = EE_Registry::instance()->load_class( 'Registration_Processor' );
771
			// grab the saved registrations from the transaction
772
			foreach ( $this->transaction->registrations( $this->reg_cache_where_params ) as $registration ) {
773
				if ( $registration_processor->reg_status_updated( $registration->ID() ) ) {
774
					$this->set_reg_status_updated( $registration->ID(), true );
775
				}
776
			}
777
		}
778
	}
779
780
781
782
783
	/**
784
	 * 	visit_allows_processing_of_this_registration
785
	 *
786
	 * 	determines if the current SPCO visit should allow the passed EE_Registration to be used in processing.
787
	 * 	one of the following conditions must be met:
788
	 * 		EITHER: 	A) first time thru SPCO -> process ALL registrations ( NOT a revisit )
789
	 * 		OR : 		B) primary registrant is editing info -> process ALL registrations ( primary_revisit )
790
	 * 		OR : 		C) another registrant is editing info -> ONLY process their registration ( revisit AND their reg_url_link matches )
791
	 *
792
	 * 	@access public
793
	 * @param 	EE_Registration 	$registration
794
	 * 	@return 	bool
795
	 */
796
	public function visit_allows_processing_of_this_registration( EE_Registration $registration ) {
797
		return ! $this->revisit || $this->primary_revisit || ( $this->revisit && $this->reg_url_link == $registration->reg_url_link() ) ? TRUE : FALSE;
798
	}
799
800
801
802
	/**
803
	 * 	_transaction_has_primary_registration
804
	 *
805
	 * 	@access 		private
806
	 * 	@return 		bool
807
	 */
808
	public function transaction_has_primary_registrant() {
809
		return $this->primary_attendee_obj instanceof EE_Attendee ? TRUE : FALSE;
810
	}
811
812
813
814
	/**
815
	 *    save_all_data
816
	 *    simply loops through the current transaction and saves all data for each registration
817
	 *
818
	 * @access public
819
	 * @param bool $show_errors
820
	 * @return bool
821
	 */
822
	public function save_all_data( $show_errors = TRUE ) {
823
		// verify the transaction
824
		if ( $this->transaction instanceof EE_Transaction ) {
825
			// save to ensure that TXN has ID
826
			$this->transaction->save();
827
			// grab the saved registrations from the transaction
828
			foreach ( $this->transaction->registrations( $this->reg_cache_where_params ) as  $registration ) {
829
				$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...
830
			}
831
		} else {
832
			if ( $show_errors ) {
833
				EE_Error::add_error( __( 'A valid Transaction was not found when attempting to save your registration information.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
834
			}
835
			return FALSE;
836
		}
837
		return TRUE;
838
	}
839
840
841
	/**
842
	 * _save_registration_attendee
843
	 *
844
	 * @param 	EE_Registration 	$registration
845
	 * @param bool $show_errors
846
	 * @return void
847
	 */
848
	private function _save_registration( $registration, $show_errors = TRUE  ) {
849
		// verify object
850
		if ( $registration instanceof EE_Registration ) {
851
			// should this registration be processed during this visit ?
852
			if ( $this->visit_allows_processing_of_this_registration( $registration ) ) {
853
				//set TXN ID
854
				if ( ! $registration->transaction_ID() ) {
855
					$registration->set_transaction_id( $this->transaction->ID() );
856
				}
857
				// verify and save the attendee
858
				$this->_save_registration_attendee( $registration, $show_errors );
859
				// save answers to reg form questions
860
				$this->_save_registration_answers( $registration, $show_errors );
861
				// save changes
862
				$registration->save();
863
				// update txn cache
864 View Code Duplication
				if ( ! $this->transaction->update_cache_after_object_save( 'Registration', $registration )) {
865
					if ( $show_errors ) {
866
						EE_Error::add_error( __( 'The newly saved Registration object could not be cached on the Transaction.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
867
					}
868
				}
869
			}
870
		} else {
871
			if ( $show_errors ) {
872
				EE_Error::add_error(
873
					__( 'An invalid Registration object was discovered when attempting to save your registration information.', 'event_espresso' ),
874
					__FILE__, __FUNCTION__, __LINE__
875
				);
876
			}
877
		}
878
	}
879
880
881
882
	/**
883
	 * _save_registration_attendee
884
	 *
885
	 * @param 	EE_Registration 	$registration
886
	 * @param bool $show_errors
887
	 * @return void
888
	 */
889
	private function _save_registration_attendee( $registration, $show_errors = TRUE ) {
890
		if ( $registration->attendee() instanceof EE_Attendee ) {
891
			// save so that ATT has ID
892
			$registration->attendee()->save();
893 View Code Duplication
			if ( ! $registration->update_cache_after_object_save( 'Attendee', $registration->attendee() )) {
894
				if ( $show_errors ) {
895
					EE_Error::add_error(
896
						__( 'The newly saved Attendee object could not be cached on the registration.', 'event_espresso' ),
897
						__FILE__, __FUNCTION__, __LINE__
898
					);
899
				}
900
			}
901
		} else {
902
			if ( $show_errors ) {
903
				ob_start();
904
				var_dump( $registration->attendee() );
0 ignored issues
show
Security Debugging Code introduced by
var_dump($registration->attendee()); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
905
				EE_Error::add_error(
906
					sprintf(
907
						'%1$s||%1$s $attendee = %2$s',
908
						__( 'Either no Attendee information was found, or an invalid Attendee object was discovered when attempting to save your registration information.', 'event_espresso' ),
909
						ob_get_clean()
910
					),
911
					__FILE__, __FUNCTION__, __LINE__
912
				);
913
			}
914
		}
915
	}
916
917
918
919
	/**
920
	 * _save_question_answers
921
	 *
922
	 * @param 	EE_Registration 	$registration
923
	 * @param bool $show_errors
924
	 * @return void
925
	 */
926
	private function _save_registration_answers( $registration, $show_errors = TRUE ) {
927
		// now save the answers
928
		foreach ( $registration->answers() as $cache_key => $answer ) {
929
			// verify object
930
			if ( $answer instanceof EE_Answer ) {
931
				$answer->set_registration( $registration->ID() );
932
				$answer->save();
933
				if ( ! $registration->update_cache_after_object_save( 'Answer', $answer, $cache_key )) {
934
					if ( $show_errors ) {
935
						EE_Error::add_error(
936
							__( 'The newly saved Answer object could not be cached on the registration.', 'event_espresso' ),
937
							__FILE__, __FUNCTION__, __LINE__
938
						);
939
					}
940
				}
941
			} else {
942
				if ( $show_errors ) {
943
					EE_Error::add_error(
944
						__( 'An invalid Answer object was discovered when attempting to save your registration information.', 'event_espresso' ),
945
						__FILE__, __FUNCTION__, __LINE__
946
					);
947
				}
948
			}
949
		}
950
	}
951
952
953
954
	/**
955
	 *    refresh_all_entities
956
	 *   will either refresh the entity map with objects form the db or from the checkout cache
957
	 *
958
	 * @access public
959
	 * @param bool $from_db
960
	 * @return bool
961
	 */
962
	public function refresh_all_entities( $from_db = false ) {
963
		$from_db = $this->current_step->is_final_step() || $this->action == 'process_gateway_response' ? true : $from_db;
964
		//$this->log(
965
		//	__CLASS__, __FUNCTION__, __LINE__,
966
		//	array( 'from_db' =>$from_db )
967
		//);
968
		return $from_db ? $this->refresh_from_db() : $this->refresh_entity_map();
969
	}
970
971
972
973
	/**
974
	 *  refresh_entity_map
975
	 *  simply loops through the current transaction and updates each
976
	 *  model's entity map using EEM_Base::refresh_entity_map_from_db()
977
	 *
978
	 * @access public
979
	 * @return bool
980
	 */
981
	protected function refresh_from_db() {
982
		// verify the transaction
983
		if ( $this->transaction instanceof EE_Transaction && $this->transaction->ID() ) {
984
			// pull fresh TXN data from the db
985
			$this->transaction = $this->transaction->get_model()->refresh_entity_map_from_db( $this->transaction->ID() );
986
			// update EE_Checkout's cached primary_attendee object
987
			$this->primary_attendee_obj = $this->_refresh_primary_attendee_obj_from_db( $this->transaction );
988
			// update EE_Checkout's cached payment object
989
			$payment = $this->transaction->last_payment();
990
			$this->payment = $payment instanceof EE_Payment ? $payment : $this->payment;
991
			// update EE_Checkout's cached payment_method object
992
			$payment_method = $this->payment instanceof EE_Payment ? $this->payment->payment_method() : null;
993
			$this->payment_method = $payment_method instanceof EE_Payment_Method ? $payment_method : $this->payment_method;
994
			//now refresh the cart, based on the TXN
995
			$this->cart = $this->get_cart_for_transaction( $this->transaction );
996
		} else {
997
			EE_Error::add_error( __( 'A valid Transaction was not found when attempting to update the model entity mapper.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
998
			return FALSE;
999
		}
1000
		return TRUE;
1001
	}
1002
1003
1004
1005
	/**
1006
	 * _refresh_primary_attendee_obj_from_db
1007
	 *
1008
	 * @param   EE_Transaction $transaction
1009
	 * @return  EE_Attendee | null
1010
	 */
1011
	protected function _refresh_primary_attendee_obj_from_db( EE_Transaction $transaction ) {
1012
1013
		$primary_attendee_obj = null;
1014
		// grab the saved registrations from the transaction
1015
		foreach ( $transaction->registrations( $this->reg_cache_where_params, true ) as $registration ) {
1016
			// verify object
1017
			if ( $registration instanceof EE_Registration ) {
1018
				$attendee = $registration->attendee();
1019
				// verify object
1020
				if ( $attendee instanceof EE_Attendee  ) {
1021
					// maybe cache primary_attendee_obj ?
1022
					if ( $registration->is_primary_registrant() ) {
1023
						$primary_attendee_obj = $attendee;
1024
					}
1025
				}
1026
			} else {
1027
				EE_Error::add_error(
1028
						__( 'An invalid Registration object was discovered when attempting to update the model entity mapper.', 'event_espresso' ),
1029
						__FILE__, __FUNCTION__, __LINE__
1030
				);
1031
			}
1032
		}
1033
		return $primary_attendee_obj;
1034
	}
1035
1036
1037
1038
	/**
1039
	 *  refresh_entity_map
1040
	 *  simply loops through the current transaction and updates
1041
	 *  each model's entity map using EEM_Base::refresh_entity_map_with()
1042
	 *
1043
	 * @access public
1044
	 * @return bool
1045
	 */
1046
	protected function refresh_entity_map() {
1047
		// verify the transaction
1048
		if ( $this->transaction instanceof EE_Transaction && $this->transaction->ID() ) {
1049
			// never cache payment info
1050
			$this->transaction->clear_cache( 'Payment' );
1051
			/** @type EE_Transaction_Processor $transaction_processor */
1052
			$transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' );
1053
			// is the Payment Options Reg Step completed ?
1054
			if ( $transaction_processor->reg_step_completed( $this->transaction, 'payment_options' ) ) {
1055
				// then check for payments and update TXN accordingly
1056
				/** @type EE_Transaction_Payments $transaction_payments */
1057
				$transaction_payments = EE_Registry::instance()->load_class( 'Transaction_Payments' );
1058
				$transaction_payments->calculate_total_payments_and_update_status( $this->transaction );
1059
			}
1060
			// grab the saved registrations from the transaction
1061
			foreach ( $this->transaction->registrations( $this->reg_cache_where_params ) as $reg_cache_ID => $registration ) {
1062
				$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...
1063
			}
1064
			// make sure our cached TXN is added to the model entity mapper
1065
			$this->transaction = $this->transaction->get_model()->refresh_entity_map_with( $this->transaction->ID(), $this->transaction );
1066
1067
		} else {
1068
			EE_Error::add_error( __( 'A valid Transaction was not found when attempting to update the model entity mapper.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
1069
			return FALSE;
1070
		}
1071
		// verify and update the cart because inaccurate totals are not so much fun
1072
		if ( $this->cart instanceof EE_Cart ) {
1073
			$grand_total = $this->cart->get_grand_total();
1074
			if ( $grand_total instanceof EE_Line_Item && $grand_total->ID() ) {
1075
				$grand_total->recalculate_total_including_taxes();
1076
				$grand_total = $grand_total->get_model()->refresh_entity_map_with(
1077
					$this->cart->get_grand_total()->ID(),
0 ignored issues
show
Documentation introduced by
$this->cart->get_grand_total()->ID() is of type boolean, but the function expects a integer|string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1078
					$this->cart->get_grand_total()
1079
				);
1080
			}
1081 View Code Duplication
			if ( $grand_total instanceof EE_Line_Item ) {
1082
				$this->cart = EE_Cart::instance( $grand_total );
1083
			} else {
1084
				EE_Error::add_error( __( 'A valid Cart was not found when attempting to update the model entity mapper.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__ );
1085
				return false;
1086
			}
1087
		}
1088
		return TRUE;
1089
	}
1090
1091
1092
1093
	/**
1094
	 * _refresh_registration
1095
	 *
1096
	 * @param 	string | int 	$reg_cache_ID
1097
	 * @param 	EE_Registration 	$registration
1098
	 * @return void
1099
	 */
1100
	protected function _refresh_registration( $reg_cache_ID, $registration ) {
1101
1102
		// verify object
1103 View Code Duplication
		if ( $registration instanceof EE_Registration ) {
1104
			// update the entity mapper attendee
1105
			$this->_refresh_registration_attendee( $registration );
1106
			// update the entity mapper answers for reg form questions
1107
			$this->_refresh_registration_answers( $registration );
1108
			// make sure the cached registration is added to the model entity mapper
1109
			$registration->get_model()->refresh_entity_map_with( $reg_cache_ID, $registration );
1110
		} else {
1111
			EE_Error::add_error(
1112
				__( 'An invalid Registration object was discovered when attempting to update the model entity mapper.', 'event_espresso' ),
1113
				__FILE__, __FUNCTION__, __LINE__
1114
			);
1115
		}
1116
	}
1117
1118
1119
1120
	/**
1121
	 * _save_registration_attendee
1122
	 *
1123
	 * @param 	EE_Registration 	$registration
1124
	 * @return void
1125
	 */
1126
	protected function _refresh_registration_attendee( $registration ) {
1127
1128
		$attendee = $registration->attendee();
1129
		// verify object
1130
		if ( $attendee instanceof EE_Attendee && $attendee->ID() ) {
1131
			// make sure the cached attendee is added to the model entity mapper
1132
			$registration->attendee()->get_model()->refresh_entity_map_with( $attendee->ID(), $attendee );
1133
			// maybe cache primary_attendee_obj ?
1134
			if ( $registration->is_primary_registrant() ) {
1135
				$this->primary_attendee_obj = $attendee;
1136
			}
1137
		}
1138
	}
1139
1140
1141
1142
	/**
1143
	 * _refresh_registration_answers
1144
	 *
1145
	 * @param 	EE_Registration 	$registration
1146
	 * @return void
1147
	 */
1148
	protected function _refresh_registration_answers( $registration ) {
1149
1150
		// now update the answers
1151
		foreach ( $registration->answers() as $cache_key => $answer ) {
1152
			// verify object
1153 View Code Duplication
			if ( $answer instanceof EE_Answer ) {
1154
				if ( $answer->ID() ) {
1155
					// make sure the cached answer is added to the model entity mapper
1156
					$answer->get_model()->refresh_entity_map_with( $answer->ID(), $answer );
1157
				}
1158
			} else {
1159
				EE_Error::add_error(
1160
					__( 'An invalid Answer object was discovered when attempting to update the model entity mapper.', 'event_espresso' ),
1161
					__FILE__, __FUNCTION__, __LINE__
1162
				);
1163
			}
1164
		}
1165
	}
1166
1167
1168
1169
	/**
1170
	 * 	__wakeup
1171
	 * to conserve db space, we are removing the EE_Checkout object from EE_SPCO_Reg_Step objects upon serialization
1172
	 * this will reinstate the EE_Checkout object on each EE_SPCO_Reg_Step object
1173
	 */
1174
	function __wakeup() {
1175
		foreach ( $this->reg_steps as $reg_step ) {
1176
			$reg_step->checkout = $this;
1177
		}
1178
	}
1179
1180
1181
1182
	/**
1183
	 * debug
1184
	 *
1185
	 * @param string $class
1186
	 * @param string $func
1187
	 * @param string $line
1188
	 * @param array $info
1189
	 * @param bool $display_request
1190
	 */
1191
	function log( $class = '', $func = '', $line = '', $info = array(), $display_request = false ) {
1192
		if ( WP_DEBUG && false ) {
1193
			$debug_data = get_option( 'EE_DEBUG_SPCO_' . EE_Session::instance()->id(), array() );
1194
			$default_data = array(
1195
				$class 		=> $func . '() : ' . $line,
1196
				'request->step' 		=> $this->step,
1197
				'request->action' 	=> $this->action,
1198
				'current_step->slug' => $this->current_step instanceof EE_SPCO_Reg_Step ?
1199
					$this->current_step->slug() : '',
1200
				'current_step->completed' => $this->current_step instanceof EE_SPCO_Reg_Step ?
1201
					$this->current_step->completed() : '',
1202
				'txn_status_updated' => $this->txn_status_updated,
1203
				'reg_status_updated' => $this->reg_status_updated,
1204
				'reg_url_link' => $this->reg_url_link,
1205
				'REQ' => $display_request ? $_REQUEST : '',
1206
			);
1207
			if ( $this->transaction instanceof EE_Transaction ) {
1208
				$default_data[ 'TXN_status' ] 		= $this->transaction->status_ID();
1209
				$default_data[ 'TXN_reg_steps' ] 	= $this->transaction->reg_steps();
1210
				foreach ( $this->transaction->registrations( $this->reg_cache_where_params ) as $REG_ID => $registration ) {
1211
					$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...
1212
				}
1213
				if ( $this->transaction->ID() ) {
1214
					$TXN_ID = 'EE_Transaction: ' . $this->transaction->ID();
1215
					// don't serialize objects
1216
					$info = $this->_strip_objects( $info );
1217
					if ( ! isset( $debug_data[ $TXN_ID ] ) ) {
1218
						$debug_data[ $TXN_ID ] = array();
1219
					}
1220
					$debug_data[ $TXN_ID ][ microtime() ] = array_merge(
1221
						$default_data,
1222
						$info
1223
					);
1224
					update_option( 'EE_DEBUG_SPCO_' . EE_Session::instance()->id(), $debug_data );
1225
				}
1226
			}
1227
		}
1228
	}
1229
1230
1231
	/**
1232
	 * _strip_objects
1233
	 *
1234
	 * @param array $info
1235
	 * @return array
1236
	 */
1237
	function _strip_objects( $info = array() ) {
1238
		foreach ( $info as $key => $value ) {
1239 View Code Duplication
			if ( is_array( $value )) {
1240
				$info[ $key ] = $this->_strip_objects( $value );
1241
			} else if ( is_object( $value ) ) {
1242
				$object_class = get_class( $value );
1243
				$info[ $object_class ] = array();
1244
				$info[ $object_class ][ 'ID' ] = method_exists( $value, 'ID' ) ? $value->ID() : 0;
1245
				if ( method_exists( $value, 'status' ) ) {
1246
					$info[ $object_class ][ 'status' ] = $value->status();
1247
				} else if ( method_exists( $value, 'status_ID' ) ) {
1248
					$info[ $object_class ][ 'status' ] = $value->status_ID();
1249
				}
1250
				unset( $info[ $key ] );
1251
			}
1252
		}
1253
		return (array)$info;
1254
	}
1255
1256
1257
1258
1259
}
1260
// End of file EE_Checkout.class.php
1261
// Location: /EE_Checkout.class.php