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

EE_Registration::ticket_ID()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php use EventEspresso\core\exceptions\EntityNotFoundException;
2
3
if ( !defined( 'EVENT_ESPRESSO_VERSION' ) ) {
4
	exit( 'No direct script access allowed' );
5
}
6
/**
7
 * EE_Registration class
8
 *
9
 * @package 			Event Espresso
10
 * @subpackage 	includes/classes/EE_Registration.class.php
11
 * @author 				Mike Nelson, Brent Christensen
12
 */
13
class EE_Registration extends EE_Soft_Delete_Base_Class implements EEI_Registration, EEI_Admin_Links {
14
15
16
	/**
17
	 * Used to reference when a registration has never been checked in.
18
	 * @type int
19
	 */
20
	const checkin_status_never = 2;
21
22
	/**
23
	 * Used to reference when a registration has been checked in.
24
	 * @type int
25
	 */
26
	const checkin_status_in = 1;
27
28
29
	/**
30
	 * Used to reference when a registration has been checked out.
31
	 * @type int
32
	 */
33
	const checkin_status_out = 0;
34
35
36
37
	/**
38
	 *
39
	 * @param array $props_n_values  incoming values
40
	 * @param string $timezone  incoming timezone (if not set the timezone set for the website will be
41
	 *                          		used.)
42
	 * @param array $date_formats  incoming date_formats in an array where the first value is the
43
	 *                             		    date_format and the second value is the time format
44
	 * @return EE_Registration
45
	 */
46
	public static function new_instance( $props_n_values = array(), $timezone = null, $date_formats = array() ) {
47
		$has_object = parent::_check_for_object( $props_n_values, __CLASS__, $timezone, $date_formats );
0 ignored issues
show
Bug introduced by
It seems like $timezone defined by parameter $timezone on line 46 can also be of type string; however, EE_Base_Class::_check_for_object() does only seem to accept null, 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...
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...
48
		return $has_object ? $has_object : new self( $props_n_values, false, $timezone, $date_formats );
49
	}
50
51
52
53
	/**
54
	 * @param array $props_n_values  incoming values from the database
55
	 * @param string $timezone  incoming timezone as set by the model.  If not set the timezone for
56
	 *                          		the website will be used.
57
	 * @return EE_Registration
58
	 */
59
	public static function new_instance_from_db( $props_n_values = array(), $timezone = null ) {
60
		return new self( $props_n_values, TRUE, $timezone );
61
	}
62
63
64
65
	/**
66
	 *        Set Event ID
67
	 *
68
	 * @access        public
69
	 * @param        int $EVT_ID Event ID
70
	 */
71
	public function set_event( $EVT_ID = 0 ) {
72
		$this->set( 'EVT_ID', $EVT_ID );
73
	}
74
75
76
77
	/**
78
	 * 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
79
	 * @param string $field_name
80
	 * @param mixed  $field_value
81
	 * @param bool   $use_default
82
	 */
83
	public function set( $field_name, $field_value, $use_default = FALSE ) {
84
		switch( $field_name ) {
85
			case 'REG_code' :
86
				if ( ! empty( $field_value ) && $this->reg_code() == '' ) {
87
					$this->set_reg_code( $field_value, $use_default );
88
				}
89
				break;
90
			case 'STS_ID' :
91
				$this->set_status( $field_value, $use_default );
92
				break;
93
			default :
94
				parent::set( $field_name, $field_value, $use_default );
95
		}
96
	}
97
98
99
100
	/**
101
	 * Set Status ID
102
	 * updates the registration status and ALSO...
103
	 * calls reserve_registration_space() if the reg status changes TO approved from any other reg status
104
	 * calls release_registration_space() if the reg status changes FROM approved to any other reg status
105
	 *
106
	 * @access        public
107
	 * @param string  $new_STS_ID
108
	 * @param boolean $use_default
109
	 * @return bool
110
	 * @throws \EE_Error
111
	 */
112
	public function set_status( $new_STS_ID = NULL, $use_default = FALSE ) {
113
		// get current REG_Status
114
		$old_STS_ID = $this->status_ID();
115
		// if status has changed
116
		if (
117
			$this->ID() // ensure registration is in the db
118
			&& $old_STS_ID != $new_STS_ID // and that status has actually changed
119
			&& ! empty( $old_STS_ID ) // and that old status is actually set
120
			&& ! empty( $new_STS_ID ) // as well as the new status
121
		) {
122
			// TO approved
123
			if ( $new_STS_ID === EEM_Registration::status_id_approved ) {
124
				// reserve a space by incrementing ticket and datetime sold values
125
				$this->_reserve_registration_space();
126
				do_action( 'AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID );
127
			// OR FROM  approved
128
			} else if ( $old_STS_ID === EEM_Registration::status_id_approved ) {
129
				// release a space by decrementing ticket and datetime sold values
130
				$this->_release_registration_space();
131
				do_action( 'AHEE__EE_Registration__set_status__from_approved', $this, $old_STS_ID, $new_STS_ID );
132
			}
133
			// update status
134
			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...
135
			/** @type EE_Registration_Processor $registration_processor */
136
			$registration_processor = EE_Registry::instance()->load_class( 'Registration_Processor' );
137
			/** @type EE_Transaction_Processor $transaction_processor */
138
			$transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' );
139
			/** @type EE_Transaction_Payments $transaction_payments */
140
			$transaction_payments = EE_Registry::instance()->load_class( 'Transaction_Payments' );
141
			// these reg statuses should not be considered in any calculations involving monies owing
142
			$closed_reg_statuses = ! empty( $closed_reg_statuses )
0 ignored issues
show
Bug introduced by
The variable $closed_reg_statuses seems only to be defined at a later point. As such the call to empty() seems to always evaluate to true.

This check marks calls to isset(...) or empty(...) that are found before the variable itself is defined. These will always have the same result.

This is likely the result of code being shifted around. Consider removing these calls.

Loading history...
143
				? $closed_reg_statuses
144
				: EEM_Registration::closed_reg_statuses();
145
			if (
146
				in_array( $new_STS_ID, $closed_reg_statuses )
147
				&& ! in_array( $old_STS_ID, $closed_reg_statuses )
148
			) {
149
				// cancelled or declined registration
150
				$registration_processor->update_registration_after_being_canceled_or_declined(
151
					$this,
152
					$closed_reg_statuses
153
				);
154
				$transaction_processor->update_transaction_after_canceled_or_declined_registration(
155
					$this,
156
					$closed_reg_statuses,
157
					false
158
				);
159
			} else if (
160
				in_array( $old_STS_ID, $closed_reg_statuses )
161
				&& ! in_array( $new_STS_ID, $closed_reg_statuses )
162
			) {
163
				// reinstating cancelled or declined registration
164
				$registration_processor->update_canceled_or_declined_registration_after_being_reinstated(
165
					$this,
166
					$closed_reg_statuses
167
				);
168
				$transaction_processor->update_transaction_after_reinstating_canceled_registration( $this );
169
			}
170
			$transaction_payments->recalculate_transaction_total( $this->transaction(), false );
171
			$transaction_payments->update_transaction_status_based_on_total_paid( $this->transaction(), true );
0 ignored issues
show
Deprecated Code introduced by
The method EE_Transaction_Payments:...s_based_on_total_paid() has been deprecated with message: 4.9.1

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
172
			do_action( 'AHEE__EE_Registration__set_status__after_update', $this );
173
			return TRUE;
174
		} else {
175
			//even though the old value matches the new value, it's still good to
176
			//allow the parent set method to have a say
177
			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...
178
			return TRUE;
179
		}
180
	}
181
182
183
184
	/**
185
	 *        get Status ID
186
	 * @access        public
187
	 */
188
	public function status_ID() {
189
		return $this->get( 'STS_ID' );
190
	}
191
192
193
194
	/**
195
	 * increments this registration's related ticket sold and corresponding datetime sold values
196
	 * @return void
197
	 */
198
	private function _reserve_registration_space() {
199
		$ticket = $this->ticket();
200
		$ticket->increase_sold();
201
		$ticket->save();
202
		// possibly set event status to sold out
203
		$this->event()->perform_sold_out_status_check();
204
	}
205
206
207
208
	/**
209
	 * Gets the ticket this registration is for
210
	 *
211
	 * @param boolean $include_archived whether to include archived tickets or not.
212
	 * @return EE_Ticket
213
	 */
214
	public function ticket( $include_archived = TRUE ) {
215
		$query_params = array();
216
		if ( $include_archived ) {
217
			$query_params[ 'default_where_conditions' ] = 'none';
218
		}
219
		return $this->get_first_related( 'Ticket', $query_params );
220
	}
221
222
223
224
	/**
225
	 * Gets the event this registration is for
226
	 * @return EE_Event
227
	 */
228
	public function event() {
229
		$event = $this->get_first_related('Event');
230
		if ( ! $event instanceof \EE_Event) {
231
			throw new EntityNotFoundException('Event ID', $this->event_ID());
232
		}
233
		return $event;
234
	}
235
236
237
238
	/**
239
	 * 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.
240
	 *
241
	 * @since 4.5.0
242
	 *
243
	 * @return int
244
	 */
245
	public function wp_user() {
246
		$event = $this->event();
247
		if ( $event instanceof EE_Event ) {
248
			return $event->wp_user();
249
		}
250
		return 0;
251
	}
252
253
254
255
	/**
256
	 * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values
257
	 * @return void
258
	 */
259
	private function _release_registration_space() {
260
		$ticket = $this->ticket();
261
		$ticket->decrease_sold();
262
		$ticket->save();
263
	}
264
265
266
267
	/**
268
	 *        Set Attendee ID
269
	 *
270
	 * @access        public
271
	 * @param        int $ATT_ID Attendee ID
272
	 */
273
	public function set_attendee_id( $ATT_ID = 0 ) {
274
		$this->set( 'ATT_ID', $ATT_ID );
275
	}
276
277
278
279
	/**
280
	 *        Set Transaction ID
281
	 *
282
	 * @access        public
283
	 * @param        int $TXN_ID Transaction ID
284
	 */
285
	public function set_transaction_id( $TXN_ID = 0 ) {
286
		$this->set( 'TXN_ID', $TXN_ID );
287
	}
288
289
290
291
	/**
292
	 *        Set Session
293
	 *
294
	 * @access    public
295
	 * @param    string $REG_session PHP Session ID
296
	 */
297
	public function set_session( $REG_session = '' ) {
298
		$this->set( 'REG_session', $REG_session );
299
	}
300
301
302
303
	/**
304
	 *        Set Registration URL Link
305
	 *
306
	 * @access    public
307
	 * @param    string $REG_url_link Registration URL Link
308
	 */
309
	public function set_reg_url_link( $REG_url_link = '' ) {
310
		$this->set( 'REG_url_link', $REG_url_link );
311
	}
312
313
314
315
	/**
316
	 *        Set Attendee Counter
317
	 *
318
	 * @access        public
319
	 * @param        int $REG_count Primary Attendee
320
	 */
321
	public function set_count( $REG_count = 1 ) {
322
		$this->set( 'REG_count', $REG_count );
323
	}
324
325
326
327
	/**
328
	 *        Set Group Size
329
	 *
330
	 * @access        public
331
	 * @param        boolean $REG_group_size Group Registration
332
	 */
333
	public function set_group_size( $REG_group_size = FALSE ) {
334
		$this->set( 'REG_group_size', $REG_group_size );
335
	}
336
337
338
339
	/**
340
	 *    is_not_approved -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_not_approved
341
	 *
342
	 * @access        public
343
	 * @return        boolean
344
	 */
345
	public function is_not_approved() {
346
		return $this->status_ID() == EEM_Registration::status_id_not_approved ? TRUE : FALSE;
347
	}
348
349
350
351
	/**
352
	 *    is_pending_payment -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_pending_payment
353
	 *
354
	 * @access        public
355
	 * @return        boolean
356
	 */
357
	public function is_pending_payment() {
358
		return $this->status_ID() == EEM_Registration::status_id_pending_payment ? TRUE : FALSE;
359
	}
360
361
362
363
	/**
364
	 *    is_approved -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved
365
	 *
366
	 * @access        public
367
	 * @return        boolean
368
	 */
369
	public function is_approved() {
370
		return $this->status_ID() == EEM_Registration::status_id_approved ? TRUE : FALSE;
371
	}
372
373
374
375
	/**
376
	 *    is_cancelled -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled
377
	 *
378
	 * @access        public
379
	 * @return        boolean
380
	 */
381
	public function is_cancelled() {
382
		return $this->status_ID() == EEM_Registration::status_id_cancelled ? TRUE : FALSE;
383
	}
384
385
386
387
	/**
388
	 *    is_declined -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined
389
	 *
390
	 * @access        public
391
	 * @return        boolean
392
	 */
393
	public function is_declined() {
394
		return $this->status_ID() == EEM_Registration::status_id_declined ? TRUE : FALSE;
395
	}
396
397
398
399
	/**
400
	 *    is_incomplete -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_incomplete
401
	 *
402
	 * @access        public
403
	 * @return        boolean
404
	 */
405
	public function is_incomplete() {
406
		return $this->status_ID() == EEM_Registration::status_id_incomplete ? TRUE : FALSE;
407
	}
408
409
410
411
	/**
412
	 *        Set Registration Date
413
	 *
414
	 * @access        public
415
	 * @param        mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of Date
416
	 */
417
	public function set_reg_date( $REG_date = FALSE ) {
418
		$this->set( 'REG_date', $REG_date );
419
	}
420
421
422
423
	/**
424
	 *    Set final price owing for this registration after all ticket/price modifications
425
	 *
426
	 * @access    public
427
	 * @param    float $REG_final_price
428
	 */
429
	public function set_final_price( $REG_final_price = 0.00 ) {
430
		$this->set( 'REG_final_price', $REG_final_price );
431
	}
432
433
434
435
	/**
436
	 *    Set amount paid towards this registration's final price
437
	 *
438
	 * @access    public
439
	 * @param    float $REG_paid
440
	 */
441
	public function set_paid( $REG_paid = 0.00 ) {
442
		$this->set( 'REG_paid', $REG_paid );
443
	}
444
445
446
447
	/**
448
	 *        Attendee Is Going
449
	 *
450
	 * @access        public
451
	 * @param        boolean $REG_att_is_going Attendee Is Going
452
	 */
453
	public function set_att_is_going( $REG_att_is_going = FALSE ) {
454
		$this->set( 'REG_att_is_going', $REG_att_is_going );
455
	}
456
457
458
459
	/**
460
	 * Gets the related attendee
461
	 * @return EE_Attendee
462
	 */
463
	public function attendee() {
464
		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...
465
	}
466
467
468
469
	/**
470
	 *        get Event ID
471
	 * @access        public
472
	 */
473
	public function event_ID() {
474
		return $this->get( 'EVT_ID' );
475
	}
476
477
478
479
	/**
480
	 *        get Event ID
481
	 * @access        public
482
	 */
483
	public function event_name() {
484
		$event = $this->event_obj();
485
		if ( $event ) {
486
			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...
487
		} else {
488
			return NULL;
489
		}
490
	}
491
492
493
494
	/**
495
	 * Fetches the event this registration is for
496
	 * @return EE_Event
497
	 */
498
	public function event_obj() {
499
		return $this->get_first_related( 'Event' );
500
	}
501
502
503
504
	/**
505
	 *        get Attendee ID
506
	 * @access        public
507
	 */
508
	public function attendee_ID() {
509
		return $this->get( 'ATT_ID' );
510
	}
511
512
513
514
	/**
515
	 *        get PHP Session ID
516
	 * @access        public
517
	 */
518
	public function session_ID() {
519
		return $this->get( 'REG_session' );
520
	}
521
522
523
524
	/**
525
	 * Gets the string which represents the URL trigger for the receipt template in the message template system.
526
	 * @param string $messenger 'pdf' or 'html'.  Default 'html'.
527
	 * @return string
528
	 */
529
	public function receipt_url( $messenger = 'html' ) {
530
531
		/**
532
		 * 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.
533
		 *
534
		 * @since 4.5.0
535
		 */
536
		$template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php';
537
		$has_custom = EEH_Template::locate_template( $template_relative_path , array(), TRUE, TRUE, TRUE );
538
539
		if ( $has_custom ) {
540
			return add_query_arg( array( 'receipt' => 'true' ), $this->invoice_url( 'launch' ) );
541
		}
542
		return apply_filters( 'FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt' );
543
	}
544
545
546
547
548
	/**
549
	 * Gets the string which represents the URL trigger for the invoice template in the message template system.
550
	 * @param string $messenger 'pdf' or 'html'.  Default 'html'.
551
	 * @return string
552
	 */
553
	public function invoice_url( $messenger = 'html' ) {
554
		/**
555
		 * 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.
556
		 *
557
		 * @since 4.5.0
558
		 */
559
		$template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php';
560
		$has_custom = EEH_Template::locate_template( $template_relative_path , array(), TRUE, TRUE, TRUE );
561
562
		if ( $has_custom ) {
563
			if ( $messenger == 'html' ) {
564
				return $this->invoice_url( 'launch' );
565
			}
566
			$route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice';
567
568
			$query_args = array( 'ee' => $route, 'id' => $this->reg_url_link() );
569
			if ( $messenger == 'html' ) {
570
				$query_args['html'] = TRUE;
571
			}
572
			return add_query_arg( $query_args, get_permalink( EE_Registry::instance()->CFG->core->thank_you_page_id ) );
573
		}
574
		return apply_filters( 'FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice' );
575
	}
576
577
578
579
	/**
580
	 * get Registration URL Link
581
	 *
582
	 * @access public
583
	 * @return string
584
	 * @throws \EE_Error
585
	 */
586
	public function reg_url_link() {
587
		return (string)$this->get( 'REG_url_link' );
588
	}
589
590
591
592
	/**
593
	 * Echoes out invoice_url()
594
	 * @param string $type 'download','launch', or 'html' (default is 'launch')
595
	 * @return void
596
	 */
597
	public function e_invoice_url( $type = 'launch' ) {
598
		echo $this->invoice_url( $type );
599
	}
600
601
602
603
	/**
604
	 * Echoes out payment_overview_url
605
	 */
606
	public function e_payment_overview_url() {
607
		echo $this->payment_overview_url();
608
	}
609
610
611
612
	/**
613
	 * Gets the URL of the thank you page with this registration REG_url_link added as
614
	 * a query parameter
615
	 * @return string
616
	 */
617
	public function payment_overview_url() {
618
		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() );
619
	}
620
621
622
623
	/**
624
	 * Gets the URL of the thank you page with this registration REG_url_link added as
625
	 * a query parameter
626
	 * @return string
627
	 */
628
	public function edit_attendee_information_url() {
629
		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() );
630
	}
