Completed
Branch BUG-9871-email-validation (e62b1a)
by
unknown
350:41 queued 333:27
created

EE_Registration::question_groups()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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