Completed
Branch BUG-10015-set-curl-ssl-version (7bdf86)
by
unknown
30:31 queued 13:32
created

EE_Transaction_Processor   F

Complexity

Total Complexity 100

Size/Duplication

Total Lines 920
Duplicated Lines 1.09 %

Coupling/Cohesion

Components 3
Dependencies 12

Importance

Changes 0
Metric Value
dl 10
loc 920
rs 3.4285
c 0
b 0
f 0
wmc 100
lcom 3
cbo 12

32 Methods

Rating   Name   Duplication   Size   Complexity  
A instance() 0 7 2
A __construct() 0 4 1
A _set_registration_query_params() 0 3 2
A old_txn_status() 0 3 1
A set_old_txn_status() 0 6 2
A new_txn_status() 0 3 1
A set_new_txn_status() 0 3 1
A txn_status_updated() 0 3 3
D _reg_steps_completed() 0 35 9
A all_reg_steps_completed() 0 3 1
A all_reg_steps_completed_except() 0 3 1
A all_reg_steps_completed_except_final_step() 0 3 1
A reg_step_completed() 0 3 1
A final_reg_step_completed() 0 3 1
A set_reg_step_initiated() 0 3 1
A set_reg_step_completed() 0 3 1
A set_reg_step_not_completed() 0 3 1
D _set_reg_step_completed_status() 0 43 10
A remove_reg_step() 0 6 1
A toggle_failed_transaction_status() 0 14 2
B toggle_abandoned_transaction_status() 0 26 5
B manually_update_registration_statuses() 0 25 1
A toggle_registration_statuses_for_default_approved_events() 0 16 1
A toggle_registration_statuses_if_no_monies_owing() 0 16 1
B update_transaction_and_registrations_after_checkout_or_payment() 0 49 5
B update_transaction_after_reinstating_canceled_registration() 0 35 6
B update_transaction_after_canceled_or_declined_registration() 0 31 6
A get_transaction_for_registration() 0 12 2
A get_ticket_line_item_for_transaction_registration() 10 21 2
C toggle_transaction_status_if_all_registrations_canceled_or_declined() 0 32 8
C _call_method_on_registrations_via_Registration_Processor() 0 31 7
C set_transaction_payment_method_based_on_registration_statuses() 0 56 13

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_Transaction_Processor 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_Transaction_Processor, and based on these observations, apply Extract Interface, too.

1
<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) { exit('No direct script access allowed'); }
2
EE_Registry::instance()->load_class( 'Processor_Base' );
3
4
/**
5
 * Class EE_Transaction_Processor
6
 * This class contains business logic pertaining specifically to
7
 * the interaction of EE_Transaction and EE_Registration model objects
8
 * Provides methods for manipulating and processing changes to an EE_Transaction
9
 * and it's related EE_Registrations with regards to the checkout/registration process
10
11
*
12
*@package     Event Espresso
13
 * @subpackage 	core
14
 * @author      Brent Christensen
15
 * @since       4.6.0
16
 */