631
632
633
634
	/**
635
	 * Simply generates and returns the appropriate admin_url link to edit this registration
636
	 * @return string
637
	 */
638
	public function get_admin_edit_url() {
639
		return EEH_URL::add_query_args_and_nonce( array( 'page' => 'espresso_registrations', 'action' => 'view_registration', '_REG_ID' => $this->ID() ), admin_url( 'admin.php' ) );
640
	}
641
642
643
644
	/**
645
	 *    is_primary_registrant?
646
	 * @access        public
647
	 */
648
	public function is_primary_registrant() {
649
		return $this->get( 'REG_count' ) == 1 ? TRUE : FALSE;
650
	}
651
652
653
654
	/**
655
	 * This returns the primary registration object for this registration group (which may be this object).
656
	 * @return EE_Registration
657
	 */
658
	public function get_primary_registration()  {
659
		if ( $this->is_primary_registrant() )
660
			return $this;
661
662
		//k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1
663
		$primary_registrant = EEM_Registration::instance()->get_one( array( array('TXN_ID' => $this->transaction_ID(), 'REG_count' => 1 ) ) );
664
		return $primary_registrant;
665
	}
666
667
668
669
	/**
670
	*		get  Attendee Number
671
	* 		@access		public
672
	*/
673
	public function count() {
674
		return $this->get( 'REG_count' );
675
	}
