Completed
Branch TASK-9118-extensions-page (04eaec)
by
unknown
38:06 queued 23:39
created

EE_Registration::set_session()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php if ( !defined( 'EVENT_ESPRESSO_VERSION' ) ) {
2
	exit( 'No direct script access allowed' );
3
}
4
/**
5
 * EE_Registration class
6
 *
7
 * @package 			Event Espresso
8
 * @subpackage 	includes/classes/EE_Registration.class.php
9
 * @author 				Mike Nelson, Brent Christensen
10
 */
11
class EE_Registration extends EE_Soft_Delete_Base_Class implements EEI_Registration {
12
13
14
	/**
15
	 * Used to reference when a registration has never been checked in.
16
	 * @type int
17
	 */
18
	const checkin_status_never = 2;
19
20
	/**
21
	 * Used to reference when a registration has been checked in.
22
	 * @type int
23
	 */
24
	const checkin_status_in = 1;
25
26
27
	/**
28
	 * Used to reference when a registration has been checked out.
29
	 * @type int
30
	 */
31
	const checkin_status_out = 0;
32
33
34
35
	/**
36
	 *
37
	 * @param array $props_n_values  incoming values
38
	 * @param string $timezone  incoming timezone (if not set the timezone set for the website will be
39
	 *                          		used.)
40
	 * @param array $date_formats  incoming date_formats in an array where the first value is the
41
	 *                             		    date_format and the second value is the time format
42
	 * @return EE_Registration
43
	 */
44
	public static function new_instance( $props_n_values = array(), $timezone = null, $date_formats = array() ) {
45
		$has_object = parent::_check_for_object( $props_n_values, __CLASS__ );
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (_check_for_object() instead of new_instance()). Are you sure this is correct? If so, you might want to change this to $this->_check_for_object().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
46
		return $has_object ? $has_object : new self( $props_n_values, false, $timezone, $date_formats );
47
	}
48
49
50
51
	/**
52
	 * @param array $props_n_values  incoming values from the database
53
	 * @param string $timezone  incoming timezone as set by the model.  If not set the timezone for
54
	 *                          		the website will be used.
55
	 * @return EE_Registration
56
	 */
57
	public static function new_instance_from_db( $props_n_values = array(), $timezone = null ) {
58
		return new self( $props_n_values, TRUE, $timezone );
59
	}
60
61
62
63
	/**
64
	 *        Set Event ID
65
	 *
66
	 * @access        public
67
	 * @param        int $EVT_ID Event ID
68
	 */
69
	public function set_event( $EVT_ID = 0 ) {
70
		$this->set( 'EVT_ID', $EVT_ID );
71
	}
72
73
74
75
	/**
76
	 * Overrides parent set() method so that all calls to set( 'REG_code', $REG_code ) OR set( 'STS_ID', $STS_ID ) can be routed to internal methods
77
	 * @param string $field_name
78
	 * @param mixed  $field_value
79
	 * @param bool   $use_default
80
	 */
81
	public function set( $field_name, $field_value, $use_default = FALSE ) {
82
		switch( $field_name ) {
83
			case 'REG_code' :
84
				if ( ! empty( $field_value ) && $this->reg_code() == '' ) {
85
					$this->set_reg_code( $field_value, $use_default );
86
				}
87
				break;
88
			case 'STS_ID' :
89
				$this->set_status( $field_value, $use_default );
90
				break;
91
			default :
92
				parent::set( $field_name, $field_value, $use_default );
93
		}
94
	}
95
96
97
98
	/**
99
	 *    Set Status ID
100
	 *    updates the registration status and ALSO...
101
	 *    calls reserve_registration_space() if the reg status changes TO approved from any other reg status
102
	 *    calls release_registration_space() if the reg status changes FROM approved to any other reg status
103
	 *
104
	 * @access        public
105
	 * @param string $new_STS_ID
106
	 * @param boolean $use_default
107
	 * @return bool
108
	 */
109
	public function set_status( $new_STS_ID = NULL, $use_default = FALSE ) {
110
		// get current REG_Status
111
		$old_STS_ID = $this->status_ID();
112
		// if status has changed
113 View Code Duplication
		if ( $old_STS_ID != $new_STS_ID  ) {
114
			// TO approved
115
			if ( $new_STS_ID == EEM_Registration::status_id_approved ) {
116
				// reserve a space by incrementing ticket and datetime sold values
117
				$this->_reserve_registration_space();
118
				do_action( 'AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID );
119
			// OR FROM  approved
120
			} else if ( $old_STS_ID == EEM_Registration::status_id_approved ) {
121
				// release a space by decrementing ticket and datetime sold values
122
				$this->_release_registration_space();
123
				do_action( 'AHEE__EE_Registration__set_status__from_approved', $this, $old_STS_ID, $new_STS_ID );
124
			}
125
			// update status
126
			parent::set( 'STS_ID', $new_STS_ID, $use_default );
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (set() instead of set_status()). Are you sure this is correct? If so, you might want to change this to $this->set().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
127
			do_action( 'AHEE__EE_Registration__set_status__after_update', $this );
128
			return TRUE;
129
		}else{
130
			//even though the old value matches the new value, it's still good to
131
			//allow the parent set method to have a say
132
			parent::set( 'STS_ID', $new_STS_ID, $use_default );
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (set() instead of set_status()). Are you sure this is correct? If so, you might want to change this to $this->set().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
133
			return TRUE;
134
		}
135
	}
136
137
138
139
	/**
140
	 *        get Status ID
141
	 * @access        public
142
	 */
143
	public function status_ID() {
144
		return $this->get( 'STS_ID' );
145
	}
146
147
148
149
	/**
150
	 * increments this registration's related ticket sold and corresponding datetime sold values
151
	 * @return void
152
	 */
153
	private function _reserve_registration_space() {
154
		$ticket = $this->ticket();
155
		$ticket->increase_sold();
156
		$ticket->save();
157
		// possibly set event status to sold out
158
		$this->event()->perform_sold_out_status_check();
159
	}
160
161
162
163
	/**
164
	 * Gets the ticket this registration is for
165
	 *
166
	 * @param boolean $include_archived whether to include archived tickets or not.
167
	 * @return EE_Ticket
168
	 */
169
	public function ticket( $include_archived = TRUE ) {
170
		$query_params = array();
171
		if ( $include_archived ) {
172
			$query_params[ 'default_where_conditions' ] = 'none';
173
		}
174
		return $this->get_first_related( 'Ticket', $query_params );
175
	}
176
177
178
179
	/**
180
	 * Gets the event this registration is for
181
	 * @return EE_Event
182
	 */
183
	public function event() {
184
		return $this->get_first_related( 'Event' );
185
	}
186
187
188
189
	/**
190
	 * Gets the "author" of the registration.  Note that for the purposes of registrations, the author will correspond with the author of the event this registration is for.
191
	 *
192
	 * @since 4.5.0
193
	 *
194
	 * @return int
195
	 */
196
	public function wp_user() {
197
		$event = $this->event();
198
		if ( $event instanceof EE_Event ) {
199
			return $event->wp_user();
200
		}
201
		return 0;
202
	}
203
204
205
206
	/**
207
	 * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values
208
	 * @return void
209
	 */
210
	private function _release_registration_space() {
211
		$ticket = $this->ticket();
212
		$ticket->decrease_sold();
213
		$ticket->save();
214
	}
215
216
217
218
	/**
219
	 *        Set Attendee ID
220
	 *
221
	 * @access        public
222
	 * @param        int $ATT_ID Attendee ID
223
	 */
224
	public function set_attendee_id( $ATT_ID = 0 ) {
225
		$this->set( 'ATT_ID', $ATT_ID );
226
	}
227
228
229
230
	/**
231
	 *        Set Transaction ID
232
	 *
233
	 * @access        public
234
	 * @param        int $TXN_ID Transaction ID
235
	 */
236
	public function set_transaction_id( $TXN_ID = 0 ) {
237
		$this->set( 'TXN_ID', $TXN_ID );
238
	}
239
240
241
242
	/**
243
	 *        Set Session
244
	 *
245
	 * @access    public
246
	 * @param    string $REG_session PHP Session ID
247
	 */
248
	public function set_session( $REG_session = '' ) {
249
		$this->set( 'REG_session', $REG_session );
250
	}
251
252
253
254
	/**
255
	 *        Set Registration URL Link
256
	 *
257
	 * @access    public
258
	 * @param    string $REG_url_link Registration URL Link
259
	 */
260
	public function set_reg_url_link( $REG_url_link = '' ) {
261
		$this->set( 'REG_url_link', $REG_url_link );
262
	}
263
264
265
266
	/**
267
	 *        Set Attendee Counter
268
	 *
269
	 * @access        public
270
	 * @param        int $REG_count Primary Attendee
271
	 */
272
	public function set_count( $REG_count = 1 ) {
273
		$this->set( 'REG_count', $REG_count );
274
	}
275
276
277
278
	/**
279
	 *        Set Group Size
280
	 *
281
	 * @access        public
282
	 * @param        boolean $REG_group_size Group Registration
283
	 */
284
	public function set_group_size( $REG_group_size = FALSE ) {
285
		$this->set( 'REG_group_size', $REG_group_size );
286
	}
287
288
289
290
	/**
291
	 *    is_not_approved -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_not_approved
292
	 *
293
	 * @access        public
294
	 * @return        boolean
295
	 */
296
	public function is_not_approved() {
297
		return $this->status_ID() == EEM_Registration::status_id_not_approved ? TRUE : FALSE;
298
	}
299
300
301
302
	/**
303
	 *    is_pending_payment -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_pending_payment
304
	 *
305
	 * @access        public
306
	 * @return        boolean
307
	 */
308
	public function is_pending_payment() {
309
		return $this->status_ID() == EEM_Registration::status_id_pending_payment ? TRUE : FALSE;
310
	}
311
312
313
314
	/**
315
	 *    is_approved -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved
316
	 *
317
	 * @access        public
318
	 * @return        boolean
319
	 */
320
	public function is_approved() {
321
		return $this->status_ID() == EEM_Registration::status_id_approved ? TRUE : FALSE;
322
	}
323
324
325
326
	/**
327
	 *    is_cancelled -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled
328
	 *
329
	 * @access        public
330
	 * @return        boolean
331
	 */
332
	public function is_cancelled() {
333
		return $this->status_ID() == EEM_Registration::status_id_cancelled ? TRUE : FALSE;
334
	}
335
336
337
338
	/**
339
	 *    is_declined -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined
340
	 *
341
	 * @access        public
342
	 * @return        boolean
343
	 */
344
	public function is_declined() {
345
		return $this->status_ID() == EEM_Registration::status_id_declined ? TRUE : FALSE;
346
	}
347
348
349
350
	/**
351
	 *    is_incomplete -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_incomplete
352
	 *
353
	 * @access        public
354
	 * @return        boolean
355
	 */
356
	public function is_incomplete() {
357
		return $this->status_ID() == EEM_Registration::status_id_incomplete ? TRUE : FALSE;
358
	}
359
360
361
362
	/**
363
	 *        Set Registration Date
364
	 *
365
	 * @access        public
366
	 * @param        mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of Date
367
	 */
368
	public function set_reg_date( $REG_date = FALSE ) {
369
		$this->set( 'REG_date', $REG_date );
370
	}
371
372
373
374
	/**
375
	 *    Set final price owing for this registration after all ticket/price modifications
376
	 *
377
	 * @access    public
378
	 * @param    float $REG_final_price
379
	 */
380
	public function set_final_price( $REG_final_price = 0.00 ) {
381
		$this->set( 'REG_final_price', $REG_final_price );
382
	}
383
384
385
386
	/**
387
	 *    Set amount paid towards this registration's final price
388
	 *
389
	 * @access    public
390
	 * @param    float $REG_paid
391
	 */
392
	public function set_paid( $REG_paid = 0.00 ) {
393
		$this->set( 'REG_paid', $REG_paid );
394
	}
395
396
397
398
	/**
399
	 *        Attendee Is Going
400
	 *
401
	 * @access        public
402
	 * @param        boolean $REG_att_is_going Attendee Is Going
403
	 */
404
	public function set_att_is_going( $REG_att_is_going = FALSE ) {
405
		$this->set( 'REG_att_is_going', $REG_att_is_going );
406
	}
407
408
409
410
	/**
411
	 * Gets the related attendee
412
	 * @return EE_Attendee
413
	 */
414
	public function attendee() {
415
		return $this->get_first_related( 'Attendee' );
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->get_first_related('Attendee'); (EE_Base_Class) is incompatible with the return type declared by the interface EEI_Registration::attendee of type EEI_Attendee.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
416
	}
417
418
419
420
	/**
421
	 *        get Event ID
422
	 * @access        public
423
	 */
424
	public function event_ID() {
425
		return $this->get( 'EVT_ID' );
426
	}
427
428
429
430
	/**
431
	 *        get Event ID
432
	 * @access        public
433
	 */
434
	public function event_name() {
435
		$event = $this->event_obj();
436
		if ( $event ) {
437
			return $event->name();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $event->name(); (boolean) is incompatible with the return type declared by the interface EEI_Registration::event_name of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
438
		} else {
439
			return NULL;
440
		}
441
	}
442
443
444
445
	/**
446
	 * Fetches the event this registration is for
447
	 * @return EE_Event
448
	 */
449
	public function event_obj() {
450
		return $this->get_first_related( 'Event' );
451
	}
452
453
454
455
	/**
456
	 *        get Attendee ID
457
	 * @access        public
458
	 */
459
	public function attendee_ID() {
460
		return $this->get( 'ATT_ID' );
461
	}
462
463
464
465
	/**
466
	 *        get PHP Session ID
467
	 * @access        public
468
	 */
469
	public function session_ID() {
470
		return $this->get( 'REG_session' );
471
	}
472
473
474
475
	/**
476
	 * Gets the string which represents the URL trigger for the receipt template in the message template system.
477
	 * @param string $messenger 'pdf' or 'html'.  Default 'html'.
478
	 * @return string
479
	 */
480
	public function receipt_url( $messenger = 'html' ) {
481
482
		/**
483
		 * The below will be deprecated one version after this.  We check first if there is a custom receipt template already in use on old system.  If there is then we just return the standard url for it.
484
		 *
485
		 * @since 4.5.0
486
		 */
487
		EE_Registry::instance()->load_helper('Template');
488
		$template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php';
489
		$has_custom = EEH_Template::locate_template( $template_relative_path , array(), TRUE, TRUE, TRUE );
490
491
		if ( $has_custom ) {
492
			return add_query_arg( array( 'receipt' => 'true' ), $this->invoice_url( 'launch' ) );
493
		}
494
		return apply_filters( 'FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt' );
495
	}
496
497
498
499
500
	/**
501
	 * Gets the string which represents the URL trigger for the invoice template in the message template system.
502
	 * @param string $messenger 'pdf' or 'html'.  Default 'html'.
503
	 * @return string
504
	 */
505
	public function invoice_url( $messenger = 'html' ) {
506
		/**
507
		 * The below will be deprecated one version after this.  We check first if there is a custom invoice template already in use on old system.  If there is then we just return the standard url for it.
508
		 *
509
		 * @since 4.5.0
510
		 */
511
		EE_Registry::instance()->load_helper('Template');
512
		$template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php';
513
		$has_custom = EEH_Template::locate_template( $template_relative_path , array(), TRUE, TRUE, TRUE );
514
515
		if ( $has_custom ) {
516
			if ( $messenger == 'html' ) {
517
				return $this->invoice_url( 'launch' );
518
			}
519
			$route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice';
520
521
			$query_args = array( 'ee' => $route, 'id' => $this->reg_url_link() );
522
			if ( $messenger == 'html' ) {
523
				$query_args['html'] = TRUE;
524
			}
525
			return add_query_arg( $query_args, get_permalink( EE_Registry::instance()->CFG->core->thank_you_page_id ) );
526
		}
527
		return apply_filters( 'FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice' );
528
	}
529
530
531
532
	/**
533
	 * get Registration URL Link
534
	 * @access        public
535
	 */
536
	public function reg_url_link() {
537
		return $this->get( 'REG_url_link' );
538
	}
539
540
541
542
	/**
543
	 * Echoes out invoice_url()
544
	 * @param string $type 'download','launch', or 'html' (default is 'launch')
545
	 * @return void
546
	 */
547
	public function e_invoice_url( $type = 'launch' ) {
548
		echo $this->invoice_url( $type );
549
	}
550
551
552
553
	/**
554
	 * Echoes out payment_overview_url
555
	 */
556
	public function e_payment_overview_url() {
557
		echo $this->payment_overview_url();
558
	}
559
560
561
562
	/**
563
	 * Gets the URL of the thank you page with this registration REG_url_link added as
564
	 * a query parameter
565
	 * @return string
566
	 */
567
	public function payment_overview_url() {
568
		return add_query_arg( array( 'e_reg_url_link' => $this->reg_url_link(), 'step' => 'payment_options', 'revisit' => TRUE ), EE_Registry::instance()->CFG->core->reg_page_url() );
569
	}
570
571
572
573
	/**
574
	 * Gets the URL of the thank you page with this registration REG_url_link added as
575
	 * a query parameter
576
	 * @return string
577
	 */
578
	public function edit_attendee_information_url() {
579
		return add_query_arg( array( 'e_reg_url_link' => $this->reg_url_link(), 'step' => 'attendee_information', 'revisit' => TRUE ), EE_Registry::instance()->CFG->core->reg_page_url() );
580
	}
581
582
583
584
	/**
585
	 * Simply generates and returns the appropriate admin_url link to edit this registration
586
	 * @return string
587
	 */
588
	public function get_admin_edit_url() {
589
		EE_Registry::instance()->load_helper( 'URL' );
590
		return EEH_URL::add_query_args_and_nonce( array( 'page' => 'espresso_registrations', 'action' => 'view_registration', '_REG_ID' => $this->ID() ), admin_url( 'admin.php' ) );
591
	}
592
593
594
595
	/**
596
	 *    is_primary_registrant?
597
	 * @access        public
598
	 */
599
	public function is_primary_registrant() {
600
		return $this->get( 'REG_count' ) == 1 ? TRUE : FALSE;
601
	}
602
603
604
605
	/**
606
	 * This returns the primary registration object for this registration group (which may be this object).
607
	 * @return EE_Registration
608
	 */
609
	public function get_primary_registration()  {
610
		if ( $this->is_primary_registrant() )
611
			return $this;
612
613
		//k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1
614
		$primary_registrant = EEM_Registration::instance()->get_one( array( array('TXN_ID' => $this->transaction_ID(), 'REG_count' => 1 ) ) );
615
		return $primary_registrant;
616
	}
617
618
619
620
	/**
621
	*		get  Attendee Number
622
	* 		@access		public
623
	*/
624
	public function count() {
625
		return $this->get( 'REG_count' );
626
	}
627
628
629
630
	/**
631
	 *        get Group Size
632
	 * @access        public
633
	 */
634
	public function group_size() {
635
		return $this->get( 'REG_group_size' );
636
	}
637
638
639
640
	/**
641
	 *        get Registration Date
642
	 * @access        public
643
	 */
644
	public function date() {
645
		return $this->get( 'REG_date' );
646
	}
647
648
649
650
	/**
651
	 * gets a pretty date
652
	 * @param string $date_format
653
	 * @param string $time_format
654
	 * @return string
655
	 */
656
	public function pretty_date( $date_format = NULL, $time_format = NULL ) {
657
		return $this->get_datetime( 'REG_date', $date_format, $time_format );
658
	}
659
660
661
662
	/**
663
	 * final_price
664
	 * the registration's share of the transaction total, so that the
665
	 * sum of all the transaction's REG_final_prices equal the transaction's total
666
	 * @access        public
667
	 * @return    float
668
	 */
669
	public function final_price() {
670
		return $this->get( 'REG_final_price' );
671
	}
672
673
674
675
	/**
676
	 * pretty_final_price
677
	 *  final price as formatted string, with correct decimal places and currency symbol
678
	 * @return string
679
	 */
680
	public function pretty_final_price() {
681
		return $this->get_pretty( 'REG_final_price' );
682
	}
683
684
685
686
	/**
687
	 * get paid (yeah)
688
	 * @access        public
689
	 * @return 	float
690
	 */
691
	public function paid() {
692
		return $this->get( 'REG_paid' );
693
	}
694
695
696
697
	/**
698
	 * pretty_paid
699
	 * @access        public
700
	 * @return 	float
701
	 */
702
	public function pretty_paid() {
703
		return $this->get_pretty( 'REG_paid' );
704
	}
705
706
707
708
	/**
709
	 * owes_monies_and_can_pay
710
	 * whether or not this registration has monies owing and it's' status allows payment
711
	 * @access        public
712
	 * @param array $requires_payment
713
	 * @return bool
714
	 */
715
	public function owes_monies_and_can_pay( $requires_payment = array()) {
716
		// these reg statuses require payment (if event is not free)
717
		$requires_payment = ! empty( $requires_payment ) ? $requires_payment : EEM_Registration::reg_statuses_that_allow_payment();
718
		if (
719
			in_array( $this->status_ID(), $requires_payment ) &&
720
			$this->final_price() != 0 &&
721
			$this->final_price() != $this->paid()
722
		) {
723
			return true;
724
		} else {
725
			return false;
726
		}
727
	}
728
729
730
731
	/**
732
	 * Prints out the return value of $this->pretty_status()
733
	 * @param bool $show_icons
734
	 * @return void
735
	 */
736
	public function e_pretty_status( $show_icons = FALSE ) {
737
		echo $this->pretty_status( $show_icons );
738
	}
739
740
741
742
743
	/**
744
	 * Returns a nice version of the status for displaying to customers
745
	 * @param bool $show_icons
746
	 * @return string
747
	 */
748
	public function pretty_status( $show_icons = FALSE ) {
749
		$status = EEM_Status::instance()->localized_status( array( $this->status_ID() => __( 'unknown', 'event_espresso' ) ), FALSE, 'sentence' );
750
		$icon = '';
751
		switch ( $this->status_ID() ) {
752
			case EEM_Registration::status_id_approved:
753
				$icon = $show_icons ? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>' : '';
754
				break;
755
			case EEM_Registration::status_id_pending_payment:
756
				$icon = $show_icons ? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>' : '';
757
				break;
758
			case EEM_Registration::status_id_not_approved:
759
				$icon = $show_icons ? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>' : '';
760
				break;
761
			case EEM_Registration::status_id_cancelled:
762
				$icon = $show_icons ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>' : '';
763
				break;
764
			case EEM_Registration::status_id_incomplete:
765
				$icon = $show_icons ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>' : '';
766
				break;
767
			case EEM_Registration::status_id_declined:
768
				$icon = $show_icons ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' : '';
769
				break;
770
		}
771
		return $icon . $status[ $this->status_ID() ];
772
	}
773
774
775
776
	/**
777
	 *        get Attendee Is Going
778
	 * @access        public
779
	 */
780
	public function att_is_going() {
781
		return $this->get( 'REG_att_is_going' );
782
	}
783
784
785
786
	/**
787
	 * Gets related answers
788
	 * @param array $query_params like EEM_Base::get_all
789
	 * @return EE_Answer[]
790
	 */
791
	public function answers( $query_params = NULL ) {
792
		return $this->get_many_related( 'Answer', $query_params );
0 ignored issues
show
Bug introduced by
It seems like $query_params defined by parameter $query_params on line 791 can also be of type null; however, EE_Base_Class::get_many_related() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
793
	}
794
795
796
797
	/**
798
	 * Gets the registration's answer value to the specified question
799
	 * (either the question's ID or a question object)
800
	 * @param EE_Question|int $question
801
	 * @param bool            $pretty_value
802
	 * @return array|string if pretty_value= true, the result will always be a string
803
	 * (because the answer might be an array of answer values, so passing pretty_value=true
804
	 * will convert it into some kind of string)
805
	 */
806
	public function answer_value_to_question( $question, $pretty_value=true ) {
807
		$question_id = EEM_Question::instance()->ensure_is_ID($question);
808
		return EEM_Answer::instance()->get_answer_value_to_question($this,$question_id,$pretty_value);
809
	}
810
811
812
813
	/**
814
	 * question_groups
815
	 * returns an array of EE_Question_Group objects for this registration
816
	 *
817
	 * @return EE_Question_Group[]
818
	 */
819
	public function question_groups() {
820
		$question_groups = array();
821
		if ( $this->event() instanceof EE_Event ) {
822
			$question_groups = $this->event()->question_groups(
823
				array(
824
					array(
825
						'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false
826
					),
827
					'order_by' => array( 'QSG_order' => 'ASC' )
828
				)
829
			);
830
		}
831
		return $question_groups;
832
	}
833
834
835
836
	/**
837
	 * count_question_groups
838
	 * returns a count of the number of EE_Question_Group objects for this registration
839
	 *
840
	 * @return int
841
	 */
842
	public function count_question_groups() {
843
		$qg_count = 0;
844
		if ( $this->event() instanceof EE_Event ) {
845
			$qg_count = $this->event()->count_related(
846
				'Question_Group',
847
				array(
848
					array(
849
						'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false
850
					)
851
				)
852
			);
853
		}
854
		return $qg_count;
855
	}
856
857
858
859
	/**
860
	 * Returns the registration date in the 'standard' string format
861
	 * (function may be improved in the future to allow for different formats and timezones)
862
	 * @return string
863
	 */
864
	public function reg_date() {
865
		return $this->get_datetime( 'REG_date' );
866
	}
867
868
869
870
	/**
871
	 * Gets the datetime-ticket for this registration (ie, it can be used to isolate
872
	 * the ticket this registration purchased, or the datetime they have registered
873
	 * to attend)
874
	 * @return EE_Datetime_Ticket
875
	 */
876
	public function datetime_ticket() {
877
		return $this->get_first_related( 'Datetime_Ticket' );
878
	}
879
880
881
882
	/**
883
	 * Sets the registration's datetime_ticket.
884
	 * @param EE_Datetime_Ticket $datetime_ticket
885
	 * @return EE_Datetime_Ticket
886
	 */
887
	public function set_datetime_ticket( $datetime_ticket ) {
888
		return $this->_add_relation_to( $datetime_ticket, 'Datetime_Ticket' );
889
	}
890
	/**
891
	 * Gets deleted
892
	 * @return boolean
893
	 */
894
	public function deleted() {
895
		return $this->get( 'REG_deleted' );
896
	}
897
898
	/**
899
	 * Sets deleted
900
	 * @param boolean $deleted
901
	 * @return boolean
902
	 */
903
	public function set_deleted($deleted) {
904
		$this->set( 'REG_deleted', $deleted );
905
	}
906
907
908
909
	/**
910
	 * Get the status object of this object
911
	 * @return EE_Status
912
	 */
913
	public function status_obj() {
914
		return $this->get_first_related( 'Status' );
915
	}
916
917
918
919
	/**
920
	 * Returns the number of times this registration has checked into any of the datetimes
921
	 * its available for
922
	 * @return int
923
	 */
924
	public function count_checkins() {
925
		return $this->get_model()->count_related( $this, 'Checkin' );
0 ignored issues
show
Bug introduced by
The method count_related cannot be called on $this->get_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
926
	}
927
928
929
930
	/**
931
	 * Returns the number of current Check-ins this registration is checked into for any of the datetimes the registration is for.  Note, this is ONLY checked in (does not include checkedout)
932
	 * @return int
933
	 */
934
	public function count_checkins_not_checkedout() {
935
		return $this->get_model()->count_related( $this, 'Checkin', array( array( 'CHK_in' => 1 ) ) );
0 ignored issues
show
Bug introduced by
The method count_related cannot be called on $this->get_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
936
	}
937
938
939
940
	/**
941
	 * The purpose of this method is simply to check whether this registration can checkin to the given datetime.
942
	 *
943
	 * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against
944
	 * @param bool   $check_approved   This is used to indicate whether the caller wants can_checkin to also consider registration status as well as datetime access.
945
	 *
946
	 * @return bool
947
	 */
948
	public function can_checkin( $DTT_OR_ID, $check_approved = TRUE ) {
949
		$DTT_ID = EEM_Datetime::instance()->ensure_is_ID( $DTT_OR_ID );
950
951
		//first check registration status
952
		if (  ( $check_approved && ! $this->is_approved() ) || ! $DTT_ID ) {
953
			return false;
954
		}
955
		//is there a datetime ticket that matches this dtt_ID?
956
		if ( ! ( EEM_Datetime_Ticket::instance()->exists( array( array( 'TKT_ID' => $this->get('TKT_ID' ), 'DTT_ID' => $DTT_ID ) ) ) ) ) {
957
			return false;
958
		}
959
960
		//final check is against TKT_uses
961
		return $this->verify_can_checkin_against_TKT_uses( $DTT_ID );
962
	}
963
964
965
	/**
966
	 * This method verifies whether the user can checkin for the given datetime considering the max uses value set on the ticket.
967
	 *
968
	 * To do this,  a query is done to get the count of the datetime records already checked into.  If the datetime given does
969
	 * not have a check-in record and checking in for that datetime will exceed the allowed uses, then return false.  Otherwise return true.
970
	 *
971
	 * @param int | EE_Datetime  $DTT_OR_ID  The datetime the registration is being checked against
972
	 * @return bool   true means can checkin.  false means cannot checkin.
973
	 */
974
	public function verify_can_checkin_against_TKT_uses( $DTT_OR_ID ) {
975
		$DTT_ID = EEM_Datetime::instance()->ensure_is_ID( $DTT_OR_ID );
976
977
		if ( ! $DTT_ID ) {
978
			return false;
979
		}
980
981
		$max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF;
982
983
		// if max uses is not set or equals infinity then return true cause its not a factor for whether user can check-in
984
		// or not.
985
		if ( ! $max_uses || $max_uses === EE_INF ) {
986
			return true;
987
		}
988
989
		//does this datetime have a checkin record?  If so, then the dtt count has already been verified so we can just
990
		//go ahead and toggle.
991
		if ( EEM_Checkin::instance()->exists( array( array( 'REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID ) ) ) ) {
992
			return true;
993
		}
994
995
		//made it here so the last check is whether the number of checkins per unique datetime on this registration
996
		//disallows further check-ins.
997
		$count_unique_dtt_checkins = EEM_Checkin::instance()->count( array( array( 'REG_ID' => $this->ID(), 'CHK_in' => true ) ), 'DTT_ID', true );
998
		// checkins have already reached their max number of uses
999
		// so registrant can NOT checkin
1000
		if ( $count_unique_dtt_checkins >= $max_uses ) {
1001
			EE_Error::add_error( __( 'Check-in denied because number of datetime uses for the ticket has been reached or exceeded.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__ );
1002
			return false;
1003
		}
1004
		return true;
1005
	}
1006
1007
1008
1009
	/**
1010
	 * toggle Check-in status for this registration
1011
	 *
1012
	 * Check-ins are toggled in the following order:
1013
	 * never checked in -> checked in
1014
	 * checked in -> checked out
1015
	 * checked out -> checked in
1016
	 *
1017
	 *
1018
	 * @param  int $DTT_ID include specific datetime to toggle Check-in for.  If not included or null, then it is assumed primary datetime is being toggled.
1019
	 * @param  bool $verify  If true then can_checkin() is used to verify whether the person can be checked in or not.  Otherwise this forces change in checkin status.
1020
	 * @return int|BOOL            the chk_in status toggled to OR false if nothing got changed.
1021
	 */
1022
	public function toggle_checkin_status( $DTT_ID = null, $verify = false ) {
1023
		if ( empty( $DTT_ID ) ) {
1024
			$datetime = $this->get_related_primary_datetime();
1025
			$DTT_ID = $datetime->ID();
1026
		// verify the registration can checkin for the given DTT_ID
1027
		} elseif ( ! $this->can_checkin( $DTT_ID, $verify ) ) {
1028
			EE_Error::add_error(
1029
					sprintf(
1030
						__( 'The given registration (ID:%1$d) can not be checked in to the given DTT_ID (%2$d), because the registration does not have access', 'event_espresso'),
1031
						$this->ID(),
1032
						$DTT_ID
1033
					),
1034
					__FILE__, __FUNCTION__, __LINE__
1035
			);
1036
			return false;
1037
		}
1038
		$status_paths = array(
1039
			EE_Registration::checkin_status_never => EE_Registration::checkin_status_in,
1040
			EE_Registration::checkin_status_in => EE_Registration::checkin_status_out,
1041
			EE_Registration::checkin_status_out => EE_Registration::checkin_status_in
1042
		);
1043
		//start by getting the current status so we know what status we'll be changing to.
1044
		$cur_status = $this->check_in_status_for_datetime( $DTT_ID, NULL );
1045
		$status_to = $status_paths[ $cur_status ];
1046
		// database only records true for checked IN or false for checked OUT
1047
		// no record ( null ) means checked in NEVER, but we obviously don't save that
1048
		$new_status = $status_to == EE_Registration::checkin_status_in ? true : false;
1049
		// add relation - note Check-ins are always creating new rows
1050
		// because we are keeping track of Check-ins over time.
1051
		// Eventually we'll probably want to show a list table
1052
		// for the individual Check-ins so that they can be managed.
1053
		$checkin = EE_Checkin::new_instance( array(
1054
				'REG_ID' => $this->ID(),
1055
				'DTT_ID' => $DTT_ID,
1056
				'CHK_in' => $new_status
1057
		) );
1058
		// if the record could not be saved then return false
1059
		if ( $checkin->save() === 0 ) {
1060
			if ( WP_DEBUG ) {
1061
				global $wpdb;
1062
				$error = sprintf(
1063
					__( 'Registration check in update failed because of the following database error: %1$s%2$s', 'event_espresso' ),
1064
					'<br />',
1065
					$wpdb->last_error
1066
				);
1067
			} else {
1068
				$error = __( 'Registration check in update failed because of an unknown database error', 'event_espresso' );
1069
			}
1070
			EE_Error::add_error( $error, __FILE__, __FUNCTION__, __LINE__ );
1071
			return false;
1072
		}
1073
		return $status_to;
1074
	}
1075
1076
1077
1078
	/**
1079
	 * Gets the primary datetime related to this registration via the related Event to this registration
1080
	 * @return EE_Datetime
1081
	 */
1082
	public function get_related_primary_datetime() {
1083
		return $this->event()->primary_datetime();
1084
	}
1085
1086
1087
1088
	/**
1089
	 * This method simply returns the check-in status for this registration and the given datetime.
1090
	 * @param  int          $DTT_ID  The ID of the datetime we're checking against (if empty we'll get the primary datetime for this registration (via event) and use it's ID);
1091
	 * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id.
1092
	 * @return int            Integer representing Check-in status.
1093
	 */
1094
	public function check_in_status_for_datetime( $DTT_ID = 0, $checkin = NULL ) {
1095
		if ( empty( $DTT_ID ) && ! $checkin instanceof EE_Checkin ) {
1096
			$datetime = $this->get_related_primary_datetime();
1097
			if ( ! $datetime instanceof EE_Datetime ) {
1098
				return 0;
1099
			}
1100
			$DTT_ID = $datetime->ID();
1101
		//verify the registration can checkin for the given DTT_ID
1102
		}
1103
		//get checkin object (if exists)
1104
		$checkin = $checkin instanceof EE_Checkin ? $checkin : $this->get_first_related( 'Checkin', array( array( 'DTT_ID' => $DTT_ID ), 'order_by' => array( 'CHK_timestamp' => 'DESC' ) ) );
1105
		if ( $checkin instanceof EE_Checkin ) {
1106
			if ( $checkin->get( 'CHK_in' ) ) {
1107
				return EE_Registration::checkin_status_in; //checked in
1108
			} else {
1109
				return EE_Registration::checkin_status_out; //had checked in but is now checked out.
1110
			}
1111
		} else {
1112
			return EE_Registration::checkin_status_never; //never been checked in
1113
		}
1114
	}
1115
1116
1117
1118
	/**
1119
	 * This method returns a localized message for the toggled Check-in message.
1120
	 * @param  int $DTT_ID include specific datetime to get the correct Check-in message.  If not included or null, then it is assumed Check-in for primary datetime was toggled.
1121
	 * @param bool $error  This just flags that you want an error message returned. This is put in so that the error message can be customized with the attendee name.
1122
	 * @return string         internationalized message
1123
	 */
1124
	public function get_checkin_msg( $DTT_ID, $error = FALSE ) {
1125
		//let's get the attendee first so we can include the name of the attendee
1126
		$attendee = $this->get_first_related( 'Attendee' );
1127
		if ( $attendee instanceof EE_Attendee ) {
1128
			if ( $error ) {
1129
				return sprintf( __( "%s's check-in status was not changed.", "event_espresso" ), $attendee->full_name() );
1130
			}
1131
			$cur_status = $this->check_in_status_for_datetime( $DTT_ID );
1132
			//what is the status message going to be?
1133
			switch ( $cur_status ) {
1134
				case EE_Registration::checkin_status_never :
1135
					return sprintf( __( "%s has been removed from Check-in records", "event_espresso" ), $attendee->full_name() );
1136
					break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1137
				case EE_Registration::checkin_status_in :
1138
					return sprintf( __( '%s has been checked in', 'event_espresso' ), $attendee->full_name() );
1139
					break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1140
				case EE_Registration::checkin_status_out :
1141
					return sprintf( __( '%s has been checked out', 'event_espresso' ), $attendee->full_name() );
1142
					break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1143
			}
1144
		}
1145
		return __( "The check-in status could not be determined.", "event_espresso" );
1146
	}
1147
1148
1149
1150
	/**
1151
	 * Returns the related EE_Transaction to this registration
1152
	 * @return EE_Transaction
1153
	 */
1154
	public function transaction() {
1155
		return $this->get_first_related( 'Transaction' );
1156
	}
1157
1158
1159
1160
1161
	/**
1162
	 *        get Registration Code
1163
	 * @access        public
1164
	 */
1165
	public function reg_code() {
1166
		return $this->get( 'REG_code' );
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->get('REG_code'); (boolean) is incompatible with the return type declared by the interface EEI_Registration::reg_code of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
1167
	}
1168
1169
1170
1171
	/**
1172
	 *        get Transaction ID
1173
	 * @access        public
1174
	 */
1175
	public function transaction_ID() {
1176
		return $this->get( 'TXN_ID' );
1177
	}
1178
1179
1180
1181
	/**
1182
	 * @return int
1183
	 */
1184
	public function ticket_ID() {
1185
		return $this->get( 'TKT_ID' );
1186
	}
1187
1188
1189
1190
	/**
1191
	 *        Set Registration Code
1192
	 *
1193
	 * @access    public
1194
	 * @param    string $REG_code Registration Code
1195
	 * @param	boolean $use_default
1196
	 */
1197
	public function set_reg_code( $REG_code, $use_default = FALSE ) {
1198
		if ( empty( $REG_code )) {
1199
			EE_Error::add_error( __( 'REG_code can not be empty.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
1200
			return;
1201
		}
1202
		if ( ! $this->reg_code() ) {
1203
			parent::set( 'REG_code', $REG_code, $use_default );
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (set() instead of set_reg_code()). Are you sure this is correct? If so, you might want to change this to $this->set().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
1204
		} else {
1205
			EE_Error::doing_it_wrong(
1206
				__CLASS__ . '::' . __FUNCTION__,
1207
				__( 'Can not change a registration REG_code once it has been set.', 'event_espresso' ),
1208
				'4.6.0'
1209
			);
1210
		}
1211
	}
1212
1213
1214
1215
1216
	/**
1217
	 * Returns all other registrations in the same group as this registrant who have the same ticket option.
1218
	 *
1219
	 * Note, if you want to just get all registrations in the same transaction (group), use:
1220
	 * 	$registration->transaction()->registrations();
1221
	 *
1222
	 * @since 4.5.0
1223
	 *
1224
	 * @return EE_Registration[]  or empty array if this isn't a group registration.
1225
	 */
1226
	public function get_all_other_registrations_in_group() {
1227
		if ( $this->group_size() < 2 ) {
1228
			return array();
1229
		}
1230
1231
		$query[0] = array(
0 ignored issues
show
Coding Style Comprehensibility introduced by
$query was never initialized. Although not strictly required by PHP, it is generally a good practice to add $query = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1232
			'TXN_ID' => $this->transaction_ID(),
1233
			'REG_ID' => array( '!=', $this->ID() ),
1234
			'TKT_ID' => $this->ticket_ID()
1235
			);
1236
1237
		$registrations = $this->get_model()->get_all( $query );
0 ignored issues
show
Bug introduced by
The method get_all cannot be called on $this->get_model() (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1238
		return $registrations;
1239
	}
1240
1241
1242
1243
	/**
1244
	 * @param array $query_params
1245
	 * @return \EE_Registration[]
1246
	 */
1247
	public function payments( $query_params = array() ) {
1248
		return $this->get_many_related( 'Payment', $query_params );
1249
	}
1250
1251
1252
1253
	/**
1254
	 * @param array $query_params
1255
	 * @return \EE_Registration[]
1256
	 */
1257
	public function registration_payments( $query_params = array() ) {
1258
		return $this->get_many_related( 'Registration_Payment', $query_params );
1259
	}
1260
1261
1262
1263
	/**
1264
	 * @deprecated
1265
	 * @since 4.7.0
1266
	 * @access 	public
1267
	 */
1268
	public function price_paid() {
1269
		EE_Error::doing_it_wrong( 'EE_Registration::price_paid()', __( 'This method is deprecated, please use EE_Registration::final_price() instead.', 'event_espresso' ), '4.7.0' );
1270
		return $this->final_price();
1271
	}
1272
1273
1274
1275
	/**
1276
	 * @deprecated
1277
	 * @since 4.7.0
1278
	 * @access    public
1279
	 * @param    float $REG_final_price
1280
	 */
1281
	public function set_price_paid( $REG_final_price = 0.00 ) {
1282
		EE_Error::doing_it_wrong( 'EE_Registration::set_price_paid()', __( 'This method is deprecated, please use EE_Registration::set_final_price() instead.', 'event_espresso' ), '4.7.0' );
1283
		$this->set_final_price( $REG_final_price );
1284
	}
1285
1286
1287
1288
	/**
1289
	 * @deprecated
1290
	 * @since 4.7.0
1291
	 * @return string
1292
	 */
1293
	public function pretty_price_paid() {
1294
		EE_Error::doing_it_wrong( 'EE_Registration::pretty_price_paid()', __( 'This method is deprecated, please use EE_Registration::pretty_final_price() instead.', 'event_espresso' ), '4.7.0' );
1295
		return $this->pretty_final_price();
1296
	}
1297
1298
1299
}
1300
/* End of file EE_Registration.class.php */
1301
/* Location: includes/classes/EE_Registration.class.php */
1302