17
class EE_Transaction_Processor extends EE_Processor_Base {
18
19
	/**
20
	 * 	@var EE_Registration_Processor $_instance
21
	 * 	@access 	private
22
	 */
23
	private static $_instance;
24
25
	/**
26
	 * array of query WHERE params to use when retrieving cached registrations from a transaction
27
	 *
28
	 * @var array $registration_query_params
29
	 * @access private
30
	 */
31
	private $_registration_query_params = array();
32
33
	/**
34
	 * initial txn status at the beginning of this request.
35
	 *
36
	 * @var string
37
	 */
38
	protected $_old_txn_status;
39
40
	/**
41
	 * txn status at the end of the request after all processing.
42
	 *
43
	 * @var string
44
	 */
45
	protected $_new_txn_status;
46
47
48
49
	/**
50
	 *@singleton method used to instantiate class object
51
	 *@access public
52
	 * @param array $registration_query_params
53
	 *@return EE_Transaction_Processor instance
54
	 */
55
	public static function instance( $registration_query_params = array() ) {
56
		// check if class object is instantiated
57
		if ( ! self::$_instance instanceof EE_Transaction_Processor ) {
58
			self::$_instance = new self( $registration_query_params );
0 ignored issues
show
Documentation Bug introduced by
It seems like new self($registration_query_params) of type object<EE_Transaction_Processor> is incompatible with the declared type object<EE_Registration_Processor> of property $_instance.

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

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

Loading history...
59
		}
60
		return self::$_instance;
61
	}
62
63
64
65
	/**
66
	 * @param array $registration_query_params
67
	 * @return EE_Transaction_Processor
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...
68
	 */
69
	private function __construct( $registration_query_params = array() ) {
70
		// make sure some query params are set for retrieving registrations
71
		$this->_set_registration_query_params( $registration_query_params );
72
	}
73
74
75
76
	/**
77
	 * @access private
78
	 * @param array $registration_query_params
79
	 */
80
	private function _set_registration_query_params( $registration_query_params ) {
81
		$this->_registration_query_params = ! empty( $registration_query_params ) ? $registration_query_params : array( 'order_by' => array( 'REG_count' => 'ASC' ));
82
	}
83
84
85
86
	/**
87
	 * @return string
88
	 */
89
	public function old_txn_status() {
90
		return $this->_old_txn_status;
91
	}
92
93
94
95
	/**
96
	 * @param string $old_txn_status
97
	 */
98
	public function set_old_txn_status( $old_txn_status ) {
99
		// only set the first time
100
		if ( $this->_old_txn_status === null ) {
101
			$this->_old_txn_status = $old_txn_status;
102
		}
103
	}
104
105
106
107
	/**
108
	 * @return string
109
	 */
110
	public function new_txn_status() {
111
		return $this->_new_txn_status;
112
	}
113
114
115
116
	/**
117
	 * @param string $new_txn_status
118
	 */
119
	public function set_new_txn_status( $new_txn_status ) {
120
		$this->_new_txn_status = $new_txn_status;
121
	}
122
123
124
125
	/**
126
	 * reg_status_updated
127
	 *
128
	 * @return bool
129
	 */
130
	public function txn_status_updated() {
131
		return $this->_new_txn_status !== $this->_old_txn_status && $this->_old_txn_status !== null ? true : false;
132
	}
133
134
135
136
	/**
137
	 * _reg_steps_completed
138
	 *
139
	 * if $check_all is TRUE, then returns TRUE if ALL reg steps have been marked as completed,
140
	 * if a $reg_step_slug is provided, then this step will be skipped when testing for completion
141
	 *
142
	 * if $check_all is FALSE and a $reg_step_slug is provided, then ONLY that reg step will be tested for completion
143
	 *
144
	 * @access private
145
	 * @param EE_Transaction $transaction
146
	 * @param string $reg_step_slug
147
	 * @param bool   $check_all
148
	 * @return boolean | int
149
	 */
150
	private function _reg_steps_completed( EE_Transaction $transaction, $reg_step_slug = '', $check_all = TRUE ) {
151
		$reg_steps = $transaction->reg_steps();
152
		if ( ! is_array( $reg_steps ) || empty( $reg_steps )) {
153
			return false;
154
		}
155
		// loop thru reg steps array)
156
		foreach ( $reg_steps as $slug => $reg_step_completed ) {
157
			// if NOT checking ALL steps (only checking one step)
158
			if ( ! $check_all ) {
159
				// and this is the one
160
				if ( $slug === $reg_step_slug ) {
161
					return $reg_step_completed;
162
				} else {
163
					// skip to next reg step in loop
164
					continue;
165
				}
166
			}
167
			// $check_all must be true, else we would never have gotten to this point
168
			if ( $slug === $reg_step_slug ) {
169
				// if we reach this point, then we are testing either:
170
				// all_reg_steps_completed_except() or
171
				// all_reg_steps_completed_except_final_step(),
172
				// and since this is the reg step EXCEPTION being tested
173
				// we want to return true (yes true) if this reg step is NOT completed
174
				// ie: "is everything completed except the final step?"
175
				// "that is correct... the final step is not completed, but all others are."
176
				return $reg_step_completed !== true ? true : false;
177
			} else if ( $reg_step_completed !== true ) {
178
				// if any reg step is NOT completed, then ALL steps are not completed
179
				return false;
180
			}
181
		}
182
183
		return true;
184
	}
185
186
187
188
	/**
189
	 * all_reg_steps_completed
190
	 *
191
	 * returns:
192
	 *  	true if ALL reg steps have been marked as completed
193
	 * 		or false if any step is not completed
194
	 *
195
	 * @param EE_Transaction $transaction
196
	 * @return boolean
197
	 */
198
	public function all_reg_steps_completed( EE_Transaction $transaction ) {
199
		return $this->_reg_steps_completed( $transaction );
200
	}
201
202
203
204
	/**
205
	 * all_reg_steps_completed_except
206
	 *
207
	 * returns:
208
	 * 		true if ALL reg steps, except a particular step that you wish to skip over, have been marked as completed
209
	 * 		or false if any other step is not completed
210
	 * 		or false if ALL steps are completed including the exception you are testing !!!
211
	 *
212
	 * @param EE_Transaction $transaction
213
	 * @param string $exception
214
	 * @return boolean
215
	 */
216
	public function all_reg_steps_completed_except( EE_Transaction $transaction, $exception = '' ) {
217
		return $this->_reg_steps_completed( $transaction, $exception );
218
	}
219
220
221
222
	/**
223
	 * all_reg_steps_completed_except
224
	 *
225
	 * returns:
226
	 * 		true if ALL reg steps, except the final step, have been marked as completed
227
	 * 		or false if any step is not completed
228
	 *  	or false if ALL steps are completed including the final step !!!
229
	 *
230
	 * @param EE_Transaction $transaction
231
	 * @return boolean
232
	 */
233
	public function all_reg_steps_completed_except_final_step( EE_Transaction $transaction ) {
234
		return $this->_reg_steps_completed( $transaction, 'finalize_registration' );
235
	}
236
237
238
239
	/**
240
	 * reg_step_completed
241
	 *
242
	 * returns:
243
	 *    true if a specific reg step has been marked as completed
244
	 *    a Unix timestamp if it has been initialized but not yet completed,
245
	 *    or false if it has not yet been initialized
246
	 *
247
	 * @param EE_Transaction $transaction
248
	 * @param string $reg_step_slug
249
	 * @return boolean | int
250
	 */
251
	public function reg_step_completed( EE_Transaction $transaction, $reg_step_slug ) {
252
		return $this->_reg_steps_completed( $transaction, $reg_step_slug, FALSE );
253
	}
254
255
256
257
	/**
258
	 * completed_final_reg_step
259
	 *
260
	 * returns:
261
	 *  	true if the finalize_registration reg step has been marked as completed
262
	 *  	a Unix timestamp if it has been initialized but not yet completed,
263
	 *  	or false if it has not yet been initialized
264
	 *
265
	 * @param EE_Transaction $transaction
266
	 * @return boolean | int
267
	 */
268
	public function final_reg_step_completed( EE_Transaction $transaction ) {
269
		return $this->_reg_steps_completed( $transaction, 'finalize_registration', FALSE );
270
	}
271
272
273
274
	/**
275
	 * set_reg_step_initiated
276
	 * given a valid TXN_reg_step, this sets it's value to a unix timestamp
277
	 *
278
	 * @access public
279
	 * @param \EE_Transaction $transaction
280
	 * @param string          $reg_step_slug
281
	 * @return boolean
282
	 * @throws \EE_Error
283
	 */
284
	public function set_reg_step_initiated( EE_Transaction $transaction, $reg_step_slug ) {
285
		return $this->_set_reg_step_completed_status( $transaction, $reg_step_slug, time() );
286
	}
287
288
289
290
	/**
291
	 * set_reg_step_completed
292
	 * given a valid TXN_reg_step, this sets the step as completed
293
	 *
294
	 * @access public
295
	 * @param \EE_Transaction $transaction
296
	 * @param string          $reg_step_slug
297
	 * @return boolean
298
	 * @throws \EE_Error
299
	 */
300
	public function set_reg_step_completed( EE_Transaction $transaction, $reg_step_slug ) {
301
		return $this->_set_reg_step_completed_status( $transaction, $reg_step_slug, true );
302
	}
303
304
305
306
	/**
307
	 * set_reg_step_completed
308
	 * given a valid TXN_reg_step slug, this sets the step as NOT completed
309
	 *
310
	 * @access public
311
	 * @param \EE_Transaction $transaction
312
	 * @param string          $reg_step_slug
313
	 * @return boolean
314
	 * @throws \EE_Error
315
	 */
316
	public function set_reg_step_not_completed( EE_Transaction $transaction, $reg_step_slug ) {
317
		return $this->_set_reg_step_completed_status( $transaction, $reg_step_slug, false );
318
	}
319
320
321
322
	/**
323
	 * set_reg_step_completed
324
	 * given a valid reg step slug, this sets the TXN_reg_step completed status which is either:
325
	 *
326
	 * @access private
327
	 * @param  \EE_Transaction $transaction
328
	 * @param  string          $reg_step_slug
329
	 * @param  boolean|int     $status
330
	 * @return boolean
331
	 * @throws \EE_Error
332
	 */
333
	private function _set_reg_step_completed_status( EE_Transaction $transaction, $reg_step_slug, $status ) {
334
		// validate status
335
		$status = is_bool( $status ) || is_int( $status ) ? $status : false;
336
		// get reg steps array
337
		$txn_reg_steps = $transaction->reg_steps();
338
		// if reg step does NOT exist
339
		if ( ! isset( $txn_reg_steps[ $reg_step_slug ] )) {
340
			return false;
341
		}
342
		// if  we're trying to complete a step that is already completed
343
		if ( $txn_reg_steps[ $reg_step_slug ] === true ) {
344
			return true;
345
		}
346
		// if  we're trying to complete a step that hasn't even started
347
		if ( $status === true && $txn_reg_steps[ $reg_step_slug ] === false ) {
348
			return false;
349
		}
350
		// if current status value matches the incoming value (no change)
351
		// type casting as int means values should collapse to either 0, 1, or a timestamp like 1234567890
352
		if ( (int)$txn_reg_steps[ $reg_step_slug ] === (int)$status ) {
353
			// this will happen in cases where multiple AJAX requests occur during the same step
354
			return true;
355
		}
356
		// if we're trying to set a start time, but it has already been set...
357
		if ( is_numeric( $status ) && is_numeric( $txn_reg_steps[ $reg_step_slug ] )) {
358
			// skip the update below, but don't return FALSE so that errors won't be displayed
359
			return true;
360
		}
361
		// update completed status
362
		$txn_reg_steps[ $reg_step_slug ] = $status;
363
		$transaction->set_reg_steps( $txn_reg_steps );
364
		$transaction->save();
365
		// DEBUG LOG
366
		//$this->log(
367
		//	__CLASS__, __FUNCTION__, __LINE__,
368
		//	$transaction,
369
		//	array(
370
		//		'reg_step_slug' => $reg_step_slug,
371
		//		'status' => $status,
372
		//	)
373
		//);
374
		return true;
375
	}
376
377
378
379
	/**
380
	 * remove_reg_step
381
	 * given a valid TXN_reg_step slug, this will remove (unset)
382
	 * the reg step from the TXN reg step array
383
	 *
384
	 * @access public
385
	 * @param \EE_Transaction $transaction
386
	 * @param string $reg_step_slug
387
	 * @return void
388
	 */
389
	public function remove_reg_step( EE_Transaction $transaction, $reg_step_slug ) {
390
		// get reg steps array
391
		$txn_reg_steps = $transaction->reg_steps();
392
		unset( $txn_reg_steps[ $reg_step_slug ] );
393
		$transaction->set_reg_steps( $txn_reg_steps );
394
	}
395
396
397
398
	/**
399
	 *    toggle_failed_transaction_status
400
	 * upgrades a TXNs status from failed to abandoned,
401
	 * meaning that contact information has been captured for at least one registrant
402
	 *
403
	 * @access public
404
	 * @param EE_Transaction $transaction
405
	 * @return    boolean
406
	 * @throws \EE_Error
407
	 */
408
	public function toggle_failed_transaction_status( EE_Transaction $transaction ) {
409
		$existing_txn_status = $transaction->status_ID();
410
		// set incoming TXN_Status
411
		$this->set_old_txn_status( $existing_txn_status );
412
		// if TXN status is still set as "failed"...
413
		if ( $existing_txn_status === EEM_Transaction::failed_status_code ) {
414
			// set incoming TXN_Status
415
			$this->set_new_txn_status( EEM_Transaction::abandoned_status_code );
416
			$transaction->set_status( EEM_Transaction::abandoned_status_code );
417
			$transaction->save();
418
			return TRUE;
419
		}
420
		return FALSE;
421
	}
422
423
424
425
	/**
426
	 * toggle_abandoned_transaction_status
427
	 * upgrades a TXNs status from failed or abandoned to incomplete
428
	 *
429
	 * @access public
430
	 * @param  EE_Transaction $transaction
431
	 * @return boolean
432
	 */
433
	public function toggle_abandoned_transaction_status( EE_Transaction $transaction ) {
434
		// set incoming TXN_Status
435
		$this->set_old_txn_status( $transaction->status_ID() );
436
		// if TXN status has not been updated already due to a payment, and is still set as "failed" or "abandoned"...
437
		$txn_status = $transaction->status_ID();
438
		if (
439
			$txn_status === EEM_Transaction::failed_status_code
440
			|| $txn_status === EEM_Transaction::abandoned_status_code
441
		) {
442
			$this->set_new_txn_status( EEM_Transaction::incomplete_status_code );
443
			// if a contact record for the primary registrant has been created
444
			if (
445
				$transaction->primary_registration() instanceof EE_Registration
446
				&& $transaction->primary_registration()->attendee() instanceof EE_Attendee
447
			) {
448
				$transaction->set_status( EEM_Transaction::incomplete_status_code );
449
				$this->set_new_txn_status( EEM_Transaction::incomplete_status_code );
450
			} else {
451
				// no contact record? yer abandoned!
452
				$transaction->set_status( EEM_Transaction::abandoned_status_code );
453
				$this->set_new_txn_status( EEM_Transaction::abandoned_status_code );
454
			}
455
			return TRUE;
456
		}
457
		return FALSE;
458
	}
459
460
461
462
	/**
463
	 * manually_update_registration_statuses
464
	 *
465
	 * @access public
466
	 * @param EE_Transaction $transaction
467
	 * @param string         $new_reg_status
468
	 * @param array          $registration_query_params array of query WHERE params to use
469
	 *                                                  when retrieving cached registrations from a transaction
470
	 * @return    boolean
471
	 * @throws \EE_Error
472
	 */
473
	public function manually_update_registration_statuses(
474
		EE_Transaction $transaction,
475
		$new_reg_status = '',
476
		$registration_query_params = array()
477
	) {
478
		$status_updates = $this->_call_method_on_registrations_via_Registration_Processor(
479
			'manually_update_registration_status',
480
			$transaction,
481
			$registration_query_params,
482
			$new_reg_status
483
		);
484
		// send messages
485
		/** @type EE_Registration_Processor $registration_processor */
486
		$registration_processor = EE_Registry::instance()->load_class( 'Registration_Processor' );
487
		$registration_processor->trigger_registration_update_notifications(
488
			$transaction->primary_registration(),
489
			array( 'manually_updated' 	=> true )
490
		);
491
		do_action(
492
			'AHEE__EE_Transaction_Processor__manually_update_registration_statuses',
493
			$transaction,
494
			$status_updates
495
		);
496
		return $status_updates;
497
	}
498
499
500
501
	/**
502
	 * toggle_registration_statuses_for_default_approved_events
503
	 *
504
	 * @access public
505
	 * @param EE_Transaction $transaction
506
	 * @param array          $registration_query_params array of query WHERE params to use
507
	 *                                                  when retrieving cached registrations from a transaction
508
	 * @return    boolean
509
	 * @throws \EE_Error
510
	 */
511
	public function toggle_registration_statuses_for_default_approved_events(
512
		EE_Transaction $transaction,
513
		$registration_query_params = array()
514
	) {
515
		$status_updates = $this->_call_method_on_registrations_via_Registration_Processor(
516
			'toggle_registration_status_for_default_approved_events',
517
			$transaction,
518
			$registration_query_params
519
		);
520
		do_action(
521
			'AHEE__EE_Transaction_Processor__toggle_registration_statuses_for_default_approved_events',
522
			$transaction,
523
			$status_updates
524
		);
525
		return $status_updates;
526
	}
527
528
529
530
	/**
531
	 * toggle_registration_statuses_if_no_monies_owing
532
	 *
533
	 * @access public
534
	 * @param EE_Transaction $transaction
535
	 * @param array          $registration_query_params array of query WHERE params to use
536
	 *                                                  when retrieving cached registrations from a transaction
537
	 * @return    boolean
538
	 * @throws \EE_Error
539
	 */
540
	public function toggle_registration_statuses_if_no_monies_owing(
541
		EE_Transaction $transaction,
542
		$registration_query_params = array()
543
	) {
544
		$status_updates = $this->_call_method_on_registrations_via_Registration_Processor(
545
			'toggle_registration_status_if_no_monies_owing',
546
			$transaction,
547
			$registration_query_params
548
		);
549
		do_action(
550
			'AHEE__EE_Transaction_Processor__toggle_registration_statuses_if_no_monies_owing',
551
			$transaction,
552
			$status_updates
553
		);
554
		return $status_updates;
555
	}
556
557
558
559
	/**
560
	 * update_transaction_and_registrations_after_checkout_or_payment
561
	 * cycles thru related registrations and calls update_registration_after_checkout_or_payment() on each
562
	 *
563
	 * @param EE_Transaction     $transaction
564
	 * @param \EE_Payment | NULL $payment
565
	 * @param array              $registration_query_params    array of query WHERE params to use
566
	 *                                                         when retrieving cached registrations from a transaction
567
	 * @throws \EE_Error
568
	 * @return array
569
	 */
570
	public function update_transaction_and_registrations_after_checkout_or_payment(
571
		EE_Transaction $transaction,
572
		$payment = null,
573
		$registration_query_params = array()
574
	) {
575
		// set incoming TXN_Status, and consider it new since old status should have been set
576
		$this->set_new_txn_status( $transaction->status_ID() );
577
		// make sure some query params are set for retrieving registrations
578
		$this->_set_registration_query_params( $registration_query_params );
579
		// get final reg step status
580
		$finalized = $this->final_reg_step_completed( $transaction );
581
		// if the 'finalize_registration' step has been initiated (has a timestamp)
582
		// but has not yet been fully completed (TRUE)
583
		if ( is_int( $finalized ) && $finalized !== false && $finalized !== true ) {
584
			$this->set_reg_step_completed( $transaction, 'finalize_registration' );
585
			$finalized = true;
586
		}
587
		$transaction->save();
588
		// array of details to aid in decision making by systems
589
		$update_params = array(
590
			'old_txn_status'  => $this->old_txn_status(),
591
			'new_txn_status'  => $this->new_txn_status(),
592
			'finalized'       => $finalized,
593
			'revisit'         => $this->_revisit,
594
			'payment_updates' => $payment instanceof EE_Payment ? true : false,
595
			'last_payment'    => $payment
596
		);
597
		// now update the registrations and add the results to our $update_params
598
		$update_params['status_updates'] = $this->_call_method_on_registrations_via_Registration_Processor(
599
			'update_registration_after_checkout_or_payment',
600
			$transaction,
601
			$this->_registration_query_params,
602
			$update_params
0 ignored issues
show
Documentation introduced by
$update_params is of type array<string,?,{"old_txn...n","last_payment":"?"}>, but the function expects a string|null.

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...
603
		);
604
605
		// send messages
606
		/** @type EE_Registration_Processor $registration_processor */
607
		$registration_processor = EE_Registry::instance()->load_class( 'Registration_Processor' );
608
		$registration_processor->trigger_registration_update_notifications(
609
			$transaction->primary_registration(),
610
			$update_params
611
		);
612
		do_action(
613
			'AHEE__EE_Transaction_Processor__update_transaction_and_registrations_after_checkout_or_payment',
614
			$transaction,
615
			$update_params
616
		);
617
		return $update_params;
618
	}
619
620
621
622
	/**
623
	 * update_transaction_after_registration_reopened
624
	 * readjusts TXN and Line Item totals after a registration is changed from
625
	 * cancelled or declined to another reg status such as pending payment or approved
626
	 *
627
	 * @param \EE_Registration $registration
628
	 * @param array            $closed_reg_statuses
629
	 * @param bool             $update_txn
630
	 * @return bool
631
	 */
632
	public function update_transaction_after_reinstating_canceled_registration(
633
		EE_Registration $registration,
634
		$closed_reg_statuses = array(),
635
		$update_txn = true
636
	) {
637
		// these reg statuses should not be considered in any calculations involving monies owing
638
		$closed_reg_statuses = ! empty( $closed_reg_statuses ) ? $closed_reg_statuses : EEM_Registration::closed_reg_statuses();
639
		if ( in_array( $registration->status_ID(), $closed_reg_statuses ) ) {
640
			return false;
641
		}
642
		try {
643
			$transaction = $this->get_transaction_for_registration( $registration );
644
			$ticket_line_item = $this->get_ticket_line_item_for_transaction_registration(
645
				$transaction,
646
				$registration
647
			);
648
			// un-cancel the ticket
649
			$success = EEH_Line_Item::reinstate_canceled_ticket_line_item( $ticket_line_item );
650
		} catch ( EE_Error $e ) {
651
			EE_Error::add_error(
652
				sprintf(
653
					__( 'The Ticket Line Item for Registration %1$d could not be reinstated because :%2$s%3$s', 'event_espresso' ),
654
					$registration->ID(),
655
					'<br />',
656
					$e->getMessage()
657
				),
658
				__FILE__, __FUNCTION__, __LINE__
659
			);
660
			return false;
661
		}
662
		if ( $update_txn ) {
663
			return $transaction->save() ? $success : false;
664
		}
665
		return $success;
666
	}
667
668
669
670
	/**
671
	 * update_transaction_after_canceled_or_declined_registration
672
	 * readjusts TXN and Line Item totals after a registration is cancelled or declined
673
	 *
674
	 * @param \EE_Registration $registration
675
	 * @param array            $closed_reg_statuses
676
	 * @param bool             $update_txn
677
	 * @return bool
678
	 * @throws \EE_Error
679
	 */
680
	public function update_transaction_after_canceled_or_declined_registration(
681
		EE_Registration $registration,
682
		$closed_reg_statuses = array(),
683
		$update_txn = true
684
	) {
685
		// these reg statuses should not be considered in any calculations involving monies owing
686
		$closed_reg_statuses = ! empty( $closed_reg_statuses ) ? $closed_reg_statuses : EEM_Registration::closed_reg_statuses();
687
		if ( ! in_array( $registration->status_ID(), $closed_reg_statuses ) ) {
688
			return false;
689
		}
690
		try {
691
			$transaction = $this->get_transaction_for_registration( $registration );
692
			$ticket_line_item = $this->get_ticket_line_item_for_transaction_registration( $transaction, $registration );
693
			EEH_Line_Item::cancel_ticket_line_item( $ticket_line_item );
694
		} catch ( EE_Error $e ) {
695
			EE_Error::add_error(
696
				sprintf(
697
					__( 'The Ticket Line Item for Registration %1$d could not be cancelled because :%2$s%3$s', 'event_espresso' ),
698
					$registration->ID(),
699
					'<br />',
700
					$e->getMessage()
701
				),
702
				__FILE__, __FUNCTION__, __LINE__
703
			);
704
			return false;
705
		}
706
		if ( $update_txn ) {
707
			return $transaction->save() ? true : false;
708
		}
709
		return true;
710
	}
711
712
713
714
	/**
715
	 * get_transaction_for_registration
716
	 *
717
	 * @access 	public
718
	 * @param 	EE_Registration $registration
719
	 * @return 	EE_Transaction
720
	 * @throws 	EE_Error
721
	 */
722
	public function get_transaction_for_registration( EE_Registration $registration ) {
723
		$transaction = $registration->transaction();
724
		if ( ! $transaction instanceof EE_Transaction ) {
725
			throw new EE_Error(
726
				sprintf(
727
					__( 'The Transaction for Registration %1$d was not found or is invalid.', 'event_espresso' ),
728
					$registration->ID()
729
				)
730
			);
731
		}
732
		return $transaction;
733
	}
734
735
736
737
	/**
738
	 * get_ticket_line_item_for_transaction_registration
739
	 *
740
	 * @access 	public
741
	 * @param 	EE_Transaction  $transaction
742
	 * @param 	EE_Registration $registration
743
	 * @return 	EE_Line_Item
744
	 * @throws 	EE_Error
745
	 */
746
	public function get_ticket_line_item_for_transaction_registration(
747
		EE_Transaction $transaction,
748
		EE_Registration $registration
749
	) {
750
		EE_Registry::instance()->load_helper( 'Line_Item' );
751
		$ticket_line_item = EEM_Line_Item::instance()->get_ticket_line_item_for_transaction(
752
			$transaction->ID(),
753
			$registration->ticket_ID()
754
		);
755 View Code Duplication
		if ( ! $ticket_line_item instanceof EE_Line_Item ) {
756
			throw new EE_Error(
757
				sprintf(
758
					__( 'The Line Item for Transaction %1$d and Ticket %2$d was not found or is invalid.',
759
						'event_espresso' ),
760
					$transaction->ID(),
761
					$registration->ticket_ID()
762
				)
763
			);
764
		}
765
		return $ticket_line_item;
766
	}
767
768
769
770
	/**
771
	 * cancel_transaction_if_all_registrations_canceled
772
	 * cycles thru related registrations and checks their statuses
773
	 * if ALL registrations are Cancelled or Declined, then this sets the TXN status to
774
	 *
775
	 * @access 	public
776
	 * @param 	EE_Transaction 	$transaction
777
	 * @param 	string 			$new_TXN_status
778
	 * @param 	array          	$registration_query_params - array of query WHERE params to use when
779
	 *                                                     retrieving cached registrations from a transaction
780
	 * @param 	array          	$closed_reg_statuses
781
	 * @param 	bool 			$update_txn
782
	 * @return 	bool 			true if TXN status was updated, false if not
783
	 */
784
	public function toggle_transaction_status_if_all_registrations_canceled_or_declined(
785
		EE_Transaction $transaction,
786
		$new_TXN_status = '',
787
		$registration_query_params = array(),
788
		$closed_reg_statuses = array(),
789
		$update_txn = true
790
	) {
791
		// make sure some query params are set for retrieving registrations
792
		$this->_set_registration_query_params( $registration_query_params );
793
		// these reg statuses should not be considered in any calculations involving monies owing
794
		$closed_reg_statuses = ! empty( $closed_reg_statuses ) ? $closed_reg_statuses : EEM_Registration::closed_reg_statuses();
795
		// loop through cached registrations
796
		foreach ( $transaction->registrations( $this->_registration_query_params ) as $registration ) {
797
			if (
798
				$registration instanceof EE_Registration
799
				&& ! in_array( $registration->status_ID(), $closed_reg_statuses )
800
			) {
801
				return false;
802
			}
803
		}
804
		if ( in_array( $new_TXN_status, EEM_Transaction::txn_status_array() ) ) {
805
			// set incoming TXN_Status
806
			$this->set_old_txn_status( $transaction->status_ID() );
807
			$transaction->set_status( $new_TXN_status );
808
			// set new TXN_Status
809
			$this->set_new_txn_status( $new_TXN_status );
810
		}
811
		if ( $update_txn ) {
812
			return $transaction->save() ? true : false;
813
		}
814
		return true;
815
	}
816
817
818
819
	/**
820
	 * _call_method_on_registrations_via_Registration_Processor
821
	 * cycles thru related registrations and calls the requested method on each
822
	 *
823
	 * @access private
824
	 * @param string 		$method_name
825
	 * @param EE_Transaction $transaction
826
	 * @param array          $registration_query_params array of query WHERE params to use
827
	 *                                                  when retrieving cached registrations from a transaction
828
	 * @param string 	$additional_param
829
	 * @throws \EE_Error
830
	 * @return boolean
831
	 */
832
	private function _call_method_on_registrations_via_Registration_Processor(
833
		$method_name,
834
		EE_Transaction $transaction,
835
		$registration_query_params = array(),
836
		$additional_param = null
837
	) {
838
		$response = false;
839
		/** @type EE_Registration_Processor $registration_processor */
840
		$registration_processor = EE_Registry::instance()->load_class( 'Registration_Processor' );
841
		// check that method exists
842
		if ( ! method_exists( $registration_processor, $method_name )) {
843
			throw new EE_Error( __( 'Method does not exist.', 'event_espresso' ));
844
		}
845
		// make sure some query params are set for retrieving registrations
846
		$this->_set_registration_query_params( $registration_query_params );
847
		// loop through cached registrations
848
		foreach ( $transaction->registrations( $this->_registration_query_params ) as $registration ) {
849
			if ( $registration instanceof EE_Registration ) {
850
				if ( $additional_param ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $additional_param of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
851
					$response = $registration_processor->{$method_name}( $registration, $additional_param )
852
						? true
853
						: $response;
854
				} else {
855
					$response = $registration_processor->{$method_name}( $registration )
856
						? true
857
						: $response;
858
				}
859
			}
860
		}
861
		return $response;
862
	}
863
864
865
866
	/**
867
	 * set_transaction_payment_method_based_on_registration_statuses
868
	 * sets or unsets the PMD_ID field on the TXN based on the related REG statuses
869
	 * basically if ALL Registrations are "Not Approved", then the EE_Transaction.PMD_ID is set to null,
870
	 * but if any Registration has a different status, then EE_Transaction.PMD_ID is set to either:
871
	 *        the first "default" Payment Method
872
	 *        the first active Payment Method
873
	 *    whichever is found first.
874
	 *
875
	 * @param  EE_Registration $edited_registration
876
	 * @return void
877
	 * @throws \EE_Error
878
	 */
879
	public function set_transaction_payment_method_based_on_registration_statuses(
880
		EE_Registration $edited_registration
881
	) {
882
		if ( $edited_registration instanceof EE_Registration ) {
883
			$transaction = $edited_registration->transaction();
884
			if ( $transaction instanceof EE_Transaction ) {
885
				$all_not_approved = true;
886
				foreach ( $transaction->registrations() as $registration ) {
887
					if ( $registration instanceof EE_Registration ) {
888
						// if any REG != "Not Approved" then toggle to false
889
						$all_not_approved = $registration->is_not_approved() ? $all_not_approved : false;
890
					}
891
				}
892
				// if ALL Registrations are "Not Approved"
893
				if ( $all_not_approved ) {
894
					$transaction->set_payment_method_ID( null );
895
					$transaction->save();
896
				} else {
897
					$available_payment_methods = EEM_Payment_Method::instance()->get_all_for_transaction(
898
						$transaction,
899
						EEM_Payment_Method::scope_cart
900
					);
901
					if ( ! empty( $available_payment_methods ) ) {
902
						$PMD_ID = 0;
903
						foreach ( $available_payment_methods as $available_payment_method ) {
904
							if (
905
								$available_payment_method instanceof EE_Payment_Method
906
							    && $available_payment_method->open_by_default()
907
							) {
908
								$PMD_ID = $available_payment_method->ID();
909
								break;
910
							}
911
						}
912
						if ( ! $PMD_ID ) {
913
							$first_payment_method = reset( $available_payment_methods );
914
							if ( $first_payment_method instanceof EE_Payment_Method ) {
915
								$PMD_ID = $first_payment_method->ID();
916
							} else {
917
								EE_Error::add_error(
918
									__( 'A valid Payment Method could not be determined. Please ensure that at least one Payment Method is activated.', 'event_espresso' ),
919
									__FILE__, __LINE__, __FUNCTION__
920
								);
921
							}
922
						}
923
						$transaction->set_payment_method_ID( $PMD_ID );
924
						$transaction->save();
925
					} else {
926
						EE_Error::add_error(
927
							__( 'Please activate at least one Payment Method in order for things to operate correctly.', 'event_espresso' ),
928
							__FILE__, __LINE__, __FUNCTION__
929
						);
930
					}
931
				}
932
			}
933
		}
934
	}
935
936
}
937
938
939
940
// End of file EE_Transaction_Processor.class.php
941
// Location: /EE_Transaction_Processor.class.php
942