676
677
678
679
	/**
680
	 *        get Group Size
681
	 * @access        public
682
	 */
683
	public function group_size() {
684
		return $this->get( 'REG_group_size' );
685
	}
686
687
688
689
	/**
690
	 *        get Registration Date
691
	 * @access        public
692
	 */
693
	public function date() {
694
		return $this->get( 'REG_date' );
695
	}
696
697
698
699
	/**
700
	 * gets a pretty date
701
	 * @param string $date_format
702
	 * @param string $time_format
703
	 * @return string
704
	 */
705
	public function pretty_date( $date_format = NULL, $time_format = NULL ) {
706
		return $this->get_datetime( 'REG_date', $date_format, $time_format );
707
	}
708
709
710
711
	/**
712
	 * final_price
713
	 * the registration's share of the transaction total, so that the
714
	 * sum of all the transaction's REG_final_prices equal the transaction's total
715
	 * @access        public
716
	 * @return    float
717
	 */
718
	public function final_price() {
719
		return $this->get( 'REG_final_price' );
720
	}
721
722
723
724
	/**
725
	 * pretty_final_price
726
	 *  final price as formatted string, with correct decimal places and currency symbol
727
	 * @return string
728
	 */
729
	public function pretty_final_price() {
730
		return $this->get_pretty( 'REG_final_price' );
731
	}
732
733
734
735
	/**
736
	 * get paid (yeah)
737
	 * @access        public
738
	 * @return 	float
739
	 */
740
	public function paid() {
741
		return $this->get( 'REG_paid' );
742
	}
743
744
745
746
	/**
747
	 * pretty_paid
748
	 * @access        public
749
	 * @return 	float
750
	 */
751
	public function pretty_paid() {
752
		return $this->get_pretty( 'REG_paid' );
753
	}
754
755
756
757
	/**
758
	 * owes_monies_and_can_pay
759
	 * whether or not this registration has monies owing and it's' status allows payment
760
	 * @access        public
761
	 * @param array $requires_payment
762
	 * @return bool
763
	 */
764
	public function owes_monies_and_can_pay( $requires_payment = array()) {
765
		// these reg statuses require payment (if event is not free)
766
		$requires_payment = ! empty( $requires_payment ) ? $requires_payment : EEM_Registration::reg_statuses_that_allow_payment();
767
		if (
768
			in_array( $this->status_ID(), $requires_payment ) &&
769
			$this->final_price() != 0 &&
770
			$this->final_price() != $this->paid()
771
		) {
772
			return true;
773
		} else {
774
			return false;
775
		}
776
	}
777
778
779
780
	/**
781
	 * Prints out the return value of $this->pretty_status()
782
	 * @param bool $show_icons
783
	 * @return void
784
	 */
785
	public function e_pretty_status( $show_icons = FALSE ) {
786
		echo $this->pretty_status( $show_icons );
787
	}
788
789
790
791
792
	/**
793
	 * Returns a nice version of the status for displaying to customers
794
	 * @param bool $show_icons
795
	 * @return string
796
	 */
797
	public function pretty_status( $show_icons = FALSE ) {
798
		$status = EEM_Status::instance()->localized_status( array( $this->status_ID() => __( 'unknown', 'event_espresso' ) ), FALSE, 'sentence' );
799
		$icon = '';
800
		switch ( $this->status_ID() ) {
801
			case EEM_Registration::status_id_approved:
802
				$icon = $show_icons ? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>' : '';
803
				break;
804
			case EEM_Registration::status_id_pending_payment:
805
				$icon = $show_icons ? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>' : '';
806
				break;
807
			case EEM_Registration::status_id_not_approved:
808
				$icon = $show_icons ? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>' : '';
809
				break;
810
			case EEM_Registration::status_id_cancelled:
811
				$icon = $show_icons ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>' : '';
812
				break;
813
			case EEM_Registration::status_id_incomplete:
814
				$icon = $show_icons ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>' : '';
815
				break;
816
			case EEM_Registration::status_id_declined:
817
				$icon = $show_icons ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' : '';
818
				break;
819
			case EEM_Registration::status_id_wait_list:
820
				$icon = $show_icons ? '<span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>' : '';
821
				break;
822
		}
823
		return $icon . $status[ $this->status_ID() ];
824
	}
825
826
827
828
	/**
829
	 *        get Attendee Is Going
830
	 * @access        public
831
	 */
832
	public function att_is_going() {
833
		return $this->get( 'REG_att_is_going' );
834
	}
835
836
837
838
	/**
839
	 * Gets related answers
840
	 * @param array $query_params like EEM_Base::get_all
841
	 * @return EE_Answer[]
842
	 */
843
	public function answers( $query_params = NULL ) {
844
		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 843 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...
845
	}
846
847
848
849
	/**
850
	 * Gets the registration's answer value to the specified question
851
	 * (either the question's ID or a question object)
852
	 * @param EE_Question|int $question
853
	 * @param bool            $pretty_value
854
	 * @return array|string if pretty_value= true, the result will always be a string
855
	 * (because the answer might be an array of answer values, so passing pretty_value=true
856
	 * will convert it into some kind of string)
857
	 */
858
	public function answer_value_to_question( $question, $pretty_value=true ) {
859
		$question_id = EEM_Question::instance()->ensure_is_ID($question);
860
		return EEM_Answer::instance()->get_answer_value_to_question($this,$question_id,$pretty_value);
861
	}
862
863
864
865
	/**
866
	 * question_groups
867
	 * returns an array of EE_Question_Group objects for this registration
868
	 *
869
	 * @return EE_Question_Group[]
870
	 */
871
	public function question_groups() {
872
		$question_groups = array();
873
		if ( $this->event() instanceof EE_Event ) {
874
			$question_groups = $this->event()->question_groups(
875
				array(
876
					array(
877
						'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false
878
					),
879
					'order_by' => array( 'QSG_order' => 'ASC' )
880
				)
881
			);
882
		}
883
		return $question_groups;
884
	}
885
886
887
888
	/**
889
	 * count_question_groups
890
	 * returns a count of the number of EE_Question_Group objects for this registration
891
	 *
892
	 * @return int
893
	 */
894
	public function count_question_groups() {
895
		$qg_count = 0;
896
		if ( $this->event() instanceof EE_Event ) {
897
			$qg_count = $this->event()->count_related(
898
				'Question_Group',
899
				array(
900
					array(
901
						'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false
902
					)
903
				)
904
			);
905
		}
906
		return $qg_count;
907
	}
908
909
910
911
	/**
912
	 * Returns the registration date in the 'standard' string format
913
	 * (function may be improved in the future to allow for different formats and timezones)
914
	 * @return string
915
	 */
916
	public function reg_date() {
917
		return $this->get_datetime( 'REG_date' );
918
	}
919
920
921
922
	/**
923
	 * Gets the datetime-ticket for this registration (ie, it can be used to isolate
924
	 * the ticket this registration purchased, or the datetime they have registered
925
	 * to attend)
926
	 * @return EE_Datetime_Ticket
927
	 */
928
	public function datetime_ticket() {
929
		return $this->get_first_related( 'Datetime_Ticket' );
930
	}
931
932
933
934
	/**
935
	 * Sets the registration's datetime_ticket.
936
	 * @param EE_Datetime_Ticket $datetime_ticket
937
	 * @return EE_Datetime_Ticket
938
	 */
939
	public function set_datetime_ticket( $datetime_ticket ) {
940
		return $this->_add_relation_to( $datetime_ticket, 'Datetime_Ticket' );
941
	}
942
	/**
943
	 * Gets deleted
944
	 * @return boolean
945
	 */
946
	public function deleted() {
947
		return $this->get( 'REG_deleted' );
948
	}
949
950
	/**
951
	 * Sets deleted
952
	 * @param boolean $deleted
953
	 * @return boolean
954
	 */
955
	public function set_deleted($deleted) {
956
		$this->set( 'REG_deleted', $deleted );
957
	}
958
959
960
961
	/**
962
	 * Get the status object of this object
963
	 * @return EE_Status
964
	 */
965
	public function status_obj() {
966
		return $this->get_first_related( 'Status' );
967
	}
968
969
970
971
	/**
972
	 * Returns the number of times this registration has checked into any of the datetimes
973
	 * its available for
974
	 * @return int
975
	 */
976
	public function count_checkins() {
977
		return $this->get_model()->count_related( $this, 'Checkin' );
978
	}
979
980
981
982
	/**
983
	 * 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)
984
	 * @return int
985
	 */
986
	public function count_checkins_not_checkedout() {
987
		return $this->get_model()->count_related( $this, 'Checkin', array( array( 'CHK_in' => 1 ) ) );
988
	}
989
990
991
992
	/**
993
	 * The purpose of this method is simply to check whether this registration can checkin to the given datetime.
994
	 *
995
	 * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against
996
	 * @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.
997
	 *
998
	 * @return bool
999
	 */
1000
	public function can_checkin( $DTT_OR_ID, $check_approved = TRUE ) {
1001
		$DTT_ID = EEM_Datetime::instance()->ensure_is_ID( $DTT_OR_ID );
1002
1003
		//first check registration status
1004
		if (  ( $check_approved && ! $this->is_approved() ) || ! $DTT_ID ) {
1005
			return false;
1006
		}
1007
		//is there a datetime ticket that matches this dtt_ID?
1008
		if ( ! ( EEM_Datetime_Ticket::instance()->exists( array( array( 'TKT_ID' => $this->get('TKT_ID' ), 'DTT_ID' => $DTT_ID ) ) ) ) ) {
1009
			return false;
1010
		}
1011
1012
		//final check is against TKT_uses
1013
		return $this->verify_can_checkin_against_TKT_uses( $DTT_ID );
1014
	}
1015
1016
1017
	/**
1018
	 * This method verifies whether the user can checkin for the given datetime considering the max uses value set on the ticket.
1019
	 *
1020
	 * To do this,  a query is done to get the count of the datetime records already checked into.  If the datetime given does
1021
	 * not have a check-in record and checking in for that datetime will exceed the allowed uses, then return false.  Otherwise return true.
1022
	 *
1023
	 * @param int | EE_Datetime  $DTT_OR_ID  The datetime the registration is being checked against
1024
	 * @return bool   true means can checkin.  false means cannot checkin.
1025
	 */
1026
	public function verify_can_checkin_against_TKT_uses( $DTT_OR_ID ) {
1027
		$DTT_ID = EEM_Datetime::instance()->ensure_is_ID( $DTT_OR_ID );
1028
1029
		if ( ! $DTT_ID ) {
1030
			return false;
1031
		}
1032
1033
		$max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF;
1034
1035
		// if max uses is not set or equals infinity then return true cause its not a factor for whether user can check-in
1036
		// or not.
1037
		if ( ! $max_uses || $max_uses === EE_INF ) {
1038
			return true;
1039
		}
1040
1041
		//does this datetime have a checkin record?  If so, then the dtt count has already been verified so we can just
1042
		//go ahead and toggle.
1043
		if ( EEM_Checkin::instance()->exists( array( array( 'REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID ) ) ) ) {
1044
			return true;
1045
		}
1046
1047
		//made it here so the last check is whether the number of checkins per unique datetime on this registration
1048
		//disallows further check-ins.
1049
		$count_unique_dtt_checkins = EEM_Checkin::instance()->count( array( array( 'REG_ID' => $this->ID(), 'CHK_in' => true ) ), 'DTT_ID', true );
1050
		// checkins have already reached their max number of uses
1051
		// so registrant can NOT checkin
1052
		if ( $count_unique_dtt_checkins >= $max_uses ) {
1053
			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__ );
1054
			return false;
1055
		}
1056
		return true;
1057
	}
1058
1059
1060
1061
	/**
1062
	 * toggle Check-in status for this registration
1063
	 *
1064
	 * Check-ins are toggled in the following order:
1065
	 * never checked in -> checked in
1066
	 * checked in -> checked out
1067
	 * checked out -> checked in
1068
	 *
1069
	 *
1070
	 * @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.
1071
	 * @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.
1072
	 * @return int|BOOL            the chk_in status toggled to OR false if nothing got changed.
1073
	 */
1074
	public function toggle_checkin_status( $DTT_ID = null, $verify = false ) {
1075
		if ( empty( $DTT_ID ) ) {
1076
			$datetime = $this->get_related_primary_datetime();
1077
			$DTT_ID = $datetime->ID();
1078
		// verify the registration can checkin for the given DTT_ID
1079
		} elseif ( ! $this->can_checkin( $DTT_ID, $verify ) ) {
1080
			EE_Error::add_error(
1081
					sprintf(
1082
						__( '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'),
1083
						$this->ID(),
1084
						$DTT_ID
1085
					),
1086
					__FILE__, __FUNCTION__, __LINE__
1087
			);
1088
			return false;
1089
		}
1090
		$status_paths = array(
1091
			EE_Registration::checkin_status_never => EE_Registration::checkin_status_in,
1092
			EE_Registration::checkin_status_in => EE_Registration::checkin_status_out,
1093
			EE_Registration::checkin_status_out => EE_Registration::checkin_status_in
1094
		);
1095
		//start by getting the current status so we know what status we'll be changing to.
1096
		$cur_status = $this->check_in_status_for_datetime( $DTT_ID, NULL );
1097
		$status_to = $status_paths[ $cur_status ];
1098
		// database only records true for checked IN or false for checked OUT
1099
		// no record ( null ) means checked in NEVER, but we obviously don't save that
1100
		$new_status = $status_to == EE_Registration::checkin_status_in ? true : false;
1101
		// add relation - note Check-ins are always creating new rows
1102
		// because we are keeping track of Check-ins over time.
1103
		// Eventually we'll probably want to show a list table
1104
		// for the individual Check-ins so that they can be managed.
1105
		$checkin = EE_Checkin::new_instance( array(
1106
				'REG_ID' => $this->ID(),
1107
				'DTT_ID' => $DTT_ID,
1108
				'CHK_in' => $new_status
1109
		) );
1110
		// if the record could not be saved then return false
1111
		if ( $checkin->save() === 0 ) {
1112
			if ( WP_DEBUG ) {
1113
				global $wpdb;
1114
				$error = sprintf(
1115
					__( 'Registration check in update failed because of the following database error: %1$s%2$s', 'event_espresso' ),
1116
					'<br />',
1117
					$wpdb->last_error
1118
				);
1119
			} else {
1120
				$error = __( 'Registration check in update failed because of an unknown database error', 'event_espresso' );
1121
			}
1122
			EE_Error::add_error( $error, __FILE__, __FUNCTION__, __LINE__ );
1123
			return false;
1124
		}
1125
		return $status_to;
1126
	}
1127
1128
1129
1130
	/**
1131
	 * Gets the primary datetime related to this registration via the related Event to this registration
1132
	 * @return EE_Datetime
1133
	 */
1134
	public function get_related_primary_datetime() {
1135
		return $this->event()->primary_datetime();
1136
	}
1137
1138
1139
1140
	/**
1141
	 * This method simply returns the check-in status for this registration and the given datetime.
1142
	 * @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);
1143
	 * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id.
1144
	 * @return int            Integer representing Check-in status.
1145
	 */
1146
	public function check_in_status_for_datetime( $DTT_ID = 0, $checkin = NULL ) {
1147
		if ( empty( $DTT_ID ) && ! $checkin instanceof EE_Checkin ) {
1148
			$datetime = $this->get_related_primary_datetime();
1149
			if ( ! $datetime instanceof EE_Datetime ) {
1150
				return 0;
1151
			}
1152
			$DTT_ID = $datetime->ID();
1153
		//verify the registration can checkin for the given DTT_ID
1154
		}
1155
		//get checkin object (if exists)
1156
		$checkin = $checkin instanceof EE_Checkin ? $checkin : $this->get_first_related( 'Checkin', array( array( 'DTT_ID' => $DTT_ID ), 'order_by' => array( 'CHK_timestamp' => 'DESC' ) ) );
1157
		if ( $checkin instanceof EE_Checkin ) {
1158
			if ( $checkin->get( 'CHK_in' ) ) {
1159
				return EE_Registration::checkin_status_in; //checked in
1160
			} else {
1161
				return EE_Registration::checkin_status_out; //had checked in but is now checked out.
1162
			}
1163
		} else {
1164
			return EE_Registration::checkin_status_never; //never been checked in
1165
		}
1166
	}
1167
1168
1169
1170
	/**
1171
	 * This method returns a localized message for the toggled Check-in message.
1172
	 * @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.
1173
	 * @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.
1174
	 * @return string         internationalized message
1175
	 */
1176
	public function get_checkin_msg( $DTT_ID, $error = FALSE ) {
1177
		//let's get the attendee first so we can include the name of the attendee
1178
		$attendee = $this->get_first_related( 'Attendee' );
1179
		if ( $attendee instanceof EE_Attendee ) {
1180
			if ( $error ) {
1181
				return sprintf( __( "%s's check-in status was not changed.", "event_espresso" ), $attendee->full_name() );
1182
			}
1183
			$cur_status = $this->check_in_status_for_datetime( $DTT_ID );
1184
			//what is the status message going to be?
1185
			switch ( $cur_status ) {
1186
				case EE_Registration::checkin_status_never :
1187
					return sprintf( __( "%s has been removed from Check-in records", "event_espresso" ), $attendee->full_name() );
1188
					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...
1189
				case EE_Registration::checkin_status_in :
1190
					return sprintf( __( '%s has been checked in', 'event_espresso' ), $attendee->full_name() );
1191
					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...
1192
				case EE_Registration::checkin_status_out :
1193
					return sprintf( __( '%s has been checked out', 'event_espresso' ), $attendee->full_name() );
1194
					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...
1195
			}
1196
		}
1197
		return __( "The check-in status could not be determined.", "event_espresso" );
1198
	}
1199
1200
1201
1202
	/**
1203
	 * Returns the related EE_Transaction to this registration
1204
	 * @return EE_Transaction
1205
	 */
1206
	public function transaction() {
1207
		$transaction = $this->get_first_related('Transaction');
1208
		if ( ! $transaction instanceof \EE_Transaction) {
1209
			throw new EntityNotFoundException('Transaction ID', $this->transaction_ID());
1210
		}
1211
		return $transaction;
1212
	}
1213
1214
1215
1216
1217
	/**
1218
	 *        get Registration Code
1219
	 * @access        public
1220
	 */
1221
	public function reg_code() {
1222
		return $this->get( 'REG_code' );
1223
	}
1224
1225
1226
1227
	/**
1228
	 *        get Transaction ID
1229
	 * @access        public
1230
	 */
1231
	public function transaction_ID() {
1232
		return $this->get( 'TXN_ID' );
1233
	}
1234
1235
1236
1237
	/**
1238
	 * @return int
1239
	 */
1240
	public function ticket_ID() {
1241
		return $this->get( 'TKT_ID' );
1242
	}
1243
1244
1245
1246
	/**
1247
	 *        Set Registration Code
1248
	 *
1249
	 * @access    public
1250
	 * @param    string $REG_code Registration Code
1251
	 * @param	boolean $use_default
1252
	 */
1253
	public function set_reg_code( $REG_code, $use_default = FALSE ) {
1254
		if ( empty( $REG_code )) {
1255
			EE_Error::add_error( __( 'REG_code can not be empty.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
1256
			return;
1257
		}
1258
		if ( ! $this->reg_code() ) {
1259
			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...
1260
		} else {
1261
			EE_Error::doing_it_wrong(
1262
				__CLASS__ . '::' . __FUNCTION__,
1263
				__( 'Can not change a registration REG_code once it has been set.', 'event_espresso' ),
1264
				'4.6.0'
1265
			);
1266
		}
1267
	}
1268
1269
1270
1271
1272
	/**
1273
	 * Returns all other registrations in the same group as this registrant who have the same ticket option.
1274
	 *
1275
	 * Note, if you want to just get all registrations in the same transaction (group), use:
1276
	 * 	$registration->transaction()->registrations();
1277
	 *
1278
	 * @since 4.5.0
1279
	 *
1280
	 * @return EE_Registration[]  or empty array if this isn't a group registration.
1281
	 */
1282
	public function get_all_other_registrations_in_group() {
1283
		if ( $this->group_size() < 2 ) {
1284
			return array();
1285
		}
1286
1287
		$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...
1288
			'TXN_ID' => $this->transaction_ID(),
1289
			'REG_ID' => array( '!=', $this->ID() ),
1290
			'TKT_ID' => $this->ticket_ID()
1291
			);
1292
1293
		$registrations = $this->get_model()->get_all( $query );
1294
		return $registrations;
1295
	}
1296
1297
	/**
1298
	 * Return the link to the admin details for the object.
1299
	 * @return string
1300
	 */
1301 View Code Duplication
	public function get_admin_details_link() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1302
		EE_Registry::instance()->load_helper( 'URL' );
1303
		return EEH_URL::add_query_args_and_nonce(
1304
			array(
1305
				'page' => 'espresso_registrations',
1306
				'action' => 'view_registration',
1307
				'_REG_ID' => $this->ID()
1308
			),
1309
			admin_url( 'admin.php' )
1310
		);
1311
	}
1312
1313
	/**
1314
	 * Returns the link to the editor for the object.  Sometimes this is the same as the details.
1315
	 * @return string
1316
	 */
1317
	public function get_admin_edit_link() {
1318
		return $this->get_admin_details_link();
1319
	}
1320
1321
	/**
1322
	 * Returns the link to a settings page for the object.
1323
	 * @return string
1324
	 */
1325
	public function get_admin_settings_link() {
1326
		return $this->get_admin_details_link();
1327
	}
1328
1329
	/**
1330
	 * Returns the link to the "overview" for the object (typically the "list table" view).
1331
	 * @return string
1332
	 */
1333
	public function get_admin_overview_link() {
1334
		EE_Registry::instance()->load_helper( 'URL' );
1335
		return EEH_URL::add_query_args_and_nonce(
1336
			array(
1337
				'page' => 'espresso_registrations'
1338
			),
1339
			admin_url( 'admin.php' )
1340
		);
1341
	}
1342
1343
1344
1345
	/**
1346
	 * @param array $query_params
1347
	 * @return \EE_Registration[]
1348
	 * @throws \EE_Error
1349
	 */
1350
	public function payments( $query_params = array() ) {
1351
		return $this->get_many_related( 'Payment', $query_params );
1352
	}
1353
1354
1355
1356
	/**
1357
	 * @param array $query_params
1358
	 * @return \EE_Registration_Payment[]
1359
	 * @throws \EE_Error
1360
	 */
1361
	public function registration_payments( $query_params = array() ) {
1362
		return $this->get_many_related( 'Registration_Payment', $query_params );
1363
	}
1364
1365
1366
1367
1368
	/**
1369
	 * This grabs the payment method corresponding to the last payment made for the amount owing on the registration.
1370
	 * Note: if there are no payments on the registration there will be no payment method returned.
1371
	 *
1372
	 * @return EE_Payment_Method|null
1373
	 */
1374
	public function payment_method() {
1375
		return EEM_Payment_Method::instance()->get_last_used_for_registration( $this );
1376
	}
1377
1378
1379
1380
	/**
1381
	 * @return \EE_Line_Item
1382
	 * @throws EntityNotFoundException
1383
	 * @throws \EE_Error
1384
	 */
1385
	public function ticket_line_item()
1386
	{
1387
		$ticket = $this->ticket();
1388
		$transaction = $this->transaction();
1389
		$line_item = null;
1390
		$ticket_line_items = \EEH_Line_Item::get_line_items_by_object_type_and_IDs(
1391
			$transaction->total_line_item(),
1392
			'Ticket',
1393
			array($ticket->ID())
1394
		);
1395 View Code Duplication
		foreach ($ticket_line_items as $ticket_line_item) {
1396
			if (
1397
				$ticket_line_item instanceof \EE_Line_Item
1398
				&& $ticket_line_item->OBJ_type() === 'Ticket'
1399
				&& $ticket_line_item->OBJ_ID() === $ticket->ID()
1400
			) {
1401
				$line_item = $ticket_line_item;
1402
				break;
1403
			}
1404
		}
1405 View Code Duplication
		if ( ! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) {
1406
			throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID());
1407
		}
1408
		return $line_item;
1409
	}
1410
1411
1412
1413
	/**
1414
	 * @deprecated
1415
	 * @since     4.7.0
1416
	 * @access    public
1417
	 */
1418
	public function price_paid()
1419
	{
1420
		EE_Error::doing_it_wrong('EE_Registration::price_paid()',
1421
			__('This method is deprecated, please use EE_Registration::final_price() instead.', 'event_espresso'),
1422
			'4.7.0');
1423
		return $this->final_price();
1424
	}
1425
1426
1427
1428
	/**
1429
	 * @deprecated
1430
	 * @since     4.7.0
1431
	 * @access    public
1432
	 * @param    float $REG_final_price
1433
	 */
1434
	public function set_price_paid($REG_final_price = 0.00)
1435
	{
1436
		EE_Error::doing_it_wrong('EE_Registration::set_price_paid()',
1437
			__('This method is deprecated, please use EE_Registration::set_final_price() instead.', 'event_espresso'),
1438
			'4.7.0');
1439
		$this->set_final_price($REG_final_price);
1440
	}
1441
1442
1443
1444
	/**
1445
	 * @deprecated
1446
	 * @since 4.7.0
1447
	 * @return string
1448
	 */
1449
	public function pretty_price_paid()
1450
	{
1451
		EE_Error::doing_it_wrong('EE_Registration::pretty_price_paid()',
1452
			__('This method is deprecated, please use EE_Registration::pretty_final_price() instead.',
1453
				'event_espresso'), '4.7.0');
1454
		return $this->pretty_final_price();
1455
	}
1456
1457
1458
}
1459
/* End of file EE_Registration.class.php */
1460
/* Location: includes/classes/EE_Registration.class.php */
1461