@@ -17,2077 +17,2077 @@ |
||
17 | 17 | { |
18 | 18 | |
19 | 19 | |
20 | - /** |
|
21 | - * Used to reference when a registration has never been checked in. |
|
22 | - * |
|
23 | - * @deprecated use \EE_Checkin::status_checked_never instead |
|
24 | - * @type int |
|
25 | - */ |
|
26 | - const checkin_status_never = 2; |
|
27 | - |
|
28 | - /** |
|
29 | - * Used to reference when a registration has been checked in. |
|
30 | - * |
|
31 | - * @deprecated use \EE_Checkin::status_checked_in instead |
|
32 | - * @type int |
|
33 | - */ |
|
34 | - const checkin_status_in = 1; |
|
35 | - |
|
36 | - |
|
37 | - /** |
|
38 | - * Used to reference when a registration has been checked out. |
|
39 | - * |
|
40 | - * @deprecated use \EE_Checkin::status_checked_out instead |
|
41 | - * @type int |
|
42 | - */ |
|
43 | - const checkin_status_out = 0; |
|
44 | - |
|
45 | - |
|
46 | - /** |
|
47 | - * extra meta key for tracking reg status os trashed registrations |
|
48 | - * |
|
49 | - * @type string |
|
50 | - */ |
|
51 | - const PRE_TRASH_REG_STATUS_KEY = 'pre_trash_registration_status'; |
|
52 | - |
|
53 | - |
|
54 | - /** |
|
55 | - * extra meta key for tracking if registration has reserved ticket |
|
56 | - * |
|
57 | - * @type string |
|
58 | - */ |
|
59 | - const HAS_RESERVED_TICKET_KEY = 'has_reserved_ticket'; |
|
60 | - |
|
61 | - |
|
62 | - /** |
|
63 | - * @param array $props_n_values incoming values |
|
64 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
65 | - * used.) |
|
66 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
67 | - * date_format and the second value is the time format |
|
68 | - * @return EE_Registration |
|
69 | - * @throws EE_Error |
|
70 | - */ |
|
71 | - public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
72 | - { |
|
73 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
74 | - return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
75 | - } |
|
76 | - |
|
77 | - |
|
78 | - /** |
|
79 | - * @param array $props_n_values incoming values from the database |
|
80 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
81 | - * the website will be used. |
|
82 | - * @return EE_Registration |
|
83 | - */ |
|
84 | - public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
85 | - { |
|
86 | - return new self($props_n_values, true, $timezone); |
|
87 | - } |
|
88 | - |
|
89 | - |
|
90 | - /** |
|
91 | - * Set Event ID |
|
92 | - * |
|
93 | - * @param int $EVT_ID Event ID |
|
94 | - * @throws EE_Error |
|
95 | - * @throws RuntimeException |
|
96 | - */ |
|
97 | - public function set_event($EVT_ID = 0) |
|
98 | - { |
|
99 | - $this->set('EVT_ID', $EVT_ID); |
|
100 | - } |
|
101 | - |
|
102 | - |
|
103 | - /** |
|
104 | - * Overrides parent set() method so that all calls to set( 'REG_code', $REG_code ) OR set( 'STS_ID', $STS_ID ) can |
|
105 | - * be routed to internal methods |
|
106 | - * |
|
107 | - * @param string $field_name |
|
108 | - * @param mixed $field_value |
|
109 | - * @param bool $use_default |
|
110 | - * @throws EE_Error |
|
111 | - * @throws EntityNotFoundException |
|
112 | - * @throws InvalidArgumentException |
|
113 | - * @throws InvalidDataTypeException |
|
114 | - * @throws InvalidInterfaceException |
|
115 | - * @throws ReflectionException |
|
116 | - * @throws RuntimeException |
|
117 | - */ |
|
118 | - public function set($field_name, $field_value, $use_default = false) |
|
119 | - { |
|
120 | - switch ($field_name) { |
|
121 | - case 'REG_code': |
|
122 | - if (! empty($field_value) && $this->reg_code() === null) { |
|
123 | - $this->set_reg_code($field_value, $use_default); |
|
124 | - } |
|
125 | - break; |
|
126 | - case 'STS_ID': |
|
127 | - $this->set_status($field_value, $use_default); |
|
128 | - break; |
|
129 | - default: |
|
130 | - parent::set($field_name, $field_value, $use_default); |
|
131 | - } |
|
132 | - } |
|
133 | - |
|
134 | - |
|
135 | - /** |
|
136 | - * Set Status ID |
|
137 | - * updates the registration status and ALSO... |
|
138 | - * calls reserve_registration_space() if the reg status changes TO approved from any other reg status |
|
139 | - * calls release_registration_space() if the reg status changes FROM approved to any other reg status |
|
140 | - * |
|
141 | - * @param string $new_STS_ID |
|
142 | - * @param boolean $use_default |
|
143 | - * @param ContextInterface|null $context |
|
144 | - * @return bool |
|
145 | - * @throws EE_Error |
|
146 | - * @throws EntityNotFoundException |
|
147 | - * @throws InvalidArgumentException |
|
148 | - * @throws ReflectionException |
|
149 | - * @throws RuntimeException |
|
150 | - * @throws InvalidDataTypeException |
|
151 | - * @throws InvalidInterfaceException |
|
152 | - */ |
|
153 | - public function set_status($new_STS_ID = null, $use_default = false, ContextInterface $context = null) |
|
154 | - { |
|
155 | - // get current REG_Status |
|
156 | - $old_STS_ID = $this->status_ID(); |
|
157 | - // if status has changed |
|
158 | - if ($old_STS_ID !== $new_STS_ID // and that status has actually changed |
|
159 | - && ! empty($old_STS_ID) // and that old status is actually set |
|
160 | - && ! empty($new_STS_ID) // as well as the new status |
|
161 | - && $this->ID() // ensure registration is in the db |
|
162 | - ) { |
|
163 | - // TO approved |
|
164 | - if ($new_STS_ID === EEM_Registration::status_id_approved) { |
|
165 | - // reserve a space by incrementing ticket and datetime sold values |
|
166 | - $this->_reserve_registration_space(); |
|
167 | - do_action('AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID, $context); |
|
168 | - // OR FROM approved |
|
169 | - } elseif ($old_STS_ID === EEM_Registration::status_id_approved) { |
|
170 | - // release a space by decrementing ticket and datetime sold values |
|
171 | - $this->_release_registration_space(); |
|
172 | - do_action( |
|
173 | - 'AHEE__EE_Registration__set_status__from_approved', |
|
174 | - $this, |
|
175 | - $old_STS_ID, |
|
176 | - $new_STS_ID, |
|
177 | - $context |
|
178 | - ); |
|
179 | - } |
|
180 | - // update status |
|
181 | - parent::set('STS_ID', $new_STS_ID, $use_default); |
|
182 | - $this->_update_if_canceled_or_declined($new_STS_ID, $old_STS_ID, $context); |
|
183 | - if ($this->statusChangeUpdatesTransaction($context)) { |
|
184 | - $this->updateTransactionAfterStatusChange(); |
|
185 | - } |
|
186 | - do_action('AHEE__EE_Registration__set_status__after_update', $this, $old_STS_ID, $new_STS_ID, $context); |
|
187 | - return true; |
|
188 | - } |
|
189 | - // even though the old value matches the new value, it's still good to |
|
190 | - // allow the parent set method to have a say |
|
191 | - parent::set('STS_ID', $new_STS_ID, $use_default); |
|
192 | - return true; |
|
193 | - } |
|
194 | - |
|
195 | - |
|
196 | - /** |
|
197 | - * update REGs and TXN when cancelled or declined registrations involved |
|
198 | - * |
|
199 | - * @param string $new_STS_ID |
|
200 | - * @param string $old_STS_ID |
|
201 | - * @param ContextInterface|null $context |
|
202 | - * @throws EE_Error |
|
203 | - * @throws InvalidArgumentException |
|
204 | - * @throws InvalidDataTypeException |
|
205 | - * @throws InvalidInterfaceException |
|
206 | - * @throws ReflectionException |
|
207 | - */ |
|
208 | - private function _update_if_canceled_or_declined($new_STS_ID, $old_STS_ID, ContextInterface $context = null) |
|
209 | - { |
|
210 | - // these reg statuses should not be considered in any calculations involving monies owing |
|
211 | - $closed_reg_statuses = EEM_Registration::closed_reg_statuses(); |
|
212 | - // true if registration has been cancelled or declined |
|
213 | - $this->updateIfCanceled( |
|
214 | - $closed_reg_statuses, |
|
215 | - $new_STS_ID, |
|
216 | - $old_STS_ID, |
|
217 | - $context |
|
218 | - ); |
|
219 | - $this->updateIfDeclined( |
|
220 | - $closed_reg_statuses, |
|
221 | - $new_STS_ID, |
|
222 | - $old_STS_ID, |
|
223 | - $context |
|
224 | - ); |
|
225 | - } |
|
226 | - |
|
227 | - |
|
228 | - /** |
|
229 | - * update REGs and TXN when cancelled or declined registrations involved |
|
230 | - * |
|
231 | - * @param array $closed_reg_statuses |
|
232 | - * @param string $new_STS_ID |
|
233 | - * @param string $old_STS_ID |
|
234 | - * @param ContextInterface|null $context |
|
235 | - * @throws EE_Error |
|
236 | - * @throws InvalidArgumentException |
|
237 | - * @throws InvalidDataTypeException |
|
238 | - * @throws InvalidInterfaceException |
|
239 | - * @throws ReflectionException |
|
240 | - */ |
|
241 | - private function updateIfCanceled( |
|
242 | - array $closed_reg_statuses, |
|
243 | - $new_STS_ID, |
|
244 | - $old_STS_ID, |
|
245 | - ContextInterface $context = null |
|
246 | - ) { |
|
247 | - // true if registration has been cancelled or declined |
|
248 | - if (in_array($new_STS_ID, $closed_reg_statuses, true) |
|
249 | - && ! in_array($old_STS_ID, $closed_reg_statuses, true) |
|
250 | - ) { |
|
251 | - /** @type EE_Registration_Processor $registration_processor */ |
|
252 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
253 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
254 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
255 | - // cancelled or declined registration |
|
256 | - $registration_processor->update_registration_after_being_canceled_or_declined( |
|
257 | - $this, |
|
258 | - $closed_reg_statuses |
|
259 | - ); |
|
260 | - $transaction_processor->update_transaction_after_canceled_or_declined_registration( |
|
261 | - $this, |
|
262 | - $closed_reg_statuses, |
|
263 | - false |
|
264 | - ); |
|
265 | - do_action( |
|
266 | - 'AHEE__EE_Registration__set_status__canceled_or_declined', |
|
267 | - $this, |
|
268 | - $old_STS_ID, |
|
269 | - $new_STS_ID, |
|
270 | - $context |
|
271 | - ); |
|
272 | - return; |
|
273 | - } |
|
274 | - } |
|
275 | - |
|
276 | - |
|
277 | - /** |
|
278 | - * update REGs and TXN when cancelled or declined registrations involved |
|
279 | - * |
|
280 | - * @param array $closed_reg_statuses |
|
281 | - * @param string $new_STS_ID |
|
282 | - * @param string $old_STS_ID |
|
283 | - * @param ContextInterface|null $context |
|
284 | - * @throws EE_Error |
|
285 | - * @throws InvalidArgumentException |
|
286 | - * @throws InvalidDataTypeException |
|
287 | - * @throws InvalidInterfaceException |
|
288 | - * @throws ReflectionException |
|
289 | - */ |
|
290 | - private function updateIfDeclined( |
|
291 | - array $closed_reg_statuses, |
|
292 | - $new_STS_ID, |
|
293 | - $old_STS_ID, |
|
294 | - ContextInterface $context = null |
|
295 | - ) { |
|
296 | - // true if reinstating cancelled or declined registration |
|
297 | - if (in_array($old_STS_ID, $closed_reg_statuses, true) |
|
298 | - && ! in_array($new_STS_ID, $closed_reg_statuses, true) |
|
299 | - ) { |
|
300 | - /** @type EE_Registration_Processor $registration_processor */ |
|
301 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
302 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
303 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
304 | - // reinstating cancelled or declined registration |
|
305 | - $registration_processor->update_canceled_or_declined_registration_after_being_reinstated( |
|
306 | - $this, |
|
307 | - $closed_reg_statuses |
|
308 | - ); |
|
309 | - $transaction_processor->update_transaction_after_reinstating_canceled_registration( |
|
310 | - $this, |
|
311 | - $closed_reg_statuses, |
|
312 | - false |
|
313 | - ); |
|
314 | - do_action( |
|
315 | - 'AHEE__EE_Registration__set_status__after_reinstated', |
|
316 | - $this, |
|
317 | - $old_STS_ID, |
|
318 | - $new_STS_ID, |
|
319 | - $context |
|
320 | - ); |
|
321 | - } |
|
322 | - } |
|
323 | - |
|
324 | - |
|
325 | - /** |
|
326 | - * @param ContextInterface|null $context |
|
327 | - * @return bool |
|
328 | - */ |
|
329 | - private function statusChangeUpdatesTransaction(ContextInterface $context = null) |
|
330 | - { |
|
331 | - $contexts_that_do_not_update_transaction = (array) apply_filters( |
|
332 | - 'AHEE__EE_Registration__statusChangeUpdatesTransaction__contexts_that_do_not_update_transaction', |
|
333 | - array('spco_reg_step_attendee_information_process_registrations'), |
|
334 | - $context, |
|
335 | - $this |
|
336 | - ); |
|
337 | - return ! ( |
|
338 | - $context instanceof ContextInterface |
|
339 | - && in_array($context->slug(), $contexts_that_do_not_update_transaction, true) |
|
340 | - ); |
|
341 | - } |
|
342 | - |
|
343 | - |
|
344 | - /** |
|
345 | - * @throws EE_Error |
|
346 | - * @throws EntityNotFoundException |
|
347 | - * @throws InvalidArgumentException |
|
348 | - * @throws InvalidDataTypeException |
|
349 | - * @throws InvalidInterfaceException |
|
350 | - * @throws ReflectionException |
|
351 | - * @throws RuntimeException |
|
352 | - */ |
|
353 | - private function updateTransactionAfterStatusChange() |
|
354 | - { |
|
355 | - /** @type EE_Transaction_Payments $transaction_payments */ |
|
356 | - $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
357 | - $transaction_payments->recalculate_transaction_total($this->transaction(), false); |
|
358 | - $this->transaction()->update_status_based_on_total_paid(true); |
|
359 | - } |
|
360 | - |
|
361 | - |
|
362 | - /** |
|
363 | - * get Status ID |
|
364 | - */ |
|
365 | - public function status_ID() |
|
366 | - { |
|
367 | - return $this->get('STS_ID'); |
|
368 | - } |
|
369 | - |
|
370 | - |
|
371 | - /** |
|
372 | - * Gets the ticket this registration is for |
|
373 | - * |
|
374 | - * @param boolean $include_archived whether to include archived tickets or not. |
|
375 | - * |
|
376 | - * @return EE_Ticket|EE_Base_Class |
|
377 | - * @throws EE_Error |
|
378 | - */ |
|
379 | - public function ticket($include_archived = true) |
|
380 | - { |
|
381 | - $query_params = array(); |
|
382 | - if ($include_archived) { |
|
383 | - $query_params['default_where_conditions'] = 'none'; |
|
384 | - } |
|
385 | - return $this->get_first_related('Ticket', $query_params); |
|
386 | - } |
|
387 | - |
|
388 | - |
|
389 | - /** |
|
390 | - * Gets the event this registration is for |
|
391 | - * |
|
392 | - * @return EE_Event |
|
393 | - * @throws EE_Error |
|
394 | - * @throws EntityNotFoundException |
|
395 | - */ |
|
396 | - public function event() |
|
397 | - { |
|
398 | - $event = $this->get_first_related('Event'); |
|
399 | - if (! $event instanceof \EE_Event) { |
|
400 | - throw new EntityNotFoundException('Event ID', $this->event_ID()); |
|
401 | - } |
|
402 | - return $event; |
|
403 | - } |
|
404 | - |
|
405 | - |
|
406 | - /** |
|
407 | - * Gets the "author" of the registration. Note that for the purposes of registrations, the author will correspond |
|
408 | - * with the author of the event this registration is for. |
|
409 | - * |
|
410 | - * @since 4.5.0 |
|
411 | - * @return int |
|
412 | - * @throws EE_Error |
|
413 | - * @throws EntityNotFoundException |
|
414 | - */ |
|
415 | - public function wp_user() |
|
416 | - { |
|
417 | - $event = $this->event(); |
|
418 | - if ($event instanceof EE_Event) { |
|
419 | - return $event->wp_user(); |
|
420 | - } |
|
421 | - return 0; |
|
422 | - } |
|
423 | - |
|
424 | - |
|
425 | - /** |
|
426 | - * increments this registration's related ticket sold and corresponding datetime sold values |
|
427 | - * |
|
428 | - * @return void |
|
429 | - * @throws DomainException |
|
430 | - * @throws EE_Error |
|
431 | - * @throws EntityNotFoundException |
|
432 | - * @throws InvalidArgumentException |
|
433 | - * @throws InvalidDataTypeException |
|
434 | - * @throws InvalidInterfaceException |
|
435 | - * @throws ReflectionException |
|
436 | - * @throws UnexpectedEntityException |
|
437 | - */ |
|
438 | - private function _reserve_registration_space() |
|
439 | - { |
|
440 | - // reserved ticket and datetime counts will be decremented as sold counts are incremented |
|
441 | - // so stop tracking that this reg has a ticket reserved |
|
442 | - $this->release_reserved_ticket(false, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
443 | - $ticket = $this->ticket(); |
|
444 | - $ticket->increase_sold(); |
|
445 | - $ticket->save(); |
|
446 | - // possibly set event status to sold out |
|
447 | - $this->event()->perform_sold_out_status_check(); |
|
448 | - } |
|
449 | - |
|
450 | - |
|
451 | - /** |
|
452 | - * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values |
|
453 | - * |
|
454 | - * @return void |
|
455 | - * @throws DomainException |
|
456 | - * @throws EE_Error |
|
457 | - * @throws EntityNotFoundException |
|
458 | - * @throws InvalidArgumentException |
|
459 | - * @throws InvalidDataTypeException |
|
460 | - * @throws InvalidInterfaceException |
|
461 | - * @throws ReflectionException |
|
462 | - * @throws UnexpectedEntityException |
|
463 | - */ |
|
464 | - private function _release_registration_space() |
|
465 | - { |
|
466 | - $ticket = $this->ticket(); |
|
467 | - $ticket->decrease_sold(); |
|
468 | - $ticket->save(); |
|
469 | - // possibly change event status from sold out back to previous status |
|
470 | - $this->event()->perform_sold_out_status_check(); |
|
471 | - } |
|
472 | - |
|
473 | - |
|
474 | - /** |
|
475 | - * tracks this registration's ticket reservation in extra meta |
|
476 | - * and can increment related ticket reserved and corresponding datetime reserved values |
|
477 | - * |
|
478 | - * @param bool $update_ticket if true, will increment ticket and datetime reserved count |
|
479 | - * @return void |
|
480 | - * @throws EE_Error |
|
481 | - * @throws InvalidArgumentException |
|
482 | - * @throws InvalidDataTypeException |
|
483 | - * @throws InvalidInterfaceException |
|
484 | - * @throws ReflectionException |
|
485 | - */ |
|
486 | - public function reserve_ticket($update_ticket = false, $source = 'unknown') |
|
487 | - { |
|
488 | - // only reserve ticket if space is not currently reserved |
|
489 | - if ((bool) $this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) !== true) { |
|
490 | - $this->update_extra_meta('reserve_ticket', "{$this->ticket_ID()} from {$source}"); |
|
491 | - // IMPORTANT !!! |
|
492 | - // although checking $update_ticket first would be more efficient, |
|
493 | - // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
494 | - if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) |
|
495 | - && $update_ticket |
|
496 | - ) { |
|
497 | - $ticket = $this->ticket(); |
|
498 | - $ticket->increase_reserved(1, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
499 | - $ticket->save(); |
|
500 | - } |
|
501 | - } |
|
502 | - } |
|
503 | - |
|
504 | - |
|
505 | - /** |
|
506 | - * stops tracking this registration's ticket reservation in extra meta |
|
507 | - * decrements (subtracts) related ticket reserved and corresponding datetime reserved values |
|
508 | - * |
|
509 | - * @param bool $update_ticket if true, will decrement ticket and datetime reserved count |
|
510 | - * @return void |
|
511 | - * @throws EE_Error |
|
512 | - * @throws InvalidArgumentException |
|
513 | - * @throws InvalidDataTypeException |
|
514 | - * @throws InvalidInterfaceException |
|
515 | - * @throws ReflectionException |
|
516 | - */ |
|
517 | - public function release_reserved_ticket($update_ticket = false, $source = 'unknown') |
|
518 | - { |
|
519 | - // only release ticket if space is currently reserved |
|
520 | - if ((bool) $this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) === true) { |
|
521 | - $this->update_extra_meta('release_reserved_ticket', "{$this->ticket_ID()} from {$source}"); |
|
522 | - // IMPORTANT !!! |
|
523 | - // although checking $update_ticket first would be more efficient, |
|
524 | - // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
525 | - if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, false) |
|
526 | - && $update_ticket |
|
527 | - ) { |
|
528 | - $ticket = $this->ticket(); |
|
529 | - $ticket->decrease_reserved(1, true, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
530 | - $ticket->save(); |
|
531 | - } |
|
532 | - } |
|
533 | - } |
|
534 | - |
|
535 | - |
|
536 | - /** |
|
537 | - * Set Attendee ID |
|
538 | - * |
|
539 | - * @param int $ATT_ID Attendee ID |
|
540 | - * @throws EE_Error |
|
541 | - * @throws RuntimeException |
|
542 | - */ |
|
543 | - public function set_attendee_id($ATT_ID = 0) |
|
544 | - { |
|
545 | - $this->set('ATT_ID', $ATT_ID); |
|
546 | - } |
|
547 | - |
|
548 | - |
|
549 | - /** |
|
550 | - * Set Transaction ID |
|
551 | - * |
|
552 | - * @param int $TXN_ID Transaction ID |
|
553 | - * @throws EE_Error |
|
554 | - * @throws RuntimeException |
|
555 | - */ |
|
556 | - public function set_transaction_id($TXN_ID = 0) |
|
557 | - { |
|
558 | - $this->set('TXN_ID', $TXN_ID); |
|
559 | - } |
|
560 | - |
|
561 | - |
|
562 | - /** |
|
563 | - * Set Session |
|
564 | - * |
|
565 | - * @param string $REG_session PHP Session ID |
|
566 | - * @throws EE_Error |
|
567 | - * @throws RuntimeException |
|
568 | - */ |
|
569 | - public function set_session($REG_session = '') |
|
570 | - { |
|
571 | - $this->set('REG_session', $REG_session); |
|
572 | - } |
|
573 | - |
|
574 | - |
|
575 | - /** |
|
576 | - * Set Registration URL Link |
|
577 | - * |
|
578 | - * @param string $REG_url_link Registration URL Link |
|
579 | - * @throws EE_Error |
|
580 | - * @throws RuntimeException |
|
581 | - */ |
|
582 | - public function set_reg_url_link($REG_url_link = '') |
|
583 | - { |
|
584 | - $this->set('REG_url_link', $REG_url_link); |
|
585 | - } |
|
586 | - |
|
587 | - |
|
588 | - /** |
|
589 | - * Set Attendee Counter |
|
590 | - * |
|
591 | - * @param int $REG_count Primary Attendee |
|
592 | - * @throws EE_Error |
|
593 | - * @throws RuntimeException |
|
594 | - */ |
|
595 | - public function set_count($REG_count = 1) |
|
596 | - { |
|
597 | - $this->set('REG_count', $REG_count); |
|
598 | - } |
|
599 | - |
|
600 | - |
|
601 | - /** |
|
602 | - * Set Group Size |
|
603 | - * |
|
604 | - * @param boolean $REG_group_size Group Registration |
|
605 | - * @throws EE_Error |
|
606 | - * @throws RuntimeException |
|
607 | - */ |
|
608 | - public function set_group_size($REG_group_size = false) |
|
609 | - { |
|
610 | - $this->set('REG_group_size', $REG_group_size); |
|
611 | - } |
|
612 | - |
|
613 | - |
|
614 | - /** |
|
615 | - * is_not_approved - convenience method that returns TRUE if REG status ID == |
|
616 | - * EEM_Registration::status_id_not_approved |
|
617 | - * |
|
618 | - * @return boolean |
|
619 | - */ |
|
620 | - public function is_not_approved() |
|
621 | - { |
|
622 | - return $this->status_ID() == EEM_Registration::status_id_not_approved ? true : false; |
|
623 | - } |
|
624 | - |
|
625 | - |
|
626 | - /** |
|
627 | - * is_pending_payment - convenience method that returns TRUE if REG status ID == |
|
628 | - * EEM_Registration::status_id_pending_payment |
|
629 | - * |
|
630 | - * @return boolean |
|
631 | - */ |
|
632 | - public function is_pending_payment() |
|
633 | - { |
|
634 | - return $this->status_ID() == EEM_Registration::status_id_pending_payment ? true : false; |
|
635 | - } |
|
636 | - |
|
637 | - |
|
638 | - /** |
|
639 | - * is_approved - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved |
|
640 | - * |
|
641 | - * @return boolean |
|
642 | - */ |
|
643 | - public function is_approved() |
|
644 | - { |
|
645 | - return $this->status_ID() == EEM_Registration::status_id_approved ? true : false; |
|
646 | - } |
|
647 | - |
|
648 | - |
|
649 | - /** |
|
650 | - * is_cancelled - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled |
|
651 | - * |
|
652 | - * @return boolean |
|
653 | - */ |
|
654 | - public function is_cancelled() |
|
655 | - { |
|
656 | - return $this->status_ID() == EEM_Registration::status_id_cancelled ? true : false; |
|
657 | - } |
|
658 | - |
|
659 | - |
|
660 | - /** |
|
661 | - * is_declined - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined |
|
662 | - * |
|
663 | - * @return boolean |
|
664 | - */ |
|
665 | - public function is_declined() |
|
666 | - { |
|
667 | - return $this->status_ID() == EEM_Registration::status_id_declined ? true : false; |
|
668 | - } |
|
669 | - |
|
670 | - |
|
671 | - /** |
|
672 | - * is_incomplete - convenience method that returns TRUE if REG status ID == |
|
673 | - * EEM_Registration::status_id_incomplete |
|
674 | - * |
|
675 | - * @return boolean |
|
676 | - */ |
|
677 | - public function is_incomplete() |
|
678 | - { |
|
679 | - return $this->status_ID() == EEM_Registration::status_id_incomplete ? true : false; |
|
680 | - } |
|
681 | - |
|
682 | - |
|
683 | - /** |
|
684 | - * Set Registration Date |
|
685 | - * |
|
686 | - * @param mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of |
|
687 | - * Date |
|
688 | - * @throws EE_Error |
|
689 | - * @throws RuntimeException |
|
690 | - */ |
|
691 | - public function set_reg_date($REG_date = false) |
|
692 | - { |
|
693 | - $this->set('REG_date', $REG_date); |
|
694 | - } |
|
695 | - |
|
696 | - |
|
697 | - /** |
|
698 | - * Set final price owing for this registration after all ticket/price modifications |
|
699 | - * |
|
700 | - * @access public |
|
701 | - * @param float $REG_final_price |
|
702 | - * @throws EE_Error |
|
703 | - * @throws RuntimeException |
|
704 | - */ |
|
705 | - public function set_final_price($REG_final_price = 0.00) |
|
706 | - { |
|
707 | - $this->set('REG_final_price', $REG_final_price); |
|
708 | - } |
|
709 | - |
|
710 | - |
|
711 | - /** |
|
712 | - * Set amount paid towards this registration's final price |
|
713 | - * |
|
714 | - * @access public |
|
715 | - * @param float $REG_paid |
|
716 | - * @throws EE_Error |
|
717 | - * @throws RuntimeException |
|
718 | - */ |
|
719 | - public function set_paid($REG_paid = 0.00) |
|
720 | - { |
|
721 | - $this->set('REG_paid', $REG_paid); |
|
722 | - } |
|
723 | - |
|
724 | - |
|
725 | - /** |
|
726 | - * Attendee Is Going |
|
727 | - * |
|
728 | - * @param boolean $REG_att_is_going Attendee Is Going |
|
729 | - * @throws EE_Error |
|
730 | - * @throws RuntimeException |
|
731 | - */ |
|
732 | - public function set_att_is_going($REG_att_is_going = false) |
|
733 | - { |
|
734 | - $this->set('REG_att_is_going', $REG_att_is_going); |
|
735 | - } |
|
736 | - |
|
737 | - |
|
738 | - /** |
|
739 | - * Gets the related attendee |
|
740 | - * |
|
741 | - * @return EE_Attendee |
|
742 | - * @throws EE_Error |
|
743 | - */ |
|
744 | - public function attendee() |
|
745 | - { |
|
746 | - return $this->get_first_related('Attendee'); |
|
747 | - } |
|
748 | - |
|
749 | - |
|
750 | - /** |
|
751 | - * get Event ID |
|
752 | - */ |
|
753 | - public function event_ID() |
|
754 | - { |
|
755 | - return $this->get('EVT_ID'); |
|
756 | - } |
|
757 | - |
|
758 | - |
|
759 | - /** |
|
760 | - * get Event ID |
|
761 | - */ |
|
762 | - public function event_name() |
|
763 | - { |
|
764 | - $event = $this->event_obj(); |
|
765 | - if ($event) { |
|
766 | - return $event->name(); |
|
767 | - } else { |
|
768 | - return null; |
|
769 | - } |
|
770 | - } |
|
771 | - |
|
772 | - |
|
773 | - /** |
|
774 | - * Fetches the event this registration is for |
|
775 | - * |
|
776 | - * @return EE_Event |
|
777 | - * @throws EE_Error |
|
778 | - */ |
|
779 | - public function event_obj() |
|
780 | - { |
|
781 | - return $this->get_first_related('Event'); |
|
782 | - } |
|
783 | - |
|
784 | - |
|
785 | - /** |
|
786 | - * get Attendee ID |
|
787 | - */ |
|
788 | - public function attendee_ID() |
|
789 | - { |
|
790 | - return $this->get('ATT_ID'); |
|
791 | - } |
|
792 | - |
|
793 | - |
|
794 | - /** |
|
795 | - * get PHP Session ID |
|
796 | - */ |
|
797 | - public function session_ID() |
|
798 | - { |
|
799 | - return $this->get('REG_session'); |
|
800 | - } |
|
801 | - |
|
802 | - |
|
803 | - /** |
|
804 | - * Gets the string which represents the URL trigger for the receipt template in the message template system. |
|
805 | - * |
|
806 | - * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
807 | - * @return string |
|
808 | - */ |
|
809 | - public function receipt_url($messenger = 'html') |
|
810 | - { |
|
811 | - |
|
812 | - /** |
|
813 | - * The below will be deprecated one version after this. We check first if there is a custom receipt template |
|
814 | - * already in use on old system. If there is then we just return the standard url for it. |
|
815 | - * |
|
816 | - * @since 4.5.0 |
|
817 | - */ |
|
818 | - $template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php'; |
|
819 | - $has_custom = EEH_Template::locate_template( |
|
820 | - $template_relative_path, |
|
821 | - array(), |
|
822 | - true, |
|
823 | - true, |
|
824 | - true |
|
825 | - ); |
|
826 | - |
|
827 | - if ($has_custom) { |
|
828 | - return add_query_arg(array('receipt' => 'true'), $this->invoice_url('launch')); |
|
829 | - } |
|
830 | - return apply_filters('FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt'); |
|
831 | - } |
|
832 | - |
|
833 | - |
|
834 | - /** |
|
835 | - * Gets the string which represents the URL trigger for the invoice template in the message template system. |
|
836 | - * |
|
837 | - * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
838 | - * @return string |
|
839 | - * @throws EE_Error |
|
840 | - */ |
|
841 | - public function invoice_url($messenger = 'html') |
|
842 | - { |
|
843 | - /** |
|
844 | - * The below will be deprecated one version after this. We check first if there is a custom invoice template |
|
845 | - * already in use on old system. If there is then we just return the standard url for it. |
|
846 | - * |
|
847 | - * @since 4.5.0 |
|
848 | - */ |
|
849 | - $template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php'; |
|
850 | - $has_custom = EEH_Template::locate_template( |
|
851 | - $template_relative_path, |
|
852 | - array(), |
|
853 | - true, |
|
854 | - true, |
|
855 | - true |
|
856 | - ); |
|
857 | - |
|
858 | - if ($has_custom) { |
|
859 | - if ($messenger == 'html') { |
|
860 | - return $this->invoice_url('launch'); |
|
861 | - } |
|
862 | - $route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice'; |
|
863 | - |
|
864 | - $query_args = array('ee' => $route, 'id' => $this->reg_url_link()); |
|
865 | - if ($messenger == 'html') { |
|
866 | - $query_args['html'] = true; |
|
867 | - } |
|
868 | - return add_query_arg($query_args, get_permalink(EE_Registry::instance()->CFG->core->thank_you_page_id)); |
|
869 | - } |
|
870 | - return apply_filters('FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice'); |
|
871 | - } |
|
872 | - |
|
873 | - |
|
874 | - /** |
|
875 | - * get Registration URL Link |
|
876 | - * |
|
877 | - * @access public |
|
878 | - * @return string |
|
879 | - * @throws EE_Error |
|
880 | - */ |
|
881 | - public function reg_url_link() |
|
882 | - { |
|
883 | - return (string) $this->get('REG_url_link'); |
|
884 | - } |
|
885 | - |
|
886 | - |
|
887 | - /** |
|
888 | - * Echoes out invoice_url() |
|
889 | - * |
|
890 | - * @param string $type 'download','launch', or 'html' (default is 'launch') |
|
891 | - * @return void |
|
892 | - * @throws EE_Error |
|
893 | - */ |
|
894 | - public function e_invoice_url($type = 'launch') |
|
895 | - { |
|
896 | - echo $this->invoice_url($type); |
|
897 | - } |
|
898 | - |
|
899 | - |
|
900 | - /** |
|
901 | - * Echoes out payment_overview_url |
|
902 | - */ |
|
903 | - public function e_payment_overview_url() |
|
904 | - { |
|
905 | - echo $this->payment_overview_url(); |
|
906 | - } |
|
907 | - |
|
908 | - |
|
909 | - /** |
|
910 | - * Gets the URL for the checkout payment options reg step |
|
911 | - * with this registration's REG_url_link added as a query parameter |
|
912 | - * |
|
913 | - * @param bool $clear_session Set to true when you want to clear the session on revisiting the |
|
914 | - * payment overview url. |
|
915 | - * @return string |
|
916 | - * @throws InvalidInterfaceException |
|
917 | - * @throws InvalidDataTypeException |
|
918 | - * @throws EE_Error |
|
919 | - * @throws InvalidArgumentException |
|
920 | - */ |
|
921 | - public function payment_overview_url($clear_session = false) |
|
922 | - { |
|
923 | - return add_query_arg( |
|
924 | - (array) apply_filters( |
|
925 | - 'FHEE__EE_Registration__payment_overview_url__query_args', |
|
926 | - array( |
|
927 | - 'e_reg_url_link' => $this->reg_url_link(), |
|
928 | - 'step' => 'payment_options', |
|
929 | - 'revisit' => true, |
|
930 | - 'clear_session' => (bool) $clear_session, |
|
931 | - ), |
|
932 | - $this |
|
933 | - ), |
|
934 | - EE_Registry::instance()->CFG->core->reg_page_url() |
|
935 | - ); |
|
936 | - } |
|
937 | - |
|
938 | - |
|
939 | - /** |
|
940 | - * Gets the URL for the checkout attendee information reg step |
|
941 | - * with this registration's REG_url_link added as a query parameter |
|
942 | - * |
|
943 | - * @return string |
|
944 | - * @throws InvalidInterfaceException |
|
945 | - * @throws InvalidDataTypeException |
|
946 | - * @throws EE_Error |
|
947 | - * @throws InvalidArgumentException |
|
948 | - */ |
|
949 | - public function edit_attendee_information_url() |
|
950 | - { |
|
951 | - return add_query_arg( |
|
952 | - (array) apply_filters( |
|
953 | - 'FHEE__EE_Registration__edit_attendee_information_url__query_args', |
|
954 | - array( |
|
955 | - 'e_reg_url_link' => $this->reg_url_link(), |
|
956 | - 'step' => 'attendee_information', |
|
957 | - 'revisit' => true, |
|
958 | - ), |
|
959 | - $this |
|
960 | - ), |
|
961 | - EE_Registry::instance()->CFG->core->reg_page_url() |
|
962 | - ); |
|
963 | - } |
|
964 | - |
|
965 | - |
|
966 | - /** |
|
967 | - * Simply generates and returns the appropriate admin_url link to edit this registration |
|
968 | - * |
|
969 | - * @return string |
|
970 | - * @throws EE_Error |
|
971 | - */ |
|
972 | - public function get_admin_edit_url() |
|
973 | - { |
|
974 | - return EEH_URL::add_query_args_and_nonce( |
|
975 | - array( |
|
976 | - 'page' => 'espresso_registrations', |
|
977 | - 'action' => 'view_registration', |
|
978 | - '_REG_ID' => $this->ID(), |
|
979 | - ), |
|
980 | - admin_url('admin.php') |
|
981 | - ); |
|
982 | - } |
|
983 | - |
|
984 | - |
|
985 | - /** |
|
986 | - * is_primary_registrant? |
|
987 | - */ |
|
988 | - public function is_primary_registrant() |
|
989 | - { |
|
990 | - return $this->get('REG_count') === 1 ? true : false; |
|
991 | - } |
|
992 | - |
|
993 | - |
|
994 | - /** |
|
995 | - * This returns the primary registration object for this registration group (which may be this object). |
|
996 | - * |
|
997 | - * @return EE_Registration |
|
998 | - * @throws EE_Error |
|
999 | - */ |
|
1000 | - public function get_primary_registration() |
|
1001 | - { |
|
1002 | - if ($this->is_primary_registrant()) { |
|
1003 | - return $this; |
|
1004 | - } |
|
1005 | - |
|
1006 | - // k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1 |
|
1007 | - /** @var EE_Registration $primary_registrant */ |
|
1008 | - $primary_registrant = EEM_Registration::instance()->get_one( |
|
1009 | - array( |
|
1010 | - array( |
|
1011 | - 'TXN_ID' => $this->transaction_ID(), |
|
1012 | - 'REG_count' => 1, |
|
1013 | - ), |
|
1014 | - ) |
|
1015 | - ); |
|
1016 | - return $primary_registrant; |
|
1017 | - } |
|
1018 | - |
|
1019 | - |
|
1020 | - /** |
|
1021 | - * get Attendee Number |
|
1022 | - * |
|
1023 | - * @access public |
|
1024 | - */ |
|
1025 | - public function count() |
|
1026 | - { |
|
1027 | - return $this->get('REG_count'); |
|
1028 | - } |
|
1029 | - |
|
1030 | - |
|
1031 | - /** |
|
1032 | - * get Group Size |
|
1033 | - */ |
|
1034 | - public function group_size() |
|
1035 | - { |
|
1036 | - return $this->get('REG_group_size'); |
|
1037 | - } |
|
1038 | - |
|
1039 | - |
|
1040 | - /** |
|
1041 | - * get Registration Date |
|
1042 | - */ |
|
1043 | - public function date() |
|
1044 | - { |
|
1045 | - return $this->get('REG_date'); |
|
1046 | - } |
|
1047 | - |
|
1048 | - |
|
1049 | - /** |
|
1050 | - * gets a pretty date |
|
1051 | - * |
|
1052 | - * @param string $date_format |
|
1053 | - * @param string $time_format |
|
1054 | - * @return string |
|
1055 | - * @throws EE_Error |
|
1056 | - */ |
|
1057 | - public function pretty_date($date_format = null, $time_format = null) |
|
1058 | - { |
|
1059 | - return $this->get_datetime('REG_date', $date_format, $time_format); |
|
1060 | - } |
|
1061 | - |
|
1062 | - |
|
1063 | - /** |
|
1064 | - * final_price |
|
1065 | - * the registration's share of the transaction total, so that the |
|
1066 | - * sum of all the transaction's REG_final_prices equal the transaction's total |
|
1067 | - * |
|
1068 | - * @return float |
|
1069 | - * @throws EE_Error |
|
1070 | - */ |
|
1071 | - public function final_price() |
|
1072 | - { |
|
1073 | - return $this->get('REG_final_price'); |
|
1074 | - } |
|
1075 | - |
|
1076 | - |
|
1077 | - /** |
|
1078 | - * pretty_final_price |
|
1079 | - * final price as formatted string, with correct decimal places and currency symbol |
|
1080 | - * |
|
1081 | - * @return string |
|
1082 | - * @throws EE_Error |
|
1083 | - */ |
|
1084 | - public function pretty_final_price() |
|
1085 | - { |
|
1086 | - return $this->get_pretty('REG_final_price'); |
|
1087 | - } |
|
1088 | - |
|
1089 | - |
|
1090 | - /** |
|
1091 | - * get paid (yeah) |
|
1092 | - * |
|
1093 | - * @return float |
|
1094 | - * @throws EE_Error |
|
1095 | - */ |
|
1096 | - public function paid() |
|
1097 | - { |
|
1098 | - return $this->get('REG_paid'); |
|
1099 | - } |
|
1100 | - |
|
1101 | - |
|
1102 | - /** |
|
1103 | - * pretty_paid |
|
1104 | - * |
|
1105 | - * @return float |
|
1106 | - * @throws EE_Error |
|
1107 | - */ |
|
1108 | - public function pretty_paid() |
|
1109 | - { |
|
1110 | - return $this->get_pretty('REG_paid'); |
|
1111 | - } |
|
1112 | - |
|
1113 | - |
|
1114 | - /** |
|
1115 | - * owes_monies_and_can_pay |
|
1116 | - * whether or not this registration has monies owing and it's' status allows payment |
|
1117 | - * |
|
1118 | - * @param array $requires_payment |
|
1119 | - * @return bool |
|
1120 | - * @throws EE_Error |
|
1121 | - */ |
|
1122 | - public function owes_monies_and_can_pay($requires_payment = array()) |
|
1123 | - { |
|
1124 | - // these reg statuses require payment (if event is not free) |
|
1125 | - $requires_payment = ! empty($requires_payment) |
|
1126 | - ? $requires_payment |
|
1127 | - : EEM_Registration::reg_statuses_that_allow_payment(); |
|
1128 | - if (in_array($this->status_ID(), $requires_payment) && |
|
1129 | - $this->final_price() != 0 && |
|
1130 | - $this->final_price() != $this->paid() |
|
1131 | - ) { |
|
1132 | - return true; |
|
1133 | - } else { |
|
1134 | - return false; |
|
1135 | - } |
|
1136 | - } |
|
1137 | - |
|
1138 | - |
|
1139 | - /** |
|
1140 | - * Prints out the return value of $this->pretty_status() |
|
1141 | - * |
|
1142 | - * @param bool $show_icons |
|
1143 | - * @return void |
|
1144 | - * @throws EE_Error |
|
1145 | - */ |
|
1146 | - public function e_pretty_status($show_icons = false) |
|
1147 | - { |
|
1148 | - echo $this->pretty_status($show_icons); |
|
1149 | - } |
|
1150 | - |
|
1151 | - |
|
1152 | - /** |
|
1153 | - * Returns a nice version of the status for displaying to customers |
|
1154 | - * |
|
1155 | - * @param bool $show_icons |
|
1156 | - * @return string |
|
1157 | - * @throws EE_Error |
|
1158 | - */ |
|
1159 | - public function pretty_status($show_icons = false) |
|
1160 | - { |
|
1161 | - $status = EEM_Status::instance()->localized_status( |
|
1162 | - array($this->status_ID() => esc_html__('unknown', 'event_espresso')), |
|
1163 | - false, |
|
1164 | - 'sentence' |
|
1165 | - ); |
|
1166 | - $icon = ''; |
|
1167 | - switch ($this->status_ID()) { |
|
1168 | - case EEM_Registration::status_id_approved: |
|
1169 | - $icon = $show_icons |
|
1170 | - ? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>' |
|
1171 | - : ''; |
|
1172 | - break; |
|
1173 | - case EEM_Registration::status_id_pending_payment: |
|
1174 | - $icon = $show_icons |
|
1175 | - ? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>' |
|
1176 | - : ''; |
|
1177 | - break; |
|
1178 | - case EEM_Registration::status_id_not_approved: |
|
1179 | - $icon = $show_icons |
|
1180 | - ? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>' |
|
1181 | - : ''; |
|
1182 | - break; |
|
1183 | - case EEM_Registration::status_id_cancelled: |
|
1184 | - $icon = $show_icons |
|
1185 | - ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>' |
|
1186 | - : ''; |
|
1187 | - break; |
|
1188 | - case EEM_Registration::status_id_incomplete: |
|
1189 | - $icon = $show_icons |
|
1190 | - ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>' |
|
1191 | - : ''; |
|
1192 | - break; |
|
1193 | - case EEM_Registration::status_id_declined: |
|
1194 | - $icon = $show_icons |
|
1195 | - ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' |
|
1196 | - : ''; |
|
1197 | - break; |
|
1198 | - case EEM_Registration::status_id_wait_list: |
|
1199 | - $icon = $show_icons |
|
1200 | - ? '<span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>' |
|
1201 | - : ''; |
|
1202 | - break; |
|
1203 | - } |
|
1204 | - return $icon . $status[ $this->status_ID() ]; |
|
1205 | - } |
|
1206 | - |
|
1207 | - |
|
1208 | - /** |
|
1209 | - * get Attendee Is Going |
|
1210 | - */ |
|
1211 | - public function att_is_going() |
|
1212 | - { |
|
1213 | - return $this->get('REG_att_is_going'); |
|
1214 | - } |
|
1215 | - |
|
1216 | - |
|
1217 | - /** |
|
1218 | - * Gets related answers |
|
1219 | - * |
|
1220 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1221 | - * @return EE_Answer[] |
|
1222 | - * @throws EE_Error |
|
1223 | - */ |
|
1224 | - public function answers($query_params = null) |
|
1225 | - { |
|
1226 | - return $this->get_many_related('Answer', $query_params); |
|
1227 | - } |
|
1228 | - |
|
1229 | - |
|
1230 | - /** |
|
1231 | - * Gets the registration's answer value to the specified question |
|
1232 | - * (either the question's ID or a question object) |
|
1233 | - * |
|
1234 | - * @param EE_Question|int $question |
|
1235 | - * @param bool $pretty_value |
|
1236 | - * @return array|string if pretty_value= true, the result will always be a string |
|
1237 | - * (because the answer might be an array of answer values, so passing pretty_value=true |
|
1238 | - * will convert it into some kind of string) |
|
1239 | - * @throws EE_Error |
|
1240 | - */ |
|
1241 | - public function answer_value_to_question($question, $pretty_value = true) |
|
1242 | - { |
|
1243 | - $question_id = EEM_Question::instance()->ensure_is_ID($question); |
|
1244 | - return EEM_Answer::instance()->get_answer_value_to_question($this, $question_id, $pretty_value); |
|
1245 | - } |
|
1246 | - |
|
1247 | - |
|
1248 | - /** |
|
1249 | - * question_groups |
|
1250 | - * returns an array of EE_Question_Group objects for this registration |
|
1251 | - * |
|
1252 | - * @return EE_Question_Group[] |
|
1253 | - * @throws EE_Error |
|
1254 | - * @throws EntityNotFoundException |
|
1255 | - */ |
|
1256 | - public function question_groups() |
|
1257 | - { |
|
1258 | - $question_groups = array(); |
|
1259 | - if ($this->event() instanceof EE_Event) { |
|
1260 | - $query_params = [ |
|
1261 | - [ |
|
1262 | - 'Event_Question_Group.' |
|
1263 | - . EEM_Event_Question_Group::instance()->fieldNameForContext( |
|
1264 | - $this->is_primary_registrant() |
|
1265 | - ) => true |
|
1266 | - ], |
|
1267 | - 'order_by' => ['QSG_order' => 'ASC']]; |
|
1268 | - $question_groups = $this->event()->question_groups($query_params); |
|
1269 | - } |
|
1270 | - return $question_groups; |
|
1271 | - } |
|
1272 | - |
|
1273 | - |
|
1274 | - /** |
|
1275 | - * count_question_groups |
|
1276 | - * returns a count of the number of EE_Question_Group objects for this registration |
|
1277 | - * |
|
1278 | - * @return int |
|
1279 | - * @throws EE_Error |
|
1280 | - * @throws EntityNotFoundException |
|
1281 | - * @throws InvalidArgumentException |
|
1282 | - * @throws InvalidDataTypeException |
|
1283 | - * @throws InvalidInterfaceException |
|
1284 | - * @throws ReflectionException |
|
1285 | - */ |
|
1286 | - public function count_question_groups() |
|
1287 | - { |
|
1288 | - $qg_count = 0; |
|
1289 | - if ($this->event() instanceof EE_Event) { |
|
1290 | - if ($this->is_primary_registrant()) { |
|
1291 | - $query_params =[['Event_Question_Group.EQG_primary' => true]]; |
|
1292 | - } else { |
|
1293 | - $query_params = [['Event_Question_Group.EQG_additional' => true]]; |
|
1294 | - } |
|
1295 | - $qg_count = $this->event()->count_related( |
|
1296 | - 'Question_Group', |
|
1297 | - $query_params |
|
1298 | - ); |
|
1299 | - } |
|
1300 | - return $qg_count; |
|
1301 | - } |
|
1302 | - |
|
1303 | - |
|
1304 | - /** |
|
1305 | - * Returns the registration date in the 'standard' string format |
|
1306 | - * (function may be improved in the future to allow for different formats and timezones) |
|
1307 | - * |
|
1308 | - * @return string |
|
1309 | - * @throws EE_Error |
|
1310 | - */ |
|
1311 | - public function reg_date() |
|
1312 | - { |
|
1313 | - return $this->get_datetime('REG_date'); |
|
1314 | - } |
|
1315 | - |
|
1316 | - |
|
1317 | - /** |
|
1318 | - * Gets the datetime-ticket for this registration (ie, it can be used to isolate |
|
1319 | - * the ticket this registration purchased, or the datetime they have registered |
|
1320 | - * to attend) |
|
1321 | - * |
|
1322 | - * @return EE_Datetime_Ticket |
|
1323 | - * @throws EE_Error |
|
1324 | - */ |
|
1325 | - public function datetime_ticket() |
|
1326 | - { |
|
1327 | - return $this->get_first_related('Datetime_Ticket'); |
|
1328 | - } |
|
1329 | - |
|
1330 | - |
|
1331 | - /** |
|
1332 | - * Sets the registration's datetime_ticket. |
|
1333 | - * |
|
1334 | - * @param EE_Datetime_Ticket $datetime_ticket |
|
1335 | - * @return EE_Datetime_Ticket |
|
1336 | - * @throws EE_Error |
|
1337 | - */ |
|
1338 | - public function set_datetime_ticket($datetime_ticket) |
|
1339 | - { |
|
1340 | - return $this->_add_relation_to($datetime_ticket, 'Datetime_Ticket'); |
|
1341 | - } |
|
1342 | - |
|
1343 | - /** |
|
1344 | - * Gets deleted |
|
1345 | - * |
|
1346 | - * @return bool |
|
1347 | - * @throws EE_Error |
|
1348 | - */ |
|
1349 | - public function deleted() |
|
1350 | - { |
|
1351 | - return $this->get('REG_deleted'); |
|
1352 | - } |
|
1353 | - |
|
1354 | - /** |
|
1355 | - * Sets deleted |
|
1356 | - * |
|
1357 | - * @param boolean $deleted |
|
1358 | - * @return bool |
|
1359 | - * @throws EE_Error |
|
1360 | - * @throws RuntimeException |
|
1361 | - */ |
|
1362 | - public function set_deleted($deleted) |
|
1363 | - { |
|
1364 | - if ($deleted) { |
|
1365 | - $this->delete(); |
|
1366 | - } else { |
|
1367 | - $this->restore(); |
|
1368 | - } |
|
1369 | - } |
|
1370 | - |
|
1371 | - |
|
1372 | - /** |
|
1373 | - * Get the status object of this object |
|
1374 | - * |
|
1375 | - * @return EE_Status |
|
1376 | - * @throws EE_Error |
|
1377 | - */ |
|
1378 | - public function status_obj() |
|
1379 | - { |
|
1380 | - return $this->get_first_related('Status'); |
|
1381 | - } |
|
1382 | - |
|
1383 | - |
|
1384 | - /** |
|
1385 | - * Returns the number of times this registration has checked into any of the datetimes |
|
1386 | - * its available for |
|
1387 | - * |
|
1388 | - * @return int |
|
1389 | - * @throws EE_Error |
|
1390 | - */ |
|
1391 | - public function count_checkins() |
|
1392 | - { |
|
1393 | - return $this->get_model()->count_related($this, 'Checkin'); |
|
1394 | - } |
|
1395 | - |
|
1396 | - |
|
1397 | - /** |
|
1398 | - * Returns the number of current Check-ins this registration is checked into for any of the datetimes the |
|
1399 | - * registration is for. Note, this is ONLY checked in (does not include checkedout) |
|
1400 | - * |
|
1401 | - * @return int |
|
1402 | - * @throws EE_Error |
|
1403 | - */ |
|
1404 | - public function count_checkins_not_checkedout() |
|
1405 | - { |
|
1406 | - return $this->get_model()->count_related($this, 'Checkin', array(array('CHK_in' => 1))); |
|
1407 | - } |
|
1408 | - |
|
1409 | - |
|
1410 | - /** |
|
1411 | - * The purpose of this method is simply to check whether this registration can checkin to the given datetime. |
|
1412 | - * |
|
1413 | - * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
1414 | - * @param bool $check_approved This is used to indicate whether the caller wants can_checkin to also |
|
1415 | - * consider registration status as well as datetime access. |
|
1416 | - * @return bool |
|
1417 | - * @throws EE_Error |
|
1418 | - */ |
|
1419 | - public function can_checkin($DTT_OR_ID, $check_approved = true) |
|
1420 | - { |
|
1421 | - $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
1422 | - |
|
1423 | - // first check registration status |
|
1424 | - if (($check_approved && ! $this->is_approved()) || ! $DTT_ID) { |
|
1425 | - return false; |
|
1426 | - } |
|
1427 | - // is there a datetime ticket that matches this dtt_ID? |
|
1428 | - if (! (EEM_Datetime_Ticket::instance()->exists( |
|
1429 | - array( |
|
1430 | - array( |
|
1431 | - 'TKT_ID' => $this->get('TKT_ID'), |
|
1432 | - 'DTT_ID' => $DTT_ID, |
|
1433 | - ), |
|
1434 | - ) |
|
1435 | - )) |
|
1436 | - ) { |
|
1437 | - return false; |
|
1438 | - } |
|
1439 | - |
|
1440 | - // final check is against TKT_uses |
|
1441 | - return $this->verify_can_checkin_against_TKT_uses($DTT_ID); |
|
1442 | - } |
|
1443 | - |
|
1444 | - |
|
1445 | - /** |
|
1446 | - * This method verifies whether the user can checkin for the given datetime considering the max uses value set on |
|
1447 | - * the ticket. To do this, a query is done to get the count of the datetime records already checked into. If the |
|
1448 | - * datetime given does not have a check-in record and checking in for that datetime will exceed the allowed uses, |
|
1449 | - * then return false. Otherwise return true. |
|
1450 | - * |
|
1451 | - * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
1452 | - * @return bool true means can checkin. false means cannot checkin. |
|
1453 | - * @throws EE_Error |
|
1454 | - */ |
|
1455 | - public function verify_can_checkin_against_TKT_uses($DTT_OR_ID) |
|
1456 | - { |
|
1457 | - $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
1458 | - |
|
1459 | - if (! $DTT_ID) { |
|
1460 | - return false; |
|
1461 | - } |
|
1462 | - |
|
1463 | - $max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF; |
|
1464 | - |
|
1465 | - // if max uses is not set or equals infinity then return true cause its not a factor for whether user can |
|
1466 | - // check-in or not. |
|
1467 | - if (! $max_uses || $max_uses === EE_INF) { |
|
1468 | - return true; |
|
1469 | - } |
|
1470 | - |
|
1471 | - // does this datetime have a checkin record? If so, then the dtt count has already been verified so we can just |
|
1472 | - // go ahead and toggle. |
|
1473 | - if (EEM_Checkin::instance()->exists(array(array('REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID)))) { |
|
1474 | - return true; |
|
1475 | - } |
|
1476 | - |
|
1477 | - // made it here so the last check is whether the number of checkins per unique datetime on this registration |
|
1478 | - // disallows further check-ins. |
|
1479 | - $count_unique_dtt_checkins = EEM_Checkin::instance()->count( |
|
1480 | - array( |
|
1481 | - array( |
|
1482 | - 'REG_ID' => $this->ID(), |
|
1483 | - 'CHK_in' => true, |
|
1484 | - ), |
|
1485 | - ), |
|
1486 | - 'DTT_ID', |
|
1487 | - true |
|
1488 | - ); |
|
1489 | - // checkins have already reached their max number of uses |
|
1490 | - // so registrant can NOT checkin |
|
1491 | - if ($count_unique_dtt_checkins >= $max_uses) { |
|
1492 | - EE_Error::add_error( |
|
1493 | - esc_html__( |
|
1494 | - 'Check-in denied because number of datetime uses for the ticket has been reached or exceeded.', |
|
1495 | - 'event_espresso' |
|
1496 | - ), |
|
1497 | - __FILE__, |
|
1498 | - __FUNCTION__, |
|
1499 | - __LINE__ |
|
1500 | - ); |
|
1501 | - return false; |
|
1502 | - } |
|
1503 | - return true; |
|
1504 | - } |
|
1505 | - |
|
1506 | - |
|
1507 | - /** |
|
1508 | - * toggle Check-in status for this registration |
|
1509 | - * Check-ins are toggled in the following order: |
|
1510 | - * never checked in -> checked in |
|
1511 | - * checked in -> checked out |
|
1512 | - * checked out -> checked in |
|
1513 | - * |
|
1514 | - * @param int $DTT_ID include specific datetime to toggle Check-in for. |
|
1515 | - * If not included or null, then it is assumed latest datetime is being toggled. |
|
1516 | - * @param bool $verify If true then can_checkin() is used to verify whether the person |
|
1517 | - * can be checked in or not. Otherwise this forces change in checkin status. |
|
1518 | - * @return bool|int the chk_in status toggled to OR false if nothing got changed. |
|
1519 | - * @throws EE_Error |
|
1520 | - */ |
|
1521 | - public function toggle_checkin_status($DTT_ID = null, $verify = false) |
|
1522 | - { |
|
1523 | - if (empty($DTT_ID)) { |
|
1524 | - $datetime = $this->get_latest_related_datetime(); |
|
1525 | - $DTT_ID = $datetime instanceof EE_Datetime ? $datetime->ID() : 0; |
|
1526 | - // verify the registration can checkin for the given DTT_ID |
|
1527 | - } elseif (! $this->can_checkin($DTT_ID, $verify)) { |
|
1528 | - EE_Error::add_error( |
|
1529 | - sprintf( |
|
1530 | - esc_html__( |
|
1531 | - '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', |
|
1532 | - 'event_espresso' |
|
1533 | - ), |
|
1534 | - $this->ID(), |
|
1535 | - $DTT_ID |
|
1536 | - ), |
|
1537 | - __FILE__, |
|
1538 | - __FUNCTION__, |
|
1539 | - __LINE__ |
|
1540 | - ); |
|
1541 | - return false; |
|
1542 | - } |
|
1543 | - $status_paths = array( |
|
1544 | - EE_Checkin::status_checked_never => EE_Checkin::status_checked_in, |
|
1545 | - EE_Checkin::status_checked_in => EE_Checkin::status_checked_out, |
|
1546 | - EE_Checkin::status_checked_out => EE_Checkin::status_checked_in, |
|
1547 | - ); |
|
1548 | - // start by getting the current status so we know what status we'll be changing to. |
|
1549 | - $cur_status = $this->check_in_status_for_datetime($DTT_ID, null); |
|
1550 | - $status_to = $status_paths[ $cur_status ]; |
|
1551 | - // database only records true for checked IN or false for checked OUT |
|
1552 | - // no record ( null ) means checked in NEVER, but we obviously don't save that |
|
1553 | - $new_status = $status_to === EE_Checkin::status_checked_in ? true : false; |
|
1554 | - // add relation - note Check-ins are always creating new rows |
|
1555 | - // because we are keeping track of Check-ins over time. |
|
1556 | - // Eventually we'll probably want to show a list table |
|
1557 | - // for the individual Check-ins so that they can be managed. |
|
1558 | - $checkin = EE_Checkin::new_instance( |
|
1559 | - array( |
|
1560 | - 'REG_ID' => $this->ID(), |
|
1561 | - 'DTT_ID' => $DTT_ID, |
|
1562 | - 'CHK_in' => $new_status, |
|
1563 | - ) |
|
1564 | - ); |
|
1565 | - // if the record could not be saved then return false |
|
1566 | - if ($checkin->save() === 0) { |
|
1567 | - if (WP_DEBUG) { |
|
1568 | - global $wpdb; |
|
1569 | - $error = sprintf( |
|
1570 | - esc_html__( |
|
1571 | - 'Registration check in update failed because of the following database error: %1$s%2$s', |
|
1572 | - 'event_espresso' |
|
1573 | - ), |
|
1574 | - '<br />', |
|
1575 | - $wpdb->last_error |
|
1576 | - ); |
|
1577 | - } else { |
|
1578 | - $error = esc_html__( |
|
1579 | - 'Registration check in update failed because of an unknown database error', |
|
1580 | - 'event_espresso' |
|
1581 | - ); |
|
1582 | - } |
|
1583 | - EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__); |
|
1584 | - return false; |
|
1585 | - } |
|
1586 | - return $status_to; |
|
1587 | - } |
|
1588 | - |
|
1589 | - |
|
1590 | - /** |
|
1591 | - * Returns the latest datetime related to this registration (via the ticket attached to the registration). |
|
1592 | - * "Latest" is defined by the `DTT_EVT_start` column. |
|
1593 | - * |
|
1594 | - * @return EE_Datetime|null |
|
1595 | - * @throws EE_Error |
|
1596 | - */ |
|
1597 | - public function get_latest_related_datetime() |
|
1598 | - { |
|
1599 | - return EEM_Datetime::instance()->get_one( |
|
1600 | - array( |
|
1601 | - array( |
|
1602 | - 'Ticket.Registration.REG_ID' => $this->ID(), |
|
1603 | - ), |
|
1604 | - 'order_by' => array('DTT_EVT_start' => 'DESC'), |
|
1605 | - ) |
|
1606 | - ); |
|
1607 | - } |
|
1608 | - |
|
1609 | - |
|
1610 | - /** |
|
1611 | - * Returns the earliest datetime related to this registration (via the ticket attached to the registration). |
|
1612 | - * "Earliest" is defined by the `DTT_EVT_start` column. |
|
1613 | - * |
|
1614 | - * @throws EE_Error |
|
1615 | - */ |
|
1616 | - public function get_earliest_related_datetime() |
|
1617 | - { |
|
1618 | - return EEM_Datetime::instance()->get_one( |
|
1619 | - array( |
|
1620 | - array( |
|
1621 | - 'Ticket.Registration.REG_ID' => $this->ID(), |
|
1622 | - ), |
|
1623 | - 'order_by' => array('DTT_EVT_start' => 'ASC'), |
|
1624 | - ) |
|
1625 | - ); |
|
1626 | - } |
|
1627 | - |
|
1628 | - |
|
1629 | - /** |
|
1630 | - * This method simply returns the check-in status for this registration and the given datetime. |
|
1631 | - * If neither the datetime nor the checkin values are provided as arguments, |
|
1632 | - * then this will return the LATEST check-in status for the registration across all datetimes it belongs to. |
|
1633 | - * |
|
1634 | - * @param int $DTT_ID The ID of the datetime we're checking against |
|
1635 | - * (if empty we'll get the primary datetime for |
|
1636 | - * this registration (via event) and use it's ID); |
|
1637 | - * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id. |
|
1638 | - * |
|
1639 | - * @return int Integer representing Check-in status. |
|
1640 | - * @throws EE_Error |
|
1641 | - */ |
|
1642 | - public function check_in_status_for_datetime($DTT_ID = 0, $checkin = null) |
|
1643 | - { |
|
1644 | - $checkin_query_params = array( |
|
1645 | - 'order_by' => array('CHK_timestamp' => 'DESC'), |
|
1646 | - ); |
|
1647 | - |
|
1648 | - if ($DTT_ID > 0) { |
|
1649 | - $checkin_query_params[0] = array('DTT_ID' => $DTT_ID); |
|
1650 | - } |
|
1651 | - |
|
1652 | - // get checkin object (if exists) |
|
1653 | - $checkin = $checkin instanceof EE_Checkin |
|
1654 | - ? $checkin |
|
1655 | - : $this->get_first_related('Checkin', $checkin_query_params); |
|
1656 | - if ($checkin instanceof EE_Checkin) { |
|
1657 | - if ($checkin->get('CHK_in')) { |
|
1658 | - return EE_Checkin::status_checked_in; // checked in |
|
1659 | - } |
|
1660 | - return EE_Checkin::status_checked_out; // had checked in but is now checked out. |
|
1661 | - } |
|
1662 | - return EE_Checkin::status_checked_never; // never been checked in |
|
1663 | - } |
|
1664 | - |
|
1665 | - |
|
1666 | - /** |
|
1667 | - * This method returns a localized message for the toggled Check-in message. |
|
1668 | - * |
|
1669 | - * @param int $DTT_ID include specific datetime to get the correct Check-in message. If not included or null, |
|
1670 | - * then it is assumed Check-in for primary datetime was toggled. |
|
1671 | - * @param bool $error This just flags that you want an error message returned. This is put in so that the error |
|
1672 | - * message can be customized with the attendee name. |
|
1673 | - * @return string internationalized message |
|
1674 | - * @throws EE_Error |
|
1675 | - */ |
|
1676 | - public function get_checkin_msg($DTT_ID, $error = false) |
|
1677 | - { |
|
1678 | - // let's get the attendee first so we can include the name of the attendee |
|
1679 | - $attendee = $this->get_first_related('Attendee'); |
|
1680 | - if ($attendee instanceof EE_Attendee) { |
|
1681 | - if ($error) { |
|
1682 | - return sprintf(__("%s's check-in status was not changed.", "event_espresso"), $attendee->full_name()); |
|
1683 | - } |
|
1684 | - $cur_status = $this->check_in_status_for_datetime($DTT_ID); |
|
1685 | - // what is the status message going to be? |
|
1686 | - switch ($cur_status) { |
|
1687 | - case EE_Checkin::status_checked_never: |
|
1688 | - return sprintf( |
|
1689 | - __("%s has been removed from Check-in records", "event_espresso"), |
|
1690 | - $attendee->full_name() |
|
1691 | - ); |
|
1692 | - break; |
|
1693 | - case EE_Checkin::status_checked_in: |
|
1694 | - return sprintf(__('%s has been checked in', 'event_espresso'), $attendee->full_name()); |
|
1695 | - break; |
|
1696 | - case EE_Checkin::status_checked_out: |
|
1697 | - return sprintf(__('%s has been checked out', 'event_espresso'), $attendee->full_name()); |
|
1698 | - break; |
|
1699 | - } |
|
1700 | - } |
|
1701 | - return esc_html__("The check-in status could not be determined.", "event_espresso"); |
|
1702 | - } |
|
1703 | - |
|
1704 | - |
|
1705 | - /** |
|
1706 | - * Returns the related EE_Transaction to this registration |
|
1707 | - * |
|
1708 | - * @return EE_Transaction |
|
1709 | - * @throws EE_Error |
|
1710 | - * @throws EntityNotFoundException |
|
1711 | - */ |
|
1712 | - public function transaction() |
|
1713 | - { |
|
1714 | - $transaction = $this->get_first_related('Transaction'); |
|
1715 | - if (! $transaction instanceof \EE_Transaction) { |
|
1716 | - throw new EntityNotFoundException('Transaction ID', $this->transaction_ID()); |
|
1717 | - } |
|
1718 | - return $transaction; |
|
1719 | - } |
|
1720 | - |
|
1721 | - |
|
1722 | - /** |
|
1723 | - * get Registration Code |
|
1724 | - */ |
|
1725 | - public function reg_code() |
|
1726 | - { |
|
1727 | - return $this->get('REG_code'); |
|
1728 | - } |
|
1729 | - |
|
1730 | - |
|
1731 | - /** |
|
1732 | - * get Transaction ID |
|
1733 | - */ |
|
1734 | - public function transaction_ID() |
|
1735 | - { |
|
1736 | - return $this->get('TXN_ID'); |
|
1737 | - } |
|
1738 | - |
|
1739 | - |
|
1740 | - /** |
|
1741 | - * @return int |
|
1742 | - * @throws EE_Error |
|
1743 | - */ |
|
1744 | - public function ticket_ID() |
|
1745 | - { |
|
1746 | - return $this->get('TKT_ID'); |
|
1747 | - } |
|
1748 | - |
|
1749 | - |
|
1750 | - /** |
|
1751 | - * Set Registration Code |
|
1752 | - * |
|
1753 | - * @access public |
|
1754 | - * @param string $REG_code Registration Code |
|
1755 | - * @param boolean $use_default |
|
1756 | - * @throws EE_Error |
|
1757 | - */ |
|
1758 | - public function set_reg_code($REG_code, $use_default = false) |
|
1759 | - { |
|
1760 | - if (empty($REG_code)) { |
|
1761 | - EE_Error::add_error( |
|
1762 | - esc_html__('REG_code can not be empty.', 'event_espresso'), |
|
1763 | - __FILE__, |
|
1764 | - __FUNCTION__, |
|
1765 | - __LINE__ |
|
1766 | - ); |
|
1767 | - return; |
|
1768 | - } |
|
1769 | - if (! $this->reg_code()) { |
|
1770 | - parent::set('REG_code', $REG_code, $use_default); |
|
1771 | - } else { |
|
1772 | - EE_Error::doing_it_wrong( |
|
1773 | - __CLASS__ . '::' . __FUNCTION__, |
|
1774 | - esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'), |
|
1775 | - '4.6.0' |
|
1776 | - ); |
|
1777 | - } |
|
1778 | - } |
|
1779 | - |
|
1780 | - |
|
1781 | - /** |
|
1782 | - * Returns all other registrations in the same group as this registrant who have the same ticket option. |
|
1783 | - * Note, if you want to just get all registrations in the same transaction (group), use: |
|
1784 | - * $registration->transaction()->registrations(); |
|
1785 | - * |
|
1786 | - * @since 4.5.0 |
|
1787 | - * @return EE_Registration[] or empty array if this isn't a group registration. |
|
1788 | - * @throws EE_Error |
|
1789 | - */ |
|
1790 | - public function get_all_other_registrations_in_group() |
|
1791 | - { |
|
1792 | - if ($this->group_size() < 2) { |
|
1793 | - return array(); |
|
1794 | - } |
|
1795 | - |
|
1796 | - $query[0] = array( |
|
1797 | - 'TXN_ID' => $this->transaction_ID(), |
|
1798 | - 'REG_ID' => array('!=', $this->ID()), |
|
1799 | - 'TKT_ID' => $this->ticket_ID(), |
|
1800 | - ); |
|
1801 | - /** @var EE_Registration[] $registrations */ |
|
1802 | - $registrations = $this->get_model()->get_all($query); |
|
1803 | - return $registrations; |
|
1804 | - } |
|
1805 | - |
|
1806 | - /** |
|
1807 | - * Return the link to the admin details for the object. |
|
1808 | - * |
|
1809 | - * @return string |
|
1810 | - * @throws EE_Error |
|
1811 | - */ |
|
1812 | - public function get_admin_details_link() |
|
1813 | - { |
|
1814 | - EE_Registry::instance()->load_helper('URL'); |
|
1815 | - return EEH_URL::add_query_args_and_nonce( |
|
1816 | - array( |
|
1817 | - 'page' => 'espresso_registrations', |
|
1818 | - 'action' => 'view_registration', |
|
1819 | - '_REG_ID' => $this->ID(), |
|
1820 | - ), |
|
1821 | - admin_url('admin.php') |
|
1822 | - ); |
|
1823 | - } |
|
1824 | - |
|
1825 | - /** |
|
1826 | - * Returns the link to the editor for the object. Sometimes this is the same as the details. |
|
1827 | - * |
|
1828 | - * @return string |
|
1829 | - * @throws EE_Error |
|
1830 | - */ |
|
1831 | - public function get_admin_edit_link() |
|
1832 | - { |
|
1833 | - return $this->get_admin_details_link(); |
|
1834 | - } |
|
1835 | - |
|
1836 | - /** |
|
1837 | - * Returns the link to a settings page for the object. |
|
1838 | - * |
|
1839 | - * @return string |
|
1840 | - * @throws EE_Error |
|
1841 | - */ |
|
1842 | - public function get_admin_settings_link() |
|
1843 | - { |
|
1844 | - return $this->get_admin_details_link(); |
|
1845 | - } |
|
1846 | - |
|
1847 | - /** |
|
1848 | - * Returns the link to the "overview" for the object (typically the "list table" view). |
|
1849 | - * |
|
1850 | - * @return string |
|
1851 | - */ |
|
1852 | - public function get_admin_overview_link() |
|
1853 | - { |
|
1854 | - EE_Registry::instance()->load_helper('URL'); |
|
1855 | - return EEH_URL::add_query_args_and_nonce( |
|
1856 | - array( |
|
1857 | - 'page' => 'espresso_registrations', |
|
1858 | - ), |
|
1859 | - admin_url('admin.php') |
|
1860 | - ); |
|
1861 | - } |
|
1862 | - |
|
1863 | - |
|
1864 | - /** |
|
1865 | - * @param array $query_params |
|
1866 | - * |
|
1867 | - * @return \EE_Registration[] |
|
1868 | - * @throws EE_Error |
|
1869 | - */ |
|
1870 | - public function payments($query_params = array()) |
|
1871 | - { |
|
1872 | - return $this->get_many_related('Payment', $query_params); |
|
1873 | - } |
|
1874 | - |
|
1875 | - |
|
1876 | - /** |
|
1877 | - * @param array $query_params |
|
1878 | - * |
|
1879 | - * @return \EE_Registration_Payment[] |
|
1880 | - * @throws EE_Error |
|
1881 | - */ |
|
1882 | - public function registration_payments($query_params = array()) |
|
1883 | - { |
|
1884 | - return $this->get_many_related('Registration_Payment', $query_params); |
|
1885 | - } |
|
1886 | - |
|
1887 | - |
|
1888 | - /** |
|
1889 | - * This grabs the payment method corresponding to the last payment made for the amount owing on the registration. |
|
1890 | - * Note: if there are no payments on the registration there will be no payment method returned. |
|
1891 | - * |
|
1892 | - * @return EE_Payment_Method|null |
|
1893 | - */ |
|
1894 | - public function payment_method() |
|
1895 | - { |
|
1896 | - return EEM_Payment_Method::instance()->get_last_used_for_registration($this); |
|
1897 | - } |
|
1898 | - |
|
1899 | - |
|
1900 | - /** |
|
1901 | - * @return \EE_Line_Item |
|
1902 | - * @throws EntityNotFoundException |
|
1903 | - * @throws EE_Error |
|
1904 | - */ |
|
1905 | - public function ticket_line_item() |
|
1906 | - { |
|
1907 | - $ticket = $this->ticket(); |
|
1908 | - $transaction = $this->transaction(); |
|
1909 | - $line_item = null; |
|
1910 | - $ticket_line_items = \EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
1911 | - $transaction->total_line_item(), |
|
1912 | - 'Ticket', |
|
1913 | - array($ticket->ID()) |
|
1914 | - ); |
|
1915 | - foreach ($ticket_line_items as $ticket_line_item) { |
|
1916 | - if ($ticket_line_item instanceof \EE_Line_Item |
|
1917 | - && $ticket_line_item->OBJ_type() === 'Ticket' |
|
1918 | - && $ticket_line_item->OBJ_ID() === $ticket->ID() |
|
1919 | - ) { |
|
1920 | - $line_item = $ticket_line_item; |
|
1921 | - break; |
|
1922 | - } |
|
1923 | - } |
|
1924 | - if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) { |
|
1925 | - throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID()); |
|
1926 | - } |
|
1927 | - return $line_item; |
|
1928 | - } |
|
1929 | - |
|
1930 | - |
|
1931 | - /** |
|
1932 | - * Soft Deletes this model object. |
|
1933 | - * |
|
1934 | - * @return boolean | int |
|
1935 | - * @throws RuntimeException |
|
1936 | - * @throws EE_Error |
|
1937 | - */ |
|
1938 | - public function delete() |
|
1939 | - { |
|
1940 | - if ($this->update_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY, $this->status_ID()) === true) { |
|
1941 | - $this->set_status(EEM_Registration::status_id_cancelled); |
|
1942 | - } |
|
1943 | - return parent::delete(); |
|
1944 | - } |
|
1945 | - |
|
1946 | - |
|
1947 | - /** |
|
1948 | - * Restores whatever the previous status was on a registration before it was trashed (if possible) |
|
1949 | - * |
|
1950 | - * @throws EE_Error |
|
1951 | - * @throws RuntimeException |
|
1952 | - */ |
|
1953 | - public function restore() |
|
1954 | - { |
|
1955 | - $previous_status = $this->get_extra_meta( |
|
1956 | - EE_Registration::PRE_TRASH_REG_STATUS_KEY, |
|
1957 | - true, |
|
1958 | - EEM_Registration::status_id_cancelled |
|
1959 | - ); |
|
1960 | - if ($previous_status) { |
|
1961 | - $this->delete_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY); |
|
1962 | - $this->set_status($previous_status); |
|
1963 | - } |
|
1964 | - return parent::restore(); |
|
1965 | - } |
|
1966 | - |
|
1967 | - |
|
1968 | - /** |
|
1969 | - * possibly toggle Registration status based on comparison of REG_paid vs REG_final_price |
|
1970 | - * |
|
1971 | - * @param boolean $trigger_set_status_logic EE_Registration::set_status() can trigger additional logic |
|
1972 | - * depending on whether the reg status changes to or from "Approved" |
|
1973 | - * @return boolean whether the Registration status was updated |
|
1974 | - * @throws EE_Error |
|
1975 | - * @throws RuntimeException |
|
1976 | - */ |
|
1977 | - public function updateStatusBasedOnTotalPaid($trigger_set_status_logic = true) |
|
1978 | - { |
|
1979 | - $paid = $this->paid(); |
|
1980 | - $price = $this->final_price(); |
|
1981 | - switch (true) { |
|
1982 | - // overpaid or paid |
|
1983 | - case EEH_Money::compare_floats($paid, $price, '>'): |
|
1984 | - case EEH_Money::compare_floats($paid, $price): |
|
1985 | - $new_status = EEM_Registration::status_id_approved; |
|
1986 | - break; |
|
1987 | - // underpaid |
|
1988 | - case EEH_Money::compare_floats($paid, $price, '<'): |
|
1989 | - $new_status = EEM_Registration::status_id_pending_payment; |
|
1990 | - break; |
|
1991 | - // uhhh Houston... |
|
1992 | - default: |
|
1993 | - throw new RuntimeException( |
|
1994 | - esc_html__('The total paid calculation for this registration is inaccurate.', 'event_espresso') |
|
1995 | - ); |
|
1996 | - } |
|
1997 | - if ($new_status !== $this->status_ID()) { |
|
1998 | - if ($trigger_set_status_logic) { |
|
1999 | - return $this->set_status($new_status); |
|
2000 | - } |
|
2001 | - parent::set('STS_ID', $new_status); |
|
2002 | - return true; |
|
2003 | - } |
|
2004 | - return false; |
|
2005 | - } |
|
2006 | - |
|
2007 | - |
|
2008 | - /*************************** DEPRECATED ***************************/ |
|
2009 | - |
|
2010 | - |
|
2011 | - /** |
|
2012 | - * @deprecated |
|
2013 | - * @since 4.7.0 |
|
2014 | - * @access public |
|
2015 | - */ |
|
2016 | - public function price_paid() |
|
2017 | - { |
|
2018 | - EE_Error::doing_it_wrong( |
|
2019 | - 'EE_Registration::price_paid()', |
|
2020 | - esc_html__( |
|
2021 | - 'This method is deprecated, please use EE_Registration::final_price() instead.', |
|
2022 | - 'event_espresso' |
|
2023 | - ), |
|
2024 | - '4.7.0' |
|
2025 | - ); |
|
2026 | - return $this->final_price(); |
|
2027 | - } |
|
2028 | - |
|
2029 | - |
|
2030 | - /** |
|
2031 | - * @deprecated |
|
2032 | - * @since 4.7.0 |
|
2033 | - * @access public |
|
2034 | - * @param float $REG_final_price |
|
2035 | - * @throws EE_Error |
|
2036 | - * @throws RuntimeException |
|
2037 | - */ |
|
2038 | - public function set_price_paid($REG_final_price = 0.00) |
|
2039 | - { |
|
2040 | - EE_Error::doing_it_wrong( |
|
2041 | - 'EE_Registration::set_price_paid()', |
|
2042 | - esc_html__( |
|
2043 | - 'This method is deprecated, please use EE_Registration::set_final_price() instead.', |
|
2044 | - 'event_espresso' |
|
2045 | - ), |
|
2046 | - '4.7.0' |
|
2047 | - ); |
|
2048 | - $this->set_final_price($REG_final_price); |
|
2049 | - } |
|
2050 | - |
|
2051 | - |
|
2052 | - /** |
|
2053 | - * @deprecated |
|
2054 | - * @since 4.7.0 |
|
2055 | - * @return string |
|
2056 | - * @throws EE_Error |
|
2057 | - */ |
|
2058 | - public function pretty_price_paid() |
|
2059 | - { |
|
2060 | - EE_Error::doing_it_wrong( |
|
2061 | - 'EE_Registration::pretty_price_paid()', |
|
2062 | - esc_html__( |
|
2063 | - 'This method is deprecated, please use EE_Registration::pretty_final_price() instead.', |
|
2064 | - 'event_espresso' |
|
2065 | - ), |
|
2066 | - '4.7.0' |
|
2067 | - ); |
|
2068 | - return $this->pretty_final_price(); |
|
2069 | - } |
|
2070 | - |
|
2071 | - |
|
2072 | - /** |
|
2073 | - * Gets the primary datetime related to this registration via the related Event to this registration |
|
2074 | - * |
|
2075 | - * @deprecated 4.9.17 |
|
2076 | - * @return EE_Datetime |
|
2077 | - * @throws EE_Error |
|
2078 | - * @throws EntityNotFoundException |
|
2079 | - */ |
|
2080 | - public function get_related_primary_datetime() |
|
2081 | - { |
|
2082 | - EE_Error::doing_it_wrong( |
|
2083 | - __METHOD__, |
|
2084 | - esc_html__( |
|
2085 | - 'Use EE_Registration::get_latest_related_datetime() or EE_Registration::get_earliest_related_datetime()', |
|
2086 | - 'event_espresso' |
|
2087 | - ), |
|
2088 | - '4.9.17', |
|
2089 | - '5.0.0' |
|
2090 | - ); |
|
2091 | - return $this->event()->primary_datetime(); |
|
2092 | - } |
|
20 | + /** |
|
21 | + * Used to reference when a registration has never been checked in. |
|
22 | + * |
|
23 | + * @deprecated use \EE_Checkin::status_checked_never instead |
|
24 | + * @type int |
|
25 | + */ |
|
26 | + const checkin_status_never = 2; |
|
27 | + |
|
28 | + /** |
|
29 | + * Used to reference when a registration has been checked in. |
|
30 | + * |
|
31 | + * @deprecated use \EE_Checkin::status_checked_in instead |
|
32 | + * @type int |
|
33 | + */ |
|
34 | + const checkin_status_in = 1; |
|
35 | + |
|
36 | + |
|
37 | + /** |
|
38 | + * Used to reference when a registration has been checked out. |
|
39 | + * |
|
40 | + * @deprecated use \EE_Checkin::status_checked_out instead |
|
41 | + * @type int |
|
42 | + */ |
|
43 | + const checkin_status_out = 0; |
|
44 | + |
|
45 | + |
|
46 | + /** |
|
47 | + * extra meta key for tracking reg status os trashed registrations |
|
48 | + * |
|
49 | + * @type string |
|
50 | + */ |
|
51 | + const PRE_TRASH_REG_STATUS_KEY = 'pre_trash_registration_status'; |
|
52 | + |
|
53 | + |
|
54 | + /** |
|
55 | + * extra meta key for tracking if registration has reserved ticket |
|
56 | + * |
|
57 | + * @type string |
|
58 | + */ |
|
59 | + const HAS_RESERVED_TICKET_KEY = 'has_reserved_ticket'; |
|
60 | + |
|
61 | + |
|
62 | + /** |
|
63 | + * @param array $props_n_values incoming values |
|
64 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
65 | + * used.) |
|
66 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
67 | + * date_format and the second value is the time format |
|
68 | + * @return EE_Registration |
|
69 | + * @throws EE_Error |
|
70 | + */ |
|
71 | + public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
72 | + { |
|
73 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
74 | + return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
75 | + } |
|
76 | + |
|
77 | + |
|
78 | + /** |
|
79 | + * @param array $props_n_values incoming values from the database |
|
80 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
81 | + * the website will be used. |
|
82 | + * @return EE_Registration |
|
83 | + */ |
|
84 | + public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
85 | + { |
|
86 | + return new self($props_n_values, true, $timezone); |
|
87 | + } |
|
88 | + |
|
89 | + |
|
90 | + /** |
|
91 | + * Set Event ID |
|
92 | + * |
|
93 | + * @param int $EVT_ID Event ID |
|
94 | + * @throws EE_Error |
|
95 | + * @throws RuntimeException |
|
96 | + */ |
|
97 | + public function set_event($EVT_ID = 0) |
|
98 | + { |
|
99 | + $this->set('EVT_ID', $EVT_ID); |
|
100 | + } |
|
101 | + |
|
102 | + |
|
103 | + /** |
|
104 | + * Overrides parent set() method so that all calls to set( 'REG_code', $REG_code ) OR set( 'STS_ID', $STS_ID ) can |
|
105 | + * be routed to internal methods |
|
106 | + * |
|
107 | + * @param string $field_name |
|
108 | + * @param mixed $field_value |
|
109 | + * @param bool $use_default |
|
110 | + * @throws EE_Error |
|
111 | + * @throws EntityNotFoundException |
|
112 | + * @throws InvalidArgumentException |
|
113 | + * @throws InvalidDataTypeException |
|
114 | + * @throws InvalidInterfaceException |
|
115 | + * @throws ReflectionException |
|
116 | + * @throws RuntimeException |
|
117 | + */ |
|
118 | + public function set($field_name, $field_value, $use_default = false) |
|
119 | + { |
|
120 | + switch ($field_name) { |
|
121 | + case 'REG_code': |
|
122 | + if (! empty($field_value) && $this->reg_code() === null) { |
|
123 | + $this->set_reg_code($field_value, $use_default); |
|
124 | + } |
|
125 | + break; |
|
126 | + case 'STS_ID': |
|
127 | + $this->set_status($field_value, $use_default); |
|
128 | + break; |
|
129 | + default: |
|
130 | + parent::set($field_name, $field_value, $use_default); |
|
131 | + } |
|
132 | + } |
|
133 | + |
|
134 | + |
|
135 | + /** |
|
136 | + * Set Status ID |
|
137 | + * updates the registration status and ALSO... |
|
138 | + * calls reserve_registration_space() if the reg status changes TO approved from any other reg status |
|
139 | + * calls release_registration_space() if the reg status changes FROM approved to any other reg status |
|
140 | + * |
|
141 | + * @param string $new_STS_ID |
|
142 | + * @param boolean $use_default |
|
143 | + * @param ContextInterface|null $context |
|
144 | + * @return bool |
|
145 | + * @throws EE_Error |
|
146 | + * @throws EntityNotFoundException |
|
147 | + * @throws InvalidArgumentException |
|
148 | + * @throws ReflectionException |
|
149 | + * @throws RuntimeException |
|
150 | + * @throws InvalidDataTypeException |
|
151 | + * @throws InvalidInterfaceException |
|
152 | + */ |
|
153 | + public function set_status($new_STS_ID = null, $use_default = false, ContextInterface $context = null) |
|
154 | + { |
|
155 | + // get current REG_Status |
|
156 | + $old_STS_ID = $this->status_ID(); |
|
157 | + // if status has changed |
|
158 | + if ($old_STS_ID !== $new_STS_ID // and that status has actually changed |
|
159 | + && ! empty($old_STS_ID) // and that old status is actually set |
|
160 | + && ! empty($new_STS_ID) // as well as the new status |
|
161 | + && $this->ID() // ensure registration is in the db |
|
162 | + ) { |
|
163 | + // TO approved |
|
164 | + if ($new_STS_ID === EEM_Registration::status_id_approved) { |
|
165 | + // reserve a space by incrementing ticket and datetime sold values |
|
166 | + $this->_reserve_registration_space(); |
|
167 | + do_action('AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID, $context); |
|
168 | + // OR FROM approved |
|
169 | + } elseif ($old_STS_ID === EEM_Registration::status_id_approved) { |
|
170 | + // release a space by decrementing ticket and datetime sold values |
|
171 | + $this->_release_registration_space(); |
|
172 | + do_action( |
|
173 | + 'AHEE__EE_Registration__set_status__from_approved', |
|
174 | + $this, |
|
175 | + $old_STS_ID, |
|
176 | + $new_STS_ID, |
|
177 | + $context |
|
178 | + ); |
|
179 | + } |
|
180 | + // update status |
|
181 | + parent::set('STS_ID', $new_STS_ID, $use_default); |
|
182 | + $this->_update_if_canceled_or_declined($new_STS_ID, $old_STS_ID, $context); |
|
183 | + if ($this->statusChangeUpdatesTransaction($context)) { |
|
184 | + $this->updateTransactionAfterStatusChange(); |
|
185 | + } |
|
186 | + do_action('AHEE__EE_Registration__set_status__after_update', $this, $old_STS_ID, $new_STS_ID, $context); |
|
187 | + return true; |
|
188 | + } |
|
189 | + // even though the old value matches the new value, it's still good to |
|
190 | + // allow the parent set method to have a say |
|
191 | + parent::set('STS_ID', $new_STS_ID, $use_default); |
|
192 | + return true; |
|
193 | + } |
|
194 | + |
|
195 | + |
|
196 | + /** |
|
197 | + * update REGs and TXN when cancelled or declined registrations involved |
|
198 | + * |
|
199 | + * @param string $new_STS_ID |
|
200 | + * @param string $old_STS_ID |
|
201 | + * @param ContextInterface|null $context |
|
202 | + * @throws EE_Error |
|
203 | + * @throws InvalidArgumentException |
|
204 | + * @throws InvalidDataTypeException |
|
205 | + * @throws InvalidInterfaceException |
|
206 | + * @throws ReflectionException |
|
207 | + */ |
|
208 | + private function _update_if_canceled_or_declined($new_STS_ID, $old_STS_ID, ContextInterface $context = null) |
|
209 | + { |
|
210 | + // these reg statuses should not be considered in any calculations involving monies owing |
|
211 | + $closed_reg_statuses = EEM_Registration::closed_reg_statuses(); |
|
212 | + // true if registration has been cancelled or declined |
|
213 | + $this->updateIfCanceled( |
|
214 | + $closed_reg_statuses, |
|
215 | + $new_STS_ID, |
|
216 | + $old_STS_ID, |
|
217 | + $context |
|
218 | + ); |
|
219 | + $this->updateIfDeclined( |
|
220 | + $closed_reg_statuses, |
|
221 | + $new_STS_ID, |
|
222 | + $old_STS_ID, |
|
223 | + $context |
|
224 | + ); |
|
225 | + } |
|
226 | + |
|
227 | + |
|
228 | + /** |
|
229 | + * update REGs and TXN when cancelled or declined registrations involved |
|
230 | + * |
|
231 | + * @param array $closed_reg_statuses |
|
232 | + * @param string $new_STS_ID |
|
233 | + * @param string $old_STS_ID |
|
234 | + * @param ContextInterface|null $context |
|
235 | + * @throws EE_Error |
|
236 | + * @throws InvalidArgumentException |
|
237 | + * @throws InvalidDataTypeException |
|
238 | + * @throws InvalidInterfaceException |
|
239 | + * @throws ReflectionException |
|
240 | + */ |
|
241 | + private function updateIfCanceled( |
|
242 | + array $closed_reg_statuses, |
|
243 | + $new_STS_ID, |
|
244 | + $old_STS_ID, |
|
245 | + ContextInterface $context = null |
|
246 | + ) { |
|
247 | + // true if registration has been cancelled or declined |
|
248 | + if (in_array($new_STS_ID, $closed_reg_statuses, true) |
|
249 | + && ! in_array($old_STS_ID, $closed_reg_statuses, true) |
|
250 | + ) { |
|
251 | + /** @type EE_Registration_Processor $registration_processor */ |
|
252 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
253 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
254 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
255 | + // cancelled or declined registration |
|
256 | + $registration_processor->update_registration_after_being_canceled_or_declined( |
|
257 | + $this, |
|
258 | + $closed_reg_statuses |
|
259 | + ); |
|
260 | + $transaction_processor->update_transaction_after_canceled_or_declined_registration( |
|
261 | + $this, |
|
262 | + $closed_reg_statuses, |
|
263 | + false |
|
264 | + ); |
|
265 | + do_action( |
|
266 | + 'AHEE__EE_Registration__set_status__canceled_or_declined', |
|
267 | + $this, |
|
268 | + $old_STS_ID, |
|
269 | + $new_STS_ID, |
|
270 | + $context |
|
271 | + ); |
|
272 | + return; |
|
273 | + } |
|
274 | + } |
|
275 | + |
|
276 | + |
|
277 | + /** |
|
278 | + * update REGs and TXN when cancelled or declined registrations involved |
|
279 | + * |
|
280 | + * @param array $closed_reg_statuses |
|
281 | + * @param string $new_STS_ID |
|
282 | + * @param string $old_STS_ID |
|
283 | + * @param ContextInterface|null $context |
|
284 | + * @throws EE_Error |
|
285 | + * @throws InvalidArgumentException |
|
286 | + * @throws InvalidDataTypeException |
|
287 | + * @throws InvalidInterfaceException |
|
288 | + * @throws ReflectionException |
|
289 | + */ |
|
290 | + private function updateIfDeclined( |
|
291 | + array $closed_reg_statuses, |
|
292 | + $new_STS_ID, |
|
293 | + $old_STS_ID, |
|
294 | + ContextInterface $context = null |
|
295 | + ) { |
|
296 | + // true if reinstating cancelled or declined registration |
|
297 | + if (in_array($old_STS_ID, $closed_reg_statuses, true) |
|
298 | + && ! in_array($new_STS_ID, $closed_reg_statuses, true) |
|
299 | + ) { |
|
300 | + /** @type EE_Registration_Processor $registration_processor */ |
|
301 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
302 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
303 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
304 | + // reinstating cancelled or declined registration |
|
305 | + $registration_processor->update_canceled_or_declined_registration_after_being_reinstated( |
|
306 | + $this, |
|
307 | + $closed_reg_statuses |
|
308 | + ); |
|
309 | + $transaction_processor->update_transaction_after_reinstating_canceled_registration( |
|
310 | + $this, |
|
311 | + $closed_reg_statuses, |
|
312 | + false |
|
313 | + ); |
|
314 | + do_action( |
|
315 | + 'AHEE__EE_Registration__set_status__after_reinstated', |
|
316 | + $this, |
|
317 | + $old_STS_ID, |
|
318 | + $new_STS_ID, |
|
319 | + $context |
|
320 | + ); |
|
321 | + } |
|
322 | + } |
|
323 | + |
|
324 | + |
|
325 | + /** |
|
326 | + * @param ContextInterface|null $context |
|
327 | + * @return bool |
|
328 | + */ |
|
329 | + private function statusChangeUpdatesTransaction(ContextInterface $context = null) |
|
330 | + { |
|
331 | + $contexts_that_do_not_update_transaction = (array) apply_filters( |
|
332 | + 'AHEE__EE_Registration__statusChangeUpdatesTransaction__contexts_that_do_not_update_transaction', |
|
333 | + array('spco_reg_step_attendee_information_process_registrations'), |
|
334 | + $context, |
|
335 | + $this |
|
336 | + ); |
|
337 | + return ! ( |
|
338 | + $context instanceof ContextInterface |
|
339 | + && in_array($context->slug(), $contexts_that_do_not_update_transaction, true) |
|
340 | + ); |
|
341 | + } |
|
342 | + |
|
343 | + |
|
344 | + /** |
|
345 | + * @throws EE_Error |
|
346 | + * @throws EntityNotFoundException |
|
347 | + * @throws InvalidArgumentException |
|
348 | + * @throws InvalidDataTypeException |
|
349 | + * @throws InvalidInterfaceException |
|
350 | + * @throws ReflectionException |
|
351 | + * @throws RuntimeException |
|
352 | + */ |
|
353 | + private function updateTransactionAfterStatusChange() |
|
354 | + { |
|
355 | + /** @type EE_Transaction_Payments $transaction_payments */ |
|
356 | + $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
357 | + $transaction_payments->recalculate_transaction_total($this->transaction(), false); |
|
358 | + $this->transaction()->update_status_based_on_total_paid(true); |
|
359 | + } |
|
360 | + |
|
361 | + |
|
362 | + /** |
|
363 | + * get Status ID |
|
364 | + */ |
|
365 | + public function status_ID() |
|
366 | + { |
|
367 | + return $this->get('STS_ID'); |
|
368 | + } |
|
369 | + |
|
370 | + |
|
371 | + /** |
|
372 | + * Gets the ticket this registration is for |
|
373 | + * |
|
374 | + * @param boolean $include_archived whether to include archived tickets or not. |
|
375 | + * |
|
376 | + * @return EE_Ticket|EE_Base_Class |
|
377 | + * @throws EE_Error |
|
378 | + */ |
|
379 | + public function ticket($include_archived = true) |
|
380 | + { |
|
381 | + $query_params = array(); |
|
382 | + if ($include_archived) { |
|
383 | + $query_params['default_where_conditions'] = 'none'; |
|
384 | + } |
|
385 | + return $this->get_first_related('Ticket', $query_params); |
|
386 | + } |
|
387 | + |
|
388 | + |
|
389 | + /** |
|
390 | + * Gets the event this registration is for |
|
391 | + * |
|
392 | + * @return EE_Event |
|
393 | + * @throws EE_Error |
|
394 | + * @throws EntityNotFoundException |
|
395 | + */ |
|
396 | + public function event() |
|
397 | + { |
|
398 | + $event = $this->get_first_related('Event'); |
|
399 | + if (! $event instanceof \EE_Event) { |
|
400 | + throw new EntityNotFoundException('Event ID', $this->event_ID()); |
|
401 | + } |
|
402 | + return $event; |
|
403 | + } |
|
404 | + |
|
405 | + |
|
406 | + /** |
|
407 | + * Gets the "author" of the registration. Note that for the purposes of registrations, the author will correspond |
|
408 | + * with the author of the event this registration is for. |
|
409 | + * |
|
410 | + * @since 4.5.0 |
|
411 | + * @return int |
|
412 | + * @throws EE_Error |
|
413 | + * @throws EntityNotFoundException |
|
414 | + */ |
|
415 | + public function wp_user() |
|
416 | + { |
|
417 | + $event = $this->event(); |
|
418 | + if ($event instanceof EE_Event) { |
|
419 | + return $event->wp_user(); |
|
420 | + } |
|
421 | + return 0; |
|
422 | + } |
|
423 | + |
|
424 | + |
|
425 | + /** |
|
426 | + * increments this registration's related ticket sold and corresponding datetime sold values |
|
427 | + * |
|
428 | + * @return void |
|
429 | + * @throws DomainException |
|
430 | + * @throws EE_Error |
|
431 | + * @throws EntityNotFoundException |
|
432 | + * @throws InvalidArgumentException |
|
433 | + * @throws InvalidDataTypeException |
|
434 | + * @throws InvalidInterfaceException |
|
435 | + * @throws ReflectionException |
|
436 | + * @throws UnexpectedEntityException |
|
437 | + */ |
|
438 | + private function _reserve_registration_space() |
|
439 | + { |
|
440 | + // reserved ticket and datetime counts will be decremented as sold counts are incremented |
|
441 | + // so stop tracking that this reg has a ticket reserved |
|
442 | + $this->release_reserved_ticket(false, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
443 | + $ticket = $this->ticket(); |
|
444 | + $ticket->increase_sold(); |
|
445 | + $ticket->save(); |
|
446 | + // possibly set event status to sold out |
|
447 | + $this->event()->perform_sold_out_status_check(); |
|
448 | + } |
|
449 | + |
|
450 | + |
|
451 | + /** |
|
452 | + * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values |
|
453 | + * |
|
454 | + * @return void |
|
455 | + * @throws DomainException |
|
456 | + * @throws EE_Error |
|
457 | + * @throws EntityNotFoundException |
|
458 | + * @throws InvalidArgumentException |
|
459 | + * @throws InvalidDataTypeException |
|
460 | + * @throws InvalidInterfaceException |
|
461 | + * @throws ReflectionException |
|
462 | + * @throws UnexpectedEntityException |
|
463 | + */ |
|
464 | + private function _release_registration_space() |
|
465 | + { |
|
466 | + $ticket = $this->ticket(); |
|
467 | + $ticket->decrease_sold(); |
|
468 | + $ticket->save(); |
|
469 | + // possibly change event status from sold out back to previous status |
|
470 | + $this->event()->perform_sold_out_status_check(); |
|
471 | + } |
|
472 | + |
|
473 | + |
|
474 | + /** |
|
475 | + * tracks this registration's ticket reservation in extra meta |
|
476 | + * and can increment related ticket reserved and corresponding datetime reserved values |
|
477 | + * |
|
478 | + * @param bool $update_ticket if true, will increment ticket and datetime reserved count |
|
479 | + * @return void |
|
480 | + * @throws EE_Error |
|
481 | + * @throws InvalidArgumentException |
|
482 | + * @throws InvalidDataTypeException |
|
483 | + * @throws InvalidInterfaceException |
|
484 | + * @throws ReflectionException |
|
485 | + */ |
|
486 | + public function reserve_ticket($update_ticket = false, $source = 'unknown') |
|
487 | + { |
|
488 | + // only reserve ticket if space is not currently reserved |
|
489 | + if ((bool) $this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) !== true) { |
|
490 | + $this->update_extra_meta('reserve_ticket', "{$this->ticket_ID()} from {$source}"); |
|
491 | + // IMPORTANT !!! |
|
492 | + // although checking $update_ticket first would be more efficient, |
|
493 | + // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
494 | + if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) |
|
495 | + && $update_ticket |
|
496 | + ) { |
|
497 | + $ticket = $this->ticket(); |
|
498 | + $ticket->increase_reserved(1, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
499 | + $ticket->save(); |
|
500 | + } |
|
501 | + } |
|
502 | + } |
|
503 | + |
|
504 | + |
|
505 | + /** |
|
506 | + * stops tracking this registration's ticket reservation in extra meta |
|
507 | + * decrements (subtracts) related ticket reserved and corresponding datetime reserved values |
|
508 | + * |
|
509 | + * @param bool $update_ticket if true, will decrement ticket and datetime reserved count |
|
510 | + * @return void |
|
511 | + * @throws EE_Error |
|
512 | + * @throws InvalidArgumentException |
|
513 | + * @throws InvalidDataTypeException |
|
514 | + * @throws InvalidInterfaceException |
|
515 | + * @throws ReflectionException |
|
516 | + */ |
|
517 | + public function release_reserved_ticket($update_ticket = false, $source = 'unknown') |
|
518 | + { |
|
519 | + // only release ticket if space is currently reserved |
|
520 | + if ((bool) $this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true) === true) { |
|
521 | + $this->update_extra_meta('release_reserved_ticket', "{$this->ticket_ID()} from {$source}"); |
|
522 | + // IMPORTANT !!! |
|
523 | + // although checking $update_ticket first would be more efficient, |
|
524 | + // we NEED to ALWAYS call update_extra_meta(), which is why that is done first |
|
525 | + if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, false) |
|
526 | + && $update_ticket |
|
527 | + ) { |
|
528 | + $ticket = $this->ticket(); |
|
529 | + $ticket->decrease_reserved(1, true, "REG: {$this->ID()} (ln:" . __LINE__ . ')'); |
|
530 | + $ticket->save(); |
|
531 | + } |
|
532 | + } |
|
533 | + } |
|
534 | + |
|
535 | + |
|
536 | + /** |
|
537 | + * Set Attendee ID |
|
538 | + * |
|
539 | + * @param int $ATT_ID Attendee ID |
|
540 | + * @throws EE_Error |
|
541 | + * @throws RuntimeException |
|
542 | + */ |
|
543 | + public function set_attendee_id($ATT_ID = 0) |
|
544 | + { |
|
545 | + $this->set('ATT_ID', $ATT_ID); |
|
546 | + } |
|
547 | + |
|
548 | + |
|
549 | + /** |
|
550 | + * Set Transaction ID |
|
551 | + * |
|
552 | + * @param int $TXN_ID Transaction ID |
|
553 | + * @throws EE_Error |
|
554 | + * @throws RuntimeException |
|
555 | + */ |
|
556 | + public function set_transaction_id($TXN_ID = 0) |
|
557 | + { |
|
558 | + $this->set('TXN_ID', $TXN_ID); |
|
559 | + } |
|
560 | + |
|
561 | + |
|
562 | + /** |
|
563 | + * Set Session |
|
564 | + * |
|
565 | + * @param string $REG_session PHP Session ID |
|
566 | + * @throws EE_Error |
|
567 | + * @throws RuntimeException |
|
568 | + */ |
|
569 | + public function set_session($REG_session = '') |
|
570 | + { |
|
571 | + $this->set('REG_session', $REG_session); |
|
572 | + } |
|
573 | + |
|
574 | + |
|
575 | + /** |
|
576 | + * Set Registration URL Link |
|
577 | + * |
|
578 | + * @param string $REG_url_link Registration URL Link |
|
579 | + * @throws EE_Error |
|
580 | + * @throws RuntimeException |
|
581 | + */ |
|
582 | + public function set_reg_url_link($REG_url_link = '') |
|
583 | + { |
|
584 | + $this->set('REG_url_link', $REG_url_link); |
|
585 | + } |
|
586 | + |
|
587 | + |
|
588 | + /** |
|
589 | + * Set Attendee Counter |
|
590 | + * |
|
591 | + * @param int $REG_count Primary Attendee |
|
592 | + * @throws EE_Error |
|
593 | + * @throws RuntimeException |
|
594 | + */ |
|
595 | + public function set_count($REG_count = 1) |
|
596 | + { |
|
597 | + $this->set('REG_count', $REG_count); |
|
598 | + } |
|
599 | + |
|
600 | + |
|
601 | + /** |
|
602 | + * Set Group Size |
|
603 | + * |
|
604 | + * @param boolean $REG_group_size Group Registration |
|
605 | + * @throws EE_Error |
|
606 | + * @throws RuntimeException |
|
607 | + */ |
|
608 | + public function set_group_size($REG_group_size = false) |
|
609 | + { |
|
610 | + $this->set('REG_group_size', $REG_group_size); |
|
611 | + } |
|
612 | + |
|
613 | + |
|
614 | + /** |
|
615 | + * is_not_approved - convenience method that returns TRUE if REG status ID == |
|
616 | + * EEM_Registration::status_id_not_approved |
|
617 | + * |
|
618 | + * @return boolean |
|
619 | + */ |
|
620 | + public function is_not_approved() |
|
621 | + { |
|
622 | + return $this->status_ID() == EEM_Registration::status_id_not_approved ? true : false; |
|
623 | + } |
|
624 | + |
|
625 | + |
|
626 | + /** |
|
627 | + * is_pending_payment - convenience method that returns TRUE if REG status ID == |
|
628 | + * EEM_Registration::status_id_pending_payment |
|
629 | + * |
|
630 | + * @return boolean |
|
631 | + */ |
|
632 | + public function is_pending_payment() |
|
633 | + { |
|
634 | + return $this->status_ID() == EEM_Registration::status_id_pending_payment ? true : false; |
|
635 | + } |
|
636 | + |
|
637 | + |
|
638 | + /** |
|
639 | + * is_approved - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved |
|
640 | + * |
|
641 | + * @return boolean |
|
642 | + */ |
|
643 | + public function is_approved() |
|
644 | + { |
|
645 | + return $this->status_ID() == EEM_Registration::status_id_approved ? true : false; |
|
646 | + } |
|
647 | + |
|
648 | + |
|
649 | + /** |
|
650 | + * is_cancelled - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled |
|
651 | + * |
|
652 | + * @return boolean |
|
653 | + */ |
|
654 | + public function is_cancelled() |
|
655 | + { |
|
656 | + return $this->status_ID() == EEM_Registration::status_id_cancelled ? true : false; |
|
657 | + } |
|
658 | + |
|
659 | + |
|
660 | + /** |
|
661 | + * is_declined - convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined |
|
662 | + * |
|
663 | + * @return boolean |
|
664 | + */ |
|
665 | + public function is_declined() |
|
666 | + { |
|
667 | + return $this->status_ID() == EEM_Registration::status_id_declined ? true : false; |
|
668 | + } |
|
669 | + |
|
670 | + |
|
671 | + /** |
|
672 | + * is_incomplete - convenience method that returns TRUE if REG status ID == |
|
673 | + * EEM_Registration::status_id_incomplete |
|
674 | + * |
|
675 | + * @return boolean |
|
676 | + */ |
|
677 | + public function is_incomplete() |
|
678 | + { |
|
679 | + return $this->status_ID() == EEM_Registration::status_id_incomplete ? true : false; |
|
680 | + } |
|
681 | + |
|
682 | + |
|
683 | + /** |
|
684 | + * Set Registration Date |
|
685 | + * |
|
686 | + * @param mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of |
|
687 | + * Date |
|
688 | + * @throws EE_Error |
|
689 | + * @throws RuntimeException |
|
690 | + */ |
|
691 | + public function set_reg_date($REG_date = false) |
|
692 | + { |
|
693 | + $this->set('REG_date', $REG_date); |
|
694 | + } |
|
695 | + |
|
696 | + |
|
697 | + /** |
|
698 | + * Set final price owing for this registration after all ticket/price modifications |
|
699 | + * |
|
700 | + * @access public |
|
701 | + * @param float $REG_final_price |
|
702 | + * @throws EE_Error |
|
703 | + * @throws RuntimeException |
|
704 | + */ |
|
705 | + public function set_final_price($REG_final_price = 0.00) |
|
706 | + { |
|
707 | + $this->set('REG_final_price', $REG_final_price); |
|
708 | + } |
|
709 | + |
|
710 | + |
|
711 | + /** |
|
712 | + * Set amount paid towards this registration's final price |
|
713 | + * |
|
714 | + * @access public |
|
715 | + * @param float $REG_paid |
|
716 | + * @throws EE_Error |
|
717 | + * @throws RuntimeException |
|
718 | + */ |
|
719 | + public function set_paid($REG_paid = 0.00) |
|
720 | + { |
|
721 | + $this->set('REG_paid', $REG_paid); |
|
722 | + } |
|
723 | + |
|
724 | + |
|
725 | + /** |
|
726 | + * Attendee Is Going |
|
727 | + * |
|
728 | + * @param boolean $REG_att_is_going Attendee Is Going |
|
729 | + * @throws EE_Error |
|
730 | + * @throws RuntimeException |
|
731 | + */ |
|
732 | + public function set_att_is_going($REG_att_is_going = false) |
|
733 | + { |
|
734 | + $this->set('REG_att_is_going', $REG_att_is_going); |
|
735 | + } |
|
736 | + |
|
737 | + |
|
738 | + /** |
|
739 | + * Gets the related attendee |
|
740 | + * |
|
741 | + * @return EE_Attendee |
|
742 | + * @throws EE_Error |
|
743 | + */ |
|
744 | + public function attendee() |
|
745 | + { |
|
746 | + return $this->get_first_related('Attendee'); |
|
747 | + } |
|
748 | + |
|
749 | + |
|
750 | + /** |
|
751 | + * get Event ID |
|
752 | + */ |
|
753 | + public function event_ID() |
|
754 | + { |
|
755 | + return $this->get('EVT_ID'); |
|
756 | + } |
|
757 | + |
|
758 | + |
|
759 | + /** |
|
760 | + * get Event ID |
|
761 | + */ |
|
762 | + public function event_name() |
|
763 | + { |
|
764 | + $event = $this->event_obj(); |
|
765 | + if ($event) { |
|
766 | + return $event->name(); |
|
767 | + } else { |
|
768 | + return null; |
|
769 | + } |
|
770 | + } |
|
771 | + |
|
772 | + |
|
773 | + /** |
|
774 | + * Fetches the event this registration is for |
|
775 | + * |
|
776 | + * @return EE_Event |
|
777 | + * @throws EE_Error |
|
778 | + */ |
|
779 | + public function event_obj() |
|
780 | + { |
|
781 | + return $this->get_first_related('Event'); |
|
782 | + } |
|
783 | + |
|
784 | + |
|
785 | + /** |
|
786 | + * get Attendee ID |
|
787 | + */ |
|
788 | + public function attendee_ID() |
|
789 | + { |
|
790 | + return $this->get('ATT_ID'); |
|
791 | + } |
|
792 | + |
|
793 | + |
|
794 | + /** |
|
795 | + * get PHP Session ID |
|
796 | + */ |
|
797 | + public function session_ID() |
|
798 | + { |
|
799 | + return $this->get('REG_session'); |
|
800 | + } |
|
801 | + |
|
802 | + |
|
803 | + /** |
|
804 | + * Gets the string which represents the URL trigger for the receipt template in the message template system. |
|
805 | + * |
|
806 | + * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
807 | + * @return string |
|
808 | + */ |
|
809 | + public function receipt_url($messenger = 'html') |
|
810 | + { |
|
811 | + |
|
812 | + /** |
|
813 | + * The below will be deprecated one version after this. We check first if there is a custom receipt template |
|
814 | + * already in use on old system. If there is then we just return the standard url for it. |
|
815 | + * |
|
816 | + * @since 4.5.0 |
|
817 | + */ |
|
818 | + $template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php'; |
|
819 | + $has_custom = EEH_Template::locate_template( |
|
820 | + $template_relative_path, |
|
821 | + array(), |
|
822 | + true, |
|
823 | + true, |
|
824 | + true |
|
825 | + ); |
|
826 | + |
|
827 | + if ($has_custom) { |
|
828 | + return add_query_arg(array('receipt' => 'true'), $this->invoice_url('launch')); |
|
829 | + } |
|
830 | + return apply_filters('FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt'); |
|
831 | + } |
|
832 | + |
|
833 | + |
|
834 | + /** |
|
835 | + * Gets the string which represents the URL trigger for the invoice template in the message template system. |
|
836 | + * |
|
837 | + * @param string $messenger 'pdf' or 'html'. Default 'html'. |
|
838 | + * @return string |
|
839 | + * @throws EE_Error |
|
840 | + */ |
|
841 | + public function invoice_url($messenger = 'html') |
|
842 | + { |
|
843 | + /** |
|
844 | + * The below will be deprecated one version after this. We check first if there is a custom invoice template |
|
845 | + * already in use on old system. If there is then we just return the standard url for it. |
|
846 | + * |
|
847 | + * @since 4.5.0 |
|
848 | + */ |
|
849 | + $template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php'; |
|
850 | + $has_custom = EEH_Template::locate_template( |
|
851 | + $template_relative_path, |
|
852 | + array(), |
|
853 | + true, |
|
854 | + true, |
|
855 | + true |
|
856 | + ); |
|
857 | + |
|
858 | + if ($has_custom) { |
|
859 | + if ($messenger == 'html') { |
|
860 | + return $this->invoice_url('launch'); |
|
861 | + } |
|
862 | + $route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice'; |
|
863 | + |
|
864 | + $query_args = array('ee' => $route, 'id' => $this->reg_url_link()); |
|
865 | + if ($messenger == 'html') { |
|
866 | + $query_args['html'] = true; |
|
867 | + } |
|
868 | + return add_query_arg($query_args, get_permalink(EE_Registry::instance()->CFG->core->thank_you_page_id)); |
|
869 | + } |
|
870 | + return apply_filters('FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice'); |
|
871 | + } |
|
872 | + |
|
873 | + |
|
874 | + /** |
|
875 | + * get Registration URL Link |
|
876 | + * |
|
877 | + * @access public |
|
878 | + * @return string |
|
879 | + * @throws EE_Error |
|
880 | + */ |
|
881 | + public function reg_url_link() |
|
882 | + { |
|
883 | + return (string) $this->get('REG_url_link'); |
|
884 | + } |
|
885 | + |
|
886 | + |
|
887 | + /** |
|
888 | + * Echoes out invoice_url() |
|
889 | + * |
|
890 | + * @param string $type 'download','launch', or 'html' (default is 'launch') |
|
891 | + * @return void |
|
892 | + * @throws EE_Error |
|
893 | + */ |
|
894 | + public function e_invoice_url($type = 'launch') |
|
895 | + { |
|
896 | + echo $this->invoice_url($type); |
|
897 | + } |
|
898 | + |
|
899 | + |
|
900 | + /** |
|
901 | + * Echoes out payment_overview_url |
|
902 | + */ |
|
903 | + public function e_payment_overview_url() |
|
904 | + { |
|
905 | + echo $this->payment_overview_url(); |
|
906 | + } |
|
907 | + |
|
908 | + |
|
909 | + /** |
|
910 | + * Gets the URL for the checkout payment options reg step |
|
911 | + * with this registration's REG_url_link added as a query parameter |
|
912 | + * |
|
913 | + * @param bool $clear_session Set to true when you want to clear the session on revisiting the |
|
914 | + * payment overview url. |
|
915 | + * @return string |
|
916 | + * @throws InvalidInterfaceException |
|
917 | + * @throws InvalidDataTypeException |
|
918 | + * @throws EE_Error |
|
919 | + * @throws InvalidArgumentException |
|
920 | + */ |
|
921 | + public function payment_overview_url($clear_session = false) |
|
922 | + { |
|
923 | + return add_query_arg( |
|
924 | + (array) apply_filters( |
|
925 | + 'FHEE__EE_Registration__payment_overview_url__query_args', |
|
926 | + array( |
|
927 | + 'e_reg_url_link' => $this->reg_url_link(), |
|
928 | + 'step' => 'payment_options', |
|
929 | + 'revisit' => true, |
|
930 | + 'clear_session' => (bool) $clear_session, |
|
931 | + ), |
|
932 | + $this |
|
933 | + ), |
|
934 | + EE_Registry::instance()->CFG->core->reg_page_url() |
|
935 | + ); |
|
936 | + } |
|
937 | + |
|
938 | + |
|
939 | + /** |
|
940 | + * Gets the URL for the checkout attendee information reg step |
|
941 | + * with this registration's REG_url_link added as a query parameter |
|
942 | + * |
|
943 | + * @return string |
|
944 | + * @throws InvalidInterfaceException |
|
945 | + * @throws InvalidDataTypeException |
|
946 | + * @throws EE_Error |
|
947 | + * @throws InvalidArgumentException |
|
948 | + */ |
|
949 | + public function edit_attendee_information_url() |
|
950 | + { |
|
951 | + return add_query_arg( |
|
952 | + (array) apply_filters( |
|
953 | + 'FHEE__EE_Registration__edit_attendee_information_url__query_args', |
|
954 | + array( |
|
955 | + 'e_reg_url_link' => $this->reg_url_link(), |
|
956 | + 'step' => 'attendee_information', |
|
957 | + 'revisit' => true, |
|
958 | + ), |
|
959 | + $this |
|
960 | + ), |
|
961 | + EE_Registry::instance()->CFG->core->reg_page_url() |
|
962 | + ); |
|
963 | + } |
|
964 | + |
|
965 | + |
|
966 | + /** |
|
967 | + * Simply generates and returns the appropriate admin_url link to edit this registration |
|
968 | + * |
|
969 | + * @return string |
|
970 | + * @throws EE_Error |
|
971 | + */ |
|
972 | + public function get_admin_edit_url() |
|
973 | + { |
|
974 | + return EEH_URL::add_query_args_and_nonce( |
|
975 | + array( |
|
976 | + 'page' => 'espresso_registrations', |
|
977 | + 'action' => 'view_registration', |
|
978 | + '_REG_ID' => $this->ID(), |
|
979 | + ), |
|
980 | + admin_url('admin.php') |
|
981 | + ); |
|
982 | + } |
|
983 | + |
|
984 | + |
|
985 | + /** |
|
986 | + * is_primary_registrant? |
|
987 | + */ |
|
988 | + public function is_primary_registrant() |
|
989 | + { |
|
990 | + return $this->get('REG_count') === 1 ? true : false; |
|
991 | + } |
|
992 | + |
|
993 | + |
|
994 | + /** |
|
995 | + * This returns the primary registration object for this registration group (which may be this object). |
|
996 | + * |
|
997 | + * @return EE_Registration |
|
998 | + * @throws EE_Error |
|
999 | + */ |
|
1000 | + public function get_primary_registration() |
|
1001 | + { |
|
1002 | + if ($this->is_primary_registrant()) { |
|
1003 | + return $this; |
|
1004 | + } |
|
1005 | + |
|
1006 | + // k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1 |
|
1007 | + /** @var EE_Registration $primary_registrant */ |
|
1008 | + $primary_registrant = EEM_Registration::instance()->get_one( |
|
1009 | + array( |
|
1010 | + array( |
|
1011 | + 'TXN_ID' => $this->transaction_ID(), |
|
1012 | + 'REG_count' => 1, |
|
1013 | + ), |
|
1014 | + ) |
|
1015 | + ); |
|
1016 | + return $primary_registrant; |
|
1017 | + } |
|
1018 | + |
|
1019 | + |
|
1020 | + /** |
|
1021 | + * get Attendee Number |
|
1022 | + * |
|
1023 | + * @access public |
|
1024 | + */ |
|
1025 | + public function count() |
|
1026 | + { |
|
1027 | + return $this->get('REG_count'); |
|
1028 | + } |
|
1029 | + |
|
1030 | + |
|
1031 | + /** |
|
1032 | + * get Group Size |
|
1033 | + */ |
|
1034 | + public function group_size() |
|
1035 | + { |
|
1036 | + return $this->get('REG_group_size'); |
|
1037 | + } |
|
1038 | + |
|
1039 | + |
|
1040 | + /** |
|
1041 | + * get Registration Date |
|
1042 | + */ |
|
1043 | + public function date() |
|
1044 | + { |
|
1045 | + return $this->get('REG_date'); |
|
1046 | + } |
|
1047 | + |
|
1048 | + |
|
1049 | + /** |
|
1050 | + * gets a pretty date |
|
1051 | + * |
|
1052 | + * @param string $date_format |
|
1053 | + * @param string $time_format |
|
1054 | + * @return string |
|
1055 | + * @throws EE_Error |
|
1056 | + */ |
|
1057 | + public function pretty_date($date_format = null, $time_format = null) |
|
1058 | + { |
|
1059 | + return $this->get_datetime('REG_date', $date_format, $time_format); |
|
1060 | + } |
|
1061 | + |
|
1062 | + |
|
1063 | + /** |
|
1064 | + * final_price |
|
1065 | + * the registration's share of the transaction total, so that the |
|
1066 | + * sum of all the transaction's REG_final_prices equal the transaction's total |
|
1067 | + * |
|
1068 | + * @return float |
|
1069 | + * @throws EE_Error |
|
1070 | + */ |
|
1071 | + public function final_price() |
|
1072 | + { |
|
1073 | + return $this->get('REG_final_price'); |
|
1074 | + } |
|
1075 | + |
|
1076 | + |
|
1077 | + /** |
|
1078 | + * pretty_final_price |
|
1079 | + * final price as formatted string, with correct decimal places and currency symbol |
|
1080 | + * |
|
1081 | + * @return string |
|
1082 | + * @throws EE_Error |
|
1083 | + */ |
|
1084 | + public function pretty_final_price() |
|
1085 | + { |
|
1086 | + return $this->get_pretty('REG_final_price'); |
|
1087 | + } |
|
1088 | + |
|
1089 | + |
|
1090 | + /** |
|
1091 | + * get paid (yeah) |
|
1092 | + * |
|
1093 | + * @return float |
|
1094 | + * @throws EE_Error |
|
1095 | + */ |
|
1096 | + public function paid() |
|
1097 | + { |
|
1098 | + return $this->get('REG_paid'); |
|
1099 | + } |
|
1100 | + |
|
1101 | + |
|
1102 | + /** |
|
1103 | + * pretty_paid |
|
1104 | + * |
|
1105 | + * @return float |
|
1106 | + * @throws EE_Error |
|
1107 | + */ |
|
1108 | + public function pretty_paid() |
|
1109 | + { |
|
1110 | + return $this->get_pretty('REG_paid'); |
|
1111 | + } |
|
1112 | + |
|
1113 | + |
|
1114 | + /** |
|
1115 | + * owes_monies_and_can_pay |
|
1116 | + * whether or not this registration has monies owing and it's' status allows payment |
|
1117 | + * |
|
1118 | + * @param array $requires_payment |
|
1119 | + * @return bool |
|
1120 | + * @throws EE_Error |
|
1121 | + */ |
|
1122 | + public function owes_monies_and_can_pay($requires_payment = array()) |
|
1123 | + { |
|
1124 | + // these reg statuses require payment (if event is not free) |
|
1125 | + $requires_payment = ! empty($requires_payment) |
|
1126 | + ? $requires_payment |
|
1127 | + : EEM_Registration::reg_statuses_that_allow_payment(); |
|
1128 | + if (in_array($this->status_ID(), $requires_payment) && |
|
1129 | + $this->final_price() != 0 && |
|
1130 | + $this->final_price() != $this->paid() |
|
1131 | + ) { |
|
1132 | + return true; |
|
1133 | + } else { |
|
1134 | + return false; |
|
1135 | + } |
|
1136 | + } |
|
1137 | + |
|
1138 | + |
|
1139 | + /** |
|
1140 | + * Prints out the return value of $this->pretty_status() |
|
1141 | + * |
|
1142 | + * @param bool $show_icons |
|
1143 | + * @return void |
|
1144 | + * @throws EE_Error |
|
1145 | + */ |
|
1146 | + public function e_pretty_status($show_icons = false) |
|
1147 | + { |
|
1148 | + echo $this->pretty_status($show_icons); |
|
1149 | + } |
|
1150 | + |
|
1151 | + |
|
1152 | + /** |
|
1153 | + * Returns a nice version of the status for displaying to customers |
|
1154 | + * |
|
1155 | + * @param bool $show_icons |
|
1156 | + * @return string |
|
1157 | + * @throws EE_Error |
|
1158 | + */ |
|
1159 | + public function pretty_status($show_icons = false) |
|
1160 | + { |
|
1161 | + $status = EEM_Status::instance()->localized_status( |
|
1162 | + array($this->status_ID() => esc_html__('unknown', 'event_espresso')), |
|
1163 | + false, |
|
1164 | + 'sentence' |
|
1165 | + ); |
|
1166 | + $icon = ''; |
|
1167 | + switch ($this->status_ID()) { |
|
1168 | + case EEM_Registration::status_id_approved: |
|
1169 | + $icon = $show_icons |
|
1170 | + ? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>' |
|
1171 | + : ''; |
|
1172 | + break; |
|
1173 | + case EEM_Registration::status_id_pending_payment: |
|
1174 | + $icon = $show_icons |
|
1175 | + ? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>' |
|
1176 | + : ''; |
|
1177 | + break; |
|
1178 | + case EEM_Registration::status_id_not_approved: |
|
1179 | + $icon = $show_icons |
|
1180 | + ? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>' |
|
1181 | + : ''; |
|
1182 | + break; |
|
1183 | + case EEM_Registration::status_id_cancelled: |
|
1184 | + $icon = $show_icons |
|
1185 | + ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>' |
|
1186 | + : ''; |
|
1187 | + break; |
|
1188 | + case EEM_Registration::status_id_incomplete: |
|
1189 | + $icon = $show_icons |
|
1190 | + ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>' |
|
1191 | + : ''; |
|
1192 | + break; |
|
1193 | + case EEM_Registration::status_id_declined: |
|
1194 | + $icon = $show_icons |
|
1195 | + ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>' |
|
1196 | + : ''; |
|
1197 | + break; |
|
1198 | + case EEM_Registration::status_id_wait_list: |
|
1199 | + $icon = $show_icons |
|
1200 | + ? '<span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>' |
|
1201 | + : ''; |
|
1202 | + break; |
|
1203 | + } |
|
1204 | + return $icon . $status[ $this->status_ID() ]; |
|
1205 | + } |
|
1206 | + |
|
1207 | + |
|
1208 | + /** |
|
1209 | + * get Attendee Is Going |
|
1210 | + */ |
|
1211 | + public function att_is_going() |
|
1212 | + { |
|
1213 | + return $this->get('REG_att_is_going'); |
|
1214 | + } |
|
1215 | + |
|
1216 | + |
|
1217 | + /** |
|
1218 | + * Gets related answers |
|
1219 | + * |
|
1220 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1221 | + * @return EE_Answer[] |
|
1222 | + * @throws EE_Error |
|
1223 | + */ |
|
1224 | + public function answers($query_params = null) |
|
1225 | + { |
|
1226 | + return $this->get_many_related('Answer', $query_params); |
|
1227 | + } |
|
1228 | + |
|
1229 | + |
|
1230 | + /** |
|
1231 | + * Gets the registration's answer value to the specified question |
|
1232 | + * (either the question's ID or a question object) |
|
1233 | + * |
|
1234 | + * @param EE_Question|int $question |
|
1235 | + * @param bool $pretty_value |
|
1236 | + * @return array|string if pretty_value= true, the result will always be a string |
|
1237 | + * (because the answer might be an array of answer values, so passing pretty_value=true |
|
1238 | + * will convert it into some kind of string) |
|
1239 | + * @throws EE_Error |
|
1240 | + */ |
|
1241 | + public function answer_value_to_question($question, $pretty_value = true) |
|
1242 | + { |
|
1243 | + $question_id = EEM_Question::instance()->ensure_is_ID($question); |
|
1244 | + return EEM_Answer::instance()->get_answer_value_to_question($this, $question_id, $pretty_value); |
|
1245 | + } |
|
1246 | + |
|
1247 | + |
|
1248 | + /** |
|
1249 | + * question_groups |
|
1250 | + * returns an array of EE_Question_Group objects for this registration |
|
1251 | + * |
|
1252 | + * @return EE_Question_Group[] |
|
1253 | + * @throws EE_Error |
|
1254 | + * @throws EntityNotFoundException |
|
1255 | + */ |
|
1256 | + public function question_groups() |
|
1257 | + { |
|
1258 | + $question_groups = array(); |
|
1259 | + if ($this->event() instanceof EE_Event) { |
|
1260 | + $query_params = [ |
|
1261 | + [ |
|
1262 | + 'Event_Question_Group.' |
|
1263 | + . EEM_Event_Question_Group::instance()->fieldNameForContext( |
|
1264 | + $this->is_primary_registrant() |
|
1265 | + ) => true |
|
1266 | + ], |
|
1267 | + 'order_by' => ['QSG_order' => 'ASC']]; |
|
1268 | + $question_groups = $this->event()->question_groups($query_params); |
|
1269 | + } |
|
1270 | + return $question_groups; |
|
1271 | + } |
|
1272 | + |
|
1273 | + |
|
1274 | + /** |
|
1275 | + * count_question_groups |
|
1276 | + * returns a count of the number of EE_Question_Group objects for this registration |
|
1277 | + * |
|
1278 | + * @return int |
|
1279 | + * @throws EE_Error |
|
1280 | + * @throws EntityNotFoundException |
|
1281 | + * @throws InvalidArgumentException |
|
1282 | + * @throws InvalidDataTypeException |
|
1283 | + * @throws InvalidInterfaceException |
|
1284 | + * @throws ReflectionException |
|
1285 | + */ |
|
1286 | + public function count_question_groups() |
|
1287 | + { |
|
1288 | + $qg_count = 0; |
|
1289 | + if ($this->event() instanceof EE_Event) { |
|
1290 | + if ($this->is_primary_registrant()) { |
|
1291 | + $query_params =[['Event_Question_Group.EQG_primary' => true]]; |
|
1292 | + } else { |
|
1293 | + $query_params = [['Event_Question_Group.EQG_additional' => true]]; |
|
1294 | + } |
|
1295 | + $qg_count = $this->event()->count_related( |
|
1296 | + 'Question_Group', |
|
1297 | + $query_params |
|
1298 | + ); |
|
1299 | + } |
|
1300 | + return $qg_count; |
|
1301 | + } |
|
1302 | + |
|
1303 | + |
|
1304 | + /** |
|
1305 | + * Returns the registration date in the 'standard' string format |
|
1306 | + * (function may be improved in the future to allow for different formats and timezones) |
|
1307 | + * |
|
1308 | + * @return string |
|
1309 | + * @throws EE_Error |
|
1310 | + */ |
|
1311 | + public function reg_date() |
|
1312 | + { |
|
1313 | + return $this->get_datetime('REG_date'); |
|
1314 | + } |
|
1315 | + |
|
1316 | + |
|
1317 | + /** |
|
1318 | + * Gets the datetime-ticket for this registration (ie, it can be used to isolate |
|
1319 | + * the ticket this registration purchased, or the datetime they have registered |
|
1320 | + * to attend) |
|
1321 | + * |
|
1322 | + * @return EE_Datetime_Ticket |
|
1323 | + * @throws EE_Error |
|
1324 | + */ |
|
1325 | + public function datetime_ticket() |
|
1326 | + { |
|
1327 | + return $this->get_first_related('Datetime_Ticket'); |
|
1328 | + } |
|
1329 | + |
|
1330 | + |
|
1331 | + /** |
|
1332 | + * Sets the registration's datetime_ticket. |
|
1333 | + * |
|
1334 | + * @param EE_Datetime_Ticket $datetime_ticket |
|
1335 | + * @return EE_Datetime_Ticket |
|
1336 | + * @throws EE_Error |
|
1337 | + */ |
|
1338 | + public function set_datetime_ticket($datetime_ticket) |
|
1339 | + { |
|
1340 | + return $this->_add_relation_to($datetime_ticket, 'Datetime_Ticket'); |
|
1341 | + } |
|
1342 | + |
|
1343 | + /** |
|
1344 | + * Gets deleted |
|
1345 | + * |
|
1346 | + * @return bool |
|
1347 | + * @throws EE_Error |
|
1348 | + */ |
|
1349 | + public function deleted() |
|
1350 | + { |
|
1351 | + return $this->get('REG_deleted'); |
|
1352 | + } |
|
1353 | + |
|
1354 | + /** |
|
1355 | + * Sets deleted |
|
1356 | + * |
|
1357 | + * @param boolean $deleted |
|
1358 | + * @return bool |
|
1359 | + * @throws EE_Error |
|
1360 | + * @throws RuntimeException |
|
1361 | + */ |
|
1362 | + public function set_deleted($deleted) |
|
1363 | + { |
|
1364 | + if ($deleted) { |
|
1365 | + $this->delete(); |
|
1366 | + } else { |
|
1367 | + $this->restore(); |
|
1368 | + } |
|
1369 | + } |
|
1370 | + |
|
1371 | + |
|
1372 | + /** |
|
1373 | + * Get the status object of this object |
|
1374 | + * |
|
1375 | + * @return EE_Status |
|
1376 | + * @throws EE_Error |
|
1377 | + */ |
|
1378 | + public function status_obj() |
|
1379 | + { |
|
1380 | + return $this->get_first_related('Status'); |
|
1381 | + } |
|
1382 | + |
|
1383 | + |
|
1384 | + /** |
|
1385 | + * Returns the number of times this registration has checked into any of the datetimes |
|
1386 | + * its available for |
|
1387 | + * |
|
1388 | + * @return int |
|
1389 | + * @throws EE_Error |
|
1390 | + */ |
|
1391 | + public function count_checkins() |
|
1392 | + { |
|
1393 | + return $this->get_model()->count_related($this, 'Checkin'); |
|
1394 | + } |
|
1395 | + |
|
1396 | + |
|
1397 | + /** |
|
1398 | + * Returns the number of current Check-ins this registration is checked into for any of the datetimes the |
|
1399 | + * registration is for. Note, this is ONLY checked in (does not include checkedout) |
|
1400 | + * |
|
1401 | + * @return int |
|
1402 | + * @throws EE_Error |
|
1403 | + */ |
|
1404 | + public function count_checkins_not_checkedout() |
|
1405 | + { |
|
1406 | + return $this->get_model()->count_related($this, 'Checkin', array(array('CHK_in' => 1))); |
|
1407 | + } |
|
1408 | + |
|
1409 | + |
|
1410 | + /** |
|
1411 | + * The purpose of this method is simply to check whether this registration can checkin to the given datetime. |
|
1412 | + * |
|
1413 | + * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
1414 | + * @param bool $check_approved This is used to indicate whether the caller wants can_checkin to also |
|
1415 | + * consider registration status as well as datetime access. |
|
1416 | + * @return bool |
|
1417 | + * @throws EE_Error |
|
1418 | + */ |
|
1419 | + public function can_checkin($DTT_OR_ID, $check_approved = true) |
|
1420 | + { |
|
1421 | + $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
1422 | + |
|
1423 | + // first check registration status |
|
1424 | + if (($check_approved && ! $this->is_approved()) || ! $DTT_ID) { |
|
1425 | + return false; |
|
1426 | + } |
|
1427 | + // is there a datetime ticket that matches this dtt_ID? |
|
1428 | + if (! (EEM_Datetime_Ticket::instance()->exists( |
|
1429 | + array( |
|
1430 | + array( |
|
1431 | + 'TKT_ID' => $this->get('TKT_ID'), |
|
1432 | + 'DTT_ID' => $DTT_ID, |
|
1433 | + ), |
|
1434 | + ) |
|
1435 | + )) |
|
1436 | + ) { |
|
1437 | + return false; |
|
1438 | + } |
|
1439 | + |
|
1440 | + // final check is against TKT_uses |
|
1441 | + return $this->verify_can_checkin_against_TKT_uses($DTT_ID); |
|
1442 | + } |
|
1443 | + |
|
1444 | + |
|
1445 | + /** |
|
1446 | + * This method verifies whether the user can checkin for the given datetime considering the max uses value set on |
|
1447 | + * the ticket. To do this, a query is done to get the count of the datetime records already checked into. If the |
|
1448 | + * datetime given does not have a check-in record and checking in for that datetime will exceed the allowed uses, |
|
1449 | + * then return false. Otherwise return true. |
|
1450 | + * |
|
1451 | + * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against |
|
1452 | + * @return bool true means can checkin. false means cannot checkin. |
|
1453 | + * @throws EE_Error |
|
1454 | + */ |
|
1455 | + public function verify_can_checkin_against_TKT_uses($DTT_OR_ID) |
|
1456 | + { |
|
1457 | + $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID); |
|
1458 | + |
|
1459 | + if (! $DTT_ID) { |
|
1460 | + return false; |
|
1461 | + } |
|
1462 | + |
|
1463 | + $max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF; |
|
1464 | + |
|
1465 | + // if max uses is not set or equals infinity then return true cause its not a factor for whether user can |
|
1466 | + // check-in or not. |
|
1467 | + if (! $max_uses || $max_uses === EE_INF) { |
|
1468 | + return true; |
|
1469 | + } |
|
1470 | + |
|
1471 | + // does this datetime have a checkin record? If so, then the dtt count has already been verified so we can just |
|
1472 | + // go ahead and toggle. |
|
1473 | + if (EEM_Checkin::instance()->exists(array(array('REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID)))) { |
|
1474 | + return true; |
|
1475 | + } |
|
1476 | + |
|
1477 | + // made it here so the last check is whether the number of checkins per unique datetime on this registration |
|
1478 | + // disallows further check-ins. |
|
1479 | + $count_unique_dtt_checkins = EEM_Checkin::instance()->count( |
|
1480 | + array( |
|
1481 | + array( |
|
1482 | + 'REG_ID' => $this->ID(), |
|
1483 | + 'CHK_in' => true, |
|
1484 | + ), |
|
1485 | + ), |
|
1486 | + 'DTT_ID', |
|
1487 | + true |
|
1488 | + ); |
|
1489 | + // checkins have already reached their max number of uses |
|
1490 | + // so registrant can NOT checkin |
|
1491 | + if ($count_unique_dtt_checkins >= $max_uses) { |
|
1492 | + EE_Error::add_error( |
|
1493 | + esc_html__( |
|
1494 | + 'Check-in denied because number of datetime uses for the ticket has been reached or exceeded.', |
|
1495 | + 'event_espresso' |
|
1496 | + ), |
|
1497 | + __FILE__, |
|
1498 | + __FUNCTION__, |
|
1499 | + __LINE__ |
|
1500 | + ); |
|
1501 | + return false; |
|
1502 | + } |
|
1503 | + return true; |
|
1504 | + } |
|
1505 | + |
|
1506 | + |
|
1507 | + /** |
|
1508 | + * toggle Check-in status for this registration |
|
1509 | + * Check-ins are toggled in the following order: |
|
1510 | + * never checked in -> checked in |
|
1511 | + * checked in -> checked out |
|
1512 | + * checked out -> checked in |
|
1513 | + * |
|
1514 | + * @param int $DTT_ID include specific datetime to toggle Check-in for. |
|
1515 | + * If not included or null, then it is assumed latest datetime is being toggled. |
|
1516 | + * @param bool $verify If true then can_checkin() is used to verify whether the person |
|
1517 | + * can be checked in or not. Otherwise this forces change in checkin status. |
|
1518 | + * @return bool|int the chk_in status toggled to OR false if nothing got changed. |
|
1519 | + * @throws EE_Error |
|
1520 | + */ |
|
1521 | + public function toggle_checkin_status($DTT_ID = null, $verify = false) |
|
1522 | + { |
|
1523 | + if (empty($DTT_ID)) { |
|
1524 | + $datetime = $this->get_latest_related_datetime(); |
|
1525 | + $DTT_ID = $datetime instanceof EE_Datetime ? $datetime->ID() : 0; |
|
1526 | + // verify the registration can checkin for the given DTT_ID |
|
1527 | + } elseif (! $this->can_checkin($DTT_ID, $verify)) { |
|
1528 | + EE_Error::add_error( |
|
1529 | + sprintf( |
|
1530 | + esc_html__( |
|
1531 | + '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', |
|
1532 | + 'event_espresso' |
|
1533 | + ), |
|
1534 | + $this->ID(), |
|
1535 | + $DTT_ID |
|
1536 | + ), |
|
1537 | + __FILE__, |
|
1538 | + __FUNCTION__, |
|
1539 | + __LINE__ |
|
1540 | + ); |
|
1541 | + return false; |
|
1542 | + } |
|
1543 | + $status_paths = array( |
|
1544 | + EE_Checkin::status_checked_never => EE_Checkin::status_checked_in, |
|
1545 | + EE_Checkin::status_checked_in => EE_Checkin::status_checked_out, |
|
1546 | + EE_Checkin::status_checked_out => EE_Checkin::status_checked_in, |
|
1547 | + ); |
|
1548 | + // start by getting the current status so we know what status we'll be changing to. |
|
1549 | + $cur_status = $this->check_in_status_for_datetime($DTT_ID, null); |
|
1550 | + $status_to = $status_paths[ $cur_status ]; |
|
1551 | + // database only records true for checked IN or false for checked OUT |
|
1552 | + // no record ( null ) means checked in NEVER, but we obviously don't save that |
|
1553 | + $new_status = $status_to === EE_Checkin::status_checked_in ? true : false; |
|
1554 | + // add relation - note Check-ins are always creating new rows |
|
1555 | + // because we are keeping track of Check-ins over time. |
|
1556 | + // Eventually we'll probably want to show a list table |
|
1557 | + // for the individual Check-ins so that they can be managed. |
|
1558 | + $checkin = EE_Checkin::new_instance( |
|
1559 | + array( |
|
1560 | + 'REG_ID' => $this->ID(), |
|
1561 | + 'DTT_ID' => $DTT_ID, |
|
1562 | + 'CHK_in' => $new_status, |
|
1563 | + ) |
|
1564 | + ); |
|
1565 | + // if the record could not be saved then return false |
|
1566 | + if ($checkin->save() === 0) { |
|
1567 | + if (WP_DEBUG) { |
|
1568 | + global $wpdb; |
|
1569 | + $error = sprintf( |
|
1570 | + esc_html__( |
|
1571 | + 'Registration check in update failed because of the following database error: %1$s%2$s', |
|
1572 | + 'event_espresso' |
|
1573 | + ), |
|
1574 | + '<br />', |
|
1575 | + $wpdb->last_error |
|
1576 | + ); |
|
1577 | + } else { |
|
1578 | + $error = esc_html__( |
|
1579 | + 'Registration check in update failed because of an unknown database error', |
|
1580 | + 'event_espresso' |
|
1581 | + ); |
|
1582 | + } |
|
1583 | + EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__); |
|
1584 | + return false; |
|
1585 | + } |
|
1586 | + return $status_to; |
|
1587 | + } |
|
1588 | + |
|
1589 | + |
|
1590 | + /** |
|
1591 | + * Returns the latest datetime related to this registration (via the ticket attached to the registration). |
|
1592 | + * "Latest" is defined by the `DTT_EVT_start` column. |
|
1593 | + * |
|
1594 | + * @return EE_Datetime|null |
|
1595 | + * @throws EE_Error |
|
1596 | + */ |
|
1597 | + public function get_latest_related_datetime() |
|
1598 | + { |
|
1599 | + return EEM_Datetime::instance()->get_one( |
|
1600 | + array( |
|
1601 | + array( |
|
1602 | + 'Ticket.Registration.REG_ID' => $this->ID(), |
|
1603 | + ), |
|
1604 | + 'order_by' => array('DTT_EVT_start' => 'DESC'), |
|
1605 | + ) |
|
1606 | + ); |
|
1607 | + } |
|
1608 | + |
|
1609 | + |
|
1610 | + /** |
|
1611 | + * Returns the earliest datetime related to this registration (via the ticket attached to the registration). |
|
1612 | + * "Earliest" is defined by the `DTT_EVT_start` column. |
|
1613 | + * |
|
1614 | + * @throws EE_Error |
|
1615 | + */ |
|
1616 | + public function get_earliest_related_datetime() |
|
1617 | + { |
|
1618 | + return EEM_Datetime::instance()->get_one( |
|
1619 | + array( |
|
1620 | + array( |
|
1621 | + 'Ticket.Registration.REG_ID' => $this->ID(), |
|
1622 | + ), |
|
1623 | + 'order_by' => array('DTT_EVT_start' => 'ASC'), |
|
1624 | + ) |
|
1625 | + ); |
|
1626 | + } |
|
1627 | + |
|
1628 | + |
|
1629 | + /** |
|
1630 | + * This method simply returns the check-in status for this registration and the given datetime. |
|
1631 | + * If neither the datetime nor the checkin values are provided as arguments, |
|
1632 | + * then this will return the LATEST check-in status for the registration across all datetimes it belongs to. |
|
1633 | + * |
|
1634 | + * @param int $DTT_ID The ID of the datetime we're checking against |
|
1635 | + * (if empty we'll get the primary datetime for |
|
1636 | + * this registration (via event) and use it's ID); |
|
1637 | + * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id. |
|
1638 | + * |
|
1639 | + * @return int Integer representing Check-in status. |
|
1640 | + * @throws EE_Error |
|
1641 | + */ |
|
1642 | + public function check_in_status_for_datetime($DTT_ID = 0, $checkin = null) |
|
1643 | + { |
|
1644 | + $checkin_query_params = array( |
|
1645 | + 'order_by' => array('CHK_timestamp' => 'DESC'), |
|
1646 | + ); |
|
1647 | + |
|
1648 | + if ($DTT_ID > 0) { |
|
1649 | + $checkin_query_params[0] = array('DTT_ID' => $DTT_ID); |
|
1650 | + } |
|
1651 | + |
|
1652 | + // get checkin object (if exists) |
|
1653 | + $checkin = $checkin instanceof EE_Checkin |
|
1654 | + ? $checkin |
|
1655 | + : $this->get_first_related('Checkin', $checkin_query_params); |
|
1656 | + if ($checkin instanceof EE_Checkin) { |
|
1657 | + if ($checkin->get('CHK_in')) { |
|
1658 | + return EE_Checkin::status_checked_in; // checked in |
|
1659 | + } |
|
1660 | + return EE_Checkin::status_checked_out; // had checked in but is now checked out. |
|
1661 | + } |
|
1662 | + return EE_Checkin::status_checked_never; // never been checked in |
|
1663 | + } |
|
1664 | + |
|
1665 | + |
|
1666 | + /** |
|
1667 | + * This method returns a localized message for the toggled Check-in message. |
|
1668 | + * |
|
1669 | + * @param int $DTT_ID include specific datetime to get the correct Check-in message. If not included or null, |
|
1670 | + * then it is assumed Check-in for primary datetime was toggled. |
|
1671 | + * @param bool $error This just flags that you want an error message returned. This is put in so that the error |
|
1672 | + * message can be customized with the attendee name. |
|
1673 | + * @return string internationalized message |
|
1674 | + * @throws EE_Error |
|
1675 | + */ |
|
1676 | + public function get_checkin_msg($DTT_ID, $error = false) |
|
1677 | + { |
|
1678 | + // let's get the attendee first so we can include the name of the attendee |
|
1679 | + $attendee = $this->get_first_related('Attendee'); |
|
1680 | + if ($attendee instanceof EE_Attendee) { |
|
1681 | + if ($error) { |
|
1682 | + return sprintf(__("%s's check-in status was not changed.", "event_espresso"), $attendee->full_name()); |
|
1683 | + } |
|
1684 | + $cur_status = $this->check_in_status_for_datetime($DTT_ID); |
|
1685 | + // what is the status message going to be? |
|
1686 | + switch ($cur_status) { |
|
1687 | + case EE_Checkin::status_checked_never: |
|
1688 | + return sprintf( |
|
1689 | + __("%s has been removed from Check-in records", "event_espresso"), |
|
1690 | + $attendee->full_name() |
|
1691 | + ); |
|
1692 | + break; |
|
1693 | + case EE_Checkin::status_checked_in: |
|
1694 | + return sprintf(__('%s has been checked in', 'event_espresso'), $attendee->full_name()); |
|
1695 | + break; |
|
1696 | + case EE_Checkin::status_checked_out: |
|
1697 | + return sprintf(__('%s has been checked out', 'event_espresso'), $attendee->full_name()); |
|
1698 | + break; |
|
1699 | + } |
|
1700 | + } |
|
1701 | + return esc_html__("The check-in status could not be determined.", "event_espresso"); |
|
1702 | + } |
|
1703 | + |
|
1704 | + |
|
1705 | + /** |
|
1706 | + * Returns the related EE_Transaction to this registration |
|
1707 | + * |
|
1708 | + * @return EE_Transaction |
|
1709 | + * @throws EE_Error |
|
1710 | + * @throws EntityNotFoundException |
|
1711 | + */ |
|
1712 | + public function transaction() |
|
1713 | + { |
|
1714 | + $transaction = $this->get_first_related('Transaction'); |
|
1715 | + if (! $transaction instanceof \EE_Transaction) { |
|
1716 | + throw new EntityNotFoundException('Transaction ID', $this->transaction_ID()); |
|
1717 | + } |
|
1718 | + return $transaction; |
|
1719 | + } |
|
1720 | + |
|
1721 | + |
|
1722 | + /** |
|
1723 | + * get Registration Code |
|
1724 | + */ |
|
1725 | + public function reg_code() |
|
1726 | + { |
|
1727 | + return $this->get('REG_code'); |
|
1728 | + } |
|
1729 | + |
|
1730 | + |
|
1731 | + /** |
|
1732 | + * get Transaction ID |
|
1733 | + */ |
|
1734 | + public function transaction_ID() |
|
1735 | + { |
|
1736 | + return $this->get('TXN_ID'); |
|
1737 | + } |
|
1738 | + |
|
1739 | + |
|
1740 | + /** |
|
1741 | + * @return int |
|
1742 | + * @throws EE_Error |
|
1743 | + */ |
|
1744 | + public function ticket_ID() |
|
1745 | + { |
|
1746 | + return $this->get('TKT_ID'); |
|
1747 | + } |
|
1748 | + |
|
1749 | + |
|
1750 | + /** |
|
1751 | + * Set Registration Code |
|
1752 | + * |
|
1753 | + * @access public |
|
1754 | + * @param string $REG_code Registration Code |
|
1755 | + * @param boolean $use_default |
|
1756 | + * @throws EE_Error |
|
1757 | + */ |
|
1758 | + public function set_reg_code($REG_code, $use_default = false) |
|
1759 | + { |
|
1760 | + if (empty($REG_code)) { |
|
1761 | + EE_Error::add_error( |
|
1762 | + esc_html__('REG_code can not be empty.', 'event_espresso'), |
|
1763 | + __FILE__, |
|
1764 | + __FUNCTION__, |
|
1765 | + __LINE__ |
|
1766 | + ); |
|
1767 | + return; |
|
1768 | + } |
|
1769 | + if (! $this->reg_code()) { |
|
1770 | + parent::set('REG_code', $REG_code, $use_default); |
|
1771 | + } else { |
|
1772 | + EE_Error::doing_it_wrong( |
|
1773 | + __CLASS__ . '::' . __FUNCTION__, |
|
1774 | + esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'), |
|
1775 | + '4.6.0' |
|
1776 | + ); |
|
1777 | + } |
|
1778 | + } |
|
1779 | + |
|
1780 | + |
|
1781 | + /** |
|
1782 | + * Returns all other registrations in the same group as this registrant who have the same ticket option. |
|
1783 | + * Note, if you want to just get all registrations in the same transaction (group), use: |
|
1784 | + * $registration->transaction()->registrations(); |
|
1785 | + * |
|
1786 | + * @since 4.5.0 |
|
1787 | + * @return EE_Registration[] or empty array if this isn't a group registration. |
|
1788 | + * @throws EE_Error |
|
1789 | + */ |
|
1790 | + public function get_all_other_registrations_in_group() |
|
1791 | + { |
|
1792 | + if ($this->group_size() < 2) { |
|
1793 | + return array(); |
|
1794 | + } |
|
1795 | + |
|
1796 | + $query[0] = array( |
|
1797 | + 'TXN_ID' => $this->transaction_ID(), |
|
1798 | + 'REG_ID' => array('!=', $this->ID()), |
|
1799 | + 'TKT_ID' => $this->ticket_ID(), |
|
1800 | + ); |
|
1801 | + /** @var EE_Registration[] $registrations */ |
|
1802 | + $registrations = $this->get_model()->get_all($query); |
|
1803 | + return $registrations; |
|
1804 | + } |
|
1805 | + |
|
1806 | + /** |
|
1807 | + * Return the link to the admin details for the object. |
|
1808 | + * |
|
1809 | + * @return string |
|
1810 | + * @throws EE_Error |
|
1811 | + */ |
|
1812 | + public function get_admin_details_link() |
|
1813 | + { |
|
1814 | + EE_Registry::instance()->load_helper('URL'); |
|
1815 | + return EEH_URL::add_query_args_and_nonce( |
|
1816 | + array( |
|
1817 | + 'page' => 'espresso_registrations', |
|
1818 | + 'action' => 'view_registration', |
|
1819 | + '_REG_ID' => $this->ID(), |
|
1820 | + ), |
|
1821 | + admin_url('admin.php') |
|
1822 | + ); |
|
1823 | + } |
|
1824 | + |
|
1825 | + /** |
|
1826 | + * Returns the link to the editor for the object. Sometimes this is the same as the details. |
|
1827 | + * |
|
1828 | + * @return string |
|
1829 | + * @throws EE_Error |
|
1830 | + */ |
|
1831 | + public function get_admin_edit_link() |
|
1832 | + { |
|
1833 | + return $this->get_admin_details_link(); |
|
1834 | + } |
|
1835 | + |
|
1836 | + /** |
|
1837 | + * Returns the link to a settings page for the object. |
|
1838 | + * |
|
1839 | + * @return string |
|
1840 | + * @throws EE_Error |
|
1841 | + */ |
|
1842 | + public function get_admin_settings_link() |
|
1843 | + { |
|
1844 | + return $this->get_admin_details_link(); |
|
1845 | + } |
|
1846 | + |
|
1847 | + /** |
|
1848 | + * Returns the link to the "overview" for the object (typically the "list table" view). |
|
1849 | + * |
|
1850 | + * @return string |
|
1851 | + */ |
|
1852 | + public function get_admin_overview_link() |
|
1853 | + { |
|
1854 | + EE_Registry::instance()->load_helper('URL'); |
|
1855 | + return EEH_URL::add_query_args_and_nonce( |
|
1856 | + array( |
|
1857 | + 'page' => 'espresso_registrations', |
|
1858 | + ), |
|
1859 | + admin_url('admin.php') |
|
1860 | + ); |
|
1861 | + } |
|
1862 | + |
|
1863 | + |
|
1864 | + /** |
|
1865 | + * @param array $query_params |
|
1866 | + * |
|
1867 | + * @return \EE_Registration[] |
|
1868 | + * @throws EE_Error |
|
1869 | + */ |
|
1870 | + public function payments($query_params = array()) |
|
1871 | + { |
|
1872 | + return $this->get_many_related('Payment', $query_params); |
|
1873 | + } |
|
1874 | + |
|
1875 | + |
|
1876 | + /** |
|
1877 | + * @param array $query_params |
|
1878 | + * |
|
1879 | + * @return \EE_Registration_Payment[] |
|
1880 | + * @throws EE_Error |
|
1881 | + */ |
|
1882 | + public function registration_payments($query_params = array()) |
|
1883 | + { |
|
1884 | + return $this->get_many_related('Registration_Payment', $query_params); |
|
1885 | + } |
|
1886 | + |
|
1887 | + |
|
1888 | + /** |
|
1889 | + * This grabs the payment method corresponding to the last payment made for the amount owing on the registration. |
|
1890 | + * Note: if there are no payments on the registration there will be no payment method returned. |
|
1891 | + * |
|
1892 | + * @return EE_Payment_Method|null |
|
1893 | + */ |
|
1894 | + public function payment_method() |
|
1895 | + { |
|
1896 | + return EEM_Payment_Method::instance()->get_last_used_for_registration($this); |
|
1897 | + } |
|
1898 | + |
|
1899 | + |
|
1900 | + /** |
|
1901 | + * @return \EE_Line_Item |
|
1902 | + * @throws EntityNotFoundException |
|
1903 | + * @throws EE_Error |
|
1904 | + */ |
|
1905 | + public function ticket_line_item() |
|
1906 | + { |
|
1907 | + $ticket = $this->ticket(); |
|
1908 | + $transaction = $this->transaction(); |
|
1909 | + $line_item = null; |
|
1910 | + $ticket_line_items = \EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
1911 | + $transaction->total_line_item(), |
|
1912 | + 'Ticket', |
|
1913 | + array($ticket->ID()) |
|
1914 | + ); |
|
1915 | + foreach ($ticket_line_items as $ticket_line_item) { |
|
1916 | + if ($ticket_line_item instanceof \EE_Line_Item |
|
1917 | + && $ticket_line_item->OBJ_type() === 'Ticket' |
|
1918 | + && $ticket_line_item->OBJ_ID() === $ticket->ID() |
|
1919 | + ) { |
|
1920 | + $line_item = $ticket_line_item; |
|
1921 | + break; |
|
1922 | + } |
|
1923 | + } |
|
1924 | + if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) { |
|
1925 | + throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID()); |
|
1926 | + } |
|
1927 | + return $line_item; |
|
1928 | + } |
|
1929 | + |
|
1930 | + |
|
1931 | + /** |
|
1932 | + * Soft Deletes this model object. |
|
1933 | + * |
|
1934 | + * @return boolean | int |
|
1935 | + * @throws RuntimeException |
|
1936 | + * @throws EE_Error |
|
1937 | + */ |
|
1938 | + public function delete() |
|
1939 | + { |
|
1940 | + if ($this->update_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY, $this->status_ID()) === true) { |
|
1941 | + $this->set_status(EEM_Registration::status_id_cancelled); |
|
1942 | + } |
|
1943 | + return parent::delete(); |
|
1944 | + } |
|
1945 | + |
|
1946 | + |
|
1947 | + /** |
|
1948 | + * Restores whatever the previous status was on a registration before it was trashed (if possible) |
|
1949 | + * |
|
1950 | + * @throws EE_Error |
|
1951 | + * @throws RuntimeException |
|
1952 | + */ |
|
1953 | + public function restore() |
|
1954 | + { |
|
1955 | + $previous_status = $this->get_extra_meta( |
|
1956 | + EE_Registration::PRE_TRASH_REG_STATUS_KEY, |
|
1957 | + true, |
|
1958 | + EEM_Registration::status_id_cancelled |
|
1959 | + ); |
|
1960 | + if ($previous_status) { |
|
1961 | + $this->delete_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY); |
|
1962 | + $this->set_status($previous_status); |
|
1963 | + } |
|
1964 | + return parent::restore(); |
|
1965 | + } |
|
1966 | + |
|
1967 | + |
|
1968 | + /** |
|
1969 | + * possibly toggle Registration status based on comparison of REG_paid vs REG_final_price |
|
1970 | + * |
|
1971 | + * @param boolean $trigger_set_status_logic EE_Registration::set_status() can trigger additional logic |
|
1972 | + * depending on whether the reg status changes to or from "Approved" |
|
1973 | + * @return boolean whether the Registration status was updated |
|
1974 | + * @throws EE_Error |
|
1975 | + * @throws RuntimeException |
|
1976 | + */ |
|
1977 | + public function updateStatusBasedOnTotalPaid($trigger_set_status_logic = true) |
|
1978 | + { |
|
1979 | + $paid = $this->paid(); |
|
1980 | + $price = $this->final_price(); |
|
1981 | + switch (true) { |
|
1982 | + // overpaid or paid |
|
1983 | + case EEH_Money::compare_floats($paid, $price, '>'): |
|
1984 | + case EEH_Money::compare_floats($paid, $price): |
|
1985 | + $new_status = EEM_Registration::status_id_approved; |
|
1986 | + break; |
|
1987 | + // underpaid |
|
1988 | + case EEH_Money::compare_floats($paid, $price, '<'): |
|
1989 | + $new_status = EEM_Registration::status_id_pending_payment; |
|
1990 | + break; |
|
1991 | + // uhhh Houston... |
|
1992 | + default: |
|
1993 | + throw new RuntimeException( |
|
1994 | + esc_html__('The total paid calculation for this registration is inaccurate.', 'event_espresso') |
|
1995 | + ); |
|
1996 | + } |
|
1997 | + if ($new_status !== $this->status_ID()) { |
|
1998 | + if ($trigger_set_status_logic) { |
|
1999 | + return $this->set_status($new_status); |
|
2000 | + } |
|
2001 | + parent::set('STS_ID', $new_status); |
|
2002 | + return true; |
|
2003 | + } |
|
2004 | + return false; |
|
2005 | + } |
|
2006 | + |
|
2007 | + |
|
2008 | + /*************************** DEPRECATED ***************************/ |
|
2009 | + |
|
2010 | + |
|
2011 | + /** |
|
2012 | + * @deprecated |
|
2013 | + * @since 4.7.0 |
|
2014 | + * @access public |
|
2015 | + */ |
|
2016 | + public function price_paid() |
|
2017 | + { |
|
2018 | + EE_Error::doing_it_wrong( |
|
2019 | + 'EE_Registration::price_paid()', |
|
2020 | + esc_html__( |
|
2021 | + 'This method is deprecated, please use EE_Registration::final_price() instead.', |
|
2022 | + 'event_espresso' |
|
2023 | + ), |
|
2024 | + '4.7.0' |
|
2025 | + ); |
|
2026 | + return $this->final_price(); |
|
2027 | + } |
|
2028 | + |
|
2029 | + |
|
2030 | + /** |
|
2031 | + * @deprecated |
|
2032 | + * @since 4.7.0 |
|
2033 | + * @access public |
|
2034 | + * @param float $REG_final_price |
|
2035 | + * @throws EE_Error |
|
2036 | + * @throws RuntimeException |
|
2037 | + */ |
|
2038 | + public function set_price_paid($REG_final_price = 0.00) |
|
2039 | + { |
|
2040 | + EE_Error::doing_it_wrong( |
|
2041 | + 'EE_Registration::set_price_paid()', |
|
2042 | + esc_html__( |
|
2043 | + 'This method is deprecated, please use EE_Registration::set_final_price() instead.', |
|
2044 | + 'event_espresso' |
|
2045 | + ), |
|
2046 | + '4.7.0' |
|
2047 | + ); |
|
2048 | + $this->set_final_price($REG_final_price); |
|
2049 | + } |
|
2050 | + |
|
2051 | + |
|
2052 | + /** |
|
2053 | + * @deprecated |
|
2054 | + * @since 4.7.0 |
|
2055 | + * @return string |
|
2056 | + * @throws EE_Error |
|
2057 | + */ |
|
2058 | + public function pretty_price_paid() |
|
2059 | + { |
|
2060 | + EE_Error::doing_it_wrong( |
|
2061 | + 'EE_Registration::pretty_price_paid()', |
|
2062 | + esc_html__( |
|
2063 | + 'This method is deprecated, please use EE_Registration::pretty_final_price() instead.', |
|
2064 | + 'event_espresso' |
|
2065 | + ), |
|
2066 | + '4.7.0' |
|
2067 | + ); |
|
2068 | + return $this->pretty_final_price(); |
|
2069 | + } |
|
2070 | + |
|
2071 | + |
|
2072 | + /** |
|
2073 | + * Gets the primary datetime related to this registration via the related Event to this registration |
|
2074 | + * |
|
2075 | + * @deprecated 4.9.17 |
|
2076 | + * @return EE_Datetime |
|
2077 | + * @throws EE_Error |
|
2078 | + * @throws EntityNotFoundException |
|
2079 | + */ |
|
2080 | + public function get_related_primary_datetime() |
|
2081 | + { |
|
2082 | + EE_Error::doing_it_wrong( |
|
2083 | + __METHOD__, |
|
2084 | + esc_html__( |
|
2085 | + 'Use EE_Registration::get_latest_related_datetime() or EE_Registration::get_earliest_related_datetime()', |
|
2086 | + 'event_espresso' |
|
2087 | + ), |
|
2088 | + '4.9.17', |
|
2089 | + '5.0.0' |
|
2090 | + ); |
|
2091 | + return $this->event()->primary_datetime(); |
|
2092 | + } |
|
2093 | 2093 | } |
@@ -15,1386 +15,1386 @@ |
||
15 | 15 | class EE_Event extends EE_CPT_Base implements EEI_Line_Item_Object, EEI_Admin_Links, EEI_Has_Icon, EEI_Event |
16 | 16 | { |
17 | 17 | |
18 | - /** |
|
19 | - * cached value for the the logical active status for the event |
|
20 | - * |
|
21 | - * @see get_active_status() |
|
22 | - * @var string |
|
23 | - */ |
|
24 | - protected $_active_status = ''; |
|
25 | - |
|
26 | - /** |
|
27 | - * This is just used for caching the Primary Datetime for the Event on initial retrieval |
|
28 | - * |
|
29 | - * @var EE_Datetime |
|
30 | - */ |
|
31 | - protected $_Primary_Datetime; |
|
32 | - |
|
33 | - /** |
|
34 | - * @var EventSpacesCalculator $available_spaces_calculator |
|
35 | - */ |
|
36 | - protected $available_spaces_calculator; |
|
37 | - |
|
38 | - |
|
39 | - /** |
|
40 | - * @param array $props_n_values incoming values |
|
41 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
42 | - * used.) |
|
43 | - * @param array $date_formats incoming date_formats in an array where the first value is the |
|
44 | - * date_format and the second value is the time format |
|
45 | - * @return EE_Event |
|
46 | - * @throws EE_Error |
|
47 | - */ |
|
48 | - public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
49 | - { |
|
50 | - $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
51 | - return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
52 | - } |
|
53 | - |
|
54 | - |
|
55 | - /** |
|
56 | - * @param array $props_n_values incoming values from the database |
|
57 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
58 | - * the website will be used. |
|
59 | - * @return EE_Event |
|
60 | - * @throws EE_Error |
|
61 | - */ |
|
62 | - public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
63 | - { |
|
64 | - return new self($props_n_values, true, $timezone); |
|
65 | - } |
|
66 | - |
|
67 | - |
|
68 | - /** |
|
69 | - * @return EventSpacesCalculator |
|
70 | - * @throws \EE_Error |
|
71 | - */ |
|
72 | - public function getAvailableSpacesCalculator() |
|
73 | - { |
|
74 | - if (! $this->available_spaces_calculator instanceof EventSpacesCalculator) { |
|
75 | - $this->available_spaces_calculator = new EventSpacesCalculator($this); |
|
76 | - } |
|
77 | - return $this->available_spaces_calculator; |
|
78 | - } |
|
79 | - |
|
80 | - |
|
81 | - /** |
|
82 | - * Overrides parent set() method so that all calls to set( 'status', $status ) can be routed to internal methods |
|
83 | - * |
|
84 | - * @param string $field_name |
|
85 | - * @param mixed $field_value |
|
86 | - * @param bool $use_default |
|
87 | - * @throws EE_Error |
|
88 | - */ |
|
89 | - public function set($field_name, $field_value, $use_default = false) |
|
90 | - { |
|
91 | - switch ($field_name) { |
|
92 | - case 'status': |
|
93 | - $this->set_status($field_value, $use_default); |
|
94 | - break; |
|
95 | - default: |
|
96 | - parent::set($field_name, $field_value, $use_default); |
|
97 | - } |
|
98 | - } |
|
99 | - |
|
100 | - |
|
101 | - /** |
|
102 | - * set_status |
|
103 | - * Checks if event status is being changed to SOLD OUT |
|
104 | - * and updates event meta data with previous event status |
|
105 | - * so that we can revert things if/when the event is no longer sold out |
|
106 | - * |
|
107 | - * @access public |
|
108 | - * @param string $new_status |
|
109 | - * @param bool $use_default |
|
110 | - * @return void |
|
111 | - * @throws EE_Error |
|
112 | - */ |
|
113 | - public function set_status($new_status = null, $use_default = false) |
|
114 | - { |
|
115 | - // if nothing is set, and we aren't explicitly wanting to reset the status, then just leave |
|
116 | - if (empty($new_status) && ! $use_default) { |
|
117 | - return; |
|
118 | - } |
|
119 | - // get current Event status |
|
120 | - $old_status = $this->status(); |
|
121 | - // if status has changed |
|
122 | - if ($old_status !== $new_status) { |
|
123 | - // TO sold_out |
|
124 | - if ($new_status === EEM_Event::sold_out) { |
|
125 | - // save the previous event status so that we can revert if the event is no longer sold out |
|
126 | - $this->add_post_meta('_previous_event_status', $old_status); |
|
127 | - do_action('AHEE__EE_Event__set_status__to_sold_out', $this, $old_status, $new_status); |
|
128 | - // OR FROM sold_out |
|
129 | - } elseif ($old_status === EEM_Event::sold_out) { |
|
130 | - $this->delete_post_meta('_previous_event_status'); |
|
131 | - do_action('AHEE__EE_Event__set_status__from_sold_out', $this, $old_status, $new_status); |
|
132 | - } |
|
133 | - // clear out the active status so that it gets reset the next time it is requested |
|
134 | - $this->_active_status = null; |
|
135 | - // update status |
|
136 | - parent::set('status', $new_status, $use_default); |
|
137 | - do_action('AHEE__EE_Event__set_status__after_update', $this); |
|
138 | - return; |
|
139 | - } |
|
140 | - // even though the old value matches the new value, it's still good to |
|
141 | - // allow the parent set method to have a say |
|
142 | - parent::set('status', $new_status, $use_default); |
|
143 | - } |
|
144 | - |
|
145 | - |
|
146 | - /** |
|
147 | - * Gets all the datetimes for this event |
|
148 | - * |
|
149 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
150 | - * @return EE_Base_Class[]|EE_Datetime[] |
|
151 | - * @throws EE_Error |
|
152 | - */ |
|
153 | - public function datetimes($query_params = array()) |
|
154 | - { |
|
155 | - return $this->get_many_related('Datetime', $query_params); |
|
156 | - } |
|
157 | - |
|
158 | - |
|
159 | - /** |
|
160 | - * Gets all the datetimes for this event, ordered by DTT_EVT_start in ascending order |
|
161 | - * |
|
162 | - * @return EE_Base_Class[]|EE_Datetime[] |
|
163 | - * @throws EE_Error |
|
164 | - */ |
|
165 | - public function datetimes_in_chronological_order() |
|
166 | - { |
|
167 | - return $this->get_many_related('Datetime', array('order_by' => array('DTT_EVT_start' => 'ASC'))); |
|
168 | - } |
|
169 | - |
|
170 | - |
|
171 | - /** |
|
172 | - * Gets all the datetimes for this event, ordered by the DTT_order on the datetime. |
|
173 | - * @darren, we should probably UNSET timezone on the EEM_Datetime model |
|
174 | - * after running our query, so that this timezone isn't set for EVERY query |
|
175 | - * on EEM_Datetime for the rest of the request, no? |
|
176 | - * |
|
177 | - * @param boolean $show_expired whether or not to include expired events |
|
178 | - * @param boolean $show_deleted whether or not to include deleted events |
|
179 | - * @param null $limit |
|
180 | - * @return EE_Datetime[] |
|
181 | - * @throws EE_Error |
|
182 | - */ |
|
183 | - public function datetimes_ordered($show_expired = true, $show_deleted = false, $limit = null) |
|
184 | - { |
|
185 | - return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_event_ordered_by_DTT_order( |
|
186 | - $this->ID(), |
|
187 | - $show_expired, |
|
188 | - $show_deleted, |
|
189 | - $limit |
|
190 | - ); |
|
191 | - } |
|
192 | - |
|
193 | - |
|
194 | - /** |
|
195 | - * Returns one related datetime. Mostly only used by some legacy code. |
|
196 | - * |
|
197 | - * @return EE_Base_Class|EE_Datetime |
|
198 | - * @throws EE_Error |
|
199 | - */ |
|
200 | - public function first_datetime() |
|
201 | - { |
|
202 | - return $this->get_first_related('Datetime'); |
|
203 | - } |
|
204 | - |
|
205 | - |
|
206 | - /** |
|
207 | - * Returns the 'primary' datetime for the event |
|
208 | - * |
|
209 | - * @param bool $try_to_exclude_expired |
|
210 | - * @param bool $try_to_exclude_deleted |
|
211 | - * @return EE_Datetime |
|
212 | - * @throws EE_Error |
|
213 | - */ |
|
214 | - public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true) |
|
215 | - { |
|
216 | - if (! empty($this->_Primary_Datetime)) { |
|
217 | - return $this->_Primary_Datetime; |
|
218 | - } |
|
219 | - $this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)->get_primary_datetime_for_event( |
|
220 | - $this->ID(), |
|
221 | - $try_to_exclude_expired, |
|
222 | - $try_to_exclude_deleted |
|
223 | - ); |
|
224 | - return $this->_Primary_Datetime; |
|
225 | - } |
|
226 | - |
|
227 | - |
|
228 | - /** |
|
229 | - * Gets all the tickets available for purchase of this event |
|
230 | - * |
|
231 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
232 | - * @return EE_Base_Class[]|EE_Ticket[] |
|
233 | - * @throws EE_Error |
|
234 | - */ |
|
235 | - public function tickets($query_params = array()) |
|
236 | - { |
|
237 | - // first get all datetimes |
|
238 | - $datetimes = $this->datetimes_ordered(); |
|
239 | - if (! $datetimes) { |
|
240 | - return array(); |
|
241 | - } |
|
242 | - $datetime_ids = array(); |
|
243 | - foreach ($datetimes as $datetime) { |
|
244 | - $datetime_ids[] = $datetime->ID(); |
|
245 | - } |
|
246 | - $where_params = array('Datetime.DTT_ID' => array('IN', $datetime_ids)); |
|
247 | - // if incoming $query_params has where conditions let's merge but not override existing. |
|
248 | - if (is_array($query_params) && isset($query_params[0])) { |
|
249 | - $where_params = array_merge($query_params[0], $where_params); |
|
250 | - unset($query_params[0]); |
|
251 | - } |
|
252 | - // now add $where_params to $query_params |
|
253 | - $query_params[0] = $where_params; |
|
254 | - return EEM_Ticket::instance()->get_all($query_params); |
|
255 | - } |
|
256 | - |
|
257 | - |
|
258 | - /** |
|
259 | - * get all unexpired untrashed tickets |
|
260 | - * |
|
261 | - * @return EE_Ticket[] |
|
262 | - * @throws EE_Error |
|
263 | - */ |
|
264 | - public function active_tickets() |
|
265 | - { |
|
266 | - return $this->tickets( |
|
267 | - array( |
|
268 | - array( |
|
269 | - 'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')), |
|
270 | - 'TKT_deleted' => false, |
|
271 | - ), |
|
272 | - ) |
|
273 | - ); |
|
274 | - } |
|
275 | - |
|
276 | - |
|
277 | - /** |
|
278 | - * @return bool |
|
279 | - * @throws EE_Error |
|
280 | - */ |
|
281 | - public function additional_limit() |
|
282 | - { |
|
283 | - return $this->get('EVT_additional_limit'); |
|
284 | - } |
|
285 | - |
|
286 | - |
|
287 | - /** |
|
288 | - * @return bool |
|
289 | - * @throws EE_Error |
|
290 | - */ |
|
291 | - public function allow_overflow() |
|
292 | - { |
|
293 | - return $this->get('EVT_allow_overflow'); |
|
294 | - } |
|
295 | - |
|
296 | - |
|
297 | - /** |
|
298 | - * @return bool |
|
299 | - * @throws EE_Error |
|
300 | - */ |
|
301 | - public function created() |
|
302 | - { |
|
303 | - return $this->get('EVT_created'); |
|
304 | - } |
|
305 | - |
|
306 | - |
|
307 | - /** |
|
308 | - * @return bool |
|
309 | - * @throws EE_Error |
|
310 | - */ |
|
311 | - public function description() |
|
312 | - { |
|
313 | - return $this->get('EVT_desc'); |
|
314 | - } |
|
315 | - |
|
316 | - |
|
317 | - /** |
|
318 | - * Runs do_shortcode and wpautop on the description |
|
319 | - * |
|
320 | - * @return string of html |
|
321 | - * @throws EE_Error |
|
322 | - */ |
|
323 | - public function description_filtered() |
|
324 | - { |
|
325 | - return $this->get_pretty('EVT_desc'); |
|
326 | - } |
|
327 | - |
|
328 | - |
|
329 | - /** |
|
330 | - * @return bool |
|
331 | - * @throws EE_Error |
|
332 | - */ |
|
333 | - public function display_description() |
|
334 | - { |
|
335 | - return $this->get('EVT_display_desc'); |
|
336 | - } |
|
337 | - |
|
338 | - |
|
339 | - /** |
|
340 | - * @return bool |
|
341 | - * @throws EE_Error |
|
342 | - */ |
|
343 | - public function display_ticket_selector() |
|
344 | - { |
|
345 | - return (bool) $this->get('EVT_display_ticket_selector'); |
|
346 | - } |
|
347 | - |
|
348 | - |
|
349 | - /** |
|
350 | - * @return bool |
|
351 | - * @throws EE_Error |
|
352 | - */ |
|
353 | - public function external_url() |
|
354 | - { |
|
355 | - return $this->get('EVT_external_URL'); |
|
356 | - } |
|
357 | - |
|
358 | - |
|
359 | - /** |
|
360 | - * @return bool |
|
361 | - * @throws EE_Error |
|
362 | - */ |
|
363 | - public function member_only() |
|
364 | - { |
|
365 | - return $this->get('EVT_member_only'); |
|
366 | - } |
|
367 | - |
|
368 | - |
|
369 | - /** |
|
370 | - * @return bool |
|
371 | - * @throws EE_Error |
|
372 | - */ |
|
373 | - public function phone() |
|
374 | - { |
|
375 | - return $this->get('EVT_phone'); |
|
376 | - } |
|
377 | - |
|
378 | - |
|
379 | - /** |
|
380 | - * @return bool |
|
381 | - * @throws EE_Error |
|
382 | - */ |
|
383 | - public function modified() |
|
384 | - { |
|
385 | - return $this->get('EVT_modified'); |
|
386 | - } |
|
387 | - |
|
388 | - |
|
389 | - /** |
|
390 | - * @return bool |
|
391 | - * @throws EE_Error |
|
392 | - */ |
|
393 | - public function name() |
|
394 | - { |
|
395 | - return $this->get('EVT_name'); |
|
396 | - } |
|
397 | - |
|
398 | - |
|
399 | - /** |
|
400 | - * @return bool |
|
401 | - * @throws EE_Error |
|
402 | - */ |
|
403 | - public function order() |
|
404 | - { |
|
405 | - return $this->get('EVT_order'); |
|
406 | - } |
|
407 | - |
|
408 | - |
|
409 | - /** |
|
410 | - * @return bool|string |
|
411 | - * @throws EE_Error |
|
412 | - */ |
|
413 | - public function default_registration_status() |
|
414 | - { |
|
415 | - $event_default_registration_status = $this->get('EVT_default_registration_status'); |
|
416 | - return ! empty($event_default_registration_status) |
|
417 | - ? $event_default_registration_status |
|
418 | - : EE_Registry::instance()->CFG->registration->default_STS_ID; |
|
419 | - } |
|
420 | - |
|
421 | - |
|
422 | - /** |
|
423 | - * @param int $num_words |
|
424 | - * @param null $more |
|
425 | - * @param bool $not_full_desc |
|
426 | - * @return bool|string |
|
427 | - * @throws EE_Error |
|
428 | - */ |
|
429 | - public function short_description($num_words = 55, $more = null, $not_full_desc = false) |
|
430 | - { |
|
431 | - $short_desc = $this->get('EVT_short_desc'); |
|
432 | - if (! empty($short_desc) || $not_full_desc) { |
|
433 | - return $short_desc; |
|
434 | - } |
|
435 | - $full_desc = $this->get('EVT_desc'); |
|
436 | - return wp_trim_words($full_desc, $num_words, $more); |
|
437 | - } |
|
438 | - |
|
439 | - |
|
440 | - /** |
|
441 | - * @return bool |
|
442 | - * @throws EE_Error |
|
443 | - */ |
|
444 | - public function slug() |
|
445 | - { |
|
446 | - return $this->get('EVT_slug'); |
|
447 | - } |
|
448 | - |
|
449 | - |
|
450 | - /** |
|
451 | - * @return bool |
|
452 | - * @throws EE_Error |
|
453 | - */ |
|
454 | - public function timezone_string() |
|
455 | - { |
|
456 | - return $this->get('EVT_timezone_string'); |
|
457 | - } |
|
458 | - |
|
459 | - |
|
460 | - /** |
|
461 | - * @return bool |
|
462 | - * @throws EE_Error |
|
463 | - */ |
|
464 | - public function visible_on() |
|
465 | - { |
|
466 | - return $this->get('EVT_visible_on'); |
|
467 | - } |
|
468 | - |
|
469 | - |
|
470 | - /** |
|
471 | - * @return int |
|
472 | - * @throws EE_Error |
|
473 | - */ |
|
474 | - public function wp_user() |
|
475 | - { |
|
476 | - return $this->get('EVT_wp_user'); |
|
477 | - } |
|
478 | - |
|
479 | - |
|
480 | - /** |
|
481 | - * @return bool |
|
482 | - * @throws EE_Error |
|
483 | - */ |
|
484 | - public function donations() |
|
485 | - { |
|
486 | - return $this->get('EVT_donations'); |
|
487 | - } |
|
488 | - |
|
489 | - |
|
490 | - /** |
|
491 | - * @param $limit |
|
492 | - * @throws EE_Error |
|
493 | - */ |
|
494 | - public function set_additional_limit($limit) |
|
495 | - { |
|
496 | - $this->set('EVT_additional_limit', $limit); |
|
497 | - } |
|
498 | - |
|
499 | - |
|
500 | - /** |
|
501 | - * @param $created |
|
502 | - * @throws EE_Error |
|
503 | - */ |
|
504 | - public function set_created($created) |
|
505 | - { |
|
506 | - $this->set('EVT_created', $created); |
|
507 | - } |
|
508 | - |
|
509 | - |
|
510 | - /** |
|
511 | - * @param $desc |
|
512 | - * @throws EE_Error |
|
513 | - */ |
|
514 | - public function set_description($desc) |
|
515 | - { |
|
516 | - $this->set('EVT_desc', $desc); |
|
517 | - } |
|
518 | - |
|
519 | - |
|
520 | - /** |
|
521 | - * @param $display_desc |
|
522 | - * @throws EE_Error |
|
523 | - */ |
|
524 | - public function set_display_description($display_desc) |
|
525 | - { |
|
526 | - $this->set('EVT_display_desc', $display_desc); |
|
527 | - } |
|
528 | - |
|
529 | - |
|
530 | - /** |
|
531 | - * @param $display_ticket_selector |
|
532 | - * @throws EE_Error |
|
533 | - */ |
|
534 | - public function set_display_ticket_selector($display_ticket_selector) |
|
535 | - { |
|
536 | - $this->set('EVT_display_ticket_selector', $display_ticket_selector); |
|
537 | - } |
|
538 | - |
|
539 | - |
|
540 | - /** |
|
541 | - * @param $external_url |
|
542 | - * @throws EE_Error |
|
543 | - */ |
|
544 | - public function set_external_url($external_url) |
|
545 | - { |
|
546 | - $this->set('EVT_external_URL', $external_url); |
|
547 | - } |
|
548 | - |
|
549 | - |
|
550 | - /** |
|
551 | - * @param $member_only |
|
552 | - * @throws EE_Error |
|
553 | - */ |
|
554 | - public function set_member_only($member_only) |
|
555 | - { |
|
556 | - $this->set('EVT_member_only', $member_only); |
|
557 | - } |
|
558 | - |
|
559 | - |
|
560 | - /** |
|
561 | - * @param $event_phone |
|
562 | - * @throws EE_Error |
|
563 | - */ |
|
564 | - public function set_event_phone($event_phone) |
|
565 | - { |
|
566 | - $this->set('EVT_phone', $event_phone); |
|
567 | - } |
|
568 | - |
|
569 | - |
|
570 | - /** |
|
571 | - * @param $modified |
|
572 | - * @throws EE_Error |
|
573 | - */ |
|
574 | - public function set_modified($modified) |
|
575 | - { |
|
576 | - $this->set('EVT_modified', $modified); |
|
577 | - } |
|
578 | - |
|
579 | - |
|
580 | - /** |
|
581 | - * @param $name |
|
582 | - * @throws EE_Error |
|
583 | - */ |
|
584 | - public function set_name($name) |
|
585 | - { |
|
586 | - $this->set('EVT_name', $name); |
|
587 | - } |
|
588 | - |
|
589 | - |
|
590 | - /** |
|
591 | - * @param $order |
|
592 | - * @throws EE_Error |
|
593 | - */ |
|
594 | - public function set_order($order) |
|
595 | - { |
|
596 | - $this->set('EVT_order', $order); |
|
597 | - } |
|
598 | - |
|
599 | - |
|
600 | - /** |
|
601 | - * @param $short_desc |
|
602 | - * @throws EE_Error |
|
603 | - */ |
|
604 | - public function set_short_description($short_desc) |
|
605 | - { |
|
606 | - $this->set('EVT_short_desc', $short_desc); |
|
607 | - } |
|
608 | - |
|
609 | - |
|
610 | - /** |
|
611 | - * @param $slug |
|
612 | - * @throws EE_Error |
|
613 | - */ |
|
614 | - public function set_slug($slug) |
|
615 | - { |
|
616 | - $this->set('EVT_slug', $slug); |
|
617 | - } |
|
618 | - |
|
619 | - |
|
620 | - /** |
|
621 | - * @param $timezone_string |
|
622 | - * @throws EE_Error |
|
623 | - */ |
|
624 | - public function set_timezone_string($timezone_string) |
|
625 | - { |
|
626 | - $this->set('EVT_timezone_string', $timezone_string); |
|
627 | - } |
|
628 | - |
|
629 | - |
|
630 | - /** |
|
631 | - * @param $visible_on |
|
632 | - * @throws EE_Error |
|
633 | - */ |
|
634 | - public function set_visible_on($visible_on) |
|
635 | - { |
|
636 | - $this->set('EVT_visible_on', $visible_on); |
|
637 | - } |
|
638 | - |
|
639 | - |
|
640 | - /** |
|
641 | - * @param $wp_user |
|
642 | - * @throws EE_Error |
|
643 | - */ |
|
644 | - public function set_wp_user($wp_user) |
|
645 | - { |
|
646 | - $this->set('EVT_wp_user', $wp_user); |
|
647 | - } |
|
648 | - |
|
649 | - |
|
650 | - /** |
|
651 | - * @param $default_registration_status |
|
652 | - * @throws EE_Error |
|
653 | - */ |
|
654 | - public function set_default_registration_status($default_registration_status) |
|
655 | - { |
|
656 | - $this->set('EVT_default_registration_status', $default_registration_status); |
|
657 | - } |
|
658 | - |
|
659 | - |
|
660 | - /** |
|
661 | - * @param $donations |
|
662 | - * @throws EE_Error |
|
663 | - */ |
|
664 | - public function set_donations($donations) |
|
665 | - { |
|
666 | - $this->set('EVT_donations', $donations); |
|
667 | - } |
|
668 | - |
|
669 | - |
|
670 | - /** |
|
671 | - * Adds a venue to this event |
|
672 | - * |
|
673 | - * @param EE_Venue /int $venue_id_or_obj |
|
674 | - * @return EE_Base_Class|EE_Venue |
|
675 | - * @throws EE_Error |
|
676 | - */ |
|
677 | - public function add_venue($venue_id_or_obj) |
|
678 | - { |
|
679 | - return $this->_add_relation_to($venue_id_or_obj, 'Venue'); |
|
680 | - } |
|
681 | - |
|
682 | - |
|
683 | - /** |
|
684 | - * Removes a venue from the event |
|
685 | - * |
|
686 | - * @param EE_Venue /int $venue_id_or_obj |
|
687 | - * @return EE_Base_Class|EE_Venue |
|
688 | - * @throws EE_Error |
|
689 | - */ |
|
690 | - public function remove_venue($venue_id_or_obj) |
|
691 | - { |
|
692 | - return $this->_remove_relation_to($venue_id_or_obj, 'Venue'); |
|
693 | - } |
|
694 | - |
|
695 | - |
|
696 | - /** |
|
697 | - * Gets all the venues related ot the event. May provide additional $query_params if desired |
|
698 | - * |
|
699 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
700 | - * @return EE_Base_Class[]|EE_Venue[] |
|
701 | - * @throws EE_Error |
|
702 | - */ |
|
703 | - public function venues($query_params = array()) |
|
704 | - { |
|
705 | - return $this->get_many_related('Venue', $query_params); |
|
706 | - } |
|
707 | - |
|
708 | - |
|
709 | - /** |
|
710 | - * check if event id is present and if event is published |
|
711 | - * |
|
712 | - * @access public |
|
713 | - * @return boolean true yes, false no |
|
714 | - * @throws EE_Error |
|
715 | - */ |
|
716 | - private function _has_ID_and_is_published() |
|
717 | - { |
|
718 | - // first check if event id is present and not NULL, |
|
719 | - // then check if this event is published (or any of the equivalent "published" statuses) |
|
720 | - return |
|
721 | - $this->ID() && $this->ID() !== null |
|
722 | - && ( |
|
723 | - $this->status() === 'publish' |
|
724 | - || $this->status() === EEM_Event::sold_out |
|
725 | - || $this->status() === EEM_Event::postponed |
|
726 | - || $this->status() === EEM_Event::cancelled |
|
727 | - ); |
|
728 | - } |
|
729 | - |
|
730 | - |
|
731 | - /** |
|
732 | - * This simply compares the internal dates with NOW and determines if the event is upcoming or not. |
|
733 | - * |
|
734 | - * @access public |
|
735 | - * @return boolean true yes, false no |
|
736 | - * @throws EE_Error |
|
737 | - */ |
|
738 | - public function is_upcoming() |
|
739 | - { |
|
740 | - // check if event id is present and if this event is published |
|
741 | - if ($this->is_inactive()) { |
|
742 | - return false; |
|
743 | - } |
|
744 | - // set initial value |
|
745 | - $upcoming = false; |
|
746 | - // next let's get all datetimes and loop through them |
|
747 | - $datetimes = $this->datetimes_in_chronological_order(); |
|
748 | - foreach ($datetimes as $datetime) { |
|
749 | - if ($datetime instanceof EE_Datetime) { |
|
750 | - // if this dtt is expired then we continue cause one of the other datetimes might be upcoming. |
|
751 | - if ($datetime->is_expired()) { |
|
752 | - continue; |
|
753 | - } |
|
754 | - // if this dtt is active then we return false. |
|
755 | - if ($datetime->is_active()) { |
|
756 | - return false; |
|
757 | - } |
|
758 | - // otherwise let's check upcoming status |
|
759 | - $upcoming = $datetime->is_upcoming(); |
|
760 | - } |
|
761 | - } |
|
762 | - return $upcoming; |
|
763 | - } |
|
764 | - |
|
765 | - |
|
766 | - /** |
|
767 | - * @return bool |
|
768 | - * @throws EE_Error |
|
769 | - */ |
|
770 | - public function is_active() |
|
771 | - { |
|
772 | - // check if event id is present and if this event is published |
|
773 | - if ($this->is_inactive()) { |
|
774 | - return false; |
|
775 | - } |
|
776 | - // set initial value |
|
777 | - $active = false; |
|
778 | - // next let's get all datetimes and loop through them |
|
779 | - $datetimes = $this->datetimes_in_chronological_order(); |
|
780 | - foreach ($datetimes as $datetime) { |
|
781 | - if ($datetime instanceof EE_Datetime) { |
|
782 | - // if this dtt is expired then we continue cause one of the other datetimes might be active. |
|
783 | - if ($datetime->is_expired()) { |
|
784 | - continue; |
|
785 | - } |
|
786 | - // if this dtt is upcoming then we return false. |
|
787 | - if ($datetime->is_upcoming()) { |
|
788 | - return false; |
|
789 | - } |
|
790 | - // otherwise let's check active status |
|
791 | - $active = $datetime->is_active(); |
|
792 | - } |
|
793 | - } |
|
794 | - return $active; |
|
795 | - } |
|
796 | - |
|
797 | - |
|
798 | - /** |
|
799 | - * @return bool |
|
800 | - * @throws EE_Error |
|
801 | - */ |
|
802 | - public function is_expired() |
|
803 | - { |
|
804 | - // check if event id is present and if this event is published |
|
805 | - if ($this->is_inactive()) { |
|
806 | - return false; |
|
807 | - } |
|
808 | - // set initial value |
|
809 | - $expired = false; |
|
810 | - // first let's get all datetimes and loop through them |
|
811 | - $datetimes = $this->datetimes_in_chronological_order(); |
|
812 | - foreach ($datetimes as $datetime) { |
|
813 | - if ($datetime instanceof EE_Datetime) { |
|
814 | - // if this dtt is upcoming or active then we return false. |
|
815 | - if ($datetime->is_upcoming() || $datetime->is_active()) { |
|
816 | - return false; |
|
817 | - } |
|
818 | - // otherwise let's check active status |
|
819 | - $expired = $datetime->is_expired(); |
|
820 | - } |
|
821 | - } |
|
822 | - return $expired; |
|
823 | - } |
|
824 | - |
|
825 | - |
|
826 | - /** |
|
827 | - * @return bool |
|
828 | - * @throws EE_Error |
|
829 | - */ |
|
830 | - public function is_inactive() |
|
831 | - { |
|
832 | - // check if event id is present and if this event is published |
|
833 | - if ($this->_has_ID_and_is_published()) { |
|
834 | - return false; |
|
835 | - } |
|
836 | - return true; |
|
837 | - } |
|
838 | - |
|
839 | - |
|
840 | - /** |
|
841 | - * calculate spaces remaining based on "saleable" tickets |
|
842 | - * |
|
843 | - * @param array $tickets |
|
844 | - * @param bool $filtered |
|
845 | - * @return int|float |
|
846 | - * @throws EE_Error |
|
847 | - * @throws DomainException |
|
848 | - * @throws UnexpectedEntityException |
|
849 | - */ |
|
850 | - public function spaces_remaining($tickets = array(), $filtered = true) |
|
851 | - { |
|
852 | - $this->getAvailableSpacesCalculator()->setActiveTickets($tickets); |
|
853 | - $spaces_remaining = $this->getAvailableSpacesCalculator()->spacesRemaining(); |
|
854 | - return $filtered |
|
855 | - ? apply_filters( |
|
856 | - 'FHEE_EE_Event__spaces_remaining', |
|
857 | - $spaces_remaining, |
|
858 | - $this, |
|
859 | - $tickets |
|
860 | - ) |
|
861 | - : $spaces_remaining; |
|
862 | - } |
|
863 | - |
|
864 | - |
|
865 | - /** |
|
866 | - * perform_sold_out_status_check |
|
867 | - * checks all of this events's datetime reg_limit - sold values to determine if ANY datetimes have spaces |
|
868 | - * available... if NOT, then the event status will get toggled to 'sold_out' |
|
869 | - * |
|
870 | - * @return bool return the ACTUAL sold out state. |
|
871 | - * @throws EE_Error |
|
872 | - * @throws DomainException |
|
873 | - * @throws UnexpectedEntityException |
|
874 | - */ |
|
875 | - public function perform_sold_out_status_check() |
|
876 | - { |
|
877 | - // get all unexpired untrashed tickets |
|
878 | - $tickets = $this->tickets( |
|
879 | - array( |
|
880 | - array('TKT_deleted' => false), |
|
881 | - 'order_by' => array('TKT_qty' => 'ASC'), |
|
882 | - ) |
|
883 | - ); |
|
884 | - $all_expired = true; |
|
885 | - foreach ($tickets as $ticket) { |
|
886 | - if (! $ticket->is_expired()) { |
|
887 | - $all_expired = false; |
|
888 | - break; |
|
889 | - } |
|
890 | - } |
|
891 | - // if all the tickets are just expired, then don't update the event status to sold out |
|
892 | - if ($all_expired) { |
|
893 | - return true; |
|
894 | - } |
|
895 | - $spaces_remaining = $this->spaces_remaining($tickets); |
|
896 | - if ($spaces_remaining < 1) { |
|
897 | - $this->set_status(EEM_Event::sold_out); |
|
898 | - $this->save(); |
|
899 | - $sold_out = true; |
|
900 | - } else { |
|
901 | - $sold_out = false; |
|
902 | - // was event previously marked as sold out ? |
|
903 | - if ($this->status() === EEM_Event::sold_out) { |
|
904 | - // revert status to previous value, if it was set |
|
905 | - $previous_event_status = $this->get_post_meta('_previous_event_status', true); |
|
906 | - if ($previous_event_status) { |
|
907 | - $this->set_status($previous_event_status); |
|
908 | - $this->save(); |
|
909 | - } |
|
910 | - } |
|
911 | - } |
|
912 | - do_action('AHEE__EE_Event__perform_sold_out_status_check__end', $this, $sold_out, $spaces_remaining, $tickets); |
|
913 | - return $sold_out; |
|
914 | - } |
|
915 | - |
|
916 | - |
|
917 | - /** |
|
918 | - * This returns the total remaining spaces for sale on this event. |
|
919 | - * |
|
920 | - * @uses EE_Event::total_available_spaces() |
|
921 | - * @return float|int |
|
922 | - * @throws EE_Error |
|
923 | - * @throws DomainException |
|
924 | - * @throws UnexpectedEntityException |
|
925 | - */ |
|
926 | - public function spaces_remaining_for_sale() |
|
927 | - { |
|
928 | - return $this->total_available_spaces(true); |
|
929 | - } |
|
930 | - |
|
931 | - |
|
932 | - /** |
|
933 | - * This returns the total spaces available for an event |
|
934 | - * while considering all the qtys on the tickets and the reg limits |
|
935 | - * on the datetimes attached to this event. |
|
936 | - * |
|
937 | - * @param bool $consider_sold Whether to consider any tickets that have already sold in our calculation. |
|
938 | - * If this is false, then we return the most tickets that could ever be sold |
|
939 | - * for this event with the datetime and tickets setup on the event under optimal |
|
940 | - * selling conditions. Otherwise we return a live calculation of spaces available |
|
941 | - * based on tickets sold. Depending on setup and stage of sales, this |
|
942 | - * may appear to equal remaining tickets. However, the more tickets are |
|
943 | - * sold out, the more accurate the "live" total is. |
|
944 | - * @return float|int |
|
945 | - * @throws EE_Error |
|
946 | - * @throws DomainException |
|
947 | - * @throws UnexpectedEntityException |
|
948 | - */ |
|
949 | - public function total_available_spaces($consider_sold = false) |
|
950 | - { |
|
951 | - $spaces_available = $consider_sold |
|
952 | - ? $this->getAvailableSpacesCalculator()->spacesRemaining() |
|
953 | - : $this->getAvailableSpacesCalculator()->totalSpacesAvailable(); |
|
954 | - return apply_filters( |
|
955 | - 'FHEE_EE_Event__total_available_spaces__spaces_available', |
|
956 | - $spaces_available, |
|
957 | - $this, |
|
958 | - $this->getAvailableSpacesCalculator()->getDatetimes(), |
|
959 | - $this->getAvailableSpacesCalculator()->getActiveTickets() |
|
960 | - ); |
|
961 | - } |
|
962 | - |
|
963 | - |
|
964 | - /** |
|
965 | - * Checks if the event is set to sold out |
|
966 | - * |
|
967 | - * @param bool $actual whether or not to perform calculations to not only figure the |
|
968 | - * actual status but also to flip the status if necessary to sold |
|
969 | - * out If false, we just check the existing status of the event |
|
970 | - * @return boolean |
|
971 | - * @throws EE_Error |
|
972 | - */ |
|
973 | - public function is_sold_out($actual = false) |
|
974 | - { |
|
975 | - if (! $actual) { |
|
976 | - return $this->status() === EEM_Event::sold_out; |
|
977 | - } |
|
978 | - return $this->perform_sold_out_status_check(); |
|
979 | - } |
|
980 | - |
|
981 | - |
|
982 | - /** |
|
983 | - * Checks if the event is marked as postponed |
|
984 | - * |
|
985 | - * @return boolean |
|
986 | - */ |
|
987 | - public function is_postponed() |
|
988 | - { |
|
989 | - return $this->status() === EEM_Event::postponed; |
|
990 | - } |
|
991 | - |
|
992 | - |
|
993 | - /** |
|
994 | - * Checks if the event is marked as cancelled |
|
995 | - * |
|
996 | - * @return boolean |
|
997 | - */ |
|
998 | - public function is_cancelled() |
|
999 | - { |
|
1000 | - return $this->status() === EEM_Event::cancelled; |
|
1001 | - } |
|
1002 | - |
|
1003 | - |
|
1004 | - /** |
|
1005 | - * Get the logical active status in a hierarchical order for all the datetimes. Note |
|
1006 | - * Basically, we order the datetimes by EVT_start_date. Then first test on whether the event is published. If its |
|
1007 | - * NOT published then we test for whether its expired or not. IF it IS published then we test first on whether an |
|
1008 | - * event has any active dates. If no active dates then we check for any upcoming dates. If no upcoming dates then |
|
1009 | - * the event is considered expired. |
|
1010 | - * NOTE: this method does NOT calculate whether the datetimes are sold out when event is published. Sold Out is a |
|
1011 | - * status set on the EVENT when it is not published and thus is done |
|
1012 | - * |
|
1013 | - * @param bool $reset |
|
1014 | - * @return bool | string - based on EE_Datetime active constants or FALSE if error. |
|
1015 | - * @throws EE_Error |
|
1016 | - */ |
|
1017 | - public function get_active_status($reset = false) |
|
1018 | - { |
|
1019 | - // if the active status has already been set, then just use that value (unless we are resetting it) |
|
1020 | - if (! empty($this->_active_status) && ! $reset) { |
|
1021 | - return $this->_active_status; |
|
1022 | - } |
|
1023 | - // first check if event id is present on this object |
|
1024 | - if (! $this->ID()) { |
|
1025 | - return false; |
|
1026 | - } |
|
1027 | - $where_params_for_event = array(array('EVT_ID' => $this->ID())); |
|
1028 | - // if event is published: |
|
1029 | - if ($this->status() === 'publish') { |
|
1030 | - // active? |
|
1031 | - if (EEM_Datetime::instance()->get_datetime_count_for_status( |
|
1032 | - EE_Datetime::active, |
|
1033 | - $where_params_for_event |
|
1034 | - ) > 0) { |
|
1035 | - $this->_active_status = EE_Datetime::active; |
|
1036 | - } else { |
|
1037 | - // upcoming? |
|
1038 | - if (EEM_Datetime::instance()->get_datetime_count_for_status( |
|
1039 | - EE_Datetime::upcoming, |
|
1040 | - $where_params_for_event |
|
1041 | - ) > 0) { |
|
1042 | - $this->_active_status = EE_Datetime::upcoming; |
|
1043 | - } else { |
|
1044 | - // expired? |
|
1045 | - if (EEM_Datetime::instance()->get_datetime_count_for_status( |
|
1046 | - EE_Datetime::expired, |
|
1047 | - $where_params_for_event |
|
1048 | - ) > 0 |
|
1049 | - ) { |
|
1050 | - $this->_active_status = EE_Datetime::expired; |
|
1051 | - } else { |
|
1052 | - // it would be odd if things make it this far because it basically means there are no datetime's |
|
1053 | - // attached to the event. So in this case it will just be considered inactive. |
|
1054 | - $this->_active_status = EE_Datetime::inactive; |
|
1055 | - } |
|
1056 | - } |
|
1057 | - } |
|
1058 | - } else { |
|
1059 | - // the event is not published, so let's just set it's active status according to its' post status |
|
1060 | - switch ($this->status()) { |
|
1061 | - case EEM_Event::sold_out: |
|
1062 | - $this->_active_status = EE_Datetime::sold_out; |
|
1063 | - break; |
|
1064 | - case EEM_Event::cancelled: |
|
1065 | - $this->_active_status = EE_Datetime::cancelled; |
|
1066 | - break; |
|
1067 | - case EEM_Event::postponed: |
|
1068 | - $this->_active_status = EE_Datetime::postponed; |
|
1069 | - break; |
|
1070 | - default: |
|
1071 | - $this->_active_status = EE_Datetime::inactive; |
|
1072 | - } |
|
1073 | - } |
|
1074 | - return $this->_active_status; |
|
1075 | - } |
|
1076 | - |
|
1077 | - |
|
1078 | - /** |
|
1079 | - * pretty_active_status |
|
1080 | - * |
|
1081 | - * @access public |
|
1082 | - * @param boolean $echo whether to return (FALSE), or echo out the result (TRUE) |
|
1083 | - * @return mixed void|string |
|
1084 | - * @throws EE_Error |
|
1085 | - */ |
|
1086 | - public function pretty_active_status($echo = true) |
|
1087 | - { |
|
1088 | - $active_status = $this->get_active_status(); |
|
1089 | - $status = '<span class="ee-status event-active-status-' |
|
1090 | - . $active_status |
|
1091 | - . '">' |
|
1092 | - . EEH_Template::pretty_status($active_status, false, 'sentence') |
|
1093 | - . '</span>'; |
|
1094 | - if ($echo) { |
|
1095 | - echo $status; |
|
1096 | - return ''; |
|
1097 | - } |
|
1098 | - return $status; |
|
1099 | - } |
|
1100 | - |
|
1101 | - |
|
1102 | - /** |
|
1103 | - * @return bool|int |
|
1104 | - * @throws EE_Error |
|
1105 | - */ |
|
1106 | - public function get_number_of_tickets_sold() |
|
1107 | - { |
|
1108 | - $tkt_sold = 0; |
|
1109 | - if (! $this->ID()) { |
|
1110 | - return 0; |
|
1111 | - } |
|
1112 | - $datetimes = $this->datetimes(); |
|
1113 | - foreach ($datetimes as $datetime) { |
|
1114 | - if ($datetime instanceof EE_Datetime) { |
|
1115 | - $tkt_sold += $datetime->sold(); |
|
1116 | - } |
|
1117 | - } |
|
1118 | - return $tkt_sold; |
|
1119 | - } |
|
1120 | - |
|
1121 | - |
|
1122 | - /** |
|
1123 | - * This just returns a count of all the registrations for this event |
|
1124 | - * |
|
1125 | - * @access public |
|
1126 | - * @return int |
|
1127 | - * @throws EE_Error |
|
1128 | - */ |
|
1129 | - public function get_count_of_all_registrations() |
|
1130 | - { |
|
1131 | - return EEM_Event::instance()->count_related($this, 'Registration'); |
|
1132 | - } |
|
1133 | - |
|
1134 | - |
|
1135 | - /** |
|
1136 | - * This returns the ticket with the earliest start time that is |
|
1137 | - * available for this event (across all datetimes attached to the event) |
|
1138 | - * |
|
1139 | - * @return EE_Base_Class|EE_Ticket|null |
|
1140 | - * @throws EE_Error |
|
1141 | - */ |
|
1142 | - public function get_ticket_with_earliest_start_time() |
|
1143 | - { |
|
1144 | - $where['Datetime.EVT_ID'] = $this->ID(); |
|
1145 | - $query_params = array($where, 'order_by' => array('TKT_start_date' => 'ASC')); |
|
1146 | - return EE_Registry::instance()->load_model('Ticket')->get_one($query_params); |
|
1147 | - } |
|
1148 | - |
|
1149 | - |
|
1150 | - /** |
|
1151 | - * This returns the ticket with the latest end time that is available |
|
1152 | - * for this event (across all datetimes attached to the event) |
|
1153 | - * |
|
1154 | - * @return EE_Base_Class|EE_Ticket|null |
|
1155 | - * @throws EE_Error |
|
1156 | - */ |
|
1157 | - public function get_ticket_with_latest_end_time() |
|
1158 | - { |
|
1159 | - $where['Datetime.EVT_ID'] = $this->ID(); |
|
1160 | - $query_params = array($where, 'order_by' => array('TKT_end_date' => 'DESC')); |
|
1161 | - return EE_Registry::instance()->load_model('Ticket')->get_one($query_params); |
|
1162 | - } |
|
1163 | - |
|
1164 | - |
|
1165 | - /** |
|
1166 | - * This returns the number of different ticket types currently on sale for this event. |
|
1167 | - * |
|
1168 | - * @return int |
|
1169 | - * @throws EE_Error |
|
1170 | - */ |
|
1171 | - public function countTicketsOnSale() |
|
1172 | - { |
|
1173 | - $where = array( |
|
1174 | - 'Datetime.EVT_ID' => $this->ID(), |
|
1175 | - 'TKT_start_date' => array('<', time()), |
|
1176 | - 'TKT_end_date' => array('>', time()), |
|
1177 | - ); |
|
1178 | - return EEM_Ticket::instance()->count(array($where)); |
|
1179 | - } |
|
1180 | - |
|
1181 | - |
|
1182 | - /** |
|
1183 | - * This returns whether there are any tickets on sale for this event. |
|
1184 | - * |
|
1185 | - * @return bool true = YES tickets on sale. |
|
1186 | - * @throws EE_Error |
|
1187 | - */ |
|
1188 | - public function tickets_on_sale() |
|
1189 | - { |
|
1190 | - return $this->countTicketsOnSale() > 0; |
|
1191 | - } |
|
1192 | - |
|
1193 | - |
|
1194 | - /** |
|
1195 | - * Gets the URL for viewing this event on the front-end. Overrides parent |
|
1196 | - * to check for an external URL first |
|
1197 | - * |
|
1198 | - * @return string |
|
1199 | - * @throws EE_Error |
|
1200 | - */ |
|
1201 | - public function get_permalink() |
|
1202 | - { |
|
1203 | - if ($this->external_url()) { |
|
1204 | - return $this->external_url(); |
|
1205 | - } |
|
1206 | - return parent::get_permalink(); |
|
1207 | - } |
|
1208 | - |
|
1209 | - |
|
1210 | - /** |
|
1211 | - * Gets the first term for 'espresso_event_categories' we can find |
|
1212 | - * |
|
1213 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1214 | - * @return EE_Base_Class|EE_Term|null |
|
1215 | - * @throws EE_Error |
|
1216 | - */ |
|
1217 | - public function first_event_category($query_params = array()) |
|
1218 | - { |
|
1219 | - $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories'; |
|
1220 | - $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID(); |
|
1221 | - return EEM_Term::instance()->get_one($query_params); |
|
1222 | - } |
|
1223 | - |
|
1224 | - |
|
1225 | - /** |
|
1226 | - * Gets all terms for 'espresso_event_categories' we can find |
|
1227 | - * |
|
1228 | - * @param array $query_params |
|
1229 | - * @return EE_Base_Class[]|EE_Term[] |
|
1230 | - * @throws EE_Error |
|
1231 | - */ |
|
1232 | - public function get_all_event_categories($query_params = array()) |
|
1233 | - { |
|
1234 | - $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories'; |
|
1235 | - $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID(); |
|
1236 | - return EEM_Term::instance()->get_all($query_params); |
|
1237 | - } |
|
1238 | - |
|
1239 | - |
|
1240 | - /** |
|
1241 | - * Adds a question group to this event |
|
1242 | - * |
|
1243 | - * @param EE_Question_Group|int $question_group_id_or_obj |
|
1244 | - * @param bool $for_primary if true, the question group will be added for the primary |
|
1245 | - * registrant, if false will be added for others. default: false |
|
1246 | - * @return EE_Base_Class|EE_Question_Group |
|
1247 | - * @throws EE_Error |
|
1248 | - * @throws InvalidArgumentException |
|
1249 | - * @throws InvalidDataTypeException |
|
1250 | - * @throws InvalidInterfaceException |
|
1251 | - * @throws ReflectionException |
|
1252 | - */ |
|
1253 | - public function add_question_group($question_group_id_or_obj, $for_primary = false) |
|
1254 | - { |
|
1255 | - // If the row already exists, it will be updated. If it doesn't, it will be inserted. |
|
1256 | - // That's in EE_HABTM_Relation::add_relation_to(). |
|
1257 | - return $this->_add_relation_to( |
|
1258 | - $question_group_id_or_obj, |
|
1259 | - 'Question_Group', |
|
1260 | - [ |
|
1261 | - EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary) => true |
|
1262 | - ] |
|
1263 | - ); |
|
1264 | - } |
|
1265 | - |
|
1266 | - |
|
1267 | - /** |
|
1268 | - * Removes a question group from the event |
|
1269 | - * |
|
1270 | - * @param EE_Question_Group|int $question_group_id_or_obj |
|
1271 | - * @param bool $for_primary if true, the question group will be removed from the primary |
|
1272 | - * registrant, if false will be removed from others. default: false |
|
1273 | - * @return EE_Base_Class|EE_Question_Group |
|
1274 | - * @throws EE_Error |
|
1275 | - * @throws InvalidArgumentException |
|
1276 | - * @throws ReflectionException |
|
1277 | - * @throws InvalidDataTypeException |
|
1278 | - * @throws InvalidInterfaceException |
|
1279 | - */ |
|
1280 | - public function remove_question_group($question_group_id_or_obj, $for_primary = false) |
|
1281 | - { |
|
1282 | - // If the question group is used for the other type (primary or additional) |
|
1283 | - // then just update it. If not, delete it outright. |
|
1284 | - $existing_relation = $this->get_first_related( |
|
1285 | - 'Event_Question_Group', |
|
1286 | - [ |
|
1287 | - [ |
|
1288 | - 'QSG_ID' => EEM_Question_Group::instance()->ensure_is_ID($question_group_id_or_obj) |
|
1289 | - ] |
|
1290 | - ] |
|
1291 | - ); |
|
1292 | - $field_to_update = EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary); |
|
1293 | - $other_field = EEM_Event_Question_Group::instance()->fieldNameForContext(! $for_primary); |
|
1294 | - if ($existing_relation->get($other_field) === false) { |
|
1295 | - // Delete it. It's now no longer for primary or additional question groups. |
|
1296 | - return $this->_remove_relation_to($question_group_id_or_obj, 'Question_Group'); |
|
1297 | - } |
|
1298 | - // Just update it. They'll still use this question group for the other category |
|
1299 | - $existing_relation->save( |
|
1300 | - [ |
|
1301 | - $field_to_update => false |
|
1302 | - ] |
|
1303 | - ); |
|
1304 | - } |
|
1305 | - |
|
1306 | - |
|
1307 | - /** |
|
1308 | - * Gets all the question groups, ordering them by QSG_order ascending |
|
1309 | - * |
|
1310 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1311 | - * @return EE_Base_Class[]|EE_Question_Group[] |
|
1312 | - * @throws EE_Error |
|
1313 | - */ |
|
1314 | - public function question_groups($query_params = array()) |
|
1315 | - { |
|
1316 | - $query_params = ! empty($query_params) ? $query_params : array('order_by' => array('QSG_order' => 'ASC')); |
|
1317 | - return $this->get_many_related('Question_Group', $query_params); |
|
1318 | - } |
|
1319 | - |
|
1320 | - |
|
1321 | - /** |
|
1322 | - * Implementation for EEI_Has_Icon interface method. |
|
1323 | - * |
|
1324 | - * @see EEI_Visual_Representation for comments |
|
1325 | - * @return string |
|
1326 | - */ |
|
1327 | - public function get_icon() |
|
1328 | - { |
|
1329 | - return '<span class="dashicons dashicons-flag"></span>'; |
|
1330 | - } |
|
1331 | - |
|
1332 | - |
|
1333 | - /** |
|
1334 | - * Implementation for EEI_Admin_Links interface method. |
|
1335 | - * |
|
1336 | - * @see EEI_Admin_Links for comments |
|
1337 | - * @return string |
|
1338 | - * @throws EE_Error |
|
1339 | - */ |
|
1340 | - public function get_admin_details_link() |
|
1341 | - { |
|
1342 | - return $this->get_admin_edit_link(); |
|
1343 | - } |
|
1344 | - |
|
1345 | - |
|
1346 | - /** |
|
1347 | - * Implementation for EEI_Admin_Links interface method. |
|
1348 | - * |
|
1349 | - * @see EEI_Admin_Links for comments |
|
1350 | - * @return string |
|
1351 | - * @throws EE_Error |
|
1352 | - */ |
|
1353 | - public function get_admin_edit_link() |
|
1354 | - { |
|
1355 | - return EEH_URL::add_query_args_and_nonce( |
|
1356 | - array( |
|
1357 | - 'page' => 'espresso_events', |
|
1358 | - 'action' => 'edit', |
|
1359 | - 'post' => $this->ID(), |
|
1360 | - ), |
|
1361 | - admin_url('admin.php') |
|
1362 | - ); |
|
1363 | - } |
|
1364 | - |
|
1365 | - |
|
1366 | - /** |
|
1367 | - * Implementation for EEI_Admin_Links interface method. |
|
1368 | - * |
|
1369 | - * @see EEI_Admin_Links for comments |
|
1370 | - * @return string |
|
1371 | - */ |
|
1372 | - public function get_admin_settings_link() |
|
1373 | - { |
|
1374 | - return EEH_URL::add_query_args_and_nonce( |
|
1375 | - array( |
|
1376 | - 'page' => 'espresso_events', |
|
1377 | - 'action' => 'default_event_settings', |
|
1378 | - ), |
|
1379 | - admin_url('admin.php') |
|
1380 | - ); |
|
1381 | - } |
|
1382 | - |
|
1383 | - |
|
1384 | - /** |
|
1385 | - * Implementation for EEI_Admin_Links interface method. |
|
1386 | - * |
|
1387 | - * @see EEI_Admin_Links for comments |
|
1388 | - * @return string |
|
1389 | - */ |
|
1390 | - public function get_admin_overview_link() |
|
1391 | - { |
|
1392 | - return EEH_URL::add_query_args_and_nonce( |
|
1393 | - array( |
|
1394 | - 'page' => 'espresso_events', |
|
1395 | - 'action' => 'default', |
|
1396 | - ), |
|
1397 | - admin_url('admin.php') |
|
1398 | - ); |
|
1399 | - } |
|
18 | + /** |
|
19 | + * cached value for the the logical active status for the event |
|
20 | + * |
|
21 | + * @see get_active_status() |
|
22 | + * @var string |
|
23 | + */ |
|
24 | + protected $_active_status = ''; |
|
25 | + |
|
26 | + /** |
|
27 | + * This is just used for caching the Primary Datetime for the Event on initial retrieval |
|
28 | + * |
|
29 | + * @var EE_Datetime |
|
30 | + */ |
|
31 | + protected $_Primary_Datetime; |
|
32 | + |
|
33 | + /** |
|
34 | + * @var EventSpacesCalculator $available_spaces_calculator |
|
35 | + */ |
|
36 | + protected $available_spaces_calculator; |
|
37 | + |
|
38 | + |
|
39 | + /** |
|
40 | + * @param array $props_n_values incoming values |
|
41 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be |
|
42 | + * used.) |
|
43 | + * @param array $date_formats incoming date_formats in an array where the first value is the |
|
44 | + * date_format and the second value is the time format |
|
45 | + * @return EE_Event |
|
46 | + * @throws EE_Error |
|
47 | + */ |
|
48 | + public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
49 | + { |
|
50 | + $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats); |
|
51 | + return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats); |
|
52 | + } |
|
53 | + |
|
54 | + |
|
55 | + /** |
|
56 | + * @param array $props_n_values incoming values from the database |
|
57 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
58 | + * the website will be used. |
|
59 | + * @return EE_Event |
|
60 | + * @throws EE_Error |
|
61 | + */ |
|
62 | + public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
63 | + { |
|
64 | + return new self($props_n_values, true, $timezone); |
|
65 | + } |
|
66 | + |
|
67 | + |
|
68 | + /** |
|
69 | + * @return EventSpacesCalculator |
|
70 | + * @throws \EE_Error |
|
71 | + */ |
|
72 | + public function getAvailableSpacesCalculator() |
|
73 | + { |
|
74 | + if (! $this->available_spaces_calculator instanceof EventSpacesCalculator) { |
|
75 | + $this->available_spaces_calculator = new EventSpacesCalculator($this); |
|
76 | + } |
|
77 | + return $this->available_spaces_calculator; |
|
78 | + } |
|
79 | + |
|
80 | + |
|
81 | + /** |
|
82 | + * Overrides parent set() method so that all calls to set( 'status', $status ) can be routed to internal methods |
|
83 | + * |
|
84 | + * @param string $field_name |
|
85 | + * @param mixed $field_value |
|
86 | + * @param bool $use_default |
|
87 | + * @throws EE_Error |
|
88 | + */ |
|
89 | + public function set($field_name, $field_value, $use_default = false) |
|
90 | + { |
|
91 | + switch ($field_name) { |
|
92 | + case 'status': |
|
93 | + $this->set_status($field_value, $use_default); |
|
94 | + break; |
|
95 | + default: |
|
96 | + parent::set($field_name, $field_value, $use_default); |
|
97 | + } |
|
98 | + } |
|
99 | + |
|
100 | + |
|
101 | + /** |
|
102 | + * set_status |
|
103 | + * Checks if event status is being changed to SOLD OUT |
|
104 | + * and updates event meta data with previous event status |
|
105 | + * so that we can revert things if/when the event is no longer sold out |
|
106 | + * |
|
107 | + * @access public |
|
108 | + * @param string $new_status |
|
109 | + * @param bool $use_default |
|
110 | + * @return void |
|
111 | + * @throws EE_Error |
|
112 | + */ |
|
113 | + public function set_status($new_status = null, $use_default = false) |
|
114 | + { |
|
115 | + // if nothing is set, and we aren't explicitly wanting to reset the status, then just leave |
|
116 | + if (empty($new_status) && ! $use_default) { |
|
117 | + return; |
|
118 | + } |
|
119 | + // get current Event status |
|
120 | + $old_status = $this->status(); |
|
121 | + // if status has changed |
|
122 | + if ($old_status !== $new_status) { |
|
123 | + // TO sold_out |
|
124 | + if ($new_status === EEM_Event::sold_out) { |
|
125 | + // save the previous event status so that we can revert if the event is no longer sold out |
|
126 | + $this->add_post_meta('_previous_event_status', $old_status); |
|
127 | + do_action('AHEE__EE_Event__set_status__to_sold_out', $this, $old_status, $new_status); |
|
128 | + // OR FROM sold_out |
|
129 | + } elseif ($old_status === EEM_Event::sold_out) { |
|
130 | + $this->delete_post_meta('_previous_event_status'); |
|
131 | + do_action('AHEE__EE_Event__set_status__from_sold_out', $this, $old_status, $new_status); |
|
132 | + } |
|
133 | + // clear out the active status so that it gets reset the next time it is requested |
|
134 | + $this->_active_status = null; |
|
135 | + // update status |
|
136 | + parent::set('status', $new_status, $use_default); |
|
137 | + do_action('AHEE__EE_Event__set_status__after_update', $this); |
|
138 | + return; |
|
139 | + } |
|
140 | + // even though the old value matches the new value, it's still good to |
|
141 | + // allow the parent set method to have a say |
|
142 | + parent::set('status', $new_status, $use_default); |
|
143 | + } |
|
144 | + |
|
145 | + |
|
146 | + /** |
|
147 | + * Gets all the datetimes for this event |
|
148 | + * |
|
149 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
150 | + * @return EE_Base_Class[]|EE_Datetime[] |
|
151 | + * @throws EE_Error |
|
152 | + */ |
|
153 | + public function datetimes($query_params = array()) |
|
154 | + { |
|
155 | + return $this->get_many_related('Datetime', $query_params); |
|
156 | + } |
|
157 | + |
|
158 | + |
|
159 | + /** |
|
160 | + * Gets all the datetimes for this event, ordered by DTT_EVT_start in ascending order |
|
161 | + * |
|
162 | + * @return EE_Base_Class[]|EE_Datetime[] |
|
163 | + * @throws EE_Error |
|
164 | + */ |
|
165 | + public function datetimes_in_chronological_order() |
|
166 | + { |
|
167 | + return $this->get_many_related('Datetime', array('order_by' => array('DTT_EVT_start' => 'ASC'))); |
|
168 | + } |
|
169 | + |
|
170 | + |
|
171 | + /** |
|
172 | + * Gets all the datetimes for this event, ordered by the DTT_order on the datetime. |
|
173 | + * @darren, we should probably UNSET timezone on the EEM_Datetime model |
|
174 | + * after running our query, so that this timezone isn't set for EVERY query |
|
175 | + * on EEM_Datetime for the rest of the request, no? |
|
176 | + * |
|
177 | + * @param boolean $show_expired whether or not to include expired events |
|
178 | + * @param boolean $show_deleted whether or not to include deleted events |
|
179 | + * @param null $limit |
|
180 | + * @return EE_Datetime[] |
|
181 | + * @throws EE_Error |
|
182 | + */ |
|
183 | + public function datetimes_ordered($show_expired = true, $show_deleted = false, $limit = null) |
|
184 | + { |
|
185 | + return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_event_ordered_by_DTT_order( |
|
186 | + $this->ID(), |
|
187 | + $show_expired, |
|
188 | + $show_deleted, |
|
189 | + $limit |
|
190 | + ); |
|
191 | + } |
|
192 | + |
|
193 | + |
|
194 | + /** |
|
195 | + * Returns one related datetime. Mostly only used by some legacy code. |
|
196 | + * |
|
197 | + * @return EE_Base_Class|EE_Datetime |
|
198 | + * @throws EE_Error |
|
199 | + */ |
|
200 | + public function first_datetime() |
|
201 | + { |
|
202 | + return $this->get_first_related('Datetime'); |
|
203 | + } |
|
204 | + |
|
205 | + |
|
206 | + /** |
|
207 | + * Returns the 'primary' datetime for the event |
|
208 | + * |
|
209 | + * @param bool $try_to_exclude_expired |
|
210 | + * @param bool $try_to_exclude_deleted |
|
211 | + * @return EE_Datetime |
|
212 | + * @throws EE_Error |
|
213 | + */ |
|
214 | + public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true) |
|
215 | + { |
|
216 | + if (! empty($this->_Primary_Datetime)) { |
|
217 | + return $this->_Primary_Datetime; |
|
218 | + } |
|
219 | + $this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)->get_primary_datetime_for_event( |
|
220 | + $this->ID(), |
|
221 | + $try_to_exclude_expired, |
|
222 | + $try_to_exclude_deleted |
|
223 | + ); |
|
224 | + return $this->_Primary_Datetime; |
|
225 | + } |
|
226 | + |
|
227 | + |
|
228 | + /** |
|
229 | + * Gets all the tickets available for purchase of this event |
|
230 | + * |
|
231 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
232 | + * @return EE_Base_Class[]|EE_Ticket[] |
|
233 | + * @throws EE_Error |
|
234 | + */ |
|
235 | + public function tickets($query_params = array()) |
|
236 | + { |
|
237 | + // first get all datetimes |
|
238 | + $datetimes = $this->datetimes_ordered(); |
|
239 | + if (! $datetimes) { |
|
240 | + return array(); |
|
241 | + } |
|
242 | + $datetime_ids = array(); |
|
243 | + foreach ($datetimes as $datetime) { |
|
244 | + $datetime_ids[] = $datetime->ID(); |
|
245 | + } |
|
246 | + $where_params = array('Datetime.DTT_ID' => array('IN', $datetime_ids)); |
|
247 | + // if incoming $query_params has where conditions let's merge but not override existing. |
|
248 | + if (is_array($query_params) && isset($query_params[0])) { |
|
249 | + $where_params = array_merge($query_params[0], $where_params); |
|
250 | + unset($query_params[0]); |
|
251 | + } |
|
252 | + // now add $where_params to $query_params |
|
253 | + $query_params[0] = $where_params; |
|
254 | + return EEM_Ticket::instance()->get_all($query_params); |
|
255 | + } |
|
256 | + |
|
257 | + |
|
258 | + /** |
|
259 | + * get all unexpired untrashed tickets |
|
260 | + * |
|
261 | + * @return EE_Ticket[] |
|
262 | + * @throws EE_Error |
|
263 | + */ |
|
264 | + public function active_tickets() |
|
265 | + { |
|
266 | + return $this->tickets( |
|
267 | + array( |
|
268 | + array( |
|
269 | + 'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')), |
|
270 | + 'TKT_deleted' => false, |
|
271 | + ), |
|
272 | + ) |
|
273 | + ); |
|
274 | + } |
|
275 | + |
|
276 | + |
|
277 | + /** |
|
278 | + * @return bool |
|
279 | + * @throws EE_Error |
|
280 | + */ |
|
281 | + public function additional_limit() |
|
282 | + { |
|
283 | + return $this->get('EVT_additional_limit'); |
|
284 | + } |
|
285 | + |
|
286 | + |
|
287 | + /** |
|
288 | + * @return bool |
|
289 | + * @throws EE_Error |
|
290 | + */ |
|
291 | + public function allow_overflow() |
|
292 | + { |
|
293 | + return $this->get('EVT_allow_overflow'); |
|
294 | + } |
|
295 | + |
|
296 | + |
|
297 | + /** |
|
298 | + * @return bool |
|
299 | + * @throws EE_Error |
|
300 | + */ |
|
301 | + public function created() |
|
302 | + { |
|
303 | + return $this->get('EVT_created'); |
|
304 | + } |
|
305 | + |
|
306 | + |
|
307 | + /** |
|
308 | + * @return bool |
|
309 | + * @throws EE_Error |
|
310 | + */ |
|
311 | + public function description() |
|
312 | + { |
|
313 | + return $this->get('EVT_desc'); |
|
314 | + } |
|
315 | + |
|
316 | + |
|
317 | + /** |
|
318 | + * Runs do_shortcode and wpautop on the description |
|
319 | + * |
|
320 | + * @return string of html |
|
321 | + * @throws EE_Error |
|
322 | + */ |
|
323 | + public function description_filtered() |
|
324 | + { |
|
325 | + return $this->get_pretty('EVT_desc'); |
|
326 | + } |
|
327 | + |
|
328 | + |
|
329 | + /** |
|
330 | + * @return bool |
|
331 | + * @throws EE_Error |
|
332 | + */ |
|
333 | + public function display_description() |
|
334 | + { |
|
335 | + return $this->get('EVT_display_desc'); |
|
336 | + } |
|
337 | + |
|
338 | + |
|
339 | + /** |
|
340 | + * @return bool |
|
341 | + * @throws EE_Error |
|
342 | + */ |
|
343 | + public function display_ticket_selector() |
|
344 | + { |
|
345 | + return (bool) $this->get('EVT_display_ticket_selector'); |
|
346 | + } |
|
347 | + |
|
348 | + |
|
349 | + /** |
|
350 | + * @return bool |
|
351 | + * @throws EE_Error |
|
352 | + */ |
|
353 | + public function external_url() |
|
354 | + { |
|
355 | + return $this->get('EVT_external_URL'); |
|
356 | + } |
|
357 | + |
|
358 | + |
|
359 | + /** |
|
360 | + * @return bool |
|
361 | + * @throws EE_Error |
|
362 | + */ |
|
363 | + public function member_only() |
|
364 | + { |
|
365 | + return $this->get('EVT_member_only'); |
|
366 | + } |
|
367 | + |
|
368 | + |
|
369 | + /** |
|
370 | + * @return bool |
|
371 | + * @throws EE_Error |
|
372 | + */ |
|
373 | + public function phone() |
|
374 | + { |
|
375 | + return $this->get('EVT_phone'); |
|
376 | + } |
|
377 | + |
|
378 | + |
|
379 | + /** |
|
380 | + * @return bool |
|
381 | + * @throws EE_Error |
|
382 | + */ |
|
383 | + public function modified() |
|
384 | + { |
|
385 | + return $this->get('EVT_modified'); |
|
386 | + } |
|
387 | + |
|
388 | + |
|
389 | + /** |
|
390 | + * @return bool |
|
391 | + * @throws EE_Error |
|
392 | + */ |
|
393 | + public function name() |
|
394 | + { |
|
395 | + return $this->get('EVT_name'); |
|
396 | + } |
|
397 | + |
|
398 | + |
|
399 | + /** |
|
400 | + * @return bool |
|
401 | + * @throws EE_Error |
|
402 | + */ |
|
403 | + public function order() |
|
404 | + { |
|
405 | + return $this->get('EVT_order'); |
|
406 | + } |
|
407 | + |
|
408 | + |
|
409 | + /** |
|
410 | + * @return bool|string |
|
411 | + * @throws EE_Error |
|
412 | + */ |
|
413 | + public function default_registration_status() |
|
414 | + { |
|
415 | + $event_default_registration_status = $this->get('EVT_default_registration_status'); |
|
416 | + return ! empty($event_default_registration_status) |
|
417 | + ? $event_default_registration_status |
|
418 | + : EE_Registry::instance()->CFG->registration->default_STS_ID; |
|
419 | + } |
|
420 | + |
|
421 | + |
|
422 | + /** |
|
423 | + * @param int $num_words |
|
424 | + * @param null $more |
|
425 | + * @param bool $not_full_desc |
|
426 | + * @return bool|string |
|
427 | + * @throws EE_Error |
|
428 | + */ |
|
429 | + public function short_description($num_words = 55, $more = null, $not_full_desc = false) |
|
430 | + { |
|
431 | + $short_desc = $this->get('EVT_short_desc'); |
|
432 | + if (! empty($short_desc) || $not_full_desc) { |
|
433 | + return $short_desc; |
|
434 | + } |
|
435 | + $full_desc = $this->get('EVT_desc'); |
|
436 | + return wp_trim_words($full_desc, $num_words, $more); |
|
437 | + } |
|
438 | + |
|
439 | + |
|
440 | + /** |
|
441 | + * @return bool |
|
442 | + * @throws EE_Error |
|
443 | + */ |
|
444 | + public function slug() |
|
445 | + { |
|
446 | + return $this->get('EVT_slug'); |
|
447 | + } |
|
448 | + |
|
449 | + |
|
450 | + /** |
|
451 | + * @return bool |
|
452 | + * @throws EE_Error |
|
453 | + */ |
|
454 | + public function timezone_string() |
|
455 | + { |
|
456 | + return $this->get('EVT_timezone_string'); |
|
457 | + } |
|
458 | + |
|
459 | + |
|
460 | + /** |
|
461 | + * @return bool |
|
462 | + * @throws EE_Error |
|
463 | + */ |
|
464 | + public function visible_on() |
|
465 | + { |
|
466 | + return $this->get('EVT_visible_on'); |
|
467 | + } |
|
468 | + |
|
469 | + |
|
470 | + /** |
|
471 | + * @return int |
|
472 | + * @throws EE_Error |
|
473 | + */ |
|
474 | + public function wp_user() |
|
475 | + { |
|
476 | + return $this->get('EVT_wp_user'); |
|
477 | + } |
|
478 | + |
|
479 | + |
|
480 | + /** |
|
481 | + * @return bool |
|
482 | + * @throws EE_Error |
|
483 | + */ |
|
484 | + public function donations() |
|
485 | + { |
|
486 | + return $this->get('EVT_donations'); |
|
487 | + } |
|
488 | + |
|
489 | + |
|
490 | + /** |
|
491 | + * @param $limit |
|
492 | + * @throws EE_Error |
|
493 | + */ |
|
494 | + public function set_additional_limit($limit) |
|
495 | + { |
|
496 | + $this->set('EVT_additional_limit', $limit); |
|
497 | + } |
|
498 | + |
|
499 | + |
|
500 | + /** |
|
501 | + * @param $created |
|
502 | + * @throws EE_Error |
|
503 | + */ |
|
504 | + public function set_created($created) |
|
505 | + { |
|
506 | + $this->set('EVT_created', $created); |
|
507 | + } |
|
508 | + |
|
509 | + |
|
510 | + /** |
|
511 | + * @param $desc |
|
512 | + * @throws EE_Error |
|
513 | + */ |
|
514 | + public function set_description($desc) |
|
515 | + { |
|
516 | + $this->set('EVT_desc', $desc); |
|
517 | + } |
|
518 | + |
|
519 | + |
|
520 | + /** |
|
521 | + * @param $display_desc |
|
522 | + * @throws EE_Error |
|
523 | + */ |
|
524 | + public function set_display_description($display_desc) |
|
525 | + { |
|
526 | + $this->set('EVT_display_desc', $display_desc); |
|
527 | + } |
|
528 | + |
|
529 | + |
|
530 | + /** |
|
531 | + * @param $display_ticket_selector |
|
532 | + * @throws EE_Error |
|
533 | + */ |
|
534 | + public function set_display_ticket_selector($display_ticket_selector) |
|
535 | + { |
|
536 | + $this->set('EVT_display_ticket_selector', $display_ticket_selector); |
|
537 | + } |
|
538 | + |
|
539 | + |
|
540 | + /** |
|
541 | + * @param $external_url |
|
542 | + * @throws EE_Error |
|
543 | + */ |
|
544 | + public function set_external_url($external_url) |
|
545 | + { |
|
546 | + $this->set('EVT_external_URL', $external_url); |
|
547 | + } |
|
548 | + |
|
549 | + |
|
550 | + /** |
|
551 | + * @param $member_only |
|
552 | + * @throws EE_Error |
|
553 | + */ |
|
554 | + public function set_member_only($member_only) |
|
555 | + { |
|
556 | + $this->set('EVT_member_only', $member_only); |
|
557 | + } |
|
558 | + |
|
559 | + |
|
560 | + /** |
|
561 | + * @param $event_phone |
|
562 | + * @throws EE_Error |
|
563 | + */ |
|
564 | + public function set_event_phone($event_phone) |
|
565 | + { |
|
566 | + $this->set('EVT_phone', $event_phone); |
|
567 | + } |
|
568 | + |
|
569 | + |
|
570 | + /** |
|
571 | + * @param $modified |
|
572 | + * @throws EE_Error |
|
573 | + */ |
|
574 | + public function set_modified($modified) |
|
575 | + { |
|
576 | + $this->set('EVT_modified', $modified); |
|
577 | + } |
|
578 | + |
|
579 | + |
|
580 | + /** |
|
581 | + * @param $name |
|
582 | + * @throws EE_Error |
|
583 | + */ |
|
584 | + public function set_name($name) |
|
585 | + { |
|
586 | + $this->set('EVT_name', $name); |
|
587 | + } |
|
588 | + |
|
589 | + |
|
590 | + /** |
|
591 | + * @param $order |
|
592 | + * @throws EE_Error |
|
593 | + */ |
|
594 | + public function set_order($order) |
|
595 | + { |
|
596 | + $this->set('EVT_order', $order); |
|
597 | + } |
|
598 | + |
|
599 | + |
|
600 | + /** |
|
601 | + * @param $short_desc |
|
602 | + * @throws EE_Error |
|
603 | + */ |
|
604 | + public function set_short_description($short_desc) |
|
605 | + { |
|
606 | + $this->set('EVT_short_desc', $short_desc); |
|
607 | + } |
|
608 | + |
|
609 | + |
|
610 | + /** |
|
611 | + * @param $slug |
|
612 | + * @throws EE_Error |
|
613 | + */ |
|
614 | + public function set_slug($slug) |
|
615 | + { |
|
616 | + $this->set('EVT_slug', $slug); |
|
617 | + } |
|
618 | + |
|
619 | + |
|
620 | + /** |
|
621 | + * @param $timezone_string |
|
622 | + * @throws EE_Error |
|
623 | + */ |
|
624 | + public function set_timezone_string($timezone_string) |
|
625 | + { |
|
626 | + $this->set('EVT_timezone_string', $timezone_string); |
|
627 | + } |
|
628 | + |
|
629 | + |
|
630 | + /** |
|
631 | + * @param $visible_on |
|
632 | + * @throws EE_Error |
|
633 | + */ |
|
634 | + public function set_visible_on($visible_on) |
|
635 | + { |
|
636 | + $this->set('EVT_visible_on', $visible_on); |
|
637 | + } |
|
638 | + |
|
639 | + |
|
640 | + /** |
|
641 | + * @param $wp_user |
|
642 | + * @throws EE_Error |
|
643 | + */ |
|
644 | + public function set_wp_user($wp_user) |
|
645 | + { |
|
646 | + $this->set('EVT_wp_user', $wp_user); |
|
647 | + } |
|
648 | + |
|
649 | + |
|
650 | + /** |
|
651 | + * @param $default_registration_status |
|
652 | + * @throws EE_Error |
|
653 | + */ |
|
654 | + public function set_default_registration_status($default_registration_status) |
|
655 | + { |
|
656 | + $this->set('EVT_default_registration_status', $default_registration_status); |
|
657 | + } |
|
658 | + |
|
659 | + |
|
660 | + /** |
|
661 | + * @param $donations |
|
662 | + * @throws EE_Error |
|
663 | + */ |
|
664 | + public function set_donations($donations) |
|
665 | + { |
|
666 | + $this->set('EVT_donations', $donations); |
|
667 | + } |
|
668 | + |
|
669 | + |
|
670 | + /** |
|
671 | + * Adds a venue to this event |
|
672 | + * |
|
673 | + * @param EE_Venue /int $venue_id_or_obj |
|
674 | + * @return EE_Base_Class|EE_Venue |
|
675 | + * @throws EE_Error |
|
676 | + */ |
|
677 | + public function add_venue($venue_id_or_obj) |
|
678 | + { |
|
679 | + return $this->_add_relation_to($venue_id_or_obj, 'Venue'); |
|
680 | + } |
|
681 | + |
|
682 | + |
|
683 | + /** |
|
684 | + * Removes a venue from the event |
|
685 | + * |
|
686 | + * @param EE_Venue /int $venue_id_or_obj |
|
687 | + * @return EE_Base_Class|EE_Venue |
|
688 | + * @throws EE_Error |
|
689 | + */ |
|
690 | + public function remove_venue($venue_id_or_obj) |
|
691 | + { |
|
692 | + return $this->_remove_relation_to($venue_id_or_obj, 'Venue'); |
|
693 | + } |
|
694 | + |
|
695 | + |
|
696 | + /** |
|
697 | + * Gets all the venues related ot the event. May provide additional $query_params if desired |
|
698 | + * |
|
699 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
700 | + * @return EE_Base_Class[]|EE_Venue[] |
|
701 | + * @throws EE_Error |
|
702 | + */ |
|
703 | + public function venues($query_params = array()) |
|
704 | + { |
|
705 | + return $this->get_many_related('Venue', $query_params); |
|
706 | + } |
|
707 | + |
|
708 | + |
|
709 | + /** |
|
710 | + * check if event id is present and if event is published |
|
711 | + * |
|
712 | + * @access public |
|
713 | + * @return boolean true yes, false no |
|
714 | + * @throws EE_Error |
|
715 | + */ |
|
716 | + private function _has_ID_and_is_published() |
|
717 | + { |
|
718 | + // first check if event id is present and not NULL, |
|
719 | + // then check if this event is published (or any of the equivalent "published" statuses) |
|
720 | + return |
|
721 | + $this->ID() && $this->ID() !== null |
|
722 | + && ( |
|
723 | + $this->status() === 'publish' |
|
724 | + || $this->status() === EEM_Event::sold_out |
|
725 | + || $this->status() === EEM_Event::postponed |
|
726 | + || $this->status() === EEM_Event::cancelled |
|
727 | + ); |
|
728 | + } |
|
729 | + |
|
730 | + |
|
731 | + /** |
|
732 | + * This simply compares the internal dates with NOW and determines if the event is upcoming or not. |
|
733 | + * |
|
734 | + * @access public |
|
735 | + * @return boolean true yes, false no |
|
736 | + * @throws EE_Error |
|
737 | + */ |
|
738 | + public function is_upcoming() |
|
739 | + { |
|
740 | + // check if event id is present and if this event is published |
|
741 | + if ($this->is_inactive()) { |
|
742 | + return false; |
|
743 | + } |
|
744 | + // set initial value |
|
745 | + $upcoming = false; |
|
746 | + // next let's get all datetimes and loop through them |
|
747 | + $datetimes = $this->datetimes_in_chronological_order(); |
|
748 | + foreach ($datetimes as $datetime) { |
|
749 | + if ($datetime instanceof EE_Datetime) { |
|
750 | + // if this dtt is expired then we continue cause one of the other datetimes might be upcoming. |
|
751 | + if ($datetime->is_expired()) { |
|
752 | + continue; |
|
753 | + } |
|
754 | + // if this dtt is active then we return false. |
|
755 | + if ($datetime->is_active()) { |
|
756 | + return false; |
|
757 | + } |
|
758 | + // otherwise let's check upcoming status |
|
759 | + $upcoming = $datetime->is_upcoming(); |
|
760 | + } |
|
761 | + } |
|
762 | + return $upcoming; |
|
763 | + } |
|
764 | + |
|
765 | + |
|
766 | + /** |
|
767 | + * @return bool |
|
768 | + * @throws EE_Error |
|
769 | + */ |
|
770 | + public function is_active() |
|
771 | + { |
|
772 | + // check if event id is present and if this event is published |
|
773 | + if ($this->is_inactive()) { |
|
774 | + return false; |
|
775 | + } |
|
776 | + // set initial value |
|
777 | + $active = false; |
|
778 | + // next let's get all datetimes and loop through them |
|
779 | + $datetimes = $this->datetimes_in_chronological_order(); |
|
780 | + foreach ($datetimes as $datetime) { |
|
781 | + if ($datetime instanceof EE_Datetime) { |
|
782 | + // if this dtt is expired then we continue cause one of the other datetimes might be active. |
|
783 | + if ($datetime->is_expired()) { |
|
784 | + continue; |
|
785 | + } |
|
786 | + // if this dtt is upcoming then we return false. |
|
787 | + if ($datetime->is_upcoming()) { |
|
788 | + return false; |
|
789 | + } |
|
790 | + // otherwise let's check active status |
|
791 | + $active = $datetime->is_active(); |
|
792 | + } |
|
793 | + } |
|
794 | + return $active; |
|
795 | + } |
|
796 | + |
|
797 | + |
|
798 | + /** |
|
799 | + * @return bool |
|
800 | + * @throws EE_Error |
|
801 | + */ |
|
802 | + public function is_expired() |
|
803 | + { |
|
804 | + // check if event id is present and if this event is published |
|
805 | + if ($this->is_inactive()) { |
|
806 | + return false; |
|
807 | + } |
|
808 | + // set initial value |
|
809 | + $expired = false; |
|
810 | + // first let's get all datetimes and loop through them |
|
811 | + $datetimes = $this->datetimes_in_chronological_order(); |
|
812 | + foreach ($datetimes as $datetime) { |
|
813 | + if ($datetime instanceof EE_Datetime) { |
|
814 | + // if this dtt is upcoming or active then we return false. |
|
815 | + if ($datetime->is_upcoming() || $datetime->is_active()) { |
|
816 | + return false; |
|
817 | + } |
|
818 | + // otherwise let's check active status |
|
819 | + $expired = $datetime->is_expired(); |
|
820 | + } |
|
821 | + } |
|
822 | + return $expired; |
|
823 | + } |
|
824 | + |
|
825 | + |
|
826 | + /** |
|
827 | + * @return bool |
|
828 | + * @throws EE_Error |
|
829 | + */ |
|
830 | + public function is_inactive() |
|
831 | + { |
|
832 | + // check if event id is present and if this event is published |
|
833 | + if ($this->_has_ID_and_is_published()) { |
|
834 | + return false; |
|
835 | + } |
|
836 | + return true; |
|
837 | + } |
|
838 | + |
|
839 | + |
|
840 | + /** |
|
841 | + * calculate spaces remaining based on "saleable" tickets |
|
842 | + * |
|
843 | + * @param array $tickets |
|
844 | + * @param bool $filtered |
|
845 | + * @return int|float |
|
846 | + * @throws EE_Error |
|
847 | + * @throws DomainException |
|
848 | + * @throws UnexpectedEntityException |
|
849 | + */ |
|
850 | + public function spaces_remaining($tickets = array(), $filtered = true) |
|
851 | + { |
|
852 | + $this->getAvailableSpacesCalculator()->setActiveTickets($tickets); |
|
853 | + $spaces_remaining = $this->getAvailableSpacesCalculator()->spacesRemaining(); |
|
854 | + return $filtered |
|
855 | + ? apply_filters( |
|
856 | + 'FHEE_EE_Event__spaces_remaining', |
|
857 | + $spaces_remaining, |
|
858 | + $this, |
|
859 | + $tickets |
|
860 | + ) |
|
861 | + : $spaces_remaining; |
|
862 | + } |
|
863 | + |
|
864 | + |
|
865 | + /** |
|
866 | + * perform_sold_out_status_check |
|
867 | + * checks all of this events's datetime reg_limit - sold values to determine if ANY datetimes have spaces |
|
868 | + * available... if NOT, then the event status will get toggled to 'sold_out' |
|
869 | + * |
|
870 | + * @return bool return the ACTUAL sold out state. |
|
871 | + * @throws EE_Error |
|
872 | + * @throws DomainException |
|
873 | + * @throws UnexpectedEntityException |
|
874 | + */ |
|
875 | + public function perform_sold_out_status_check() |
|
876 | + { |
|
877 | + // get all unexpired untrashed tickets |
|
878 | + $tickets = $this->tickets( |
|
879 | + array( |
|
880 | + array('TKT_deleted' => false), |
|
881 | + 'order_by' => array('TKT_qty' => 'ASC'), |
|
882 | + ) |
|
883 | + ); |
|
884 | + $all_expired = true; |
|
885 | + foreach ($tickets as $ticket) { |
|
886 | + if (! $ticket->is_expired()) { |
|
887 | + $all_expired = false; |
|
888 | + break; |
|
889 | + } |
|
890 | + } |
|
891 | + // if all the tickets are just expired, then don't update the event status to sold out |
|
892 | + if ($all_expired) { |
|
893 | + return true; |
|
894 | + } |
|
895 | + $spaces_remaining = $this->spaces_remaining($tickets); |
|
896 | + if ($spaces_remaining < 1) { |
|
897 | + $this->set_status(EEM_Event::sold_out); |
|
898 | + $this->save(); |
|
899 | + $sold_out = true; |
|
900 | + } else { |
|
901 | + $sold_out = false; |
|
902 | + // was event previously marked as sold out ? |
|
903 | + if ($this->status() === EEM_Event::sold_out) { |
|
904 | + // revert status to previous value, if it was set |
|
905 | + $previous_event_status = $this->get_post_meta('_previous_event_status', true); |
|
906 | + if ($previous_event_status) { |
|
907 | + $this->set_status($previous_event_status); |
|
908 | + $this->save(); |
|
909 | + } |
|
910 | + } |
|
911 | + } |
|
912 | + do_action('AHEE__EE_Event__perform_sold_out_status_check__end', $this, $sold_out, $spaces_remaining, $tickets); |
|
913 | + return $sold_out; |
|
914 | + } |
|
915 | + |
|
916 | + |
|
917 | + /** |
|
918 | + * This returns the total remaining spaces for sale on this event. |
|
919 | + * |
|
920 | + * @uses EE_Event::total_available_spaces() |
|
921 | + * @return float|int |
|
922 | + * @throws EE_Error |
|
923 | + * @throws DomainException |
|
924 | + * @throws UnexpectedEntityException |
|
925 | + */ |
|
926 | + public function spaces_remaining_for_sale() |
|
927 | + { |
|
928 | + return $this->total_available_spaces(true); |
|
929 | + } |
|
930 | + |
|
931 | + |
|
932 | + /** |
|
933 | + * This returns the total spaces available for an event |
|
934 | + * while considering all the qtys on the tickets and the reg limits |
|
935 | + * on the datetimes attached to this event. |
|
936 | + * |
|
937 | + * @param bool $consider_sold Whether to consider any tickets that have already sold in our calculation. |
|
938 | + * If this is false, then we return the most tickets that could ever be sold |
|
939 | + * for this event with the datetime and tickets setup on the event under optimal |
|
940 | + * selling conditions. Otherwise we return a live calculation of spaces available |
|
941 | + * based on tickets sold. Depending on setup and stage of sales, this |
|
942 | + * may appear to equal remaining tickets. However, the more tickets are |
|
943 | + * sold out, the more accurate the "live" total is. |
|
944 | + * @return float|int |
|
945 | + * @throws EE_Error |
|
946 | + * @throws DomainException |
|
947 | + * @throws UnexpectedEntityException |
|
948 | + */ |
|
949 | + public function total_available_spaces($consider_sold = false) |
|
950 | + { |
|
951 | + $spaces_available = $consider_sold |
|
952 | + ? $this->getAvailableSpacesCalculator()->spacesRemaining() |
|
953 | + : $this->getAvailableSpacesCalculator()->totalSpacesAvailable(); |
|
954 | + return apply_filters( |
|
955 | + 'FHEE_EE_Event__total_available_spaces__spaces_available', |
|
956 | + $spaces_available, |
|
957 | + $this, |
|
958 | + $this->getAvailableSpacesCalculator()->getDatetimes(), |
|
959 | + $this->getAvailableSpacesCalculator()->getActiveTickets() |
|
960 | + ); |
|
961 | + } |
|
962 | + |
|
963 | + |
|
964 | + /** |
|
965 | + * Checks if the event is set to sold out |
|
966 | + * |
|
967 | + * @param bool $actual whether or not to perform calculations to not only figure the |
|
968 | + * actual status but also to flip the status if necessary to sold |
|
969 | + * out If false, we just check the existing status of the event |
|
970 | + * @return boolean |
|
971 | + * @throws EE_Error |
|
972 | + */ |
|
973 | + public function is_sold_out($actual = false) |
|
974 | + { |
|
975 | + if (! $actual) { |
|
976 | + return $this->status() === EEM_Event::sold_out; |
|
977 | + } |
|
978 | + return $this->perform_sold_out_status_check(); |
|
979 | + } |
|
980 | + |
|
981 | + |
|
982 | + /** |
|
983 | + * Checks if the event is marked as postponed |
|
984 | + * |
|
985 | + * @return boolean |
|
986 | + */ |
|
987 | + public function is_postponed() |
|
988 | + { |
|
989 | + return $this->status() === EEM_Event::postponed; |
|
990 | + } |
|
991 | + |
|
992 | + |
|
993 | + /** |
|
994 | + * Checks if the event is marked as cancelled |
|
995 | + * |
|
996 | + * @return boolean |
|
997 | + */ |
|
998 | + public function is_cancelled() |
|
999 | + { |
|
1000 | + return $this->status() === EEM_Event::cancelled; |
|
1001 | + } |
|
1002 | + |
|
1003 | + |
|
1004 | + /** |
|
1005 | + * Get the logical active status in a hierarchical order for all the datetimes. Note |
|
1006 | + * Basically, we order the datetimes by EVT_start_date. Then first test on whether the event is published. If its |
|
1007 | + * NOT published then we test for whether its expired or not. IF it IS published then we test first on whether an |
|
1008 | + * event has any active dates. If no active dates then we check for any upcoming dates. If no upcoming dates then |
|
1009 | + * the event is considered expired. |
|
1010 | + * NOTE: this method does NOT calculate whether the datetimes are sold out when event is published. Sold Out is a |
|
1011 | + * status set on the EVENT when it is not published and thus is done |
|
1012 | + * |
|
1013 | + * @param bool $reset |
|
1014 | + * @return bool | string - based on EE_Datetime active constants or FALSE if error. |
|
1015 | + * @throws EE_Error |
|
1016 | + */ |
|
1017 | + public function get_active_status($reset = false) |
|
1018 | + { |
|
1019 | + // if the active status has already been set, then just use that value (unless we are resetting it) |
|
1020 | + if (! empty($this->_active_status) && ! $reset) { |
|
1021 | + return $this->_active_status; |
|
1022 | + } |
|
1023 | + // first check if event id is present on this object |
|
1024 | + if (! $this->ID()) { |
|
1025 | + return false; |
|
1026 | + } |
|
1027 | + $where_params_for_event = array(array('EVT_ID' => $this->ID())); |
|
1028 | + // if event is published: |
|
1029 | + if ($this->status() === 'publish') { |
|
1030 | + // active? |
|
1031 | + if (EEM_Datetime::instance()->get_datetime_count_for_status( |
|
1032 | + EE_Datetime::active, |
|
1033 | + $where_params_for_event |
|
1034 | + ) > 0) { |
|
1035 | + $this->_active_status = EE_Datetime::active; |
|
1036 | + } else { |
|
1037 | + // upcoming? |
|
1038 | + if (EEM_Datetime::instance()->get_datetime_count_for_status( |
|
1039 | + EE_Datetime::upcoming, |
|
1040 | + $where_params_for_event |
|
1041 | + ) > 0) { |
|
1042 | + $this->_active_status = EE_Datetime::upcoming; |
|
1043 | + } else { |
|
1044 | + // expired? |
|
1045 | + if (EEM_Datetime::instance()->get_datetime_count_for_status( |
|
1046 | + EE_Datetime::expired, |
|
1047 | + $where_params_for_event |
|
1048 | + ) > 0 |
|
1049 | + ) { |
|
1050 | + $this->_active_status = EE_Datetime::expired; |
|
1051 | + } else { |
|
1052 | + // it would be odd if things make it this far because it basically means there are no datetime's |
|
1053 | + // attached to the event. So in this case it will just be considered inactive. |
|
1054 | + $this->_active_status = EE_Datetime::inactive; |
|
1055 | + } |
|
1056 | + } |
|
1057 | + } |
|
1058 | + } else { |
|
1059 | + // the event is not published, so let's just set it's active status according to its' post status |
|
1060 | + switch ($this->status()) { |
|
1061 | + case EEM_Event::sold_out: |
|
1062 | + $this->_active_status = EE_Datetime::sold_out; |
|
1063 | + break; |
|
1064 | + case EEM_Event::cancelled: |
|
1065 | + $this->_active_status = EE_Datetime::cancelled; |
|
1066 | + break; |
|
1067 | + case EEM_Event::postponed: |
|
1068 | + $this->_active_status = EE_Datetime::postponed; |
|
1069 | + break; |
|
1070 | + default: |
|
1071 | + $this->_active_status = EE_Datetime::inactive; |
|
1072 | + } |
|
1073 | + } |
|
1074 | + return $this->_active_status; |
|
1075 | + } |
|
1076 | + |
|
1077 | + |
|
1078 | + /** |
|
1079 | + * pretty_active_status |
|
1080 | + * |
|
1081 | + * @access public |
|
1082 | + * @param boolean $echo whether to return (FALSE), or echo out the result (TRUE) |
|
1083 | + * @return mixed void|string |
|
1084 | + * @throws EE_Error |
|
1085 | + */ |
|
1086 | + public function pretty_active_status($echo = true) |
|
1087 | + { |
|
1088 | + $active_status = $this->get_active_status(); |
|
1089 | + $status = '<span class="ee-status event-active-status-' |
|
1090 | + . $active_status |
|
1091 | + . '">' |
|
1092 | + . EEH_Template::pretty_status($active_status, false, 'sentence') |
|
1093 | + . '</span>'; |
|
1094 | + if ($echo) { |
|
1095 | + echo $status; |
|
1096 | + return ''; |
|
1097 | + } |
|
1098 | + return $status; |
|
1099 | + } |
|
1100 | + |
|
1101 | + |
|
1102 | + /** |
|
1103 | + * @return bool|int |
|
1104 | + * @throws EE_Error |
|
1105 | + */ |
|
1106 | + public function get_number_of_tickets_sold() |
|
1107 | + { |
|
1108 | + $tkt_sold = 0; |
|
1109 | + if (! $this->ID()) { |
|
1110 | + return 0; |
|
1111 | + } |
|
1112 | + $datetimes = $this->datetimes(); |
|
1113 | + foreach ($datetimes as $datetime) { |
|
1114 | + if ($datetime instanceof EE_Datetime) { |
|
1115 | + $tkt_sold += $datetime->sold(); |
|
1116 | + } |
|
1117 | + } |
|
1118 | + return $tkt_sold; |
|
1119 | + } |
|
1120 | + |
|
1121 | + |
|
1122 | + /** |
|
1123 | + * This just returns a count of all the registrations for this event |
|
1124 | + * |
|
1125 | + * @access public |
|
1126 | + * @return int |
|
1127 | + * @throws EE_Error |
|
1128 | + */ |
|
1129 | + public function get_count_of_all_registrations() |
|
1130 | + { |
|
1131 | + return EEM_Event::instance()->count_related($this, 'Registration'); |
|
1132 | + } |
|
1133 | + |
|
1134 | + |
|
1135 | + /** |
|
1136 | + * This returns the ticket with the earliest start time that is |
|
1137 | + * available for this event (across all datetimes attached to the event) |
|
1138 | + * |
|
1139 | + * @return EE_Base_Class|EE_Ticket|null |
|
1140 | + * @throws EE_Error |
|
1141 | + */ |
|
1142 | + public function get_ticket_with_earliest_start_time() |
|
1143 | + { |
|
1144 | + $where['Datetime.EVT_ID'] = $this->ID(); |
|
1145 | + $query_params = array($where, 'order_by' => array('TKT_start_date' => 'ASC')); |
|
1146 | + return EE_Registry::instance()->load_model('Ticket')->get_one($query_params); |
|
1147 | + } |
|
1148 | + |
|
1149 | + |
|
1150 | + /** |
|
1151 | + * This returns the ticket with the latest end time that is available |
|
1152 | + * for this event (across all datetimes attached to the event) |
|
1153 | + * |
|
1154 | + * @return EE_Base_Class|EE_Ticket|null |
|
1155 | + * @throws EE_Error |
|
1156 | + */ |
|
1157 | + public function get_ticket_with_latest_end_time() |
|
1158 | + { |
|
1159 | + $where['Datetime.EVT_ID'] = $this->ID(); |
|
1160 | + $query_params = array($where, 'order_by' => array('TKT_end_date' => 'DESC')); |
|
1161 | + return EE_Registry::instance()->load_model('Ticket')->get_one($query_params); |
|
1162 | + } |
|
1163 | + |
|
1164 | + |
|
1165 | + /** |
|
1166 | + * This returns the number of different ticket types currently on sale for this event. |
|
1167 | + * |
|
1168 | + * @return int |
|
1169 | + * @throws EE_Error |
|
1170 | + */ |
|
1171 | + public function countTicketsOnSale() |
|
1172 | + { |
|
1173 | + $where = array( |
|
1174 | + 'Datetime.EVT_ID' => $this->ID(), |
|
1175 | + 'TKT_start_date' => array('<', time()), |
|
1176 | + 'TKT_end_date' => array('>', time()), |
|
1177 | + ); |
|
1178 | + return EEM_Ticket::instance()->count(array($where)); |
|
1179 | + } |
|
1180 | + |
|
1181 | + |
|
1182 | + /** |
|
1183 | + * This returns whether there are any tickets on sale for this event. |
|
1184 | + * |
|
1185 | + * @return bool true = YES tickets on sale. |
|
1186 | + * @throws EE_Error |
|
1187 | + */ |
|
1188 | + public function tickets_on_sale() |
|
1189 | + { |
|
1190 | + return $this->countTicketsOnSale() > 0; |
|
1191 | + } |
|
1192 | + |
|
1193 | + |
|
1194 | + /** |
|
1195 | + * Gets the URL for viewing this event on the front-end. Overrides parent |
|
1196 | + * to check for an external URL first |
|
1197 | + * |
|
1198 | + * @return string |
|
1199 | + * @throws EE_Error |
|
1200 | + */ |
|
1201 | + public function get_permalink() |
|
1202 | + { |
|
1203 | + if ($this->external_url()) { |
|
1204 | + return $this->external_url(); |
|
1205 | + } |
|
1206 | + return parent::get_permalink(); |
|
1207 | + } |
|
1208 | + |
|
1209 | + |
|
1210 | + /** |
|
1211 | + * Gets the first term for 'espresso_event_categories' we can find |
|
1212 | + * |
|
1213 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1214 | + * @return EE_Base_Class|EE_Term|null |
|
1215 | + * @throws EE_Error |
|
1216 | + */ |
|
1217 | + public function first_event_category($query_params = array()) |
|
1218 | + { |
|
1219 | + $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories'; |
|
1220 | + $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID(); |
|
1221 | + return EEM_Term::instance()->get_one($query_params); |
|
1222 | + } |
|
1223 | + |
|
1224 | + |
|
1225 | + /** |
|
1226 | + * Gets all terms for 'espresso_event_categories' we can find |
|
1227 | + * |
|
1228 | + * @param array $query_params |
|
1229 | + * @return EE_Base_Class[]|EE_Term[] |
|
1230 | + * @throws EE_Error |
|
1231 | + */ |
|
1232 | + public function get_all_event_categories($query_params = array()) |
|
1233 | + { |
|
1234 | + $query_params[0]['Term_Taxonomy.taxonomy'] = 'espresso_event_categories'; |
|
1235 | + $query_params[0]['Term_Taxonomy.Event.EVT_ID'] = $this->ID(); |
|
1236 | + return EEM_Term::instance()->get_all($query_params); |
|
1237 | + } |
|
1238 | + |
|
1239 | + |
|
1240 | + /** |
|
1241 | + * Adds a question group to this event |
|
1242 | + * |
|
1243 | + * @param EE_Question_Group|int $question_group_id_or_obj |
|
1244 | + * @param bool $for_primary if true, the question group will be added for the primary |
|
1245 | + * registrant, if false will be added for others. default: false |
|
1246 | + * @return EE_Base_Class|EE_Question_Group |
|
1247 | + * @throws EE_Error |
|
1248 | + * @throws InvalidArgumentException |
|
1249 | + * @throws InvalidDataTypeException |
|
1250 | + * @throws InvalidInterfaceException |
|
1251 | + * @throws ReflectionException |
|
1252 | + */ |
|
1253 | + public function add_question_group($question_group_id_or_obj, $for_primary = false) |
|
1254 | + { |
|
1255 | + // If the row already exists, it will be updated. If it doesn't, it will be inserted. |
|
1256 | + // That's in EE_HABTM_Relation::add_relation_to(). |
|
1257 | + return $this->_add_relation_to( |
|
1258 | + $question_group_id_or_obj, |
|
1259 | + 'Question_Group', |
|
1260 | + [ |
|
1261 | + EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary) => true |
|
1262 | + ] |
|
1263 | + ); |
|
1264 | + } |
|
1265 | + |
|
1266 | + |
|
1267 | + /** |
|
1268 | + * Removes a question group from the event |
|
1269 | + * |
|
1270 | + * @param EE_Question_Group|int $question_group_id_or_obj |
|
1271 | + * @param bool $for_primary if true, the question group will be removed from the primary |
|
1272 | + * registrant, if false will be removed from others. default: false |
|
1273 | + * @return EE_Base_Class|EE_Question_Group |
|
1274 | + * @throws EE_Error |
|
1275 | + * @throws InvalidArgumentException |
|
1276 | + * @throws ReflectionException |
|
1277 | + * @throws InvalidDataTypeException |
|
1278 | + * @throws InvalidInterfaceException |
|
1279 | + */ |
|
1280 | + public function remove_question_group($question_group_id_or_obj, $for_primary = false) |
|
1281 | + { |
|
1282 | + // If the question group is used for the other type (primary or additional) |
|
1283 | + // then just update it. If not, delete it outright. |
|
1284 | + $existing_relation = $this->get_first_related( |
|
1285 | + 'Event_Question_Group', |
|
1286 | + [ |
|
1287 | + [ |
|
1288 | + 'QSG_ID' => EEM_Question_Group::instance()->ensure_is_ID($question_group_id_or_obj) |
|
1289 | + ] |
|
1290 | + ] |
|
1291 | + ); |
|
1292 | + $field_to_update = EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary); |
|
1293 | + $other_field = EEM_Event_Question_Group::instance()->fieldNameForContext(! $for_primary); |
|
1294 | + if ($existing_relation->get($other_field) === false) { |
|
1295 | + // Delete it. It's now no longer for primary or additional question groups. |
|
1296 | + return $this->_remove_relation_to($question_group_id_or_obj, 'Question_Group'); |
|
1297 | + } |
|
1298 | + // Just update it. They'll still use this question group for the other category |
|
1299 | + $existing_relation->save( |
|
1300 | + [ |
|
1301 | + $field_to_update => false |
|
1302 | + ] |
|
1303 | + ); |
|
1304 | + } |
|
1305 | + |
|
1306 | + |
|
1307 | + /** |
|
1308 | + * Gets all the question groups, ordering them by QSG_order ascending |
|
1309 | + * |
|
1310 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1311 | + * @return EE_Base_Class[]|EE_Question_Group[] |
|
1312 | + * @throws EE_Error |
|
1313 | + */ |
|
1314 | + public function question_groups($query_params = array()) |
|
1315 | + { |
|
1316 | + $query_params = ! empty($query_params) ? $query_params : array('order_by' => array('QSG_order' => 'ASC')); |
|
1317 | + return $this->get_many_related('Question_Group', $query_params); |
|
1318 | + } |
|
1319 | + |
|
1320 | + |
|
1321 | + /** |
|
1322 | + * Implementation for EEI_Has_Icon interface method. |
|
1323 | + * |
|
1324 | + * @see EEI_Visual_Representation for comments |
|
1325 | + * @return string |
|
1326 | + */ |
|
1327 | + public function get_icon() |
|
1328 | + { |
|
1329 | + return '<span class="dashicons dashicons-flag"></span>'; |
|
1330 | + } |
|
1331 | + |
|
1332 | + |
|
1333 | + /** |
|
1334 | + * Implementation for EEI_Admin_Links interface method. |
|
1335 | + * |
|
1336 | + * @see EEI_Admin_Links for comments |
|
1337 | + * @return string |
|
1338 | + * @throws EE_Error |
|
1339 | + */ |
|
1340 | + public function get_admin_details_link() |
|
1341 | + { |
|
1342 | + return $this->get_admin_edit_link(); |
|
1343 | + } |
|
1344 | + |
|
1345 | + |
|
1346 | + /** |
|
1347 | + * Implementation for EEI_Admin_Links interface method. |
|
1348 | + * |
|
1349 | + * @see EEI_Admin_Links for comments |
|
1350 | + * @return string |
|
1351 | + * @throws EE_Error |
|
1352 | + */ |
|
1353 | + public function get_admin_edit_link() |
|
1354 | + { |
|
1355 | + return EEH_URL::add_query_args_and_nonce( |
|
1356 | + array( |
|
1357 | + 'page' => 'espresso_events', |
|
1358 | + 'action' => 'edit', |
|
1359 | + 'post' => $this->ID(), |
|
1360 | + ), |
|
1361 | + admin_url('admin.php') |
|
1362 | + ); |
|
1363 | + } |
|
1364 | + |
|
1365 | + |
|
1366 | + /** |
|
1367 | + * Implementation for EEI_Admin_Links interface method. |
|
1368 | + * |
|
1369 | + * @see EEI_Admin_Links for comments |
|
1370 | + * @return string |
|
1371 | + */ |
|
1372 | + public function get_admin_settings_link() |
|
1373 | + { |
|
1374 | + return EEH_URL::add_query_args_and_nonce( |
|
1375 | + array( |
|
1376 | + 'page' => 'espresso_events', |
|
1377 | + 'action' => 'default_event_settings', |
|
1378 | + ), |
|
1379 | + admin_url('admin.php') |
|
1380 | + ); |
|
1381 | + } |
|
1382 | + |
|
1383 | + |
|
1384 | + /** |
|
1385 | + * Implementation for EEI_Admin_Links interface method. |
|
1386 | + * |
|
1387 | + * @see EEI_Admin_Links for comments |
|
1388 | + * @return string |
|
1389 | + */ |
|
1390 | + public function get_admin_overview_link() |
|
1391 | + { |
|
1392 | + return EEH_URL::add_query_args_and_nonce( |
|
1393 | + array( |
|
1394 | + 'page' => 'espresso_events', |
|
1395 | + 'action' => 'default', |
|
1396 | + ), |
|
1397 | + admin_url('admin.php') |
|
1398 | + ); |
|
1399 | + } |
|
1400 | 1400 | } |
@@ -71,7 +71,7 @@ discard block |
||
71 | 71 | */ |
72 | 72 | public function getAvailableSpacesCalculator() |
73 | 73 | { |
74 | - if (! $this->available_spaces_calculator instanceof EventSpacesCalculator) { |
|
74 | + if ( ! $this->available_spaces_calculator instanceof EventSpacesCalculator) { |
|
75 | 75 | $this->available_spaces_calculator = new EventSpacesCalculator($this); |
76 | 76 | } |
77 | 77 | return $this->available_spaces_calculator; |
@@ -213,7 +213,7 @@ discard block |
||
213 | 213 | */ |
214 | 214 | public function primary_datetime($try_to_exclude_expired = true, $try_to_exclude_deleted = true) |
215 | 215 | { |
216 | - if (! empty($this->_Primary_Datetime)) { |
|
216 | + if ( ! empty($this->_Primary_Datetime)) { |
|
217 | 217 | return $this->_Primary_Datetime; |
218 | 218 | } |
219 | 219 | $this->_Primary_Datetime = EEM_Datetime::instance($this->_timezone)->get_primary_datetime_for_event( |
@@ -236,7 +236,7 @@ discard block |
||
236 | 236 | { |
237 | 237 | // first get all datetimes |
238 | 238 | $datetimes = $this->datetimes_ordered(); |
239 | - if (! $datetimes) { |
|
239 | + if ( ! $datetimes) { |
|
240 | 240 | return array(); |
241 | 241 | } |
242 | 242 | $datetime_ids = array(); |
@@ -429,7 +429,7 @@ discard block |
||
429 | 429 | public function short_description($num_words = 55, $more = null, $not_full_desc = false) |
430 | 430 | { |
431 | 431 | $short_desc = $this->get('EVT_short_desc'); |
432 | - if (! empty($short_desc) || $not_full_desc) { |
|
432 | + if ( ! empty($short_desc) || $not_full_desc) { |
|
433 | 433 | return $short_desc; |
434 | 434 | } |
435 | 435 | $full_desc = $this->get('EVT_desc'); |
@@ -883,7 +883,7 @@ discard block |
||
883 | 883 | ); |
884 | 884 | $all_expired = true; |
885 | 885 | foreach ($tickets as $ticket) { |
886 | - if (! $ticket->is_expired()) { |
|
886 | + if ( ! $ticket->is_expired()) { |
|
887 | 887 | $all_expired = false; |
888 | 888 | break; |
889 | 889 | } |
@@ -972,7 +972,7 @@ discard block |
||
972 | 972 | */ |
973 | 973 | public function is_sold_out($actual = false) |
974 | 974 | { |
975 | - if (! $actual) { |
|
975 | + if ( ! $actual) { |
|
976 | 976 | return $this->status() === EEM_Event::sold_out; |
977 | 977 | } |
978 | 978 | return $this->perform_sold_out_status_check(); |
@@ -1017,11 +1017,11 @@ discard block |
||
1017 | 1017 | public function get_active_status($reset = false) |
1018 | 1018 | { |
1019 | 1019 | // if the active status has already been set, then just use that value (unless we are resetting it) |
1020 | - if (! empty($this->_active_status) && ! $reset) { |
|
1020 | + if ( ! empty($this->_active_status) && ! $reset) { |
|
1021 | 1021 | return $this->_active_status; |
1022 | 1022 | } |
1023 | 1023 | // first check if event id is present on this object |
1024 | - if (! $this->ID()) { |
|
1024 | + if ( ! $this->ID()) { |
|
1025 | 1025 | return false; |
1026 | 1026 | } |
1027 | 1027 | $where_params_for_event = array(array('EVT_ID' => $this->ID())); |
@@ -1106,7 +1106,7 @@ discard block |
||
1106 | 1106 | public function get_number_of_tickets_sold() |
1107 | 1107 | { |
1108 | 1108 | $tkt_sold = 0; |
1109 | - if (! $this->ID()) { |
|
1109 | + if ( ! $this->ID()) { |
|
1110 | 1110 | return 0; |
1111 | 1111 | } |
1112 | 1112 | $datetimes = $this->datetimes(); |
@@ -1290,7 +1290,7 @@ discard block |
||
1290 | 1290 | ] |
1291 | 1291 | ); |
1292 | 1292 | $field_to_update = EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary); |
1293 | - $other_field = EEM_Event_Question_Group::instance()->fieldNameForContext(! $for_primary); |
|
1293 | + $other_field = EEM_Event_Question_Group::instance()->fieldNameForContext( ! $for_primary); |
|
1294 | 1294 | if ($existing_relation->get($other_field) === false) { |
1295 | 1295 | // Delete it. It's now no longer for primary or additional question groups. |
1296 | 1296 | return $this->_remove_relation_to($question_group_id_or_obj, 'Question_Group'); |
@@ -15,913 +15,913 @@ |
||
15 | 15 | class EEM_Event extends EEM_CPT_Base |
16 | 16 | { |
17 | 17 | |
18 | - /** |
|
19 | - * constant used by status(), indicating that no more tickets can be purchased for any of the datetimes for the |
|
20 | - * event |
|
21 | - */ |
|
22 | - const sold_out = 'sold_out'; |
|
23 | - |
|
24 | - /** |
|
25 | - * constant used by status(), indicating that upcoming event dates have been postponed (may be pushed to a later |
|
26 | - * date) |
|
27 | - */ |
|
28 | - const postponed = 'postponed'; |
|
29 | - |
|
30 | - /** |
|
31 | - * constant used by status(), indicating that the event will no longer occur |
|
32 | - */ |
|
33 | - const cancelled = 'cancelled'; |
|
34 | - |
|
35 | - |
|
36 | - /** |
|
37 | - * @var string |
|
38 | - */ |
|
39 | - protected static $_default_reg_status; |
|
40 | - |
|
41 | - |
|
42 | - /** |
|
43 | - * This is the default for the additional limit field. |
|
44 | - * @var int |
|
45 | - */ |
|
46 | - protected static $_default_additional_limit = 10; |
|
47 | - |
|
48 | - |
|
49 | - /** |
|
50 | - * private instance of the Event object |
|
51 | - * |
|
52 | - * @var EEM_Event |
|
53 | - */ |
|
54 | - protected static $_instance; |
|
55 | - |
|
56 | - |
|
57 | - |
|
58 | - |
|
59 | - /** |
|
60 | - * Adds a relationship to Term_Taxonomy for each CPT_Base |
|
61 | - * |
|
62 | - * @param string $timezone |
|
63 | - * @throws \EE_Error |
|
64 | - */ |
|
65 | - protected function __construct($timezone = null) |
|
66 | - { |
|
67 | - EE_Registry::instance()->load_model('Registration'); |
|
68 | - $this->singular_item = esc_html__('Event', 'event_espresso'); |
|
69 | - $this->plural_item = esc_html__('Events', 'event_espresso'); |
|
70 | - // to remove Cancelled events from the frontend, copy the following filter to your functions.php file |
|
71 | - // add_filter( 'AFEE__EEM_Event__construct___custom_stati__cancelled__Public', '__return_false' ); |
|
72 | - // to remove Postponed events from the frontend, copy the following filter to your functions.php file |
|
73 | - // add_filter( 'AFEE__EEM_Event__construct___custom_stati__postponed__Public', '__return_false' ); |
|
74 | - // to remove Sold Out events from the frontend, copy the following filter to your functions.php file |
|
75 | - // add_filter( 'AFEE__EEM_Event__construct___custom_stati__sold_out__Public', '__return_false' ); |
|
76 | - $this->_custom_stati = apply_filters( |
|
77 | - 'AFEE__EEM_Event__construct___custom_stati', |
|
78 | - array( |
|
79 | - EEM_Event::cancelled => array( |
|
80 | - 'label' => esc_html__('Cancelled', 'event_espresso'), |
|
81 | - 'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__cancelled__Public', true), |
|
82 | - ), |
|
83 | - EEM_Event::postponed => array( |
|
84 | - 'label' => esc_html__('Postponed', 'event_espresso'), |
|
85 | - 'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__postponed__Public', true), |
|
86 | - ), |
|
87 | - EEM_Event::sold_out => array( |
|
88 | - 'label' => esc_html__('Sold Out', 'event_espresso'), |
|
89 | - 'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__sold_out__Public', true), |
|
90 | - ), |
|
91 | - ) |
|
92 | - ); |
|
93 | - self::$_default_reg_status = empty(self::$_default_reg_status) ? EEM_Registration::status_id_pending_payment |
|
94 | - : self::$_default_reg_status; |
|
95 | - $this->_tables = array( |
|
96 | - 'Event_CPT' => new EE_Primary_Table('posts', 'ID'), |
|
97 | - 'Event_Meta' => new EE_Secondary_Table('esp_event_meta', 'EVTM_ID', 'EVT_ID'), |
|
98 | - ); |
|
99 | - $this->_fields = array( |
|
100 | - 'Event_CPT' => array( |
|
101 | - 'EVT_ID' => new EE_Primary_Key_Int_Field( |
|
102 | - 'ID', |
|
103 | - esc_html__('Post ID for Event', 'event_espresso') |
|
104 | - ), |
|
105 | - 'EVT_name' => new EE_Plain_Text_Field( |
|
106 | - 'post_title', |
|
107 | - esc_html__('Event Name', 'event_espresso'), |
|
108 | - false, |
|
109 | - '' |
|
110 | - ), |
|
111 | - 'EVT_desc' => new EE_Post_Content_Field( |
|
112 | - 'post_content', |
|
113 | - esc_html__('Event Description', 'event_espresso'), |
|
114 | - false, |
|
115 | - '' |
|
116 | - ), |
|
117 | - 'EVT_slug' => new EE_Slug_Field( |
|
118 | - 'post_name', |
|
119 | - esc_html__('Event Slug', 'event_espresso'), |
|
120 | - false, |
|
121 | - '' |
|
122 | - ), |
|
123 | - 'EVT_created' => new EE_Datetime_Field( |
|
124 | - 'post_date', |
|
125 | - esc_html__('Date/Time Event Created', 'event_espresso'), |
|
126 | - false, |
|
127 | - EE_Datetime_Field::now |
|
128 | - ), |
|
129 | - 'EVT_short_desc' => new EE_Simple_HTML_Field( |
|
130 | - 'post_excerpt', |
|
131 | - esc_html__('Event Short Description', 'event_espresso'), |
|
132 | - false, |
|
133 | - '' |
|
134 | - ), |
|
135 | - 'EVT_modified' => new EE_Datetime_Field( |
|
136 | - 'post_modified', |
|
137 | - esc_html__('Date/Time Event Modified', 'event_espresso'), |
|
138 | - false, |
|
139 | - EE_Datetime_Field::now |
|
140 | - ), |
|
141 | - 'EVT_wp_user' => new EE_WP_User_Field( |
|
142 | - 'post_author', |
|
143 | - esc_html__('Event Creator ID', 'event_espresso'), |
|
144 | - false |
|
145 | - ), |
|
146 | - 'parent' => new EE_Integer_Field( |
|
147 | - 'post_parent', |
|
148 | - esc_html__('Event Parent ID', 'event_espresso'), |
|
149 | - false, |
|
150 | - 0 |
|
151 | - ), |
|
152 | - 'EVT_order' => new EE_Integer_Field( |
|
153 | - 'menu_order', |
|
154 | - esc_html__('Event Menu Order', 'event_espresso'), |
|
155 | - false, |
|
156 | - 1 |
|
157 | - ), |
|
158 | - 'post_type' => new EE_WP_Post_Type_Field('espresso_events'), |
|
159 | - // EE_Plain_Text_Field( 'post_type', esc_html__( 'Event Post Type', 'event_espresso' ), FALSE, 'espresso_events' ), |
|
160 | - 'status' => new EE_WP_Post_Status_Field( |
|
161 | - 'post_status', |
|
162 | - esc_html__('Event Status', 'event_espresso'), |
|
163 | - false, |
|
164 | - 'draft', |
|
165 | - $this->_custom_stati |
|
166 | - ), |
|
167 | - 'password' => new EE_Password_Field( |
|
168 | - 'post_password', |
|
169 | - __('Password', 'event_espresso'), |
|
170 | - false, |
|
171 | - '', |
|
172 | - array( |
|
173 | - 'EVT_desc', |
|
174 | - 'EVT_short_desc', |
|
175 | - 'EVT_display_desc', |
|
176 | - 'EVT_display_ticket_selector', |
|
177 | - 'EVT_visible_on', |
|
178 | - 'EVT_additional_limit', |
|
179 | - 'EVT_default_registration_status', |
|
180 | - 'EVT_member_only', |
|
181 | - 'EVT_phone', |
|
182 | - 'EVT_allow_overflow', |
|
183 | - 'EVT_timezone_string', |
|
184 | - 'EVT_external_URL', |
|
185 | - 'EVT_donations' |
|
186 | - ) |
|
187 | - ) |
|
188 | - ), |
|
189 | - 'Event_Meta' => array( |
|
190 | - 'EVTM_ID' => new EE_DB_Only_Float_Field( |
|
191 | - 'EVTM_ID', |
|
192 | - esc_html__('Event Meta Row ID', 'event_espresso'), |
|
193 | - false |
|
194 | - ), |
|
195 | - 'EVT_ID_fk' => new EE_DB_Only_Int_Field( |
|
196 | - 'EVT_ID', |
|
197 | - esc_html__('Foreign key to Event ID from Event Meta table', 'event_espresso'), |
|
198 | - false |
|
199 | - ), |
|
200 | - 'EVT_display_desc' => new EE_Boolean_Field( |
|
201 | - 'EVT_display_desc', |
|
202 | - esc_html__('Display Description Flag', 'event_espresso'), |
|
203 | - false, |
|
204 | - true |
|
205 | - ), |
|
206 | - 'EVT_display_ticket_selector' => new EE_Boolean_Field( |
|
207 | - 'EVT_display_ticket_selector', |
|
208 | - esc_html__('Display Ticket Selector Flag', 'event_espresso'), |
|
209 | - false, |
|
210 | - true |
|
211 | - ), |
|
212 | - 'EVT_visible_on' => new EE_Datetime_Field( |
|
213 | - 'EVT_visible_on', |
|
214 | - esc_html__('Event Visible Date', 'event_espresso'), |
|
215 | - true, |
|
216 | - EE_Datetime_Field::now |
|
217 | - ), |
|
218 | - 'EVT_additional_limit' => new EE_Integer_Field( |
|
219 | - 'EVT_additional_limit', |
|
220 | - esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso'), |
|
221 | - true, |
|
222 | - self::$_default_additional_limit |
|
223 | - ), |
|
224 | - 'EVT_default_registration_status' => new EE_Enum_Text_Field( |
|
225 | - 'EVT_default_registration_status', |
|
226 | - esc_html__('Default Registration Status on this Event', 'event_espresso'), |
|
227 | - false, |
|
228 | - EEM_Event::$_default_reg_status, |
|
229 | - EEM_Registration::reg_status_array() |
|
230 | - ), |
|
231 | - 'EVT_member_only' => new EE_Boolean_Field( |
|
232 | - 'EVT_member_only', |
|
233 | - esc_html__('Member-Only Event Flag', 'event_espresso'), |
|
234 | - false, |
|
235 | - false |
|
236 | - ), |
|
237 | - 'EVT_phone' => new EE_Plain_Text_Field( |
|
238 | - 'EVT_phone', |
|
239 | - esc_html__('Event Phone Number', 'event_espresso'), |
|
240 | - false, |
|
241 | - '' |
|
242 | - ), |
|
243 | - 'EVT_allow_overflow' => new EE_Boolean_Field( |
|
244 | - 'EVT_allow_overflow', |
|
245 | - esc_html__('Allow Overflow on Event', 'event_espresso'), |
|
246 | - false, |
|
247 | - false |
|
248 | - ), |
|
249 | - 'EVT_timezone_string' => new EE_Plain_Text_Field( |
|
250 | - 'EVT_timezone_string', |
|
251 | - esc_html__('Timezone (name) for Event times', 'event_espresso'), |
|
252 | - false, |
|
253 | - '' |
|
254 | - ), |
|
255 | - 'EVT_external_URL' => new EE_Plain_Text_Field( |
|
256 | - 'EVT_external_URL', |
|
257 | - esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso'), |
|
258 | - true |
|
259 | - ), |
|
260 | - 'EVT_donations' => new EE_Boolean_Field( |
|
261 | - 'EVT_donations', |
|
262 | - esc_html__('Accept Donations?', 'event_espresso'), |
|
263 | - false, |
|
264 | - false |
|
265 | - ), |
|
266 | - ), |
|
267 | - ); |
|
268 | - $this->_model_relations = array( |
|
269 | - 'Registration' => new EE_Has_Many_Relation(), |
|
270 | - 'Datetime' => new EE_Has_Many_Relation(), |
|
271 | - 'Question_Group' => new EE_HABTM_Relation('Event_Question_Group'), |
|
272 | - 'Event_Question_Group' => new EE_Has_Many_Relation(), |
|
273 | - 'Venue' => new EE_HABTM_Relation('Event_Venue'), |
|
274 | - 'Term_Relationship' => new EE_Has_Many_Relation(), |
|
275 | - 'Term_Taxonomy' => new EE_HABTM_Relation('Term_Relationship'), |
|
276 | - 'Message_Template_Group' => new EE_HABTM_Relation('Event_Message_Template'), |
|
277 | - 'Attendee' => new EE_HABTM_Relation('Registration'), |
|
278 | - 'WP_User' => new EE_Belongs_To_Relation(), |
|
279 | - ); |
|
280 | - // this model is generally available for reading |
|
281 | - $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public(); |
|
282 | - $this->model_chain_to_password = ''; |
|
283 | - parent::__construct($timezone); |
|
284 | - } |
|
285 | - |
|
286 | - |
|
287 | - |
|
288 | - /** |
|
289 | - * @param string $default_reg_status |
|
290 | - */ |
|
291 | - public static function set_default_reg_status($default_reg_status) |
|
292 | - { |
|
293 | - self::$_default_reg_status = $default_reg_status; |
|
294 | - // if EEM_Event has already been instantiated, |
|
295 | - // then we need to reset the `EVT_default_reg_status` field to use the new default. |
|
296 | - if (self::$_instance instanceof EEM_Event) { |
|
297 | - $default_reg_status = new EE_Enum_Text_Field( |
|
298 | - 'EVT_default_registration_status', |
|
299 | - esc_html__('Default Registration Status on this Event', 'event_espresso'), |
|
300 | - false, |
|
301 | - $default_reg_status, |
|
302 | - EEM_Registration::reg_status_array() |
|
303 | - ); |
|
304 | - $default_reg_status->_construct_finalize( |
|
305 | - 'Event_Meta', |
|
306 | - 'EVT_default_registration_status', |
|
307 | - 'EEM_Event' |
|
308 | - ); |
|
309 | - self::$_instance->_fields['Event_Meta']['EVT_default_registration_status'] = $default_reg_status; |
|
310 | - } |
|
311 | - } |
|
312 | - |
|
313 | - |
|
314 | - /** |
|
315 | - * Used to override the default for the additional limit field. |
|
316 | - * @param $additional_limit |
|
317 | - */ |
|
318 | - public static function set_default_additional_limit($additional_limit) |
|
319 | - { |
|
320 | - self::$_default_additional_limit = (int) $additional_limit; |
|
321 | - if (self::$_instance instanceof EEM_Event) { |
|
322 | - self::$_instance->_fields['Event_Meta']['EVT_additional_limit'] = new EE_Integer_Field( |
|
323 | - 'EVT_additional_limit', |
|
324 | - __('Limit of Additional Registrations on Same Transaction', 'event_espresso'), |
|
325 | - true, |
|
326 | - self::$_default_additional_limit |
|
327 | - ); |
|
328 | - self::$_instance->_fields['Event_Meta']['EVT_additional_limit']->_construct_finalize( |
|
329 | - 'Event_Meta', |
|
330 | - 'EVT_additional_limit', |
|
331 | - 'EEM_Event' |
|
332 | - ); |
|
333 | - } |
|
334 | - } |
|
335 | - |
|
336 | - |
|
337 | - /** |
|
338 | - * Return what is currently set as the default additional limit for the event. |
|
339 | - * @return int |
|
340 | - */ |
|
341 | - public static function get_default_additional_limit() |
|
342 | - { |
|
343 | - return apply_filters('FHEE__EEM_Event__get_default_additional_limit', self::$_default_additional_limit); |
|
344 | - } |
|
345 | - |
|
346 | - |
|
347 | - /** |
|
348 | - * get_question_groups |
|
349 | - * |
|
350 | - * @return array |
|
351 | - * @throws \EE_Error |
|
352 | - */ |
|
353 | - public function get_all_question_groups() |
|
354 | - { |
|
355 | - return EE_Registry::instance()->load_model('Question_Group')->get_all( |
|
356 | - array( |
|
357 | - array('QSG_deleted' => false), |
|
358 | - 'order_by' => array('QSG_order' => 'ASC'), |
|
359 | - ) |
|
360 | - ); |
|
361 | - } |
|
362 | - |
|
363 | - |
|
364 | - |
|
365 | - /** |
|
366 | - * get_question_groups |
|
367 | - * |
|
368 | - * @param int $EVT_ID |
|
369 | - * @return array|bool |
|
370 | - * @throws \EE_Error |
|
371 | - */ |
|
372 | - public function get_all_event_question_groups($EVT_ID = 0) |
|
373 | - { |
|
374 | - if (! isset($EVT_ID) || ! absint($EVT_ID)) { |
|
375 | - EE_Error::add_error( |
|
376 | - esc_html__( |
|
377 | - 'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.', |
|
378 | - 'event_espresso' |
|
379 | - ), |
|
380 | - __FILE__, |
|
381 | - __FUNCTION__, |
|
382 | - __LINE__ |
|
383 | - ); |
|
384 | - return false; |
|
385 | - } |
|
386 | - return EE_Registry::instance()->load_model('Event_Question_Group')->get_all( |
|
387 | - array( |
|
388 | - array('EVT_ID' => $EVT_ID), |
|
389 | - ) |
|
390 | - ); |
|
391 | - } |
|
392 | - |
|
393 | - |
|
394 | - /** |
|
395 | - * get_question_groups |
|
396 | - * |
|
397 | - * @param int $EVT_ID |
|
398 | - * @param boolean $for_primary_attendee |
|
399 | - * @return array|bool |
|
400 | - * @throws EE_Error |
|
401 | - * @throws InvalidArgumentException |
|
402 | - * @throws ReflectionException |
|
403 | - * @throws InvalidDataTypeException |
|
404 | - * @throws InvalidInterfaceException |
|
405 | - */ |
|
406 | - public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true) |
|
407 | - { |
|
408 | - if (! isset($EVT_ID) || ! absint($EVT_ID)) { |
|
409 | - EE_Error::add_error( |
|
410 | - esc_html__( |
|
411 | - // @codingStandardsIgnoreStart |
|
412 | - 'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.', |
|
413 | - // @codingStandardsIgnoreEnd |
|
414 | - 'event_espresso' |
|
415 | - ), |
|
416 | - __FILE__, |
|
417 | - __FUNCTION__, |
|
418 | - __LINE__ |
|
419 | - ); |
|
420 | - return false; |
|
421 | - } |
|
422 | - $query_params = [ |
|
423 | - [ |
|
424 | - 'EVT_ID' => $EVT_ID, |
|
425 | - EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary_attendee) => true |
|
426 | - ] |
|
427 | - ]; |
|
428 | - if ($for_primary_attendee) { |
|
429 | - $query_params[0][] = true; |
|
430 | - } else { |
|
431 | - $query_params[0]['EQG_additional'] = true; |
|
432 | - } |
|
433 | - return EE_Registry::instance()->load_model('Event_Question_Group')->get_all($query_params); |
|
434 | - } |
|
435 | - |
|
436 | - |
|
437 | - |
|
438 | - /** |
|
439 | - * get_question_groups |
|
440 | - * |
|
441 | - * @param int $EVT_ID |
|
442 | - * @param EE_Registration $registration |
|
443 | - * @return array|bool |
|
444 | - * @throws \EE_Error |
|
445 | - */ |
|
446 | - public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration) |
|
447 | - { |
|
448 | - if (! isset($EVT_ID) || ! absint($EVT_ID)) { |
|
449 | - EE_Error::add_error( |
|
450 | - esc_html__( |
|
451 | - 'An error occurred. No Question Groups could be retrieved because an Event ID was not received.', |
|
452 | - 'event_espresso' |
|
453 | - ), |
|
454 | - __FILE__, |
|
455 | - __FUNCTION__, |
|
456 | - __LINE__ |
|
457 | - ); |
|
458 | - return false; |
|
459 | - } |
|
460 | - $where_params = array( |
|
461 | - 'Event_Question_Group.EVT_ID' => $EVT_ID, |
|
462 | - 'QSG_deleted' => false, |
|
463 | - ); |
|
464 | - if( $registration->is_primary_registrant()) { |
|
465 | - $where_params['Event_Question_Group.EQG_primary'] = true; |
|
466 | - } else { |
|
467 | - $where_params['Event_Question_Group.EQG_additional'] = true; |
|
468 | - } |
|
469 | - return EE_Registry::instance()->load_model('Question_Group')->get_all( |
|
470 | - [ |
|
471 | - $where_params, |
|
472 | - 'order_by' => ['QSG_order' => 'ASC'], |
|
473 | - ] |
|
474 | - ); |
|
475 | - } |
|
476 | - |
|
477 | - |
|
478 | - |
|
479 | - /** |
|
480 | - * get_question_target_db_column |
|
481 | - * |
|
482 | - * @param string $QSG_IDs csv list of $QSG IDs |
|
483 | - * @return array|bool |
|
484 | - * @throws \EE_Error |
|
485 | - */ |
|
486 | - public function get_questions_in_groups($QSG_IDs = '') |
|
487 | - { |
|
488 | - if (empty($QSG_IDs)) { |
|
489 | - EE_Error::add_error( |
|
490 | - esc_html__('An error occurred. No Question Group IDs were received.', 'event_espresso'), |
|
491 | - __FILE__, |
|
492 | - __FUNCTION__, |
|
493 | - __LINE__ |
|
494 | - ); |
|
495 | - return false; |
|
496 | - } |
|
497 | - return EE_Registry::instance()->load_model('Question')->get_all( |
|
498 | - array( |
|
499 | - array( |
|
500 | - 'Question_Group.QSG_ID' => array('IN', $QSG_IDs), |
|
501 | - 'QST_deleted' => false, |
|
502 | - 'QST_admin_only' => is_admin(), |
|
503 | - ), |
|
504 | - 'order_by' => 'QST_order', |
|
505 | - ) |
|
506 | - ); |
|
507 | - } |
|
508 | - |
|
509 | - |
|
510 | - |
|
511 | - /** |
|
512 | - * get_options_for_question |
|
513 | - * |
|
514 | - * @param string $QST_IDs csv list of $QST IDs |
|
515 | - * @return array|bool |
|
516 | - * @throws \EE_Error |
|
517 | - */ |
|
518 | - public function get_options_for_question($QST_IDs) |
|
519 | - { |
|
520 | - if (empty($QST_IDs)) { |
|
521 | - EE_Error::add_error( |
|
522 | - esc_html__('An error occurred. No Question IDs were received.', 'event_espresso'), |
|
523 | - __FILE__, |
|
524 | - __FUNCTION__, |
|
525 | - __LINE__ |
|
526 | - ); |
|
527 | - return false; |
|
528 | - } |
|
529 | - return EE_Registry::instance()->load_model('Question_Option')->get_all( |
|
530 | - array( |
|
531 | - array( |
|
532 | - 'Question.QST_ID' => array('IN', $QST_IDs), |
|
533 | - 'QSO_deleted' => false, |
|
534 | - ), |
|
535 | - 'order_by' => 'QSO_ID', |
|
536 | - ) |
|
537 | - ); |
|
538 | - } |
|
539 | - |
|
540 | - |
|
541 | - |
|
542 | - |
|
543 | - |
|
544 | - |
|
545 | - |
|
546 | - /** |
|
547 | - * Gets all events that are published |
|
548 | - * and have event start time earlier than now and an event end time later than now |
|
549 | - * |
|
550 | - * @param array $query_params An array of query params to further filter on |
|
551 | - * (note that status and DTT_EVT_start and DTT_EVT_end will be overridden) |
|
552 | - * @param bool $count whether to return the count or not (default FALSE) |
|
553 | - * @return EE_Event[]|int |
|
554 | - * @throws \EE_Error |
|
555 | - */ |
|
556 | - public function get_active_events($query_params, $count = false) |
|
557 | - { |
|
558 | - if (array_key_exists(0, $query_params)) { |
|
559 | - $where_params = $query_params[0]; |
|
560 | - unset($query_params[0]); |
|
561 | - } else { |
|
562 | - $where_params = array(); |
|
563 | - } |
|
564 | - // if we have count make sure we don't include group by |
|
565 | - if ($count && isset($query_params['group_by'])) { |
|
566 | - unset($query_params['group_by']); |
|
567 | - } |
|
568 | - // let's add specific query_params for active_events |
|
569 | - // keep in mind this will override any sent status in the query AND any date queries. |
|
570 | - $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out)); |
|
571 | - // if already have where params for DTT_EVT_start or DTT_EVT_end then append these conditions |
|
572 | - if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
573 | - $where_params['Datetime.DTT_EVT_start******'] = array( |
|
574 | - '<', |
|
575 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
576 | - ); |
|
577 | - } else { |
|
578 | - $where_params['Datetime.DTT_EVT_start'] = array( |
|
579 | - '<', |
|
580 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
581 | - ); |
|
582 | - } |
|
583 | - if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
584 | - $where_params['Datetime.DTT_EVT_end*****'] = array( |
|
585 | - '>', |
|
586 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
587 | - ); |
|
588 | - } else { |
|
589 | - $where_params['Datetime.DTT_EVT_end'] = array( |
|
590 | - '>', |
|
591 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
592 | - ); |
|
593 | - } |
|
594 | - $query_params[0] = $where_params; |
|
595 | - // don't use $query_params with count() |
|
596 | - // because we don't want to include additional query clauses like "GROUP BY" |
|
597 | - return $count |
|
598 | - ? $this->count(array($where_params), 'EVT_ID', true) |
|
599 | - : $this->get_all($query_params); |
|
600 | - } |
|
601 | - |
|
602 | - |
|
603 | - |
|
604 | - /** |
|
605 | - * get all events that are published and have an event start time later than now |
|
606 | - * |
|
607 | - * @param array $query_params An array of query params to further filter on |
|
608 | - * (Note that status and DTT_EVT_start will be overridden) |
|
609 | - * @param bool $count whether to return the count or not (default FALSE) |
|
610 | - * @return EE_Event[]|int |
|
611 | - * @throws \EE_Error |
|
612 | - */ |
|
613 | - public function get_upcoming_events($query_params, $count = false) |
|
614 | - { |
|
615 | - if (array_key_exists(0, $query_params)) { |
|
616 | - $where_params = $query_params[0]; |
|
617 | - unset($query_params[0]); |
|
618 | - } else { |
|
619 | - $where_params = array(); |
|
620 | - } |
|
621 | - // if we have count make sure we don't include group by |
|
622 | - if ($count && isset($query_params['group_by'])) { |
|
623 | - unset($query_params['group_by']); |
|
624 | - } |
|
625 | - // let's add specific query_params for active_events |
|
626 | - // keep in mind this will override any sent status in the query AND any date queries. |
|
627 | - $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out)); |
|
628 | - // if there are already query_params matching DTT_EVT_start then we need to modify that to add them. |
|
629 | - if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
630 | - $where_params['Datetime.DTT_EVT_start*****'] = array( |
|
631 | - '>', |
|
632 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
633 | - ); |
|
634 | - } else { |
|
635 | - $where_params['Datetime.DTT_EVT_start'] = array( |
|
636 | - '>', |
|
637 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
638 | - ); |
|
639 | - } |
|
640 | - $query_params[0] = $where_params; |
|
641 | - // don't use $query_params with count() |
|
642 | - // because we don't want to include additional query clauses like "GROUP BY" |
|
643 | - return $count |
|
644 | - ? $this->count(array($where_params), 'EVT_ID', true) |
|
645 | - : $this->get_all($query_params); |
|
646 | - } |
|
647 | - |
|
648 | - |
|
649 | - |
|
650 | - /** |
|
651 | - * Gets all events that are published |
|
652 | - * and have an event end time later than now |
|
653 | - * |
|
654 | - * @param array $query_params An array of query params to further filter on |
|
655 | - * (note that status and DTT_EVT_end will be overridden) |
|
656 | - * @param bool $count whether to return the count or not (default FALSE) |
|
657 | - * @return EE_Event[]|int |
|
658 | - * @throws \EE_Error |
|
659 | - */ |
|
660 | - public function get_active_and_upcoming_events($query_params, $count = false) |
|
661 | - { |
|
662 | - if (array_key_exists(0, $query_params)) { |
|
663 | - $where_params = $query_params[0]; |
|
664 | - unset($query_params[0]); |
|
665 | - } else { |
|
666 | - $where_params = array(); |
|
667 | - } |
|
668 | - // if we have count make sure we don't include group by |
|
669 | - if ($count && isset($query_params['group_by'])) { |
|
670 | - unset($query_params['group_by']); |
|
671 | - } |
|
672 | - // let's add specific query_params for active_events |
|
673 | - // keep in mind this will override any sent status in the query AND any date queries. |
|
674 | - $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out)); |
|
675 | - // add where params for DTT_EVT_end |
|
676 | - if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
677 | - $where_params['Datetime.DTT_EVT_end*****'] = array( |
|
678 | - '>', |
|
679 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
680 | - ); |
|
681 | - } else { |
|
682 | - $where_params['Datetime.DTT_EVT_end'] = array( |
|
683 | - '>', |
|
684 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
685 | - ); |
|
686 | - } |
|
687 | - $query_params[0] = $where_params; |
|
688 | - // don't use $query_params with count() |
|
689 | - // because we don't want to include additional query clauses like "GROUP BY" |
|
690 | - return $count |
|
691 | - ? $this->count(array($where_params), 'EVT_ID', true) |
|
692 | - : $this->get_all($query_params); |
|
693 | - } |
|
694 | - |
|
695 | - |
|
696 | - |
|
697 | - /** |
|
698 | - * This only returns events that are expired. |
|
699 | - * They may still be published but all their datetimes have expired. |
|
700 | - * |
|
701 | - * @param array $query_params An array of query params to further filter on |
|
702 | - * (note that status and DTT_EVT_end will be overridden) |
|
703 | - * @param bool $count whether to return the count or not (default FALSE) |
|
704 | - * @return EE_Event[]|int |
|
705 | - * @throws \EE_Error |
|
706 | - */ |
|
707 | - public function get_expired_events($query_params, $count = false) |
|
708 | - { |
|
709 | - $where_params = isset($query_params[0]) ? $query_params[0] : array(); |
|
710 | - // if we have count make sure we don't include group by |
|
711 | - if ($count && isset($query_params['group_by'])) { |
|
712 | - unset($query_params['group_by']); |
|
713 | - } |
|
714 | - // let's add specific query_params for active_events |
|
715 | - // keep in mind this will override any sent status in the query AND any date queries. |
|
716 | - if (isset($where_params['status'])) { |
|
717 | - unset($where_params['status']); |
|
718 | - } |
|
719 | - $exclude_query = $query_params; |
|
720 | - if (isset($exclude_query[0])) { |
|
721 | - unset($exclude_query[0]); |
|
722 | - } |
|
723 | - $exclude_query[0] = array( |
|
724 | - 'Datetime.DTT_EVT_end' => array( |
|
725 | - '>', |
|
726 | - EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
727 | - ), |
|
728 | - ); |
|
729 | - // first get all events that have datetimes where its not expired. |
|
730 | - $event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Event_CPT.ID'); |
|
731 | - $event_ids = array_keys($event_ids); |
|
732 | - // if we have any additional query_params, let's add them to the 'AND' condition |
|
733 | - $and_condition = array( |
|
734 | - 'Datetime.DTT_EVT_end' => array('<', EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')), |
|
735 | - 'EVT_ID' => array('NOT IN', $event_ids), |
|
736 | - ); |
|
737 | - if (isset($where_params['OR'])) { |
|
738 | - $and_condition['OR'] = $where_params['OR']; |
|
739 | - unset($where_params['OR']); |
|
740 | - } |
|
741 | - if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
742 | - $and_condition['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end']; |
|
743 | - unset($where_params['Datetime.DTT_EVT_end']); |
|
744 | - } |
|
745 | - if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
746 | - $and_condition['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start']; |
|
747 | - unset($where_params['Datetime.DTT_EVT_start']); |
|
748 | - } |
|
749 | - // merge remaining $where params with the and conditions. |
|
750 | - $where_params['AND'] = array_merge($and_condition, $where_params); |
|
751 | - $query_params[0] = $where_params; |
|
752 | - // don't use $query_params with count() |
|
753 | - // because we don't want to include additional query clauses like "GROUP BY" |
|
754 | - return $count |
|
755 | - ? $this->count(array($where_params), 'EVT_ID', true) |
|
756 | - : $this->get_all($query_params); |
|
757 | - } |
|
758 | - |
|
759 | - |
|
760 | - |
|
761 | - /** |
|
762 | - * This basically just returns the events that do not have the publish status. |
|
763 | - * |
|
764 | - * @param array $query_params An array of query params to further filter on |
|
765 | - * (note that status will be overwritten) |
|
766 | - * @param boolean $count whether to return the count or not (default FALSE) |
|
767 | - * @return EE_Event[]|int |
|
768 | - * @throws \EE_Error |
|
769 | - */ |
|
770 | - public function get_inactive_events($query_params, $count = false) |
|
771 | - { |
|
772 | - $where_params = isset($query_params[0]) ? $query_params[0] : array(); |
|
773 | - // let's add in specific query_params for inactive events. |
|
774 | - if (isset($where_params['status'])) { |
|
775 | - unset($where_params['status']); |
|
776 | - } |
|
777 | - // if we have count make sure we don't include group by |
|
778 | - if ($count && isset($query_params['group_by'])) { |
|
779 | - unset($query_params['group_by']); |
|
780 | - } |
|
781 | - // if we have any additional query_params, let's add them to the 'AND' condition |
|
782 | - $where_params['AND']['status'] = array('!=', 'publish'); |
|
783 | - if (isset($where_params['OR'])) { |
|
784 | - $where_params['AND']['OR'] = $where_params['OR']; |
|
785 | - unset($where_params['OR']); |
|
786 | - } |
|
787 | - if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
788 | - $where_params['AND']['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end']; |
|
789 | - unset($where_params['Datetime.DTT_EVT_end']); |
|
790 | - } |
|
791 | - if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
792 | - $where_params['AND']['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start']; |
|
793 | - unset($where_params['Datetime.DTT_EVT_start']); |
|
794 | - } |
|
795 | - $query_params[0] = $where_params; |
|
796 | - // don't use $query_params with count() |
|
797 | - // because we don't want to include additional query clauses like "GROUP BY" |
|
798 | - return $count |
|
799 | - ? $this->count(array($where_params), 'EVT_ID', true) |
|
800 | - : $this->get_all($query_params); |
|
801 | - } |
|
802 | - |
|
803 | - |
|
804 | - |
|
805 | - /** |
|
806 | - * This is just injecting into the parent add_relationship_to so we do special handling on price relationships |
|
807 | - * because we don't want to override any existing global default prices but instead insert NEW prices that get |
|
808 | - * attached to the event. See parent for param descriptions |
|
809 | - * |
|
810 | - * @param $id_or_obj |
|
811 | - * @param $other_model_id_or_obj |
|
812 | - * @param string $relationName |
|
813 | - * @param array $where_query |
|
814 | - * @return EE_Base_Class |
|
815 | - * @throws EE_Error |
|
816 | - */ |
|
817 | - public function add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array()) |
|
818 | - { |
|
819 | - if ($relationName === 'Price') { |
|
820 | - // let's get the PRC object for the given ID to make sure that we aren't dealing with a default |
|
821 | - $prc_chk = $this->get_related_model_obj($relationName)->ensure_is_obj($other_model_id_or_obj); |
|
822 | - // if EVT_ID = 0, then this is a default |
|
823 | - if ((int) $prc_chk->get('EVT_ID') === 0) { |
|
824 | - // let's set the prc_id as 0 so we force an insert on the add_relation_to carried out by relation |
|
825 | - $prc_chk->set('PRC_ID', 0); |
|
826 | - } |
|
827 | - // run parent |
|
828 | - return parent::add_relationship_to($id_or_obj, $prc_chk, $relationName, $where_query); |
|
829 | - } |
|
830 | - // otherwise carry on as normal |
|
831 | - return parent::add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query); |
|
832 | - } |
|
833 | - |
|
834 | - |
|
835 | - |
|
836 | - /******************** DEPRECATED METHODS ********************/ |
|
837 | - |
|
838 | - |
|
839 | - |
|
840 | - /** |
|
841 | - * _get_question_target_db_column |
|
842 | - * |
|
843 | - * @deprecated as of 4.8.32.rc.001. Instead consider using |
|
844 | - * EE_Registration_Custom_Questions_Form located in |
|
845 | - * admin_pages/registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php |
|
846 | - * @access public |
|
847 | - * @param EE_Registration $registration (so existing answers for registration are included) |
|
848 | - * @param int $EVT_ID so all question groups are included for event (not just answers from |
|
849 | - * registration). |
|
850 | - * @throws EE_Error |
|
851 | - * @return array |
|
852 | - */ |
|
853 | - public function assemble_array_of_groups_questions_and_options(EE_Registration $registration, $EVT_ID = 0) |
|
854 | - { |
|
855 | - if (empty($EVT_ID)) { |
|
856 | - throw new EE_Error(__( |
|
857 | - 'An error occurred. No EVT_ID is included. Needed to know which question groups to retrieve.', |
|
858 | - 'event_espresso' |
|
859 | - )); |
|
860 | - } |
|
861 | - $questions = array(); |
|
862 | - // get all question groups for event |
|
863 | - $qgs = $this->get_question_groups_for_event($EVT_ID, $registration); |
|
864 | - if (! empty($qgs)) { |
|
865 | - foreach ($qgs as $qg) { |
|
866 | - $qsts = $qg->questions(); |
|
867 | - $questions[ $qg->ID() ] = $qg->model_field_array(); |
|
868 | - $questions[ $qg->ID() ]['QSG_questions'] = array(); |
|
869 | - foreach ($qsts as $qst) { |
|
870 | - if ($qst->is_system_question()) { |
|
871 | - continue; |
|
872 | - } |
|
873 | - $answer = EEM_Answer::instance()->get_one(array( |
|
874 | - array( |
|
875 | - 'QST_ID' => $qst->ID(), |
|
876 | - 'REG_ID' => $registration->ID(), |
|
877 | - ), |
|
878 | - )); |
|
879 | - $answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object(); |
|
880 | - $qst_name = $qstn_id = $qst->ID(); |
|
881 | - $ans_id = $answer->ID(); |
|
882 | - $qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']'; |
|
883 | - $input_name = ''; |
|
884 | - $input_id = sanitize_key($qst->display_text()); |
|
885 | - $input_class = ''; |
|
886 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array(); |
|
887 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn' |
|
888 | - . $input_name |
|
889 | - . $qst_name; |
|
890 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id; |
|
891 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class; |
|
892 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array(); |
|
893 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst; |
|
894 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer; |
|
895 | - // leave responses as-is, don't convert stuff into html entities please! |
|
896 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false; |
|
897 | - if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') { |
|
898 | - $QSOs = $qst->options(true, $answer->value()); |
|
899 | - if (is_array($QSOs)) { |
|
900 | - foreach ($QSOs as $QSO_ID => $QSO) { |
|
901 | - $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array(); |
|
902 | - } |
|
903 | - } |
|
904 | - } |
|
905 | - } |
|
906 | - } |
|
907 | - } |
|
908 | - return $questions; |
|
909 | - } |
|
910 | - |
|
911 | - |
|
912 | - /** |
|
913 | - * @param mixed $cols_n_values either an array of where each key is the name of a field, and the value is its value |
|
914 | - * or an stdClass where each property is the name of a column, |
|
915 | - * @return EE_Base_Class |
|
916 | - * @throws \EE_Error |
|
917 | - */ |
|
918 | - public function instantiate_class_from_array_or_object($cols_n_values) |
|
919 | - { |
|
920 | - $classInstance = parent::instantiate_class_from_array_or_object($cols_n_values); |
|
921 | - if ($classInstance instanceof EE_Event) { |
|
922 | - // events have their timezone defined in the DB, so use it immediately |
|
923 | - $this->set_timezone($classInstance->get_timezone()); |
|
924 | - } |
|
925 | - return $classInstance; |
|
926 | - } |
|
18 | + /** |
|
19 | + * constant used by status(), indicating that no more tickets can be purchased for any of the datetimes for the |
|
20 | + * event |
|
21 | + */ |
|
22 | + const sold_out = 'sold_out'; |
|
23 | + |
|
24 | + /** |
|
25 | + * constant used by status(), indicating that upcoming event dates have been postponed (may be pushed to a later |
|
26 | + * date) |
|
27 | + */ |
|
28 | + const postponed = 'postponed'; |
|
29 | + |
|
30 | + /** |
|
31 | + * constant used by status(), indicating that the event will no longer occur |
|
32 | + */ |
|
33 | + const cancelled = 'cancelled'; |
|
34 | + |
|
35 | + |
|
36 | + /** |
|
37 | + * @var string |
|
38 | + */ |
|
39 | + protected static $_default_reg_status; |
|
40 | + |
|
41 | + |
|
42 | + /** |
|
43 | + * This is the default for the additional limit field. |
|
44 | + * @var int |
|
45 | + */ |
|
46 | + protected static $_default_additional_limit = 10; |
|
47 | + |
|
48 | + |
|
49 | + /** |
|
50 | + * private instance of the Event object |
|
51 | + * |
|
52 | + * @var EEM_Event |
|
53 | + */ |
|
54 | + protected static $_instance; |
|
55 | + |
|
56 | + |
|
57 | + |
|
58 | + |
|
59 | + /** |
|
60 | + * Adds a relationship to Term_Taxonomy for each CPT_Base |
|
61 | + * |
|
62 | + * @param string $timezone |
|
63 | + * @throws \EE_Error |
|
64 | + */ |
|
65 | + protected function __construct($timezone = null) |
|
66 | + { |
|
67 | + EE_Registry::instance()->load_model('Registration'); |
|
68 | + $this->singular_item = esc_html__('Event', 'event_espresso'); |
|
69 | + $this->plural_item = esc_html__('Events', 'event_espresso'); |
|
70 | + // to remove Cancelled events from the frontend, copy the following filter to your functions.php file |
|
71 | + // add_filter( 'AFEE__EEM_Event__construct___custom_stati__cancelled__Public', '__return_false' ); |
|
72 | + // to remove Postponed events from the frontend, copy the following filter to your functions.php file |
|
73 | + // add_filter( 'AFEE__EEM_Event__construct___custom_stati__postponed__Public', '__return_false' ); |
|
74 | + // to remove Sold Out events from the frontend, copy the following filter to your functions.php file |
|
75 | + // add_filter( 'AFEE__EEM_Event__construct___custom_stati__sold_out__Public', '__return_false' ); |
|
76 | + $this->_custom_stati = apply_filters( |
|
77 | + 'AFEE__EEM_Event__construct___custom_stati', |
|
78 | + array( |
|
79 | + EEM_Event::cancelled => array( |
|
80 | + 'label' => esc_html__('Cancelled', 'event_espresso'), |
|
81 | + 'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__cancelled__Public', true), |
|
82 | + ), |
|
83 | + EEM_Event::postponed => array( |
|
84 | + 'label' => esc_html__('Postponed', 'event_espresso'), |
|
85 | + 'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__postponed__Public', true), |
|
86 | + ), |
|
87 | + EEM_Event::sold_out => array( |
|
88 | + 'label' => esc_html__('Sold Out', 'event_espresso'), |
|
89 | + 'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__sold_out__Public', true), |
|
90 | + ), |
|
91 | + ) |
|
92 | + ); |
|
93 | + self::$_default_reg_status = empty(self::$_default_reg_status) ? EEM_Registration::status_id_pending_payment |
|
94 | + : self::$_default_reg_status; |
|
95 | + $this->_tables = array( |
|
96 | + 'Event_CPT' => new EE_Primary_Table('posts', 'ID'), |
|
97 | + 'Event_Meta' => new EE_Secondary_Table('esp_event_meta', 'EVTM_ID', 'EVT_ID'), |
|
98 | + ); |
|
99 | + $this->_fields = array( |
|
100 | + 'Event_CPT' => array( |
|
101 | + 'EVT_ID' => new EE_Primary_Key_Int_Field( |
|
102 | + 'ID', |
|
103 | + esc_html__('Post ID for Event', 'event_espresso') |
|
104 | + ), |
|
105 | + 'EVT_name' => new EE_Plain_Text_Field( |
|
106 | + 'post_title', |
|
107 | + esc_html__('Event Name', 'event_espresso'), |
|
108 | + false, |
|
109 | + '' |
|
110 | + ), |
|
111 | + 'EVT_desc' => new EE_Post_Content_Field( |
|
112 | + 'post_content', |
|
113 | + esc_html__('Event Description', 'event_espresso'), |
|
114 | + false, |
|
115 | + '' |
|
116 | + ), |
|
117 | + 'EVT_slug' => new EE_Slug_Field( |
|
118 | + 'post_name', |
|
119 | + esc_html__('Event Slug', 'event_espresso'), |
|
120 | + false, |
|
121 | + '' |
|
122 | + ), |
|
123 | + 'EVT_created' => new EE_Datetime_Field( |
|
124 | + 'post_date', |
|
125 | + esc_html__('Date/Time Event Created', 'event_espresso'), |
|
126 | + false, |
|
127 | + EE_Datetime_Field::now |
|
128 | + ), |
|
129 | + 'EVT_short_desc' => new EE_Simple_HTML_Field( |
|
130 | + 'post_excerpt', |
|
131 | + esc_html__('Event Short Description', 'event_espresso'), |
|
132 | + false, |
|
133 | + '' |
|
134 | + ), |
|
135 | + 'EVT_modified' => new EE_Datetime_Field( |
|
136 | + 'post_modified', |
|
137 | + esc_html__('Date/Time Event Modified', 'event_espresso'), |
|
138 | + false, |
|
139 | + EE_Datetime_Field::now |
|
140 | + ), |
|
141 | + 'EVT_wp_user' => new EE_WP_User_Field( |
|
142 | + 'post_author', |
|
143 | + esc_html__('Event Creator ID', 'event_espresso'), |
|
144 | + false |
|
145 | + ), |
|
146 | + 'parent' => new EE_Integer_Field( |
|
147 | + 'post_parent', |
|
148 | + esc_html__('Event Parent ID', 'event_espresso'), |
|
149 | + false, |
|
150 | + 0 |
|
151 | + ), |
|
152 | + 'EVT_order' => new EE_Integer_Field( |
|
153 | + 'menu_order', |
|
154 | + esc_html__('Event Menu Order', 'event_espresso'), |
|
155 | + false, |
|
156 | + 1 |
|
157 | + ), |
|
158 | + 'post_type' => new EE_WP_Post_Type_Field('espresso_events'), |
|
159 | + // EE_Plain_Text_Field( 'post_type', esc_html__( 'Event Post Type', 'event_espresso' ), FALSE, 'espresso_events' ), |
|
160 | + 'status' => new EE_WP_Post_Status_Field( |
|
161 | + 'post_status', |
|
162 | + esc_html__('Event Status', 'event_espresso'), |
|
163 | + false, |
|
164 | + 'draft', |
|
165 | + $this->_custom_stati |
|
166 | + ), |
|
167 | + 'password' => new EE_Password_Field( |
|
168 | + 'post_password', |
|
169 | + __('Password', 'event_espresso'), |
|
170 | + false, |
|
171 | + '', |
|
172 | + array( |
|
173 | + 'EVT_desc', |
|
174 | + 'EVT_short_desc', |
|
175 | + 'EVT_display_desc', |
|
176 | + 'EVT_display_ticket_selector', |
|
177 | + 'EVT_visible_on', |
|
178 | + 'EVT_additional_limit', |
|
179 | + 'EVT_default_registration_status', |
|
180 | + 'EVT_member_only', |
|
181 | + 'EVT_phone', |
|
182 | + 'EVT_allow_overflow', |
|
183 | + 'EVT_timezone_string', |
|
184 | + 'EVT_external_URL', |
|
185 | + 'EVT_donations' |
|
186 | + ) |
|
187 | + ) |
|
188 | + ), |
|
189 | + 'Event_Meta' => array( |
|
190 | + 'EVTM_ID' => new EE_DB_Only_Float_Field( |
|
191 | + 'EVTM_ID', |
|
192 | + esc_html__('Event Meta Row ID', 'event_espresso'), |
|
193 | + false |
|
194 | + ), |
|
195 | + 'EVT_ID_fk' => new EE_DB_Only_Int_Field( |
|
196 | + 'EVT_ID', |
|
197 | + esc_html__('Foreign key to Event ID from Event Meta table', 'event_espresso'), |
|
198 | + false |
|
199 | + ), |
|
200 | + 'EVT_display_desc' => new EE_Boolean_Field( |
|
201 | + 'EVT_display_desc', |
|
202 | + esc_html__('Display Description Flag', 'event_espresso'), |
|
203 | + false, |
|
204 | + true |
|
205 | + ), |
|
206 | + 'EVT_display_ticket_selector' => new EE_Boolean_Field( |
|
207 | + 'EVT_display_ticket_selector', |
|
208 | + esc_html__('Display Ticket Selector Flag', 'event_espresso'), |
|
209 | + false, |
|
210 | + true |
|
211 | + ), |
|
212 | + 'EVT_visible_on' => new EE_Datetime_Field( |
|
213 | + 'EVT_visible_on', |
|
214 | + esc_html__('Event Visible Date', 'event_espresso'), |
|
215 | + true, |
|
216 | + EE_Datetime_Field::now |
|
217 | + ), |
|
218 | + 'EVT_additional_limit' => new EE_Integer_Field( |
|
219 | + 'EVT_additional_limit', |
|
220 | + esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso'), |
|
221 | + true, |
|
222 | + self::$_default_additional_limit |
|
223 | + ), |
|
224 | + 'EVT_default_registration_status' => new EE_Enum_Text_Field( |
|
225 | + 'EVT_default_registration_status', |
|
226 | + esc_html__('Default Registration Status on this Event', 'event_espresso'), |
|
227 | + false, |
|
228 | + EEM_Event::$_default_reg_status, |
|
229 | + EEM_Registration::reg_status_array() |
|
230 | + ), |
|
231 | + 'EVT_member_only' => new EE_Boolean_Field( |
|
232 | + 'EVT_member_only', |
|
233 | + esc_html__('Member-Only Event Flag', 'event_espresso'), |
|
234 | + false, |
|
235 | + false |
|
236 | + ), |
|
237 | + 'EVT_phone' => new EE_Plain_Text_Field( |
|
238 | + 'EVT_phone', |
|
239 | + esc_html__('Event Phone Number', 'event_espresso'), |
|
240 | + false, |
|
241 | + '' |
|
242 | + ), |
|
243 | + 'EVT_allow_overflow' => new EE_Boolean_Field( |
|
244 | + 'EVT_allow_overflow', |
|
245 | + esc_html__('Allow Overflow on Event', 'event_espresso'), |
|
246 | + false, |
|
247 | + false |
|
248 | + ), |
|
249 | + 'EVT_timezone_string' => new EE_Plain_Text_Field( |
|
250 | + 'EVT_timezone_string', |
|
251 | + esc_html__('Timezone (name) for Event times', 'event_espresso'), |
|
252 | + false, |
|
253 | + '' |
|
254 | + ), |
|
255 | + 'EVT_external_URL' => new EE_Plain_Text_Field( |
|
256 | + 'EVT_external_URL', |
|
257 | + esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso'), |
|
258 | + true |
|
259 | + ), |
|
260 | + 'EVT_donations' => new EE_Boolean_Field( |
|
261 | + 'EVT_donations', |
|
262 | + esc_html__('Accept Donations?', 'event_espresso'), |
|
263 | + false, |
|
264 | + false |
|
265 | + ), |
|
266 | + ), |
|
267 | + ); |
|
268 | + $this->_model_relations = array( |
|
269 | + 'Registration' => new EE_Has_Many_Relation(), |
|
270 | + 'Datetime' => new EE_Has_Many_Relation(), |
|
271 | + 'Question_Group' => new EE_HABTM_Relation('Event_Question_Group'), |
|
272 | + 'Event_Question_Group' => new EE_Has_Many_Relation(), |
|
273 | + 'Venue' => new EE_HABTM_Relation('Event_Venue'), |
|
274 | + 'Term_Relationship' => new EE_Has_Many_Relation(), |
|
275 | + 'Term_Taxonomy' => new EE_HABTM_Relation('Term_Relationship'), |
|
276 | + 'Message_Template_Group' => new EE_HABTM_Relation('Event_Message_Template'), |
|
277 | + 'Attendee' => new EE_HABTM_Relation('Registration'), |
|
278 | + 'WP_User' => new EE_Belongs_To_Relation(), |
|
279 | + ); |
|
280 | + // this model is generally available for reading |
|
281 | + $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public(); |
|
282 | + $this->model_chain_to_password = ''; |
|
283 | + parent::__construct($timezone); |
|
284 | + } |
|
285 | + |
|
286 | + |
|
287 | + |
|
288 | + /** |
|
289 | + * @param string $default_reg_status |
|
290 | + */ |
|
291 | + public static function set_default_reg_status($default_reg_status) |
|
292 | + { |
|
293 | + self::$_default_reg_status = $default_reg_status; |
|
294 | + // if EEM_Event has already been instantiated, |
|
295 | + // then we need to reset the `EVT_default_reg_status` field to use the new default. |
|
296 | + if (self::$_instance instanceof EEM_Event) { |
|
297 | + $default_reg_status = new EE_Enum_Text_Field( |
|
298 | + 'EVT_default_registration_status', |
|
299 | + esc_html__('Default Registration Status on this Event', 'event_espresso'), |
|
300 | + false, |
|
301 | + $default_reg_status, |
|
302 | + EEM_Registration::reg_status_array() |
|
303 | + ); |
|
304 | + $default_reg_status->_construct_finalize( |
|
305 | + 'Event_Meta', |
|
306 | + 'EVT_default_registration_status', |
|
307 | + 'EEM_Event' |
|
308 | + ); |
|
309 | + self::$_instance->_fields['Event_Meta']['EVT_default_registration_status'] = $default_reg_status; |
|
310 | + } |
|
311 | + } |
|
312 | + |
|
313 | + |
|
314 | + /** |
|
315 | + * Used to override the default for the additional limit field. |
|
316 | + * @param $additional_limit |
|
317 | + */ |
|
318 | + public static function set_default_additional_limit($additional_limit) |
|
319 | + { |
|
320 | + self::$_default_additional_limit = (int) $additional_limit; |
|
321 | + if (self::$_instance instanceof EEM_Event) { |
|
322 | + self::$_instance->_fields['Event_Meta']['EVT_additional_limit'] = new EE_Integer_Field( |
|
323 | + 'EVT_additional_limit', |
|
324 | + __('Limit of Additional Registrations on Same Transaction', 'event_espresso'), |
|
325 | + true, |
|
326 | + self::$_default_additional_limit |
|
327 | + ); |
|
328 | + self::$_instance->_fields['Event_Meta']['EVT_additional_limit']->_construct_finalize( |
|
329 | + 'Event_Meta', |
|
330 | + 'EVT_additional_limit', |
|
331 | + 'EEM_Event' |
|
332 | + ); |
|
333 | + } |
|
334 | + } |
|
335 | + |
|
336 | + |
|
337 | + /** |
|
338 | + * Return what is currently set as the default additional limit for the event. |
|
339 | + * @return int |
|
340 | + */ |
|
341 | + public static function get_default_additional_limit() |
|
342 | + { |
|
343 | + return apply_filters('FHEE__EEM_Event__get_default_additional_limit', self::$_default_additional_limit); |
|
344 | + } |
|
345 | + |
|
346 | + |
|
347 | + /** |
|
348 | + * get_question_groups |
|
349 | + * |
|
350 | + * @return array |
|
351 | + * @throws \EE_Error |
|
352 | + */ |
|
353 | + public function get_all_question_groups() |
|
354 | + { |
|
355 | + return EE_Registry::instance()->load_model('Question_Group')->get_all( |
|
356 | + array( |
|
357 | + array('QSG_deleted' => false), |
|
358 | + 'order_by' => array('QSG_order' => 'ASC'), |
|
359 | + ) |
|
360 | + ); |
|
361 | + } |
|
362 | + |
|
363 | + |
|
364 | + |
|
365 | + /** |
|
366 | + * get_question_groups |
|
367 | + * |
|
368 | + * @param int $EVT_ID |
|
369 | + * @return array|bool |
|
370 | + * @throws \EE_Error |
|
371 | + */ |
|
372 | + public function get_all_event_question_groups($EVT_ID = 0) |
|
373 | + { |
|
374 | + if (! isset($EVT_ID) || ! absint($EVT_ID)) { |
|
375 | + EE_Error::add_error( |
|
376 | + esc_html__( |
|
377 | + 'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.', |
|
378 | + 'event_espresso' |
|
379 | + ), |
|
380 | + __FILE__, |
|
381 | + __FUNCTION__, |
|
382 | + __LINE__ |
|
383 | + ); |
|
384 | + return false; |
|
385 | + } |
|
386 | + return EE_Registry::instance()->load_model('Event_Question_Group')->get_all( |
|
387 | + array( |
|
388 | + array('EVT_ID' => $EVT_ID), |
|
389 | + ) |
|
390 | + ); |
|
391 | + } |
|
392 | + |
|
393 | + |
|
394 | + /** |
|
395 | + * get_question_groups |
|
396 | + * |
|
397 | + * @param int $EVT_ID |
|
398 | + * @param boolean $for_primary_attendee |
|
399 | + * @return array|bool |
|
400 | + * @throws EE_Error |
|
401 | + * @throws InvalidArgumentException |
|
402 | + * @throws ReflectionException |
|
403 | + * @throws InvalidDataTypeException |
|
404 | + * @throws InvalidInterfaceException |
|
405 | + */ |
|
406 | + public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true) |
|
407 | + { |
|
408 | + if (! isset($EVT_ID) || ! absint($EVT_ID)) { |
|
409 | + EE_Error::add_error( |
|
410 | + esc_html__( |
|
411 | + // @codingStandardsIgnoreStart |
|
412 | + 'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.', |
|
413 | + // @codingStandardsIgnoreEnd |
|
414 | + 'event_espresso' |
|
415 | + ), |
|
416 | + __FILE__, |
|
417 | + __FUNCTION__, |
|
418 | + __LINE__ |
|
419 | + ); |
|
420 | + return false; |
|
421 | + } |
|
422 | + $query_params = [ |
|
423 | + [ |
|
424 | + 'EVT_ID' => $EVT_ID, |
|
425 | + EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary_attendee) => true |
|
426 | + ] |
|
427 | + ]; |
|
428 | + if ($for_primary_attendee) { |
|
429 | + $query_params[0][] = true; |
|
430 | + } else { |
|
431 | + $query_params[0]['EQG_additional'] = true; |
|
432 | + } |
|
433 | + return EE_Registry::instance()->load_model('Event_Question_Group')->get_all($query_params); |
|
434 | + } |
|
435 | + |
|
436 | + |
|
437 | + |
|
438 | + /** |
|
439 | + * get_question_groups |
|
440 | + * |
|
441 | + * @param int $EVT_ID |
|
442 | + * @param EE_Registration $registration |
|
443 | + * @return array|bool |
|
444 | + * @throws \EE_Error |
|
445 | + */ |
|
446 | + public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration) |
|
447 | + { |
|
448 | + if (! isset($EVT_ID) || ! absint($EVT_ID)) { |
|
449 | + EE_Error::add_error( |
|
450 | + esc_html__( |
|
451 | + 'An error occurred. No Question Groups could be retrieved because an Event ID was not received.', |
|
452 | + 'event_espresso' |
|
453 | + ), |
|
454 | + __FILE__, |
|
455 | + __FUNCTION__, |
|
456 | + __LINE__ |
|
457 | + ); |
|
458 | + return false; |
|
459 | + } |
|
460 | + $where_params = array( |
|
461 | + 'Event_Question_Group.EVT_ID' => $EVT_ID, |
|
462 | + 'QSG_deleted' => false, |
|
463 | + ); |
|
464 | + if( $registration->is_primary_registrant()) { |
|
465 | + $where_params['Event_Question_Group.EQG_primary'] = true; |
|
466 | + } else { |
|
467 | + $where_params['Event_Question_Group.EQG_additional'] = true; |
|
468 | + } |
|
469 | + return EE_Registry::instance()->load_model('Question_Group')->get_all( |
|
470 | + [ |
|
471 | + $where_params, |
|
472 | + 'order_by' => ['QSG_order' => 'ASC'], |
|
473 | + ] |
|
474 | + ); |
|
475 | + } |
|
476 | + |
|
477 | + |
|
478 | + |
|
479 | + /** |
|
480 | + * get_question_target_db_column |
|
481 | + * |
|
482 | + * @param string $QSG_IDs csv list of $QSG IDs |
|
483 | + * @return array|bool |
|
484 | + * @throws \EE_Error |
|
485 | + */ |
|
486 | + public function get_questions_in_groups($QSG_IDs = '') |
|
487 | + { |
|
488 | + if (empty($QSG_IDs)) { |
|
489 | + EE_Error::add_error( |
|
490 | + esc_html__('An error occurred. No Question Group IDs were received.', 'event_espresso'), |
|
491 | + __FILE__, |
|
492 | + __FUNCTION__, |
|
493 | + __LINE__ |
|
494 | + ); |
|
495 | + return false; |
|
496 | + } |
|
497 | + return EE_Registry::instance()->load_model('Question')->get_all( |
|
498 | + array( |
|
499 | + array( |
|
500 | + 'Question_Group.QSG_ID' => array('IN', $QSG_IDs), |
|
501 | + 'QST_deleted' => false, |
|
502 | + 'QST_admin_only' => is_admin(), |
|
503 | + ), |
|
504 | + 'order_by' => 'QST_order', |
|
505 | + ) |
|
506 | + ); |
|
507 | + } |
|
508 | + |
|
509 | + |
|
510 | + |
|
511 | + /** |
|
512 | + * get_options_for_question |
|
513 | + * |
|
514 | + * @param string $QST_IDs csv list of $QST IDs |
|
515 | + * @return array|bool |
|
516 | + * @throws \EE_Error |
|
517 | + */ |
|
518 | + public function get_options_for_question($QST_IDs) |
|
519 | + { |
|
520 | + if (empty($QST_IDs)) { |
|
521 | + EE_Error::add_error( |
|
522 | + esc_html__('An error occurred. No Question IDs were received.', 'event_espresso'), |
|
523 | + __FILE__, |
|
524 | + __FUNCTION__, |
|
525 | + __LINE__ |
|
526 | + ); |
|
527 | + return false; |
|
528 | + } |
|
529 | + return EE_Registry::instance()->load_model('Question_Option')->get_all( |
|
530 | + array( |
|
531 | + array( |
|
532 | + 'Question.QST_ID' => array('IN', $QST_IDs), |
|
533 | + 'QSO_deleted' => false, |
|
534 | + ), |
|
535 | + 'order_by' => 'QSO_ID', |
|
536 | + ) |
|
537 | + ); |
|
538 | + } |
|
539 | + |
|
540 | + |
|
541 | + |
|
542 | + |
|
543 | + |
|
544 | + |
|
545 | + |
|
546 | + /** |
|
547 | + * Gets all events that are published |
|
548 | + * and have event start time earlier than now and an event end time later than now |
|
549 | + * |
|
550 | + * @param array $query_params An array of query params to further filter on |
|
551 | + * (note that status and DTT_EVT_start and DTT_EVT_end will be overridden) |
|
552 | + * @param bool $count whether to return the count or not (default FALSE) |
|
553 | + * @return EE_Event[]|int |
|
554 | + * @throws \EE_Error |
|
555 | + */ |
|
556 | + public function get_active_events($query_params, $count = false) |
|
557 | + { |
|
558 | + if (array_key_exists(0, $query_params)) { |
|
559 | + $where_params = $query_params[0]; |
|
560 | + unset($query_params[0]); |
|
561 | + } else { |
|
562 | + $where_params = array(); |
|
563 | + } |
|
564 | + // if we have count make sure we don't include group by |
|
565 | + if ($count && isset($query_params['group_by'])) { |
|
566 | + unset($query_params['group_by']); |
|
567 | + } |
|
568 | + // let's add specific query_params for active_events |
|
569 | + // keep in mind this will override any sent status in the query AND any date queries. |
|
570 | + $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out)); |
|
571 | + // if already have where params for DTT_EVT_start or DTT_EVT_end then append these conditions |
|
572 | + if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
573 | + $where_params['Datetime.DTT_EVT_start******'] = array( |
|
574 | + '<', |
|
575 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
576 | + ); |
|
577 | + } else { |
|
578 | + $where_params['Datetime.DTT_EVT_start'] = array( |
|
579 | + '<', |
|
580 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
581 | + ); |
|
582 | + } |
|
583 | + if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
584 | + $where_params['Datetime.DTT_EVT_end*****'] = array( |
|
585 | + '>', |
|
586 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
587 | + ); |
|
588 | + } else { |
|
589 | + $where_params['Datetime.DTT_EVT_end'] = array( |
|
590 | + '>', |
|
591 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
592 | + ); |
|
593 | + } |
|
594 | + $query_params[0] = $where_params; |
|
595 | + // don't use $query_params with count() |
|
596 | + // because we don't want to include additional query clauses like "GROUP BY" |
|
597 | + return $count |
|
598 | + ? $this->count(array($where_params), 'EVT_ID', true) |
|
599 | + : $this->get_all($query_params); |
|
600 | + } |
|
601 | + |
|
602 | + |
|
603 | + |
|
604 | + /** |
|
605 | + * get all events that are published and have an event start time later than now |
|
606 | + * |
|
607 | + * @param array $query_params An array of query params to further filter on |
|
608 | + * (Note that status and DTT_EVT_start will be overridden) |
|
609 | + * @param bool $count whether to return the count or not (default FALSE) |
|
610 | + * @return EE_Event[]|int |
|
611 | + * @throws \EE_Error |
|
612 | + */ |
|
613 | + public function get_upcoming_events($query_params, $count = false) |
|
614 | + { |
|
615 | + if (array_key_exists(0, $query_params)) { |
|
616 | + $where_params = $query_params[0]; |
|
617 | + unset($query_params[0]); |
|
618 | + } else { |
|
619 | + $where_params = array(); |
|
620 | + } |
|
621 | + // if we have count make sure we don't include group by |
|
622 | + if ($count && isset($query_params['group_by'])) { |
|
623 | + unset($query_params['group_by']); |
|
624 | + } |
|
625 | + // let's add specific query_params for active_events |
|
626 | + // keep in mind this will override any sent status in the query AND any date queries. |
|
627 | + $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out)); |
|
628 | + // if there are already query_params matching DTT_EVT_start then we need to modify that to add them. |
|
629 | + if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
630 | + $where_params['Datetime.DTT_EVT_start*****'] = array( |
|
631 | + '>', |
|
632 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
633 | + ); |
|
634 | + } else { |
|
635 | + $where_params['Datetime.DTT_EVT_start'] = array( |
|
636 | + '>', |
|
637 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'), |
|
638 | + ); |
|
639 | + } |
|
640 | + $query_params[0] = $where_params; |
|
641 | + // don't use $query_params with count() |
|
642 | + // because we don't want to include additional query clauses like "GROUP BY" |
|
643 | + return $count |
|
644 | + ? $this->count(array($where_params), 'EVT_ID', true) |
|
645 | + : $this->get_all($query_params); |
|
646 | + } |
|
647 | + |
|
648 | + |
|
649 | + |
|
650 | + /** |
|
651 | + * Gets all events that are published |
|
652 | + * and have an event end time later than now |
|
653 | + * |
|
654 | + * @param array $query_params An array of query params to further filter on |
|
655 | + * (note that status and DTT_EVT_end will be overridden) |
|
656 | + * @param bool $count whether to return the count or not (default FALSE) |
|
657 | + * @return EE_Event[]|int |
|
658 | + * @throws \EE_Error |
|
659 | + */ |
|
660 | + public function get_active_and_upcoming_events($query_params, $count = false) |
|
661 | + { |
|
662 | + if (array_key_exists(0, $query_params)) { |
|
663 | + $where_params = $query_params[0]; |
|
664 | + unset($query_params[0]); |
|
665 | + } else { |
|
666 | + $where_params = array(); |
|
667 | + } |
|
668 | + // if we have count make sure we don't include group by |
|
669 | + if ($count && isset($query_params['group_by'])) { |
|
670 | + unset($query_params['group_by']); |
|
671 | + } |
|
672 | + // let's add specific query_params for active_events |
|
673 | + // keep in mind this will override any sent status in the query AND any date queries. |
|
674 | + $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out)); |
|
675 | + // add where params for DTT_EVT_end |
|
676 | + if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
677 | + $where_params['Datetime.DTT_EVT_end*****'] = array( |
|
678 | + '>', |
|
679 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
680 | + ); |
|
681 | + } else { |
|
682 | + $where_params['Datetime.DTT_EVT_end'] = array( |
|
683 | + '>', |
|
684 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
685 | + ); |
|
686 | + } |
|
687 | + $query_params[0] = $where_params; |
|
688 | + // don't use $query_params with count() |
|
689 | + // because we don't want to include additional query clauses like "GROUP BY" |
|
690 | + return $count |
|
691 | + ? $this->count(array($where_params), 'EVT_ID', true) |
|
692 | + : $this->get_all($query_params); |
|
693 | + } |
|
694 | + |
|
695 | + |
|
696 | + |
|
697 | + /** |
|
698 | + * This only returns events that are expired. |
|
699 | + * They may still be published but all their datetimes have expired. |
|
700 | + * |
|
701 | + * @param array $query_params An array of query params to further filter on |
|
702 | + * (note that status and DTT_EVT_end will be overridden) |
|
703 | + * @param bool $count whether to return the count or not (default FALSE) |
|
704 | + * @return EE_Event[]|int |
|
705 | + * @throws \EE_Error |
|
706 | + */ |
|
707 | + public function get_expired_events($query_params, $count = false) |
|
708 | + { |
|
709 | + $where_params = isset($query_params[0]) ? $query_params[0] : array(); |
|
710 | + // if we have count make sure we don't include group by |
|
711 | + if ($count && isset($query_params['group_by'])) { |
|
712 | + unset($query_params['group_by']); |
|
713 | + } |
|
714 | + // let's add specific query_params for active_events |
|
715 | + // keep in mind this will override any sent status in the query AND any date queries. |
|
716 | + if (isset($where_params['status'])) { |
|
717 | + unset($where_params['status']); |
|
718 | + } |
|
719 | + $exclude_query = $query_params; |
|
720 | + if (isset($exclude_query[0])) { |
|
721 | + unset($exclude_query[0]); |
|
722 | + } |
|
723 | + $exclude_query[0] = array( |
|
724 | + 'Datetime.DTT_EVT_end' => array( |
|
725 | + '>', |
|
726 | + EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'), |
|
727 | + ), |
|
728 | + ); |
|
729 | + // first get all events that have datetimes where its not expired. |
|
730 | + $event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Event_CPT.ID'); |
|
731 | + $event_ids = array_keys($event_ids); |
|
732 | + // if we have any additional query_params, let's add them to the 'AND' condition |
|
733 | + $and_condition = array( |
|
734 | + 'Datetime.DTT_EVT_end' => array('<', EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')), |
|
735 | + 'EVT_ID' => array('NOT IN', $event_ids), |
|
736 | + ); |
|
737 | + if (isset($where_params['OR'])) { |
|
738 | + $and_condition['OR'] = $where_params['OR']; |
|
739 | + unset($where_params['OR']); |
|
740 | + } |
|
741 | + if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
742 | + $and_condition['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end']; |
|
743 | + unset($where_params['Datetime.DTT_EVT_end']); |
|
744 | + } |
|
745 | + if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
746 | + $and_condition['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start']; |
|
747 | + unset($where_params['Datetime.DTT_EVT_start']); |
|
748 | + } |
|
749 | + // merge remaining $where params with the and conditions. |
|
750 | + $where_params['AND'] = array_merge($and_condition, $where_params); |
|
751 | + $query_params[0] = $where_params; |
|
752 | + // don't use $query_params with count() |
|
753 | + // because we don't want to include additional query clauses like "GROUP BY" |
|
754 | + return $count |
|
755 | + ? $this->count(array($where_params), 'EVT_ID', true) |
|
756 | + : $this->get_all($query_params); |
|
757 | + } |
|
758 | + |
|
759 | + |
|
760 | + |
|
761 | + /** |
|
762 | + * This basically just returns the events that do not have the publish status. |
|
763 | + * |
|
764 | + * @param array $query_params An array of query params to further filter on |
|
765 | + * (note that status will be overwritten) |
|
766 | + * @param boolean $count whether to return the count or not (default FALSE) |
|
767 | + * @return EE_Event[]|int |
|
768 | + * @throws \EE_Error |
|
769 | + */ |
|
770 | + public function get_inactive_events($query_params, $count = false) |
|
771 | + { |
|
772 | + $where_params = isset($query_params[0]) ? $query_params[0] : array(); |
|
773 | + // let's add in specific query_params for inactive events. |
|
774 | + if (isset($where_params['status'])) { |
|
775 | + unset($where_params['status']); |
|
776 | + } |
|
777 | + // if we have count make sure we don't include group by |
|
778 | + if ($count && isset($query_params['group_by'])) { |
|
779 | + unset($query_params['group_by']); |
|
780 | + } |
|
781 | + // if we have any additional query_params, let's add them to the 'AND' condition |
|
782 | + $where_params['AND']['status'] = array('!=', 'publish'); |
|
783 | + if (isset($where_params['OR'])) { |
|
784 | + $where_params['AND']['OR'] = $where_params['OR']; |
|
785 | + unset($where_params['OR']); |
|
786 | + } |
|
787 | + if (isset($where_params['Datetime.DTT_EVT_end'])) { |
|
788 | + $where_params['AND']['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end']; |
|
789 | + unset($where_params['Datetime.DTT_EVT_end']); |
|
790 | + } |
|
791 | + if (isset($where_params['Datetime.DTT_EVT_start'])) { |
|
792 | + $where_params['AND']['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start']; |
|
793 | + unset($where_params['Datetime.DTT_EVT_start']); |
|
794 | + } |
|
795 | + $query_params[0] = $where_params; |
|
796 | + // don't use $query_params with count() |
|
797 | + // because we don't want to include additional query clauses like "GROUP BY" |
|
798 | + return $count |
|
799 | + ? $this->count(array($where_params), 'EVT_ID', true) |
|
800 | + : $this->get_all($query_params); |
|
801 | + } |
|
802 | + |
|
803 | + |
|
804 | + |
|
805 | + /** |
|
806 | + * This is just injecting into the parent add_relationship_to so we do special handling on price relationships |
|
807 | + * because we don't want to override any existing global default prices but instead insert NEW prices that get |
|
808 | + * attached to the event. See parent for param descriptions |
|
809 | + * |
|
810 | + * @param $id_or_obj |
|
811 | + * @param $other_model_id_or_obj |
|
812 | + * @param string $relationName |
|
813 | + * @param array $where_query |
|
814 | + * @return EE_Base_Class |
|
815 | + * @throws EE_Error |
|
816 | + */ |
|
817 | + public function add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array()) |
|
818 | + { |
|
819 | + if ($relationName === 'Price') { |
|
820 | + // let's get the PRC object for the given ID to make sure that we aren't dealing with a default |
|
821 | + $prc_chk = $this->get_related_model_obj($relationName)->ensure_is_obj($other_model_id_or_obj); |
|
822 | + // if EVT_ID = 0, then this is a default |
|
823 | + if ((int) $prc_chk->get('EVT_ID') === 0) { |
|
824 | + // let's set the prc_id as 0 so we force an insert on the add_relation_to carried out by relation |
|
825 | + $prc_chk->set('PRC_ID', 0); |
|
826 | + } |
|
827 | + // run parent |
|
828 | + return parent::add_relationship_to($id_or_obj, $prc_chk, $relationName, $where_query); |
|
829 | + } |
|
830 | + // otherwise carry on as normal |
|
831 | + return parent::add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query); |
|
832 | + } |
|
833 | + |
|
834 | + |
|
835 | + |
|
836 | + /******************** DEPRECATED METHODS ********************/ |
|
837 | + |
|
838 | + |
|
839 | + |
|
840 | + /** |
|
841 | + * _get_question_target_db_column |
|
842 | + * |
|
843 | + * @deprecated as of 4.8.32.rc.001. Instead consider using |
|
844 | + * EE_Registration_Custom_Questions_Form located in |
|
845 | + * admin_pages/registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php |
|
846 | + * @access public |
|
847 | + * @param EE_Registration $registration (so existing answers for registration are included) |
|
848 | + * @param int $EVT_ID so all question groups are included for event (not just answers from |
|
849 | + * registration). |
|
850 | + * @throws EE_Error |
|
851 | + * @return array |
|
852 | + */ |
|
853 | + public function assemble_array_of_groups_questions_and_options(EE_Registration $registration, $EVT_ID = 0) |
|
854 | + { |
|
855 | + if (empty($EVT_ID)) { |
|
856 | + throw new EE_Error(__( |
|
857 | + 'An error occurred. No EVT_ID is included. Needed to know which question groups to retrieve.', |
|
858 | + 'event_espresso' |
|
859 | + )); |
|
860 | + } |
|
861 | + $questions = array(); |
|
862 | + // get all question groups for event |
|
863 | + $qgs = $this->get_question_groups_for_event($EVT_ID, $registration); |
|
864 | + if (! empty($qgs)) { |
|
865 | + foreach ($qgs as $qg) { |
|
866 | + $qsts = $qg->questions(); |
|
867 | + $questions[ $qg->ID() ] = $qg->model_field_array(); |
|
868 | + $questions[ $qg->ID() ]['QSG_questions'] = array(); |
|
869 | + foreach ($qsts as $qst) { |
|
870 | + if ($qst->is_system_question()) { |
|
871 | + continue; |
|
872 | + } |
|
873 | + $answer = EEM_Answer::instance()->get_one(array( |
|
874 | + array( |
|
875 | + 'QST_ID' => $qst->ID(), |
|
876 | + 'REG_ID' => $registration->ID(), |
|
877 | + ), |
|
878 | + )); |
|
879 | + $answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object(); |
|
880 | + $qst_name = $qstn_id = $qst->ID(); |
|
881 | + $ans_id = $answer->ID(); |
|
882 | + $qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']'; |
|
883 | + $input_name = ''; |
|
884 | + $input_id = sanitize_key($qst->display_text()); |
|
885 | + $input_class = ''; |
|
886 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array(); |
|
887 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn' |
|
888 | + . $input_name |
|
889 | + . $qst_name; |
|
890 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id; |
|
891 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class; |
|
892 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array(); |
|
893 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst; |
|
894 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer; |
|
895 | + // leave responses as-is, don't convert stuff into html entities please! |
|
896 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false; |
|
897 | + if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') { |
|
898 | + $QSOs = $qst->options(true, $answer->value()); |
|
899 | + if (is_array($QSOs)) { |
|
900 | + foreach ($QSOs as $QSO_ID => $QSO) { |
|
901 | + $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array(); |
|
902 | + } |
|
903 | + } |
|
904 | + } |
|
905 | + } |
|
906 | + } |
|
907 | + } |
|
908 | + return $questions; |
|
909 | + } |
|
910 | + |
|
911 | + |
|
912 | + /** |
|
913 | + * @param mixed $cols_n_values either an array of where each key is the name of a field, and the value is its value |
|
914 | + * or an stdClass where each property is the name of a column, |
|
915 | + * @return EE_Base_Class |
|
916 | + * @throws \EE_Error |
|
917 | + */ |
|
918 | + public function instantiate_class_from_array_or_object($cols_n_values) |
|
919 | + { |
|
920 | + $classInstance = parent::instantiate_class_from_array_or_object($cols_n_values); |
|
921 | + if ($classInstance instanceof EE_Event) { |
|
922 | + // events have their timezone defined in the DB, so use it immediately |
|
923 | + $this->set_timezone($classInstance->get_timezone()); |
|
924 | + } |
|
925 | + return $classInstance; |
|
926 | + } |
|
927 | 927 | } |
@@ -7,71 +7,71 @@ |
||
7 | 7 | */ |
8 | 8 | class EEM_Event_Question_Group extends EEM_Base |
9 | 9 | { |
10 | - /** |
|
11 | - * Name of the field indicating an event should use the question group for the primary attendee |
|
12 | - */ |
|
13 | - const PRIMARY = 'EQG_primary'; |
|
10 | + /** |
|
11 | + * Name of the field indicating an event should use the question group for the primary attendee |
|
12 | + */ |
|
13 | + const PRIMARY = 'EQG_primary'; |
|
14 | 14 | |
15 | - /** |
|
16 | - * Name of hte field indicating an event should use the question group for additional attendees |
|
17 | - */ |
|
18 | - const ADDITIONAL = 'EQG_additional'; |
|
15 | + /** |
|
16 | + * Name of hte field indicating an event should use the question group for additional attendees |
|
17 | + */ |
|
18 | + const ADDITIONAL = 'EQG_additional'; |
|
19 | 19 | |
20 | - // private instance of the Event_Question_Group object |
|
21 | - protected static $_instance = null; |
|
20 | + // private instance of the Event_Question_Group object |
|
21 | + protected static $_instance = null; |
|
22 | 22 | |
23 | - protected function __construct($timezone = null) |
|
24 | - { |
|
25 | - $this->singular_item = __('Event to Question Group Link', 'event_espresso'); |
|
26 | - $this->plural_item = __('Event to Question Group Links', 'event_espresso'); |
|
27 | - $this->_tables = array( |
|
28 | - 'Event_Question_Group'=>new EE_Primary_Table('esp_event_question_group', 'EQG_ID') |
|
29 | - ); |
|
30 | - $this->_fields = array( |
|
31 | - 'Event_Question_Group'=>array( |
|
32 | - 'EQG_ID'=>new EE_Primary_Key_Int_Field('EQG_ID', __('Event to Question Group Link ID', 'event_espresso')), |
|
33 | - 'EVT_ID'=>new EE_Foreign_Key_Int_Field('EVT_ID', __('Event ID', 'event_espresso'), false, 0, 'Event'), |
|
34 | - 'QSG_ID'=>new EE_Foreign_Key_Int_Field('QSG_ID', __('Question Group Id', 'event_espresso'), false, 0, 'Question_Group'), |
|
35 | - 'EQG_primary'=>new EE_Boolean_Field('EQG_primary', __('Flag indicating question is only for primary attendees', 'event_espresso'), false, false), |
|
36 | - 'EQG_additional'=>new EE_Boolean_Field('EQG_additional', __('Flag indicating question is only for additional attendees', 'event_espresso'), false, false) |
|
37 | - ) |
|
38 | - ); |
|
39 | - $this->_model_relations = array( |
|
40 | - 'Event'=>new EE_Belongs_To_Relation(), |
|
41 | - 'Question_Group'=>new EE_Belongs_To_Relation() |
|
42 | - ); |
|
43 | - // this model is generally available for reading |
|
44 | - $path_to_event = 'Event'; |
|
45 | - $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Event_Related_Public($path_to_event); |
|
46 | - $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = new EE_Restriction_Generator_Event_Related_Protected($path_to_event); |
|
47 | - $this->_cap_restriction_generators[ EEM_Base::caps_edit ] = new EE_Restriction_Generator_Event_Related_Protected($path_to_event); |
|
48 | - $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = new EE_Restriction_Generator_Event_Related_Protected($path_to_event, EEM_Base::caps_edit); |
|
49 | - parent::__construct($timezone); |
|
50 | - } |
|
23 | + protected function __construct($timezone = null) |
|
24 | + { |
|
25 | + $this->singular_item = __('Event to Question Group Link', 'event_espresso'); |
|
26 | + $this->plural_item = __('Event to Question Group Links', 'event_espresso'); |
|
27 | + $this->_tables = array( |
|
28 | + 'Event_Question_Group'=>new EE_Primary_Table('esp_event_question_group', 'EQG_ID') |
|
29 | + ); |
|
30 | + $this->_fields = array( |
|
31 | + 'Event_Question_Group'=>array( |
|
32 | + 'EQG_ID'=>new EE_Primary_Key_Int_Field('EQG_ID', __('Event to Question Group Link ID', 'event_espresso')), |
|
33 | + 'EVT_ID'=>new EE_Foreign_Key_Int_Field('EVT_ID', __('Event ID', 'event_espresso'), false, 0, 'Event'), |
|
34 | + 'QSG_ID'=>new EE_Foreign_Key_Int_Field('QSG_ID', __('Question Group Id', 'event_espresso'), false, 0, 'Question_Group'), |
|
35 | + 'EQG_primary'=>new EE_Boolean_Field('EQG_primary', __('Flag indicating question is only for primary attendees', 'event_espresso'), false, false), |
|
36 | + 'EQG_additional'=>new EE_Boolean_Field('EQG_additional', __('Flag indicating question is only for additional attendees', 'event_espresso'), false, false) |
|
37 | + ) |
|
38 | + ); |
|
39 | + $this->_model_relations = array( |
|
40 | + 'Event'=>new EE_Belongs_To_Relation(), |
|
41 | + 'Question_Group'=>new EE_Belongs_To_Relation() |
|
42 | + ); |
|
43 | + // this model is generally available for reading |
|
44 | + $path_to_event = 'Event'; |
|
45 | + $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Event_Related_Public($path_to_event); |
|
46 | + $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = new EE_Restriction_Generator_Event_Related_Protected($path_to_event); |
|
47 | + $this->_cap_restriction_generators[ EEM_Base::caps_edit ] = new EE_Restriction_Generator_Event_Related_Protected($path_to_event); |
|
48 | + $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = new EE_Restriction_Generator_Event_Related_Protected($path_to_event, EEM_Base::caps_edit); |
|
49 | + parent::__construct($timezone); |
|
50 | + } |
|
51 | 51 | |
52 | - /** |
|
53 | - * Decides whether to use the 'EQG_primary' or newer 'EQG_additional' for use in queries, based on whether |
|
54 | - * this is concerning primary attendees or additional attendees. |
|
55 | - * If 1, true, or "primary" is passed in, returns EQG_primary. If 0, false, or "additional" is passed in, returns |
|
56 | - * EQG_additional. |
|
57 | - * @since $VID:$ |
|
58 | - * @param string|boolean|int $context |
|
59 | - * @return string |
|
60 | - */ |
|
61 | - public function fieldNameForContext($context) |
|
62 | - { |
|
63 | - switch ($context) { |
|
64 | - case 'additional': |
|
65 | - case false: |
|
66 | - case 0: |
|
67 | - $field_name = EEM_Event_Question_Group::ADDITIONAL; |
|
68 | - break; |
|
69 | - case 'primary': |
|
70 | - case true: |
|
71 | - case 1: |
|
72 | - default: |
|
73 | - $field_name = EEM_Event_Question_Group::PRIMARY; |
|
74 | - } |
|
75 | - return apply_filters('FHEE__EEM_Event_Question_Group__fieldNameForContext', $field_name, $context); |
|
76 | - } |
|
52 | + /** |
|
53 | + * Decides whether to use the 'EQG_primary' or newer 'EQG_additional' for use in queries, based on whether |
|
54 | + * this is concerning primary attendees or additional attendees. |
|
55 | + * If 1, true, or "primary" is passed in, returns EQG_primary. If 0, false, or "additional" is passed in, returns |
|
56 | + * EQG_additional. |
|
57 | + * @since $VID:$ |
|
58 | + * @param string|boolean|int $context |
|
59 | + * @return string |
|
60 | + */ |
|
61 | + public function fieldNameForContext($context) |
|
62 | + { |
|
63 | + switch ($context) { |
|
64 | + case 'additional': |
|
65 | + case false: |
|
66 | + case 0: |
|
67 | + $field_name = EEM_Event_Question_Group::ADDITIONAL; |
|
68 | + break; |
|
69 | + case 'primary': |
|
70 | + case true: |
|
71 | + case 1: |
|
72 | + default: |
|
73 | + $field_name = EEM_Event_Question_Group::PRIMARY; |
|
74 | + } |
|
75 | + return apply_filters('FHEE__EEM_Event_Question_Group__fieldNameForContext', $field_name, $context); |
|
76 | + } |
|
77 | 77 | } |
@@ -16,15 +16,13 @@ discard block |
||
16 | 16 | 'EQG_primary'=>new EE_Boolean_Field('EQG_primary', __('Flag indicating question is only for primary attendees','event_espresso'), false, false) |
17 | 17 | ) |
18 | 18 | ); |
19 | - |
|
20 | - |
|
21 | 19 | * |
22 | 20 | */ |
23 | 21 | class EE_DMS_4_1_0_event_question_group extends EE_Data_Migration_Script_Stage_Table |
24 | 22 | { |
25 | - private $_new_table; |
|
26 | - public function _migrate_old_row($old_row) |
|
27 | - { |
|
23 | + private $_new_table; |
|
24 | + public function _migrate_old_row($old_row) |
|
25 | + { |
|
28 | 26 | // $txn_id = $this->get_migration_script()->get_mapping_new_pk($this->_old_table, $old_row['id'], $this->_new_transaction_table); |
29 | 27 | // if ( ! $txn_id ){ |
30 | 28 | // $this->add_error(sprintf(__("Could not find the transaction for the 3.1 attendee %d from row %s", "event_espresso"),$old_row['id'],$this->_json_encode($old_row))); |
@@ -34,8 +32,8 @@ discard block |
||
34 | 32 | // $new_line_items = $this->_insert_new_line_items($txn,$old_row); |
35 | 33 | // $this->get_migration_script()->set_mapping($this->_old_table,$old_row['id'],$this->_new_line_table,$new_line_items); |
36 | 34 | |
37 | - $this->_insert_new_event_question_groups($old_row); |
|
38 | - } |
|
35 | + $this->_insert_new_event_question_groups($old_row); |
|
36 | + } |
|
39 | 37 | // function _migration_step($num_items=50){ |
40 | 38 | // global $wpdb; |
41 | 39 | // $start_at_record = $this->count_records_migrated(); |
@@ -55,109 +53,109 @@ discard block |
||
55 | 53 | // $count = $wpdb->get_var("SELECT COUNT(id) FROM ".$this->_old_table); |
56 | 54 | // return $count; |
57 | 55 | // } |
58 | - public function __construct() |
|
59 | - { |
|
60 | - global $wpdb; |
|
61 | - $this->_old_table = $wpdb->prefix."events_detail"; |
|
62 | - $this->_extra_where_sql = 'WHERE event_status!="D"'; |
|
63 | - $this->_new_table = $wpdb->prefix."esp_event_question_group"; |
|
64 | - $this->_pretty_name = __("Question Groups in each Event", "event_espresso"); |
|
65 | - parent::__construct(); |
|
66 | - } |
|
56 | + public function __construct() |
|
57 | + { |
|
58 | + global $wpdb; |
|
59 | + $this->_old_table = $wpdb->prefix."events_detail"; |
|
60 | + $this->_extra_where_sql = 'WHERE event_status!="D"'; |
|
61 | + $this->_new_table = $wpdb->prefix."esp_event_question_group"; |
|
62 | + $this->_pretty_name = __("Question Groups in each Event", "event_espresso"); |
|
63 | + parent::__construct(); |
|
64 | + } |
|
67 | 65 | |
68 | - /** |
|
69 | - * Attempts to insert a new question group inthe new format given an old one |
|
70 | - * @global type $wpdb |
|
71 | - * @param array $old_event |
|
72 | - * @return void |
|
73 | - */ |
|
74 | - private function _insert_new_event_question_groups($old_event) |
|
75 | - { |
|
76 | - $new_event_question_group_ids = array(); |
|
77 | - $question_groups_for_primary = maybe_unserialize($old_event['question_groups']); |
|
78 | - if (is_array($question_groups_for_primary)) { |
|
79 | - foreach ($question_groups_for_primary as $old_question_group_id) { |
|
80 | - $new_id = $this->_insert_event_question_group($old_event, $old_question_group_id, true); |
|
81 | - if ($new_id) { |
|
82 | - $new_event_question_group_ids[] = $new_id; |
|
83 | - } |
|
84 | - } |
|
85 | - } |
|
86 | - $event_meta = maybe_unserialize($old_event['event_meta']); |
|
87 | - if (isset($event_meta['add_attendee_question_groups'])) { |
|
88 | - if (is_array($event_meta['add_attendee_question_groups'])) { |
|
89 | - foreach ($event_meta['add_attendee_question_groups'] as $old_question_group_id) { |
|
90 | - $new_id = $this->_insert_event_question_group($old_event, $old_question_group_id, false); |
|
91 | - if ($new_id) { |
|
92 | - $new_event_question_group_ids[] = $new_id; |
|
93 | - } |
|
94 | - } |
|
95 | - } |
|
96 | - } |
|
66 | + /** |
|
67 | + * Attempts to insert a new question group inthe new format given an old one |
|
68 | + * @global type $wpdb |
|
69 | + * @param array $old_event |
|
70 | + * @return void |
|
71 | + */ |
|
72 | + private function _insert_new_event_question_groups($old_event) |
|
73 | + { |
|
74 | + $new_event_question_group_ids = array(); |
|
75 | + $question_groups_for_primary = maybe_unserialize($old_event['question_groups']); |
|
76 | + if (is_array($question_groups_for_primary)) { |
|
77 | + foreach ($question_groups_for_primary as $old_question_group_id) { |
|
78 | + $new_id = $this->_insert_event_question_group($old_event, $old_question_group_id, true); |
|
79 | + if ($new_id) { |
|
80 | + $new_event_question_group_ids[] = $new_id; |
|
81 | + } |
|
82 | + } |
|
83 | + } |
|
84 | + $event_meta = maybe_unserialize($old_event['event_meta']); |
|
85 | + if (isset($event_meta['add_attendee_question_groups'])) { |
|
86 | + if (is_array($event_meta['add_attendee_question_groups'])) { |
|
87 | + foreach ($event_meta['add_attendee_question_groups'] as $old_question_group_id) { |
|
88 | + $new_id = $this->_insert_event_question_group($old_event, $old_question_group_id, false); |
|
89 | + if ($new_id) { |
|
90 | + $new_event_question_group_ids[] = $new_id; |
|
91 | + } |
|
92 | + } |
|
93 | + } |
|
94 | + } |
|
97 | 95 | |
98 | 96 | |
99 | - $this->get_migration_script()->set_mapping($this->_old_table, $old_event['id'], $this->_new_table, $new_event_question_group_ids); |
|
100 | - } |
|
97 | + $this->get_migration_script()->set_mapping($this->_old_table, $old_event['id'], $this->_new_table, $new_event_question_group_ids); |
|
98 | + } |
|
101 | 99 | |
102 | - private function _insert_event_question_group($old_event, $old_question_group_id, $primary) |
|
103 | - { |
|
104 | - global $wpdb; |
|
105 | - $new_question_group_id = $this->get_migration_script()->get_mapping_new_pk( |
|
106 | - $wpdb->prefix . "events_qst_group", |
|
107 | - intval($old_question_group_id), |
|
108 | - $wpdb->prefix . "esp_question_group" |
|
109 | - ); |
|
100 | + private function _insert_event_question_group($old_event, $old_question_group_id, $primary) |
|
101 | + { |
|
102 | + global $wpdb; |
|
103 | + $new_question_group_id = $this->get_migration_script()->get_mapping_new_pk( |
|
104 | + $wpdb->prefix . "events_qst_group", |
|
105 | + intval($old_question_group_id), |
|
106 | + $wpdb->prefix . "esp_question_group" |
|
107 | + ); |
|
110 | 108 | |
111 | - if (! $new_question_group_id) { |
|
112 | - $this->add_error( |
|
113 | - sprintf( |
|
114 | - // translators: %s question ID, %s event ID |
|
115 | - __("Could not find 4.1 question ID for 3.1 question id #%s on event $%s", "event_espresso"), |
|
116 | - $old_question_group_id, |
|
117 | - $old_event['id'] |
|
118 | - ) |
|
119 | - ); |
|
120 | - return 0; |
|
121 | - } |
|
122 | - $new_event_id = $this->get_migration_script()->get_mapping_new_pk( |
|
123 | - $wpdb->prefix . "events_detail", |
|
124 | - intval($old_event['id']), |
|
125 | - $wpdb->posts |
|
126 | - ); |
|
127 | - if (! $new_question_group_id) { |
|
128 | - $this->add_error( |
|
129 | - sprintf( |
|
130 | - // translators: %s event ID |
|
131 | - __("Could not find 4.1 event 3.1 event id #%s", "event_espresso"), |
|
132 | - $old_event['id'] |
|
133 | - ) |
|
134 | - ); |
|
135 | - return 0; |
|
136 | - } |
|
137 | - $cols_n_values = array( |
|
138 | - 'EVT_ID'=>$new_event_id, |
|
139 | - 'QSG_ID'=>$new_question_group_id, |
|
140 | - EEM_Event_Question_Group::instance()->fieldNameForContext($primary) => true |
|
141 | - ); |
|
109 | + if (! $new_question_group_id) { |
|
110 | + $this->add_error( |
|
111 | + sprintf( |
|
112 | + // translators: %s question ID, %s event ID |
|
113 | + __("Could not find 4.1 question ID for 3.1 question id #%s on event $%s", "event_espresso"), |
|
114 | + $old_question_group_id, |
|
115 | + $old_event['id'] |
|
116 | + ) |
|
117 | + ); |
|
118 | + return 0; |
|
119 | + } |
|
120 | + $new_event_id = $this->get_migration_script()->get_mapping_new_pk( |
|
121 | + $wpdb->prefix . "events_detail", |
|
122 | + intval($old_event['id']), |
|
123 | + $wpdb->posts |
|
124 | + ); |
|
125 | + if (! $new_question_group_id) { |
|
126 | + $this->add_error( |
|
127 | + sprintf( |
|
128 | + // translators: %s event ID |
|
129 | + __("Could not find 4.1 event 3.1 event id #%s", "event_espresso"), |
|
130 | + $old_event['id'] |
|
131 | + ) |
|
132 | + ); |
|
133 | + return 0; |
|
134 | + } |
|
135 | + $cols_n_values = array( |
|
136 | + 'EVT_ID'=>$new_event_id, |
|
137 | + 'QSG_ID'=>$new_question_group_id, |
|
138 | + EEM_Event_Question_Group::instance()->fieldNameForContext($primary) => true |
|
139 | + ); |
|
142 | 140 | |
143 | - $datatypes = array( |
|
144 | - '%d',// EVT_ID |
|
145 | - '%d',// QSG_ID |
|
146 | - '%d',// EQG_primary or EQG_additional |
|
147 | - ); |
|
148 | - $success = $wpdb->insert($this->_new_table, $cols_n_values, $datatypes); |
|
149 | - if (! $success) { |
|
150 | - $this->add_error( |
|
151 | - $this->get_migration_script()->_create_error_message_for_db_insertion( |
|
152 | - $this->_old_table, |
|
153 | - $old_event, |
|
154 | - $this->_new_table, |
|
155 | - $cols_n_values, |
|
156 | - $datatypes |
|
157 | - ) |
|
158 | - ); |
|
159 | - return 0; |
|
160 | - } |
|
161 | - return $wpdb->insert_id; |
|
162 | - } |
|
141 | + $datatypes = array( |
|
142 | + '%d',// EVT_ID |
|
143 | + '%d',// QSG_ID |
|
144 | + '%d',// EQG_primary or EQG_additional |
|
145 | + ); |
|
146 | + $success = $wpdb->insert($this->_new_table, $cols_n_values, $datatypes); |
|
147 | + if (! $success) { |
|
148 | + $this->add_error( |
|
149 | + $this->get_migration_script()->_create_error_message_for_db_insertion( |
|
150 | + $this->_old_table, |
|
151 | + $old_event, |
|
152 | + $this->_new_table, |
|
153 | + $cols_n_values, |
|
154 | + $datatypes |
|
155 | + ) |
|
156 | + ); |
|
157 | + return 0; |
|
158 | + } |
|
159 | + return $wpdb->insert_id; |
|
160 | + } |
|
163 | 161 | } |
@@ -14,70 +14,70 @@ |
||
14 | 14 | |
15 | 15 | |
16 | 16 | |
17 | - /** |
|
18 | - * Just initializes the status of the migration |
|
19 | - * |
|
20 | - * @return EE_DMS_4_10_0_Event_QUestion_Group |
|
21 | - */ |
|
22 | - public function __construct() |
|
23 | - { |
|
24 | - global $wpdb; |
|
25 | - $this->_pretty_name = __('Event-Question Group Relations', 'event_espresso'); |
|
26 | - $this->_old_table = $wpdb->prefix.'esp_event_question_group'; |
|
27 | - $this->_extra_where_sql = "WHERE EQG_primary = 0"; |
|
28 | - parent::__construct(); |
|
29 | - } |
|
17 | + /** |
|
18 | + * Just initializes the status of the migration |
|
19 | + * |
|
20 | + * @return EE_DMS_4_10_0_Event_QUestion_Group |
|
21 | + */ |
|
22 | + public function __construct() |
|
23 | + { |
|
24 | + global $wpdb; |
|
25 | + $this->_pretty_name = __('Event-Question Group Relations', 'event_espresso'); |
|
26 | + $this->_old_table = $wpdb->prefix.'esp_event_question_group'; |
|
27 | + $this->_extra_where_sql = "WHERE EQG_primary = 0"; |
|
28 | + parent::__construct(); |
|
29 | + } |
|
30 | 30 | |
31 | 31 | |
32 | 32 | |
33 | - /** |
|
34 | - * Removes the duplicate event_question_group rows that only had EQG_primary=0. Now we just have one row |
|
35 | - * joining event-to-question-groups with two columns: EQG_primary and EQG_additional, indicating which question |
|
36 | - * groups apply to which category of registrant. |
|
37 | - * @param array $event_question_group an associative array where keys are column names and values are their values. |
|
38 | - * @return null |
|
39 | - */ |
|
40 | - protected function _migrate_old_row($event_question_group) |
|
41 | - { |
|
42 | - if (isset($event_question_group['EVT_ID'], $event_question_group['QSG_ID'])) { |
|
43 | - global $wpdb; |
|
44 | - $success = $wpdb->update( |
|
45 | - $this->_old_table, |
|
46 | - ['EQG_additional' => true], // data |
|
47 | - [ |
|
48 | - 'EVT_ID' => $event_question_group['EVT_ID'], |
|
49 | - 'QSG_ID' => $event_question_group['QSG_ID'] |
|
50 | - ], // where |
|
51 | - array( '%d' ), // data format |
|
52 | - array( '%d', '%d' ) // where format |
|
53 | - ); |
|
54 | - if (! $success) { |
|
55 | - $this->add_error( |
|
56 | - sprintf( |
|
57 | - __('Could not update event-question group relation for event "%1$s" and question group "%2$s" because "%3$s"', 'event_espresso'), |
|
58 | - $event_question_group['EVT_ID'], |
|
59 | - $event_question_group['QSG_ID'], |
|
60 | - $wpdb->last_error |
|
61 | - ) |
|
62 | - ); |
|
63 | - } |
|
64 | - // and delete the old row |
|
65 | - $successful_delete = $wpdb->delete( |
|
66 | - $this->_old_table, |
|
67 | - [ |
|
68 | - 'EQG_ID' => $event_question_group['EQG_ID'] |
|
69 | - ], |
|
70 | - ['%d'] |
|
71 | - ); |
|
72 | - if (! $successful_delete) { |
|
73 | - $this->add_error( |
|
74 | - sprintf( |
|
75 | - __('Could not delete old event-question group relation row "%1$s" because "%2$s"', 'event_espresso'), |
|
76 | - wp_json_encode($event_question_group), |
|
77 | - $wpdb->last_error |
|
78 | - ) |
|
79 | - ); |
|
80 | - } |
|
81 | - } |
|
82 | - } |
|
33 | + /** |
|
34 | + * Removes the duplicate event_question_group rows that only had EQG_primary=0. Now we just have one row |
|
35 | + * joining event-to-question-groups with two columns: EQG_primary and EQG_additional, indicating which question |
|
36 | + * groups apply to which category of registrant. |
|
37 | + * @param array $event_question_group an associative array where keys are column names and values are their values. |
|
38 | + * @return null |
|
39 | + */ |
|
40 | + protected function _migrate_old_row($event_question_group) |
|
41 | + { |
|
42 | + if (isset($event_question_group['EVT_ID'], $event_question_group['QSG_ID'])) { |
|
43 | + global $wpdb; |
|
44 | + $success = $wpdb->update( |
|
45 | + $this->_old_table, |
|
46 | + ['EQG_additional' => true], // data |
|
47 | + [ |
|
48 | + 'EVT_ID' => $event_question_group['EVT_ID'], |
|
49 | + 'QSG_ID' => $event_question_group['QSG_ID'] |
|
50 | + ], // where |
|
51 | + array( '%d' ), // data format |
|
52 | + array( '%d', '%d' ) // where format |
|
53 | + ); |
|
54 | + if (! $success) { |
|
55 | + $this->add_error( |
|
56 | + sprintf( |
|
57 | + __('Could not update event-question group relation for event "%1$s" and question group "%2$s" because "%3$s"', 'event_espresso'), |
|
58 | + $event_question_group['EVT_ID'], |
|
59 | + $event_question_group['QSG_ID'], |
|
60 | + $wpdb->last_error |
|
61 | + ) |
|
62 | + ); |
|
63 | + } |
|
64 | + // and delete the old row |
|
65 | + $successful_delete = $wpdb->delete( |
|
66 | + $this->_old_table, |
|
67 | + [ |
|
68 | + 'EQG_ID' => $event_question_group['EQG_ID'] |
|
69 | + ], |
|
70 | + ['%d'] |
|
71 | + ); |
|
72 | + if (! $successful_delete) { |
|
73 | + $this->add_error( |
|
74 | + sprintf( |
|
75 | + __('Could not delete old event-question group relation row "%1$s" because "%2$s"', 'event_espresso'), |
|
76 | + wp_json_encode($event_question_group), |
|
77 | + $wpdb->last_error |
|
78 | + ) |
|
79 | + ); |
|
80 | + } |
|
81 | + } |
|
82 | + } |
|
83 | 83 | } |
@@ -27,153 +27,153 @@ |
||
27 | 27 | { |
28 | 28 | |
29 | 29 | |
30 | - /** |
|
31 | - * @param EE_Registration $target_registration |
|
32 | - * @param EE_Registration $registration_to_copy |
|
33 | - * @return bool |
|
34 | - * @throws UnexpectedEntityException |
|
35 | - * @throws EntityNotFoundException |
|
36 | - * @throws RuntimeException |
|
37 | - * @throws EE_Error |
|
38 | - */ |
|
39 | - public function copyRegistrationDetails( |
|
40 | - EE_Registration $target_registration, |
|
41 | - EE_Registration $registration_to_copy |
|
42 | - ) { |
|
43 | - // copy attendee |
|
44 | - $target_registration->set_attendee_id($registration_to_copy->attendee_ID()); |
|
45 | - $target_registration->updateStatusBasedOnTotalPaid(false); |
|
46 | - $target_registration->save(); |
|
47 | - // get answers to previous reg questions |
|
48 | - $answers = $this->reindexAnswersByQuestionId($registration_to_copy->answers()); |
|
49 | - // get questions to new event reg form |
|
50 | - $new_event = $target_registration->event(); |
|
51 | - $field_name = 'Event_Question_Group.' |
|
52 | - . EEM_Event_Question_Group::instance()->fieldNameForContext( |
|
53 | - $registration_to_copy->is_primary_registrant() |
|
54 | - ); |
|
55 | - $question_groups = $new_event->question_groups([ |
|
56 | - [ |
|
57 | - 'Event.EVT_ID' => $new_event->ID(), |
|
58 | - $field_name => true, |
|
59 | - ], |
|
60 | - 'order_by' => ['QSG_order' => 'ASC'], |
|
61 | - ] |
|
30 | + /** |
|
31 | + * @param EE_Registration $target_registration |
|
32 | + * @param EE_Registration $registration_to_copy |
|
33 | + * @return bool |
|
34 | + * @throws UnexpectedEntityException |
|
35 | + * @throws EntityNotFoundException |
|
36 | + * @throws RuntimeException |
|
37 | + * @throws EE_Error |
|
38 | + */ |
|
39 | + public function copyRegistrationDetails( |
|
40 | + EE_Registration $target_registration, |
|
41 | + EE_Registration $registration_to_copy |
|
42 | + ) { |
|
43 | + // copy attendee |
|
44 | + $target_registration->set_attendee_id($registration_to_copy->attendee_ID()); |
|
45 | + $target_registration->updateStatusBasedOnTotalPaid(false); |
|
46 | + $target_registration->save(); |
|
47 | + // get answers to previous reg questions |
|
48 | + $answers = $this->reindexAnswersByQuestionId($registration_to_copy->answers()); |
|
49 | + // get questions to new event reg form |
|
50 | + $new_event = $target_registration->event(); |
|
51 | + $field_name = 'Event_Question_Group.' |
|
52 | + . EEM_Event_Question_Group::instance()->fieldNameForContext( |
|
53 | + $registration_to_copy->is_primary_registrant() |
|
54 | + ); |
|
55 | + $question_groups = $new_event->question_groups([ |
|
56 | + [ |
|
57 | + 'Event.EVT_ID' => $new_event->ID(), |
|
58 | + $field_name => true, |
|
59 | + ], |
|
60 | + 'order_by' => ['QSG_order' => 'ASC'], |
|
61 | + ] |
|
62 | 62 | |
63 | - ); |
|
64 | - foreach ($question_groups as $question_group) { |
|
65 | - if ($question_group instanceof \EE_Question_Group) { |
|
66 | - foreach ($question_group->questions() as $question) { |
|
67 | - if ($question instanceof EE_Question) { |
|
68 | - $this->generateNewAnswer( |
|
69 | - $question, |
|
70 | - $target_registration, |
|
71 | - $answers |
|
72 | - ); |
|
73 | - } |
|
74 | - } |
|
75 | - } |
|
76 | - } |
|
77 | - return true; |
|
78 | - } |
|
63 | + ); |
|
64 | + foreach ($question_groups as $question_group) { |
|
65 | + if ($question_group instanceof \EE_Question_Group) { |
|
66 | + foreach ($question_group->questions() as $question) { |
|
67 | + if ($question instanceof EE_Question) { |
|
68 | + $this->generateNewAnswer( |
|
69 | + $question, |
|
70 | + $target_registration, |
|
71 | + $answers |
|
72 | + ); |
|
73 | + } |
|
74 | + } |
|
75 | + } |
|
76 | + } |
|
77 | + return true; |
|
78 | + } |
|
79 | 79 | |
80 | 80 | |
81 | - /** |
|
82 | - * @param EE_Answer[] $answers |
|
83 | - * @return array |
|
84 | - * @throws EE_Error |
|
85 | - */ |
|
86 | - protected function reindexAnswersByQuestionId(array $answers) |
|
87 | - { |
|
88 | - $reindexed_answers = array(); |
|
89 | - foreach ($answers as $answer) { |
|
90 | - if ($answer instanceof EE_Answer) { |
|
91 | - $reindexed_answers[ $answer->question_ID() ] = $answer->value(); |
|
92 | - } |
|
93 | - } |
|
94 | - return $reindexed_answers; |
|
95 | - } |
|
81 | + /** |
|
82 | + * @param EE_Answer[] $answers |
|
83 | + * @return array |
|
84 | + * @throws EE_Error |
|
85 | + */ |
|
86 | + protected function reindexAnswersByQuestionId(array $answers) |
|
87 | + { |
|
88 | + $reindexed_answers = array(); |
|
89 | + foreach ($answers as $answer) { |
|
90 | + if ($answer instanceof EE_Answer) { |
|
91 | + $reindexed_answers[ $answer->question_ID() ] = $answer->value(); |
|
92 | + } |
|
93 | + } |
|
94 | + return $reindexed_answers; |
|
95 | + } |
|
96 | 96 | |
97 | 97 | |
98 | - /** |
|
99 | - * @param EE_Question $question |
|
100 | - * @param EE_Registration $registration |
|
101 | - * @param $previous_answers |
|
102 | - * @return EE_Answer |
|
103 | - * @throws UnexpectedEntityException |
|
104 | - * @throws EE_Error |
|
105 | - */ |
|
106 | - protected function generateNewAnswer( |
|
107 | - EE_Question $question, |
|
108 | - EE_Registration $registration, |
|
109 | - $previous_answers |
|
110 | - ) { |
|
111 | - $old_answer_value = isset($previous_answers[ $question->ID() ]) |
|
112 | - ? $previous_answers[ $question->ID() ] |
|
113 | - : ''; |
|
114 | - $new_answer = EE_Answer::new_instance( |
|
115 | - array( |
|
116 | - 'QST_ID' => $question->ID(), |
|
117 | - 'REG_ID' => $registration->ID(), |
|
118 | - 'ANS_value' => $old_answer_value, |
|
119 | - ) |
|
120 | - ); |
|
121 | - if (! $new_answer instanceof EE_Answer) { |
|
122 | - throw new UnexpectedEntityException($new_answer, 'EE_Answer'); |
|
123 | - } |
|
124 | - $new_answer->save(); |
|
125 | - return $new_answer; |
|
126 | - } |
|
98 | + /** |
|
99 | + * @param EE_Question $question |
|
100 | + * @param EE_Registration $registration |
|
101 | + * @param $previous_answers |
|
102 | + * @return EE_Answer |
|
103 | + * @throws UnexpectedEntityException |
|
104 | + * @throws EE_Error |
|
105 | + */ |
|
106 | + protected function generateNewAnswer( |
|
107 | + EE_Question $question, |
|
108 | + EE_Registration $registration, |
|
109 | + $previous_answers |
|
110 | + ) { |
|
111 | + $old_answer_value = isset($previous_answers[ $question->ID() ]) |
|
112 | + ? $previous_answers[ $question->ID() ] |
|
113 | + : ''; |
|
114 | + $new_answer = EE_Answer::new_instance( |
|
115 | + array( |
|
116 | + 'QST_ID' => $question->ID(), |
|
117 | + 'REG_ID' => $registration->ID(), |
|
118 | + 'ANS_value' => $old_answer_value, |
|
119 | + ) |
|
120 | + ); |
|
121 | + if (! $new_answer instanceof EE_Answer) { |
|
122 | + throw new UnexpectedEntityException($new_answer, 'EE_Answer'); |
|
123 | + } |
|
124 | + $new_answer->save(); |
|
125 | + return $new_answer; |
|
126 | + } |
|
127 | 127 | |
128 | 128 | |
129 | - /** |
|
130 | - * @param EE_Registration $target_registration |
|
131 | - * @param EE_Registration $registration_to_copy |
|
132 | - * @return bool |
|
133 | - * @throws RuntimeException |
|
134 | - * @throws UnexpectedEntityException |
|
135 | - * @throws EE_Error |
|
136 | - */ |
|
137 | - public function copyPaymentDetails( |
|
138 | - EE_Registration $target_registration, |
|
139 | - EE_Registration $registration_to_copy |
|
140 | - ) { |
|
141 | - $save = false; |
|
142 | - $previous_registration_payments = $registration_to_copy->registration_payments(); |
|
143 | - $new_registration_payment_total = 0; |
|
144 | - $registration_to_copy_total = $registration_to_copy->paid(); |
|
145 | - foreach ($previous_registration_payments as $previous_registration_payment) { |
|
146 | - if ($previous_registration_payment instanceof EE_Registration_Payment |
|
147 | - && $previous_registration_payment->payment() instanceof EE_Payment |
|
148 | - && $previous_registration_payment->payment()->is_approved() |
|
149 | - ) { |
|
150 | - $payment_amount = $previous_registration_payment->amount(); |
|
151 | - $new_registration_payment = EE_Registration_Payment::new_instance( |
|
152 | - array( |
|
153 | - 'REG_ID' => $target_registration->ID(), |
|
154 | - 'PAY_ID' => $previous_registration_payment->payment()->ID(), |
|
155 | - 'RPY_amount' => $payment_amount, |
|
156 | - ) |
|
157 | - ); |
|
158 | - if (! $new_registration_payment instanceof EE_Registration_Payment) { |
|
159 | - throw new UnexpectedEntityException($new_registration_payment, 'EE_Registration_Payment'); |
|
160 | - } |
|
161 | - $new_registration_payment->save(); |
|
162 | - // if new reg payment is good, then set old reg payment amount to zero |
|
163 | - $previous_registration_payment->set_amount(0); |
|
164 | - $previous_registration_payment->save(); |
|
165 | - // now increment/decrement payment amounts |
|
166 | - $new_registration_payment_total += $payment_amount; |
|
167 | - $registration_to_copy_total -= $payment_amount; |
|
168 | - $save = true; |
|
169 | - } |
|
170 | - } |
|
171 | - if ($save) { |
|
172 | - $target_registration->set_paid($new_registration_payment_total); |
|
173 | - $target_registration->save(); |
|
174 | - $registration_to_copy->set_paid($registration_to_copy_total); |
|
175 | - $registration_to_copy->save(); |
|
176 | - } |
|
177 | - return true; |
|
178 | - } |
|
129 | + /** |
|
130 | + * @param EE_Registration $target_registration |
|
131 | + * @param EE_Registration $registration_to_copy |
|
132 | + * @return bool |
|
133 | + * @throws RuntimeException |
|
134 | + * @throws UnexpectedEntityException |
|
135 | + * @throws EE_Error |
|
136 | + */ |
|
137 | + public function copyPaymentDetails( |
|
138 | + EE_Registration $target_registration, |
|
139 | + EE_Registration $registration_to_copy |
|
140 | + ) { |
|
141 | + $save = false; |
|
142 | + $previous_registration_payments = $registration_to_copy->registration_payments(); |
|
143 | + $new_registration_payment_total = 0; |
|
144 | + $registration_to_copy_total = $registration_to_copy->paid(); |
|
145 | + foreach ($previous_registration_payments as $previous_registration_payment) { |
|
146 | + if ($previous_registration_payment instanceof EE_Registration_Payment |
|
147 | + && $previous_registration_payment->payment() instanceof EE_Payment |
|
148 | + && $previous_registration_payment->payment()->is_approved() |
|
149 | + ) { |
|
150 | + $payment_amount = $previous_registration_payment->amount(); |
|
151 | + $new_registration_payment = EE_Registration_Payment::new_instance( |
|
152 | + array( |
|
153 | + 'REG_ID' => $target_registration->ID(), |
|
154 | + 'PAY_ID' => $previous_registration_payment->payment()->ID(), |
|
155 | + 'RPY_amount' => $payment_amount, |
|
156 | + ) |
|
157 | + ); |
|
158 | + if (! $new_registration_payment instanceof EE_Registration_Payment) { |
|
159 | + throw new UnexpectedEntityException($new_registration_payment, 'EE_Registration_Payment'); |
|
160 | + } |
|
161 | + $new_registration_payment->save(); |
|
162 | + // if new reg payment is good, then set old reg payment amount to zero |
|
163 | + $previous_registration_payment->set_amount(0); |
|
164 | + $previous_registration_payment->save(); |
|
165 | + // now increment/decrement payment amounts |
|
166 | + $new_registration_payment_total += $payment_amount; |
|
167 | + $registration_to_copy_total -= $payment_amount; |
|
168 | + $save = true; |
|
169 | + } |
|
170 | + } |
|
171 | + if ($save) { |
|
172 | + $target_registration->set_paid($new_registration_payment_total); |
|
173 | + $target_registration->save(); |
|
174 | + $registration_to_copy->set_paid($registration_to_copy_total); |
|
175 | + $registration_to_copy->save(); |
|
176 | + } |
|
177 | + return true; |
|
178 | + } |
|
179 | 179 | } |
@@ -18,1429 +18,1429 @@ |
||
18 | 18 | class EE_SPCO_Reg_Step_Attendee_Information extends EE_SPCO_Reg_Step |
19 | 19 | { |
20 | 20 | |
21 | - /** |
|
22 | - * @type bool $_print_copy_info |
|
23 | - */ |
|
24 | - private $_print_copy_info = false; |
|
25 | - |
|
26 | - /** |
|
27 | - * @type array $_attendee_data |
|
28 | - */ |
|
29 | - private $_attendee_data = array(); |
|
30 | - |
|
31 | - /** |
|
32 | - * @type array $_required_questions |
|
33 | - */ |
|
34 | - private $_required_questions = array(); |
|
35 | - |
|
36 | - /** |
|
37 | - * @type array $_registration_answers |
|
38 | - */ |
|
39 | - private $_registration_answers = array(); |
|
40 | - |
|
41 | - |
|
42 | - /** |
|
43 | - * class constructor |
|
44 | - * |
|
45 | - * @access public |
|
46 | - * @param EE_Checkout $checkout |
|
47 | - */ |
|
48 | - public function __construct(EE_Checkout $checkout) |
|
49 | - { |
|
50 | - $this->_slug = 'attendee_information'; |
|
51 | - $this->_name = esc_html__('Attendee Information', 'event_espresso'); |
|
52 | - $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . DS . 'attendee_info_main.template.php'; |
|
53 | - $this->checkout = $checkout; |
|
54 | - $this->_reset_success_message(); |
|
55 | - $this->set_instructions( |
|
56 | - esc_html__('Please answer the following registration questions before proceeding.', 'event_espresso') |
|
57 | - ); |
|
58 | - } |
|
59 | - |
|
60 | - |
|
61 | - public function translate_js_strings() |
|
62 | - { |
|
63 | - EE_Registry::$i18n_js_strings['required_field'] = esc_html__( |
|
64 | - ' is a required question.', |
|
65 | - 'event_espresso' |
|
66 | - ); |
|
67 | - EE_Registry::$i18n_js_strings['required_multi_field'] = esc_html__( |
|
68 | - ' is a required question. Please enter a value for at least one of the options.', |
|
69 | - 'event_espresso' |
|
70 | - ); |
|
71 | - EE_Registry::$i18n_js_strings['answer_required_questions'] = esc_html__( |
|
72 | - 'Please answer all required questions correctly before proceeding.', |
|
73 | - 'event_espresso' |
|
74 | - ); |
|
75 | - EE_Registry::$i18n_js_strings['attendee_info_copied'] = sprintf( |
|
76 | - esc_html_x( |
|
77 | - 'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.', |
|
78 | - 'The attendee information was successfully copied.(line break)Please ensure the rest of the registration form is completed before proceeding.', |
|
79 | - 'event_espresso' |
|
80 | - ), |
|
81 | - '<br/>' |
|
82 | - ); |
|
83 | - EE_Registry::$i18n_js_strings['attendee_info_copy_error'] = esc_html__( |
|
84 | - 'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.', |
|
85 | - 'event_espresso' |
|
86 | - ); |
|
87 | - EE_Registry::$i18n_js_strings['enter_valid_email'] = esc_html__( |
|
88 | - 'You must enter a valid email address.', |
|
89 | - 'event_espresso' |
|
90 | - ); |
|
91 | - EE_Registry::$i18n_js_strings['valid_email_and_questions'] = esc_html__( |
|
92 | - 'You must enter a valid email address and answer all other required questions before you can proceed.', |
|
93 | - 'event_espresso' |
|
94 | - ); |
|
95 | - } |
|
96 | - |
|
97 | - |
|
98 | - public function enqueue_styles_and_scripts() |
|
99 | - { |
|
100 | - } |
|
101 | - |
|
102 | - |
|
103 | - /** |
|
104 | - * @return boolean |
|
105 | - */ |
|
106 | - public function initialize_reg_step() |
|
107 | - { |
|
108 | - return true; |
|
109 | - } |
|
110 | - |
|
111 | - |
|
112 | - /** |
|
113 | - * @return EE_Form_Section_Proper |
|
114 | - * @throws DomainException |
|
115 | - * @throws EE_Error |
|
116 | - * @throws InvalidArgumentException |
|
117 | - * @throws ReflectionException |
|
118 | - * @throws EntityNotFoundException |
|
119 | - * @throws InvalidDataTypeException |
|
120 | - * @throws InvalidInterfaceException |
|
121 | - */ |
|
122 | - public function generate_reg_form() |
|
123 | - { |
|
124 | - $this->_print_copy_info = false; |
|
125 | - $primary_registrant = null; |
|
126 | - // autoload Line_Item_Display classes |
|
127 | - EEH_Autoloader::register_line_item_display_autoloaders(); |
|
128 | - $Line_Item_Display = new EE_Line_Item_Display(); |
|
129 | - // calculate taxes |
|
130 | - $Line_Item_Display->display_line_item( |
|
131 | - $this->checkout->cart->get_grand_total(), |
|
132 | - array('set_tax_rate' => true) |
|
133 | - ); |
|
134 | - /** @var $subsections EE_Form_Section_Proper[] */ |
|
135 | - $extra_inputs_section = $this->reg_step_hidden_inputs(); |
|
136 | - $subsections = array( |
|
137 | - 'default_hidden_inputs' => $extra_inputs_section, |
|
138 | - ); |
|
139 | - |
|
140 | - /** |
|
141 | - * @var $reg_config EE_Registration_Config |
|
142 | - */ |
|
143 | - $reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config'); |
|
144 | - // if this isn't a revisit, and they have the privacy consent box enalbed, add it |
|
145 | - if (! $this->checkout->revisit && $reg_config->isConsentCheckboxEnabled()) { |
|
146 | - $extra_inputs_section->add_subsections( |
|
147 | - array( |
|
148 | - 'consent_box' => new EE_Form_Section_Proper( |
|
149 | - array( |
|
150 | - 'layout_strategy' => |
|
151 | - new EE_Template_Layout( |
|
152 | - array( |
|
153 | - 'input_template_file' => SPCO_REG_STEPS_PATH . $this->_slug . DS . 'privacy_consent.template.php', |
|
154 | - ) |
|
155 | - ), |
|
156 | - 'subsections' => array( |
|
157 | - 'consent' => new EE_Checkbox_Multi_Input( |
|
158 | - array( |
|
159 | - 'consent' => $reg_config->getConsentCheckboxLabelText(), |
|
160 | - ), |
|
161 | - array( |
|
162 | - 'required' => true, |
|
163 | - 'required_validation_error_message' => esc_html__( |
|
164 | - 'You must consent to these terms in order to register.', |
|
165 | - 'event_espresso' |
|
166 | - ), |
|
167 | - 'html_label_text' => '', |
|
168 | - ) |
|
169 | - ), |
|
170 | - ), |
|
171 | - ) |
|
172 | - ), |
|
173 | - ), |
|
174 | - null, |
|
175 | - false |
|
176 | - ); |
|
177 | - } |
|
178 | - $template_args = array( |
|
179 | - 'revisit' => $this->checkout->revisit, |
|
180 | - 'registrations' => array(), |
|
181 | - 'ticket_count' => array(), |
|
182 | - ); |
|
183 | - // grab the saved registrations from the transaction |
|
184 | - $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
185 | - if ($registrations) { |
|
186 | - foreach ($registrations as $registration) { |
|
187 | - // can this registration be processed during this visit ? |
|
188 | - if ($registration instanceof EE_Registration |
|
189 | - && $this->checkout->visit_allows_processing_of_this_registration($registration) |
|
190 | - ) { |
|
191 | - $subsections[ $registration->reg_url_link() ] = $this->_registrations_reg_form($registration); |
|
192 | - if (! $this->checkout->admin_request) { |
|
193 | - $template_args['registrations'][ $registration->reg_url_link() ] = $registration; |
|
194 | - $template_args['ticket_count'][ $registration->ticket()->ID() ] = isset( |
|
195 | - $template_args['ticket_count'][ $registration->ticket()->ID() ] |
|
196 | - ) |
|
197 | - ? $template_args['ticket_count'][ $registration->ticket()->ID() ] + 1 |
|
198 | - : 1; |
|
199 | - $ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
200 | - $this->checkout->cart->get_grand_total(), |
|
201 | - 'Ticket', |
|
202 | - array($registration->ticket()->ID()) |
|
203 | - ); |
|
204 | - $ticket_line_item = is_array($ticket_line_item) |
|
205 | - ? reset($ticket_line_item) |
|
206 | - : $ticket_line_item; |
|
207 | - $template_args['ticket_line_item'][ $registration->ticket()->ID() ] = |
|
208 | - $Line_Item_Display->display_line_item($ticket_line_item); |
|
209 | - } |
|
210 | - if ($registration->is_primary_registrant()) { |
|
211 | - $primary_registrant = $registration->reg_url_link(); |
|
212 | - } |
|
213 | - } |
|
214 | - } |
|
215 | - // print_copy_info ? |
|
216 | - if ($primary_registrant && ! $this->checkout->admin_request && count($registrations) > 1) { |
|
217 | - // TODO: add admin option for toggling copy attendee info, |
|
218 | - // then use that value to change $this->_print_copy_info |
|
219 | - $copy_options['spco_copy_attendee_chk'] = $this->_print_copy_info |
|
220 | - ? $this->_copy_attendee_info_form() |
|
221 | - : $this->_auto_copy_attendee_info(); |
|
222 | - // generate hidden input |
|
223 | - if (isset($subsections[ $primary_registrant ]) |
|
224 | - && $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper |
|
225 | - ) { |
|
226 | - $subsections[ $primary_registrant ]->add_subsections( |
|
227 | - $copy_options, |
|
228 | - 'primary_registrant', |
|
229 | - false |
|
230 | - ); |
|
231 | - } |
|
232 | - } |
|
233 | - } |
|
234 | - return new EE_Form_Section_Proper( |
|
235 | - array( |
|
236 | - 'name' => $this->reg_form_name(), |
|
237 | - 'html_id' => $this->reg_form_name(), |
|
238 | - 'subsections' => $subsections, |
|
239 | - 'layout_strategy' => $this->checkout->admin_request |
|
240 | - ? |
|
241 | - new EE_Div_Per_Section_Layout() |
|
242 | - : |
|
243 | - new EE_Template_Layout( |
|
244 | - array( |
|
245 | - 'layout_template_file' => $this->_template, // layout_template |
|
246 | - 'template_args' => $template_args, |
|
247 | - ) |
|
248 | - ), |
|
249 | - ) |
|
250 | - ); |
|
251 | - } |
|
252 | - |
|
253 | - |
|
254 | - /** |
|
255 | - * @param EE_Registration $registration |
|
256 | - * @return EE_Form_Section_Base |
|
257 | - * @throws EE_Error |
|
258 | - * @throws InvalidArgumentException |
|
259 | - * @throws EntityNotFoundException |
|
260 | - * @throws InvalidDataTypeException |
|
261 | - * @throws InvalidInterfaceException |
|
262 | - * @throws ReflectionException |
|
263 | - */ |
|
264 | - private function _registrations_reg_form(EE_Registration $registration) |
|
265 | - { |
|
266 | - static $attendee_nmbr = 1; |
|
267 | - $form_args = array(); |
|
268 | - // verify that registration has valid event |
|
269 | - if ($registration->event() instanceof EE_Event) { |
|
270 | - $field_name = 'Event_Question_Group.' |
|
271 | - . EEM_Event_Question_Group::instance()->fieldNameForContext( |
|
272 | - $registration->is_primary_registrant() |
|
273 | - ); |
|
274 | - $question_groups = $registration->event()->question_groups( |
|
275 | - apply_filters( |
|
276 | - // @codingStandardsIgnoreStart |
|
277 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters', |
|
278 | - // @codingStandardsIgnoreEnd |
|
279 | - [ |
|
280 | - [ |
|
281 | - 'Event.EVT_ID' => $registration->event()->ID(), |
|
282 | - $field_name => true, |
|
283 | - ], |
|
284 | - 'order_by' => ['QSG_order' => 'ASC'], |
|
285 | - ], |
|
286 | - $registration, |
|
287 | - $this |
|
288 | - ) |
|
289 | - ); |
|
290 | - if ($question_groups) { |
|
291 | - // array of params to pass to parent constructor |
|
292 | - $form_args = array( |
|
293 | - 'html_id' => 'ee-registration-' . $registration->reg_url_link(), |
|
294 | - 'html_class' => 'ee-reg-form-attendee-dv', |
|
295 | - 'html_style' => $this->checkout->admin_request |
|
296 | - ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;' |
|
297 | - : '', |
|
298 | - 'subsections' => array(), |
|
299 | - 'layout_strategy' => new EE_Fieldset_Section_Layout( |
|
300 | - array( |
|
301 | - 'legend_class' => 'spco-attendee-lgnd smaller-text lt-grey-text', |
|
302 | - 'legend_text' => sprintf( |
|
303 | - esc_html_x( |
|
304 | - 'Attendee %d', |
|
305 | - 'Attendee 123', |
|
306 | - 'event_espresso' |
|
307 | - ), |
|
308 | - $attendee_nmbr |
|
309 | - ), |
|
310 | - ) |
|
311 | - ), |
|
312 | - ); |
|
313 | - foreach ($question_groups as $question_group) { |
|
314 | - if ($question_group instanceof EE_Question_Group) { |
|
315 | - $form_args['subsections'][ $question_group->identifier() ] = $this->_question_group_reg_form( |
|
316 | - $registration, |
|
317 | - $question_group |
|
318 | - ); |
|
319 | - } |
|
320 | - } |
|
321 | - // add hidden input |
|
322 | - $form_args['subsections']['additional_attendee_reg_info'] = $this->_additional_attendee_reg_info_input( |
|
323 | - $registration |
|
324 | - ); |
|
325 | - // if we have question groups for additional attendees, then display the copy options |
|
326 | - $this->_print_copy_info = $attendee_nmbr > 1 ? true : $this->_print_copy_info; |
|
327 | - if ($registration->is_primary_registrant()) { |
|
328 | - // generate hidden input |
|
329 | - $form_args['subsections']['primary_registrant'] = $this->_additional_primary_registrant_inputs( |
|
330 | - $registration |
|
331 | - ); |
|
332 | - } |
|
333 | - } |
|
334 | - } |
|
335 | - $attendee_nmbr++; |
|
336 | - return ! empty($form_args) |
|
337 | - ? new EE_Form_Section_Proper($form_args) |
|
338 | - : new EE_Form_Section_HTML(); |
|
339 | - } |
|
340 | - |
|
341 | - |
|
342 | - /** |
|
343 | - * @param EE_Registration $registration |
|
344 | - * @param bool $additional_attendee_reg_info |
|
345 | - * @return EE_Form_Input_Base |
|
346 | - * @throws EE_Error |
|
347 | - */ |
|
348 | - private function _additional_attendee_reg_info_input( |
|
349 | - EE_Registration $registration, |
|
350 | - $additional_attendee_reg_info = true |
|
351 | - ) { |
|
352 | - // generate hidden input |
|
353 | - return new EE_Hidden_Input( |
|
354 | - array( |
|
355 | - 'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(), |
|
356 | - 'default' => $additional_attendee_reg_info, |
|
357 | - ) |
|
358 | - ); |
|
359 | - } |
|
360 | - |
|
361 | - |
|
362 | - /** |
|
363 | - * @param EE_Registration $registration |
|
364 | - * @param EE_Question_Group $question_group |
|
365 | - * @return EE_Form_Section_Proper |
|
366 | - * @throws EE_Error |
|
367 | - * @throws InvalidArgumentException |
|
368 | - * @throws InvalidDataTypeException |
|
369 | - * @throws InvalidInterfaceException |
|
370 | - * @throws ReflectionException |
|
371 | - */ |
|
372 | - private function _question_group_reg_form(EE_Registration $registration, EE_Question_Group $question_group) |
|
373 | - { |
|
374 | - // array of params to pass to parent constructor |
|
375 | - $form_args = array( |
|
376 | - 'html_id' => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-' . $registration->ID(), |
|
377 | - 'html_class' => $this->checkout->admin_request |
|
378 | - ? 'form-table ee-reg-form-qstn-grp-dv' |
|
379 | - : 'ee-reg-form-qstn-grp-dv', |
|
380 | - 'html_label_id' => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-' |
|
381 | - . $registration->ID() . '-lbl', |
|
382 | - 'subsections' => array( |
|
383 | - 'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group), |
|
384 | - ), |
|
385 | - 'layout_strategy' => $this->checkout->admin_request |
|
386 | - ? new EE_Admin_Two_Column_Layout() |
|
387 | - : new EE_Div_Per_Section_Layout(), |
|
388 | - ); |
|
389 | - // where params |
|
390 | - $query_params = array('QST_deleted' => 0); |
|
391 | - // don't load admin only questions on the frontend |
|
392 | - if (! $this->checkout->admin_request) { |
|
393 | - $query_params['QST_admin_only'] = array('!=', true); |
|
394 | - } |
|
395 | - $questions = $question_group->get_many_related( |
|
396 | - 'Question', |
|
397 | - apply_filters( |
|
398 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__related_questions_query_params', |
|
399 | - array( |
|
400 | - $query_params, |
|
401 | - 'order_by' => array( |
|
402 | - 'Question_Group_Question.QGQ_order' => 'ASC', |
|
403 | - ), |
|
404 | - ), |
|
405 | - $question_group, |
|
406 | - $registration, |
|
407 | - $this |
|
408 | - ) |
|
409 | - ); |
|
410 | - // filter for additional content before questions |
|
411 | - $form_args['subsections']['reg_form_questions_before'] = new EE_Form_Section_HTML( |
|
412 | - apply_filters( |
|
413 | - 'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', |
|
414 | - '', |
|
415 | - $registration, |
|
416 | - $question_group, |
|
417 | - $this |
|
418 | - ) |
|
419 | - ); |
|
420 | - // loop thru questions |
|
421 | - foreach ($questions as $question) { |
|
422 | - if ($question instanceof EE_Question) { |
|
423 | - $identifier = $question->is_system_question() |
|
424 | - ? $question->system_ID() |
|
425 | - : $question->ID(); |
|
426 | - $form_args['subsections'][ $identifier ] = $this->reg_form_question($registration, $question); |
|
427 | - } |
|
428 | - } |
|
429 | - $form_args['subsections'] = apply_filters( |
|
430 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__question_group_reg_form__subsections_array', |
|
431 | - $form_args['subsections'], |
|
432 | - $registration, |
|
433 | - $question_group, |
|
434 | - $this |
|
435 | - ); |
|
436 | - // filter for additional content after questions |
|
437 | - $form_args['subsections']['reg_form_questions_after'] = new EE_Form_Section_HTML( |
|
438 | - apply_filters( |
|
439 | - 'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', |
|
440 | - '', |
|
441 | - $registration, |
|
442 | - $question_group, |
|
443 | - $this |
|
444 | - ) |
|
445 | - ); |
|
446 | - // d($form_args); |
|
447 | - $question_group_reg_form = new EE_Form_Section_Proper($form_args); |
|
448 | - return apply_filters( |
|
449 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form', |
|
450 | - $question_group_reg_form, |
|
451 | - $registration, |
|
452 | - $question_group, |
|
453 | - $this |
|
454 | - ); |
|
455 | - } |
|
456 | - |
|
457 | - |
|
458 | - /** |
|
459 | - * @param EE_Question_Group $question_group |
|
460 | - * @return EE_Form_Section_HTML |
|
461 | - */ |
|
462 | - private function _question_group_header(EE_Question_Group $question_group) |
|
463 | - { |
|
464 | - $html = ''; |
|
465 | - // group_name |
|
466 | - if ($question_group->show_group_name() && $question_group->name() !== '') { |
|
467 | - if ($this->checkout->admin_request) { |
|
468 | - $html .= EEH_HTML::br(); |
|
469 | - $html .= EEH_HTML::h3( |
|
470 | - $question_group->name(), |
|
471 | - '', |
|
472 | - 'ee-reg-form-qstn-grp-title title', |
|
473 | - 'font-size: 1.3em; padding-left:0;' |
|
474 | - ); |
|
475 | - } else { |
|
476 | - $html .= EEH_HTML::h4( |
|
477 | - $question_group->name(), |
|
478 | - '', |
|
479 | - 'ee-reg-form-qstn-grp-title section-title' |
|
480 | - ); |
|
481 | - } |
|
482 | - } |
|
483 | - // group_desc |
|
484 | - if ($question_group->show_group_desc() && $question_group->desc() !== '') { |
|
485 | - $html .= EEH_HTML::p( |
|
486 | - $question_group->desc(), |
|
487 | - '', |
|
488 | - $this->checkout->admin_request |
|
489 | - ? 'ee-reg-form-qstn-grp-desc-pg' |
|
490 | - : 'ee-reg-form-qstn-grp-desc-pg small-text lt-grey-text' |
|
491 | - ); |
|
492 | - } |
|
493 | - return new EE_Form_Section_HTML($html); |
|
494 | - } |
|
495 | - |
|
496 | - |
|
497 | - /** |
|
498 | - * @return EE_Form_Section_Proper |
|
499 | - * @throws EE_Error |
|
500 | - * @throws InvalidArgumentException |
|
501 | - * @throws ReflectionException |
|
502 | - * @throws InvalidDataTypeException |
|
503 | - * @throws InvalidInterfaceException |
|
504 | - */ |
|
505 | - private function _copy_attendee_info_form() |
|
506 | - { |
|
507 | - // array of params to pass to parent constructor |
|
508 | - return new EE_Form_Section_Proper( |
|
509 | - array( |
|
510 | - 'subsections' => $this->_copy_attendee_info_inputs(), |
|
511 | - 'layout_strategy' => new EE_Template_Layout( |
|
512 | - array( |
|
513 | - 'layout_template_file' => SPCO_REG_STEPS_PATH |
|
514 | - . $this->_slug |
|
515 | - . DS |
|
516 | - . 'copy_attendee_info.template.php', |
|
517 | - 'begin_template_file' => null, |
|
518 | - 'input_template_file' => null, |
|
519 | - 'subsection_template_file' => null, |
|
520 | - 'end_template_file' => null, |
|
521 | - ) |
|
522 | - ), |
|
523 | - ) |
|
524 | - ); |
|
525 | - } |
|
526 | - |
|
527 | - |
|
528 | - /** |
|
529 | - * @return EE_Form_Section_HTML |
|
530 | - * @throws DomainException |
|
531 | - * @throws InvalidArgumentException |
|
532 | - * @throws InvalidDataTypeException |
|
533 | - * @throws InvalidInterfaceException |
|
534 | - */ |
|
535 | - private function _auto_copy_attendee_info() |
|
536 | - { |
|
537 | - return new EE_Form_Section_HTML( |
|
538 | - EEH_Template::locate_template( |
|
539 | - SPCO_REG_STEPS_PATH . $this->_slug . DS . '_auto_copy_attendee_info.template.php', |
|
540 | - apply_filters( |
|
541 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args', |
|
542 | - array() |
|
543 | - ), |
|
544 | - true, |
|
545 | - true |
|
546 | - ) |
|
547 | - ); |
|
548 | - } |
|
549 | - |
|
550 | - |
|
551 | - /** |
|
552 | - * @return array |
|
553 | - * @throws EE_Error |
|
554 | - * @throws InvalidArgumentException |
|
555 | - * @throws ReflectionException |
|
556 | - * @throws InvalidDataTypeException |
|
557 | - * @throws InvalidInterfaceException |
|
558 | - */ |
|
559 | - private function _copy_attendee_info_inputs() |
|
560 | - { |
|
561 | - $copy_attendee_info_inputs = array(); |
|
562 | - $prev_ticket = null; |
|
563 | - // grab the saved registrations from the transaction |
|
564 | - $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
565 | - foreach ($registrations as $registration) { |
|
566 | - // for all attendees other than the primary attendee |
|
567 | - if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) { |
|
568 | - // if this is a new ticket OR if this is the very first additional attendee after the primary attendee |
|
569 | - if ($registration->ticket()->ID() !== $prev_ticket) { |
|
570 | - $item_name = $registration->ticket()->name(); |
|
571 | - $item_name .= $registration->ticket()->description() !== '' |
|
572 | - ? ' - ' . $registration->ticket()->description() |
|
573 | - : ''; |
|
574 | - $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID( |
|
575 | - ) . ']' ] = |
|
576 | - new EE_Form_Section_HTML( |
|
577 | - '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>' |
|
578 | - ); |
|
579 | - $prev_ticket = $registration->ticket()->ID(); |
|
580 | - } |
|
581 | - |
|
582 | - $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[' . $registration->ID() . ']' ] = |
|
583 | - new EE_Checkbox_Multi_Input( |
|
584 | - array( |
|
585 | - $registration->ID() => sprintf( |
|
586 | - esc_html_x('Attendee #%s', 'Attendee #123', 'event_espresso'), |
|
587 | - $registration->count() |
|
588 | - ), |
|
589 | - ), |
|
590 | - array( |
|
591 | - 'html_id' => 'spco-copy-attendee-chk-' . $registration->reg_url_link(), |
|
592 | - 'html_class' => 'spco-copy-attendee-chk ee-do-not-validate', |
|
593 | - 'display_html_label_text' => false, |
|
594 | - ) |
|
595 | - ); |
|
596 | - } |
|
597 | - } |
|
598 | - return $copy_attendee_info_inputs; |
|
599 | - } |
|
600 | - |
|
601 | - |
|
602 | - /** |
|
603 | - * @param EE_Registration $registration |
|
604 | - * @return EE_Form_Input_Base |
|
605 | - * @throws EE_Error |
|
606 | - */ |
|
607 | - private function _additional_primary_registrant_inputs(EE_Registration $registration) |
|
608 | - { |
|
609 | - // generate hidden input |
|
610 | - return new EE_Hidden_Input( |
|
611 | - array( |
|
612 | - 'html_id' => 'primary_registrant', |
|
613 | - 'default' => $registration->reg_url_link(), |
|
614 | - ) |
|
615 | - ); |
|
616 | - } |
|
617 | - |
|
618 | - |
|
619 | - /** |
|
620 | - * @param EE_Registration $registration |
|
621 | - * @param EE_Question $question |
|
622 | - * @return EE_Form_Input_Base |
|
623 | - * @throws EE_Error |
|
624 | - * @throws InvalidArgumentException |
|
625 | - * @throws InvalidDataTypeException |
|
626 | - * @throws InvalidInterfaceException |
|
627 | - * @throws ReflectionException |
|
628 | - */ |
|
629 | - public function reg_form_question(EE_Registration $registration, EE_Question $question) |
|
630 | - { |
|
631 | - |
|
632 | - // if this question was for an attendee detail, then check for that answer |
|
633 | - $answer_value = EEM_Answer::instance()->get_attendee_property_answer_value( |
|
634 | - $registration, |
|
635 | - $question->system_ID() |
|
636 | - ); |
|
637 | - $answer = $answer_value === null |
|
638 | - ? EEM_Answer::instance()->get_one( |
|
639 | - array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID())) |
|
640 | - ) |
|
641 | - : null; |
|
642 | - // if NOT returning to edit an existing registration |
|
643 | - // OR if this question is for an attendee property |
|
644 | - // OR we still don't have an EE_Answer object |
|
645 | - if ($answer_value || ! $answer instanceof EE_Answer || ! $registration->reg_url_link()) { |
|
646 | - // create an EE_Answer object for storing everything in |
|
647 | - $answer = EE_Answer::new_instance( |
|
648 | - array( |
|
649 | - 'QST_ID' => $question->ID(), |
|
650 | - 'REG_ID' => $registration->ID(), |
|
651 | - ) |
|
652 | - ); |
|
653 | - } |
|
654 | - // verify instance |
|
655 | - if ($answer instanceof EE_Answer) { |
|
656 | - if (! empty($answer_value)) { |
|
657 | - $answer->set('ANS_value', $answer_value); |
|
658 | - } |
|
659 | - $answer->cache('Question', $question); |
|
660 | - // remember system ID had a bug where sometimes it could be null |
|
661 | - $answer_cache_id = $question->is_system_question() |
|
662 | - ? $question->system_ID() . '-' . $registration->reg_url_link() |
|
663 | - : $question->ID() . '-' . $registration->reg_url_link(); |
|
664 | - $registration->cache('Answer', $answer, $answer_cache_id); |
|
665 | - } |
|
666 | - return $this->_generate_question_input($registration, $question, $answer); |
|
667 | - } |
|
668 | - |
|
669 | - |
|
670 | - /** |
|
671 | - * @param EE_Registration $registration |
|
672 | - * @param EE_Question $question |
|
673 | - * @param $answer |
|
674 | - * @return EE_Form_Input_Base |
|
675 | - * @throws EE_Error |
|
676 | - * @throws InvalidArgumentException |
|
677 | - * @throws ReflectionException |
|
678 | - * @throws InvalidDataTypeException |
|
679 | - * @throws InvalidInterfaceException |
|
680 | - */ |
|
681 | - private function _generate_question_input(EE_Registration $registration, EE_Question $question, $answer) |
|
682 | - { |
|
683 | - $identifier = $question->is_system_question() |
|
684 | - ? $question->system_ID() |
|
685 | - : $question->ID(); |
|
686 | - $this->_required_questions[ $identifier ] = $question->required() ? true : false; |
|
687 | - add_filter( |
|
688 | - 'FHEE__EE_Question__generate_form_input__country_options', |
|
689 | - array($this, 'use_cached_countries_for_form_input'), |
|
690 | - 10, |
|
691 | - 4 |
|
692 | - ); |
|
693 | - add_filter( |
|
694 | - 'FHEE__EE_Question__generate_form_input__state_options', |
|
695 | - array($this, 'use_cached_states_for_form_input'), |
|
696 | - 10, |
|
697 | - 4 |
|
698 | - ); |
|
699 | - $input_constructor_args = array( |
|
700 | - 'html_name' => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']', |
|
701 | - 'html_id' => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier, |
|
702 | - 'html_class' => 'ee-reg-qstn ee-reg-qstn-' . $identifier, |
|
703 | - 'html_label_id' => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier, |
|
704 | - 'html_label_class' => 'ee-reg-qstn', |
|
705 | - ); |
|
706 | - $input_constructor_args['html_label_id'] .= '-lbl'; |
|
707 | - if ($answer instanceof EE_Answer && $answer->ID()) { |
|
708 | - $input_constructor_args['html_name'] .= '[' . $answer->ID() . ']'; |
|
709 | - $input_constructor_args['html_id'] .= '-' . $answer->ID(); |
|
710 | - $input_constructor_args['html_label_id'] .= '-' . $answer->ID(); |
|
711 | - } |
|
712 | - $form_input = $question->generate_form_input( |
|
713 | - $registration, |
|
714 | - $answer, |
|
715 | - $input_constructor_args |
|
716 | - ); |
|
717 | - remove_filter( |
|
718 | - 'FHEE__EE_Question__generate_form_input__country_options', |
|
719 | - array($this, 'use_cached_countries_for_form_input') |
|
720 | - ); |
|
721 | - remove_filter( |
|
722 | - 'FHEE__EE_Question__generate_form_input__state_options', |
|
723 | - array($this, 'use_cached_states_for_form_input') |
|
724 | - ); |
|
725 | - return $form_input; |
|
726 | - } |
|
727 | - |
|
728 | - |
|
729 | - /** |
|
730 | - * Gets the list of countries for the form input |
|
731 | - * |
|
732 | - * @param array|null $countries_list |
|
733 | - * @param EE_Question $question |
|
734 | - * @param EE_Registration $registration |
|
735 | - * @param EE_Answer $answer |
|
736 | - * @return array 2d keys are country IDs, values are their names |
|
737 | - * @throws EE_Error |
|
738 | - * @throws InvalidArgumentException |
|
739 | - * @throws InvalidDataTypeException |
|
740 | - * @throws InvalidInterfaceException |
|
741 | - * @throws ReflectionException |
|
742 | - */ |
|
743 | - public function use_cached_countries_for_form_input( |
|
744 | - $countries_list, |
|
745 | - EE_Question $question = null, |
|
746 | - EE_Registration $registration = null, |
|
747 | - EE_Answer $answer = null |
|
748 | - ) { |
|
749 | - $country_options = array('' => ''); |
|
750 | - // get possibly cached list of countries |
|
751 | - $countries = $this->checkout->action === 'process_reg_step' |
|
752 | - ? EEM_Country::instance()->get_all_countries() |
|
753 | - : EEM_Country::instance()->get_all_active_countries(); |
|
754 | - if (! empty($countries)) { |
|
755 | - foreach ($countries as $country) { |
|
756 | - if ($country instanceof EE_Country) { |
|
757 | - $country_options[ $country->ID() ] = $country->name(); |
|
758 | - } |
|
759 | - } |
|
760 | - } |
|
761 | - if ($question instanceof EE_Question && $registration instanceof EE_Registration) { |
|
762 | - $answer = EEM_Answer::instance()->get_one( |
|
763 | - array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID())) |
|
764 | - ); |
|
765 | - } else { |
|
766 | - $answer = EE_Answer::new_instance(); |
|
767 | - } |
|
768 | - $country_options = apply_filters( |
|
769 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options', |
|
770 | - $country_options, |
|
771 | - $this, |
|
772 | - $registration, |
|
773 | - $question, |
|
774 | - $answer |
|
775 | - ); |
|
776 | - return $country_options; |
|
777 | - } |
|
778 | - |
|
779 | - |
|
780 | - /** |
|
781 | - * Gets the list of states for the form input |
|
782 | - * |
|
783 | - * @param array|null $states_list |
|
784 | - * @param EE_Question $question |
|
785 | - * @param EE_Registration $registration |
|
786 | - * @param EE_Answer $answer |
|
787 | - * @return array 2d keys are state IDs, values are their names |
|
788 | - * @throws EE_Error |
|
789 | - * @throws InvalidArgumentException |
|
790 | - * @throws InvalidDataTypeException |
|
791 | - * @throws InvalidInterfaceException |
|
792 | - * @throws ReflectionException |
|
793 | - */ |
|
794 | - public function use_cached_states_for_form_input( |
|
795 | - $states_list, |
|
796 | - EE_Question $question = null, |
|
797 | - EE_Registration $registration = null, |
|
798 | - EE_Answer $answer = null |
|
799 | - ) { |
|
800 | - $state_options = array('' => array('' => '')); |
|
801 | - $states = $this->checkout->action === 'process_reg_step' |
|
802 | - ? EEM_State::instance()->get_all_states() |
|
803 | - : EEM_State::instance()->get_all_active_states(); |
|
804 | - if (! empty($states)) { |
|
805 | - foreach ($states as $state) { |
|
806 | - if ($state instanceof EE_State) { |
|
807 | - $state_options[ $state->country()->name() ][ $state->ID() ] = $state->name(); |
|
808 | - } |
|
809 | - } |
|
810 | - } |
|
811 | - $state_options = apply_filters( |
|
812 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options', |
|
813 | - $state_options, |
|
814 | - $this, |
|
815 | - $registration, |
|
816 | - $question, |
|
817 | - $answer |
|
818 | - ); |
|
819 | - return $state_options; |
|
820 | - } |
|
821 | - |
|
822 | - |
|
823 | - /********************************************************************************************************/ |
|
824 | - /**************************************** PROCESS REG STEP ****************************************/ |
|
825 | - /********************************************************************************************************/ |
|
826 | - |
|
827 | - |
|
828 | - /** |
|
829 | - * @return bool |
|
830 | - * @throws EE_Error |
|
831 | - * @throws InvalidArgumentException |
|
832 | - * @throws ReflectionException |
|
833 | - * @throws RuntimeException |
|
834 | - * @throws InvalidDataTypeException |
|
835 | - * @throws InvalidInterfaceException |
|
836 | - */ |
|
837 | - public function process_reg_step() |
|
838 | - { |
|
839 | - do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
840 | - // grab validated data from form |
|
841 | - $valid_data = $this->checkout->current_step->valid_data(); |
|
842 | - // EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ ); |
|
843 | - // EEH_Debug_Tools::printr( $valid_data, '$valid_data', __FILE__, __LINE__ ); |
|
844 | - // if we don't have any $valid_data then something went TERRIBLY WRONG !!! |
|
845 | - if (empty($valid_data)) { |
|
846 | - EE_Error::add_error( |
|
847 | - esc_html__('No valid question responses were received.', 'event_espresso'), |
|
848 | - __FILE__, |
|
849 | - __FUNCTION__, |
|
850 | - __LINE__ |
|
851 | - ); |
|
852 | - return false; |
|
853 | - } |
|
854 | - if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) { |
|
855 | - EE_Error::add_error( |
|
856 | - esc_html__( |
|
857 | - 'A valid transaction could not be initiated for processing your registrations.', |
|
858 | - 'event_espresso' |
|
859 | - ), |
|
860 | - __FILE__, |
|
861 | - __FUNCTION__, |
|
862 | - __LINE__ |
|
863 | - ); |
|
864 | - return false; |
|
865 | - } |
|
866 | - // get cached registrations |
|
867 | - $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
868 | - // verify we got the goods |
|
869 | - if (empty($registrations)) { |
|
870 | - // combine the old translated string with a new one, in order to not break translations |
|
871 | - $error_message = esc_html__( |
|
872 | - 'Your form data could not be applied to any valid registrations.', |
|
873 | - 'event_espresso' |
|
874 | - ) |
|
875 | - . sprintf( |
|
876 | - esc_html_x( |
|
877 | - '%3$sThis can sometimes happen if too much time has been taken to complete the registration process.%3$sPlease return to the %1$sEvent List%2$s and reselect your tickets. If the problem continues, please contact the site administrator.', |
|
878 | - '(line break)This can sometimes happen if too much time has been taken to complete the registration process.(line break)Please return to the (link)Event List(end link) and reselect your tickets. If the problem continues, please contact the site administrator.', |
|
879 | - 'event_espresso' |
|
880 | - ), |
|
881 | - '<a href="' . get_post_type_archive_link('espresso_events') . '" >', |
|
882 | - '</a>', |
|
883 | - '<br />' |
|
884 | - ); |
|
885 | - EE_Error::add_error( |
|
886 | - $error_message, |
|
887 | - __FILE__, |
|
888 | - __FUNCTION__, |
|
889 | - __LINE__ |
|
890 | - ); |
|
891 | - return false; |
|
892 | - } |
|
893 | - // extract attendee info from form data and save to model objects |
|
894 | - $registrations_processed = $this->_process_registrations($registrations, $valid_data); |
|
895 | - // if first pass thru SPCO, |
|
896 | - // then let's check processed registrations against the total number of tickets in the cart |
|
897 | - if ($registrations_processed === false) { |
|
898 | - // but return immediately if the previous step exited early due to errors |
|
899 | - return false; |
|
900 | - } |
|
901 | - if (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) { |
|
902 | - // generate a correctly translated string for all possible singular/plural combinations |
|
903 | - if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) { |
|
904 | - $error_msg = sprintf( |
|
905 | - esc_html_x( |
|
906 | - 'There was %1$d ticket in the Event Queue, but %2$ds registrations were processed', |
|
907 | - 'There was 1 ticket in the Event Queue, but 2 registrations were processed', |
|
908 | - 'event_espresso' |
|
909 | - ), |
|
910 | - $this->checkout->total_ticket_count, |
|
911 | - $registrations_processed |
|
912 | - ); |
|
913 | - } elseif ($this->checkout->total_ticket_count !== 1 && $registrations_processed === 1) { |
|
914 | - $error_msg = sprintf( |
|
915 | - esc_html_x( |
|
916 | - 'There was a total of %1$d tickets in the Event Queue, but only %2$ds registration was processed', |
|
917 | - 'There was a total of 2 tickets in the Event Queue, but only 1 registration was processed', |
|
918 | - 'event_espresso' |
|
919 | - ), |
|
920 | - $this->checkout->total_ticket_count, |
|
921 | - $registrations_processed |
|
922 | - ); |
|
923 | - } else { |
|
924 | - $error_msg = sprintf( |
|
925 | - esc_html__( |
|
926 | - 'There was a total of 2 tickets in the Event Queue, but 2 registrations were processed', |
|
927 | - 'event_espresso' |
|
928 | - ), |
|
929 | - $this->checkout->total_ticket_count, |
|
930 | - $registrations_processed |
|
931 | - ); |
|
932 | - } |
|
933 | - EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__); |
|
934 | - return false; |
|
935 | - } |
|
936 | - // mark this reg step as completed |
|
937 | - $this->set_completed(); |
|
938 | - $this->_set_success_message( |
|
939 | - esc_html__('The Attendee Information Step has been successfully completed.', 'event_espresso') |
|
940 | - ); |
|
941 | - // do action in case a plugin wants to do something with the data submitted in step 1. |
|
942 | - // passes EE_Single_Page_Checkout, and it's posted data |
|
943 | - do_action('AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data); |
|
944 | - return true; |
|
945 | - } |
|
946 | - |
|
947 | - |
|
948 | - /** |
|
949 | - * _process_registrations |
|
950 | - * |
|
951 | - * @param EE_Registration[] $registrations |
|
952 | - * @param array[][] $valid_data |
|
953 | - * @return bool|int |
|
954 | - * @throws EntityNotFoundException |
|
955 | - * @throws EE_Error |
|
956 | - * @throws InvalidArgumentException |
|
957 | - * @throws ReflectionException |
|
958 | - * @throws RuntimeException |
|
959 | - * @throws InvalidDataTypeException |
|
960 | - * @throws InvalidInterfaceException |
|
961 | - */ |
|
962 | - private function _process_registrations($registrations = array(), $valid_data = array()) |
|
963 | - { |
|
964 | - // load resources and set some defaults |
|
965 | - EE_Registry::instance()->load_model('Attendee'); |
|
966 | - // holder for primary registrant attendee object |
|
967 | - $this->checkout->primary_attendee_obj = null; |
|
968 | - // array for tracking reg form data for the primary registrant |
|
969 | - $primary_registrant = array( |
|
970 | - 'line_item_id' => null, |
|
971 | - ); |
|
972 | - $copy_primary = false; |
|
973 | - // reg form sections that do not contain inputs |
|
974 | - $non_input_form_sections = array( |
|
975 | - 'primary_registrant', |
|
976 | - 'additional_attendee_reg_info', |
|
977 | - 'spco_copy_attendee_chk', |
|
978 | - ); |
|
979 | - // attendee counter |
|
980 | - $att_nmbr = 0; |
|
981 | - // grab the saved registrations from the transaction |
|
982 | - foreach ($registrations as $registration) { |
|
983 | - // verify EE_Registration object |
|
984 | - if (! $registration instanceof EE_Registration) { |
|
985 | - EE_Error::add_error( |
|
986 | - esc_html__( |
|
987 | - 'An invalid Registration object was discovered when attempting to process your registration information.', |
|
988 | - 'event_espresso' |
|
989 | - ), |
|
990 | - __FILE__, |
|
991 | - __FUNCTION__, |
|
992 | - __LINE__ |
|
993 | - ); |
|
994 | - return false; |
|
995 | - } |
|
996 | - /** @var string $reg_url_link */ |
|
997 | - $reg_url_link = $registration->reg_url_link(); |
|
998 | - // reg_url_link exists ? |
|
999 | - if (! empty($reg_url_link)) { |
|
1000 | - // should this registration be processed during this visit ? |
|
1001 | - if ($this->checkout->visit_allows_processing_of_this_registration($registration)) { |
|
1002 | - // if NOT revisiting, then let's save the registration now, |
|
1003 | - // so that we have a REG_ID to use when generating other objects |
|
1004 | - if (! $this->checkout->revisit) { |
|
1005 | - $registration->save(); |
|
1006 | - } |
|
1007 | - /** |
|
1008 | - * This allows plugins to trigger a fail on processing of a |
|
1009 | - * registration for any conditions they may have for it to pass. |
|
1010 | - * |
|
1011 | - * @var bool if true is returned by the plugin then the |
|
1012 | - * registration processing is halted. |
|
1013 | - */ |
|
1014 | - if (apply_filters( |
|
1015 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process', |
|
1016 | - false, |
|
1017 | - $att_nmbr, |
|
1018 | - $registration, |
|
1019 | - $registrations, |
|
1020 | - $valid_data, |
|
1021 | - $this |
|
1022 | - )) { |
|
1023 | - return false; |
|
1024 | - } |
|
1025 | - |
|
1026 | - // Houston, we have a registration! |
|
1027 | - $att_nmbr++; |
|
1028 | - $this->_attendee_data[ $reg_url_link ] = array(); |
|
1029 | - // grab any existing related answer objects |
|
1030 | - $this->_registration_answers = $registration->answers(); |
|
1031 | - // unset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] ); |
|
1032 | - if (isset($valid_data[ $reg_url_link ])) { |
|
1033 | - // do we need to copy basic info from primary attendee ? |
|
1034 | - $copy_primary = isset($valid_data[ $reg_url_link ]['additional_attendee_reg_info']) |
|
1035 | - && absint($valid_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0; |
|
1036 | - // filter form input data for this registration |
|
1037 | - $valid_data[ $reg_url_link ] = (array) apply_filters( |
|
1038 | - 'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item', |
|
1039 | - $valid_data[ $reg_url_link ] |
|
1040 | - ); |
|
1041 | - if (isset($valid_data['primary_attendee'])) { |
|
1042 | - $primary_registrant['line_item_id'] = ! empty($valid_data['primary_attendee']) |
|
1043 | - ? $valid_data['primary_attendee'] |
|
1044 | - : false; |
|
1045 | - unset($valid_data['primary_attendee']); |
|
1046 | - } |
|
1047 | - // now loop through our array of valid post data && process attendee reg forms |
|
1048 | - foreach ($valid_data[ $reg_url_link ] as $form_section => $form_inputs) { |
|
1049 | - if (! in_array($form_section, $non_input_form_sections, true)) { |
|
1050 | - foreach ($form_inputs as $form_input => $input_value) { |
|
1051 | - // \EEH_Debug_Tools::printr( $input_value, $form_input, __FILE__, __LINE__ ); |
|
1052 | - // check for critical inputs |
|
1053 | - if (! $this->_verify_critical_attendee_details_are_set_and_validate_email( |
|
1054 | - $form_input, |
|
1055 | - $input_value |
|
1056 | - ) |
|
1057 | - ) { |
|
1058 | - return false; |
|
1059 | - } |
|
1060 | - // store a bit of data about the primary attendee |
|
1061 | - if ($att_nmbr === 1 |
|
1062 | - && ! empty($input_value) |
|
1063 | - && $reg_url_link === $primary_registrant['line_item_id'] |
|
1064 | - ) { |
|
1065 | - $primary_registrant[ $form_input ] = $input_value; |
|
1066 | - } elseif ($copy_primary |
|
1067 | - && $input_value === null |
|
1068 | - && isset($primary_registrant[ $form_input ]) |
|
1069 | - ) { |
|
1070 | - $input_value = $primary_registrant[ $form_input ]; |
|
1071 | - } |
|
1072 | - // now attempt to save the input data |
|
1073 | - if (! $this->_save_registration_form_input( |
|
1074 | - $registration, |
|
1075 | - $form_input, |
|
1076 | - $input_value |
|
1077 | - ) |
|
1078 | - ) { |
|
1079 | - EE_Error::add_error( |
|
1080 | - sprintf( |
|
1081 | - esc_html_x( |
|
1082 | - 'Unable to save registration form data for the form input: "%1$s" with the submitted value: "%2$s"', |
|
1083 | - 'Unable to save registration form data for the form input: "form input name" with the submitted value: "form input value"', |
|
1084 | - 'event_espresso' |
|
1085 | - ), |
|
1086 | - $form_input, |
|
1087 | - $input_value |
|
1088 | - ), |
|
1089 | - __FILE__, |
|
1090 | - __FUNCTION__, |
|
1091 | - __LINE__ |
|
1092 | - ); |
|
1093 | - return false; |
|
1094 | - } |
|
1095 | - } |
|
1096 | - } |
|
1097 | - } // end of foreach ( $valid_data[ $reg_url_link ] as $form_section => $form_inputs ) |
|
1098 | - } |
|
1099 | - // EEH_Debug_Tools::printr( $this->_attendee_data, '$this->_attendee_data', __FILE__, __LINE__ ); |
|
1100 | - // this registration does not require additional attendee information ? |
|
1101 | - if ($copy_primary |
|
1102 | - && $att_nmbr > 1 |
|
1103 | - && $this->checkout->primary_attendee_obj instanceof EE_Attendee |
|
1104 | - ) { |
|
1105 | - // just copy the primary registrant |
|
1106 | - $attendee = $this->checkout->primary_attendee_obj; |
|
1107 | - } else { |
|
1108 | - // ensure critical details are set for additional attendees |
|
1109 | - $this->_attendee_data[ $reg_url_link ] = $att_nmbr > 1 |
|
1110 | - ? $this->_copy_critical_attendee_details_from_primary_registrant( |
|
1111 | - $this->_attendee_data[ $reg_url_link ] |
|
1112 | - ) |
|
1113 | - : $this->_attendee_data[ $reg_url_link ]; |
|
1114 | - // execute create attendee command (which may return an existing attendee) |
|
1115 | - $attendee = EE_Registry::instance()->BUS->execute( |
|
1116 | - new CreateAttendeeCommand( |
|
1117 | - $this->_attendee_data[ $reg_url_link ], |
|
1118 | - $registration |
|
1119 | - ) |
|
1120 | - ); |
|
1121 | - // who's #1 ? |
|
1122 | - if ($att_nmbr === 1) { |
|
1123 | - $this->checkout->primary_attendee_obj = $attendee; |
|
1124 | - } |
|
1125 | - } |
|
1126 | - // EEH_Debug_Tools::printr( $attendee, '$attendee', __FILE__, __LINE__ ); |
|
1127 | - // add relation to registration, set attendee ID, and cache attendee |
|
1128 | - $this->_associate_attendee_with_registration($registration, $attendee); |
|
1129 | - // \EEH_Debug_Tools::printr( $registration, '$registration', __FILE__, __LINE__ ); |
|
1130 | - if (! $registration->attendee() instanceof EE_Attendee) { |
|
1131 | - EE_Error::add_error( |
|
1132 | - sprintf( |
|
1133 | - esc_html_x( |
|
1134 | - 'Registration %s has an invalid or missing Attendee object.', |
|
1135 | - 'Registration 123-456-789 has an invalid or missing Attendee object.', |
|
1136 | - 'event_espresso' |
|
1137 | - ), |
|
1138 | - $reg_url_link |
|
1139 | - ), |
|
1140 | - __FILE__, |
|
1141 | - __FUNCTION__, |
|
1142 | - __LINE__ |
|
1143 | - ); |
|
1144 | - return false; |
|
1145 | - } |
|
1146 | - /** @type EE_Registration_Processor $registration_processor */ |
|
1147 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
1148 | - // at this point, we should have enough details about the registrant to consider the registration |
|
1149 | - // NOT incomplete |
|
1150 | - $registration_processor->toggle_incomplete_registration_status_to_default( |
|
1151 | - $registration, |
|
1152 | - false, |
|
1153 | - new Context( |
|
1154 | - 'spco_reg_step_attendee_information_process_registrations', |
|
1155 | - esc_html__( |
|
1156 | - 'Finished populating registration with details from the registration form after submitting the Attendee Information Reg Step.', |
|
1157 | - 'event_espresso' |
|
1158 | - ) |
|
1159 | - ) |
|
1160 | - ); |
|
1161 | - // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to |
|
1162 | - // abandoned |
|
1163 | - $this->checkout->transaction->toggle_failed_transaction_status(); |
|
1164 | - // if we've gotten this far, then let's save what we have |
|
1165 | - $registration->save(); |
|
1166 | - // add relation between TXN and registration |
|
1167 | - $this->_associate_registration_with_transaction($registration); |
|
1168 | - } |
|
1169 | - } else { |
|
1170 | - EE_Error::add_error( |
|
1171 | - esc_html__( |
|
1172 | - 'An invalid or missing line item ID was encountered while attempting to process the registration form.', |
|
1173 | - 'event_espresso' |
|
1174 | - ), |
|
1175 | - __FILE__, |
|
1176 | - __FUNCTION__, |
|
1177 | - __LINE__ |
|
1178 | - ); |
|
1179 | - // remove malformed data |
|
1180 | - unset($valid_data[ $reg_url_link ]); |
|
1181 | - return false; |
|
1182 | - } |
|
1183 | - } // end of foreach ( $this->checkout->transaction->registrations() as $registration ) |
|
1184 | - return $att_nmbr; |
|
1185 | - } |
|
1186 | - |
|
1187 | - |
|
1188 | - /** |
|
1189 | - * _save_registration_form_input |
|
1190 | - * |
|
1191 | - * @param EE_Registration $registration |
|
1192 | - * @param string $form_input |
|
1193 | - * @param string $input_value |
|
1194 | - * @return bool |
|
1195 | - * @throws EE_Error |
|
1196 | - * @throws InvalidArgumentException |
|
1197 | - * @throws InvalidDataTypeException |
|
1198 | - * @throws InvalidInterfaceException |
|
1199 | - * @throws ReflectionException |
|
1200 | - */ |
|
1201 | - private function _save_registration_form_input( |
|
1202 | - EE_Registration $registration, |
|
1203 | - $form_input = '', |
|
1204 | - $input_value = '' |
|
1205 | - ) { |
|
1206 | - // \EEH_Debug_Tools::printr( __FUNCTION__, __CLASS__, __FILE__, __LINE__, 2 ); |
|
1207 | - // \EEH_Debug_Tools::printr( $form_input, '$form_input', __FILE__, __LINE__ ); |
|
1208 | - // \EEH_Debug_Tools::printr( $input_value, '$input_value', __FILE__, __LINE__ ); |
|
1209 | - // allow for plugins to hook in and do their own processing of the form input. |
|
1210 | - // For plugins to bypass normal processing here, they just need to return a boolean value. |
|
1211 | - if (apply_filters( |
|
1212 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input', |
|
1213 | - false, |
|
1214 | - $registration, |
|
1215 | - $form_input, |
|
1216 | - $input_value, |
|
1217 | - $this |
|
1218 | - )) { |
|
1219 | - return true; |
|
1220 | - } |
|
1221 | - /* |
|
21 | + /** |
|
22 | + * @type bool $_print_copy_info |
|
23 | + */ |
|
24 | + private $_print_copy_info = false; |
|
25 | + |
|
26 | + /** |
|
27 | + * @type array $_attendee_data |
|
28 | + */ |
|
29 | + private $_attendee_data = array(); |
|
30 | + |
|
31 | + /** |
|
32 | + * @type array $_required_questions |
|
33 | + */ |
|
34 | + private $_required_questions = array(); |
|
35 | + |
|
36 | + /** |
|
37 | + * @type array $_registration_answers |
|
38 | + */ |
|
39 | + private $_registration_answers = array(); |
|
40 | + |
|
41 | + |
|
42 | + /** |
|
43 | + * class constructor |
|
44 | + * |
|
45 | + * @access public |
|
46 | + * @param EE_Checkout $checkout |
|
47 | + */ |
|
48 | + public function __construct(EE_Checkout $checkout) |
|
49 | + { |
|
50 | + $this->_slug = 'attendee_information'; |
|
51 | + $this->_name = esc_html__('Attendee Information', 'event_espresso'); |
|
52 | + $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . DS . 'attendee_info_main.template.php'; |
|
53 | + $this->checkout = $checkout; |
|
54 | + $this->_reset_success_message(); |
|
55 | + $this->set_instructions( |
|
56 | + esc_html__('Please answer the following registration questions before proceeding.', 'event_espresso') |
|
57 | + ); |
|
58 | + } |
|
59 | + |
|
60 | + |
|
61 | + public function translate_js_strings() |
|
62 | + { |
|
63 | + EE_Registry::$i18n_js_strings['required_field'] = esc_html__( |
|
64 | + ' is a required question.', |
|
65 | + 'event_espresso' |
|
66 | + ); |
|
67 | + EE_Registry::$i18n_js_strings['required_multi_field'] = esc_html__( |
|
68 | + ' is a required question. Please enter a value for at least one of the options.', |
|
69 | + 'event_espresso' |
|
70 | + ); |
|
71 | + EE_Registry::$i18n_js_strings['answer_required_questions'] = esc_html__( |
|
72 | + 'Please answer all required questions correctly before proceeding.', |
|
73 | + 'event_espresso' |
|
74 | + ); |
|
75 | + EE_Registry::$i18n_js_strings['attendee_info_copied'] = sprintf( |
|
76 | + esc_html_x( |
|
77 | + 'The attendee information was successfully copied.%sPlease ensure the rest of the registration form is completed before proceeding.', |
|
78 | + 'The attendee information was successfully copied.(line break)Please ensure the rest of the registration form is completed before proceeding.', |
|
79 | + 'event_espresso' |
|
80 | + ), |
|
81 | + '<br/>' |
|
82 | + ); |
|
83 | + EE_Registry::$i18n_js_strings['attendee_info_copy_error'] = esc_html__( |
|
84 | + 'An unknown error occurred on the server while attempting to copy the attendee information. Please refresh the page and try again.', |
|
85 | + 'event_espresso' |
|
86 | + ); |
|
87 | + EE_Registry::$i18n_js_strings['enter_valid_email'] = esc_html__( |
|
88 | + 'You must enter a valid email address.', |
|
89 | + 'event_espresso' |
|
90 | + ); |
|
91 | + EE_Registry::$i18n_js_strings['valid_email_and_questions'] = esc_html__( |
|
92 | + 'You must enter a valid email address and answer all other required questions before you can proceed.', |
|
93 | + 'event_espresso' |
|
94 | + ); |
|
95 | + } |
|
96 | + |
|
97 | + |
|
98 | + public function enqueue_styles_and_scripts() |
|
99 | + { |
|
100 | + } |
|
101 | + |
|
102 | + |
|
103 | + /** |
|
104 | + * @return boolean |
|
105 | + */ |
|
106 | + public function initialize_reg_step() |
|
107 | + { |
|
108 | + return true; |
|
109 | + } |
|
110 | + |
|
111 | + |
|
112 | + /** |
|
113 | + * @return EE_Form_Section_Proper |
|
114 | + * @throws DomainException |
|
115 | + * @throws EE_Error |
|
116 | + * @throws InvalidArgumentException |
|
117 | + * @throws ReflectionException |
|
118 | + * @throws EntityNotFoundException |
|
119 | + * @throws InvalidDataTypeException |
|
120 | + * @throws InvalidInterfaceException |
|
121 | + */ |
|
122 | + public function generate_reg_form() |
|
123 | + { |
|
124 | + $this->_print_copy_info = false; |
|
125 | + $primary_registrant = null; |
|
126 | + // autoload Line_Item_Display classes |
|
127 | + EEH_Autoloader::register_line_item_display_autoloaders(); |
|
128 | + $Line_Item_Display = new EE_Line_Item_Display(); |
|
129 | + // calculate taxes |
|
130 | + $Line_Item_Display->display_line_item( |
|
131 | + $this->checkout->cart->get_grand_total(), |
|
132 | + array('set_tax_rate' => true) |
|
133 | + ); |
|
134 | + /** @var $subsections EE_Form_Section_Proper[] */ |
|
135 | + $extra_inputs_section = $this->reg_step_hidden_inputs(); |
|
136 | + $subsections = array( |
|
137 | + 'default_hidden_inputs' => $extra_inputs_section, |
|
138 | + ); |
|
139 | + |
|
140 | + /** |
|
141 | + * @var $reg_config EE_Registration_Config |
|
142 | + */ |
|
143 | + $reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config'); |
|
144 | + // if this isn't a revisit, and they have the privacy consent box enalbed, add it |
|
145 | + if (! $this->checkout->revisit && $reg_config->isConsentCheckboxEnabled()) { |
|
146 | + $extra_inputs_section->add_subsections( |
|
147 | + array( |
|
148 | + 'consent_box' => new EE_Form_Section_Proper( |
|
149 | + array( |
|
150 | + 'layout_strategy' => |
|
151 | + new EE_Template_Layout( |
|
152 | + array( |
|
153 | + 'input_template_file' => SPCO_REG_STEPS_PATH . $this->_slug . DS . 'privacy_consent.template.php', |
|
154 | + ) |
|
155 | + ), |
|
156 | + 'subsections' => array( |
|
157 | + 'consent' => new EE_Checkbox_Multi_Input( |
|
158 | + array( |
|
159 | + 'consent' => $reg_config->getConsentCheckboxLabelText(), |
|
160 | + ), |
|
161 | + array( |
|
162 | + 'required' => true, |
|
163 | + 'required_validation_error_message' => esc_html__( |
|
164 | + 'You must consent to these terms in order to register.', |
|
165 | + 'event_espresso' |
|
166 | + ), |
|
167 | + 'html_label_text' => '', |
|
168 | + ) |
|
169 | + ), |
|
170 | + ), |
|
171 | + ) |
|
172 | + ), |
|
173 | + ), |
|
174 | + null, |
|
175 | + false |
|
176 | + ); |
|
177 | + } |
|
178 | + $template_args = array( |
|
179 | + 'revisit' => $this->checkout->revisit, |
|
180 | + 'registrations' => array(), |
|
181 | + 'ticket_count' => array(), |
|
182 | + ); |
|
183 | + // grab the saved registrations from the transaction |
|
184 | + $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
185 | + if ($registrations) { |
|
186 | + foreach ($registrations as $registration) { |
|
187 | + // can this registration be processed during this visit ? |
|
188 | + if ($registration instanceof EE_Registration |
|
189 | + && $this->checkout->visit_allows_processing_of_this_registration($registration) |
|
190 | + ) { |
|
191 | + $subsections[ $registration->reg_url_link() ] = $this->_registrations_reg_form($registration); |
|
192 | + if (! $this->checkout->admin_request) { |
|
193 | + $template_args['registrations'][ $registration->reg_url_link() ] = $registration; |
|
194 | + $template_args['ticket_count'][ $registration->ticket()->ID() ] = isset( |
|
195 | + $template_args['ticket_count'][ $registration->ticket()->ID() ] |
|
196 | + ) |
|
197 | + ? $template_args['ticket_count'][ $registration->ticket()->ID() ] + 1 |
|
198 | + : 1; |
|
199 | + $ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs( |
|
200 | + $this->checkout->cart->get_grand_total(), |
|
201 | + 'Ticket', |
|
202 | + array($registration->ticket()->ID()) |
|
203 | + ); |
|
204 | + $ticket_line_item = is_array($ticket_line_item) |
|
205 | + ? reset($ticket_line_item) |
|
206 | + : $ticket_line_item; |
|
207 | + $template_args['ticket_line_item'][ $registration->ticket()->ID() ] = |
|
208 | + $Line_Item_Display->display_line_item($ticket_line_item); |
|
209 | + } |
|
210 | + if ($registration->is_primary_registrant()) { |
|
211 | + $primary_registrant = $registration->reg_url_link(); |
|
212 | + } |
|
213 | + } |
|
214 | + } |
|
215 | + // print_copy_info ? |
|
216 | + if ($primary_registrant && ! $this->checkout->admin_request && count($registrations) > 1) { |
|
217 | + // TODO: add admin option for toggling copy attendee info, |
|
218 | + // then use that value to change $this->_print_copy_info |
|
219 | + $copy_options['spco_copy_attendee_chk'] = $this->_print_copy_info |
|
220 | + ? $this->_copy_attendee_info_form() |
|
221 | + : $this->_auto_copy_attendee_info(); |
|
222 | + // generate hidden input |
|
223 | + if (isset($subsections[ $primary_registrant ]) |
|
224 | + && $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper |
|
225 | + ) { |
|
226 | + $subsections[ $primary_registrant ]->add_subsections( |
|
227 | + $copy_options, |
|
228 | + 'primary_registrant', |
|
229 | + false |
|
230 | + ); |
|
231 | + } |
|
232 | + } |
|
233 | + } |
|
234 | + return new EE_Form_Section_Proper( |
|
235 | + array( |
|
236 | + 'name' => $this->reg_form_name(), |
|
237 | + 'html_id' => $this->reg_form_name(), |
|
238 | + 'subsections' => $subsections, |
|
239 | + 'layout_strategy' => $this->checkout->admin_request |
|
240 | + ? |
|
241 | + new EE_Div_Per_Section_Layout() |
|
242 | + : |
|
243 | + new EE_Template_Layout( |
|
244 | + array( |
|
245 | + 'layout_template_file' => $this->_template, // layout_template |
|
246 | + 'template_args' => $template_args, |
|
247 | + ) |
|
248 | + ), |
|
249 | + ) |
|
250 | + ); |
|
251 | + } |
|
252 | + |
|
253 | + |
|
254 | + /** |
|
255 | + * @param EE_Registration $registration |
|
256 | + * @return EE_Form_Section_Base |
|
257 | + * @throws EE_Error |
|
258 | + * @throws InvalidArgumentException |
|
259 | + * @throws EntityNotFoundException |
|
260 | + * @throws InvalidDataTypeException |
|
261 | + * @throws InvalidInterfaceException |
|
262 | + * @throws ReflectionException |
|
263 | + */ |
|
264 | + private function _registrations_reg_form(EE_Registration $registration) |
|
265 | + { |
|
266 | + static $attendee_nmbr = 1; |
|
267 | + $form_args = array(); |
|
268 | + // verify that registration has valid event |
|
269 | + if ($registration->event() instanceof EE_Event) { |
|
270 | + $field_name = 'Event_Question_Group.' |
|
271 | + . EEM_Event_Question_Group::instance()->fieldNameForContext( |
|
272 | + $registration->is_primary_registrant() |
|
273 | + ); |
|
274 | + $question_groups = $registration->event()->question_groups( |
|
275 | + apply_filters( |
|
276 | + // @codingStandardsIgnoreStart |
|
277 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___registrations_reg_form__question_groups_query_parameters', |
|
278 | + // @codingStandardsIgnoreEnd |
|
279 | + [ |
|
280 | + [ |
|
281 | + 'Event.EVT_ID' => $registration->event()->ID(), |
|
282 | + $field_name => true, |
|
283 | + ], |
|
284 | + 'order_by' => ['QSG_order' => 'ASC'], |
|
285 | + ], |
|
286 | + $registration, |
|
287 | + $this |
|
288 | + ) |
|
289 | + ); |
|
290 | + if ($question_groups) { |
|
291 | + // array of params to pass to parent constructor |
|
292 | + $form_args = array( |
|
293 | + 'html_id' => 'ee-registration-' . $registration->reg_url_link(), |
|
294 | + 'html_class' => 'ee-reg-form-attendee-dv', |
|
295 | + 'html_style' => $this->checkout->admin_request |
|
296 | + ? 'padding:0em 2em 1em; margin:3em 0 0; border:1px solid #ddd;' |
|
297 | + : '', |
|
298 | + 'subsections' => array(), |
|
299 | + 'layout_strategy' => new EE_Fieldset_Section_Layout( |
|
300 | + array( |
|
301 | + 'legend_class' => 'spco-attendee-lgnd smaller-text lt-grey-text', |
|
302 | + 'legend_text' => sprintf( |
|
303 | + esc_html_x( |
|
304 | + 'Attendee %d', |
|
305 | + 'Attendee 123', |
|
306 | + 'event_espresso' |
|
307 | + ), |
|
308 | + $attendee_nmbr |
|
309 | + ), |
|
310 | + ) |
|
311 | + ), |
|
312 | + ); |
|
313 | + foreach ($question_groups as $question_group) { |
|
314 | + if ($question_group instanceof EE_Question_Group) { |
|
315 | + $form_args['subsections'][ $question_group->identifier() ] = $this->_question_group_reg_form( |
|
316 | + $registration, |
|
317 | + $question_group |
|
318 | + ); |
|
319 | + } |
|
320 | + } |
|
321 | + // add hidden input |
|
322 | + $form_args['subsections']['additional_attendee_reg_info'] = $this->_additional_attendee_reg_info_input( |
|
323 | + $registration |
|
324 | + ); |
|
325 | + // if we have question groups for additional attendees, then display the copy options |
|
326 | + $this->_print_copy_info = $attendee_nmbr > 1 ? true : $this->_print_copy_info; |
|
327 | + if ($registration->is_primary_registrant()) { |
|
328 | + // generate hidden input |
|
329 | + $form_args['subsections']['primary_registrant'] = $this->_additional_primary_registrant_inputs( |
|
330 | + $registration |
|
331 | + ); |
|
332 | + } |
|
333 | + } |
|
334 | + } |
|
335 | + $attendee_nmbr++; |
|
336 | + return ! empty($form_args) |
|
337 | + ? new EE_Form_Section_Proper($form_args) |
|
338 | + : new EE_Form_Section_HTML(); |
|
339 | + } |
|
340 | + |
|
341 | + |
|
342 | + /** |
|
343 | + * @param EE_Registration $registration |
|
344 | + * @param bool $additional_attendee_reg_info |
|
345 | + * @return EE_Form_Input_Base |
|
346 | + * @throws EE_Error |
|
347 | + */ |
|
348 | + private function _additional_attendee_reg_info_input( |
|
349 | + EE_Registration $registration, |
|
350 | + $additional_attendee_reg_info = true |
|
351 | + ) { |
|
352 | + // generate hidden input |
|
353 | + return new EE_Hidden_Input( |
|
354 | + array( |
|
355 | + 'html_id' => 'additional-attendee-reg-info-' . $registration->reg_url_link(), |
|
356 | + 'default' => $additional_attendee_reg_info, |
|
357 | + ) |
|
358 | + ); |
|
359 | + } |
|
360 | + |
|
361 | + |
|
362 | + /** |
|
363 | + * @param EE_Registration $registration |
|
364 | + * @param EE_Question_Group $question_group |
|
365 | + * @return EE_Form_Section_Proper |
|
366 | + * @throws EE_Error |
|
367 | + * @throws InvalidArgumentException |
|
368 | + * @throws InvalidDataTypeException |
|
369 | + * @throws InvalidInterfaceException |
|
370 | + * @throws ReflectionException |
|
371 | + */ |
|
372 | + private function _question_group_reg_form(EE_Registration $registration, EE_Question_Group $question_group) |
|
373 | + { |
|
374 | + // array of params to pass to parent constructor |
|
375 | + $form_args = array( |
|
376 | + 'html_id' => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-' . $registration->ID(), |
|
377 | + 'html_class' => $this->checkout->admin_request |
|
378 | + ? 'form-table ee-reg-form-qstn-grp-dv' |
|
379 | + : 'ee-reg-form-qstn-grp-dv', |
|
380 | + 'html_label_id' => 'ee-reg-form-qstn-grp-' . $question_group->identifier() . '-' |
|
381 | + . $registration->ID() . '-lbl', |
|
382 | + 'subsections' => array( |
|
383 | + 'reg_form_qstn_grp_hdr' => $this->_question_group_header($question_group), |
|
384 | + ), |
|
385 | + 'layout_strategy' => $this->checkout->admin_request |
|
386 | + ? new EE_Admin_Two_Column_Layout() |
|
387 | + : new EE_Div_Per_Section_Layout(), |
|
388 | + ); |
|
389 | + // where params |
|
390 | + $query_params = array('QST_deleted' => 0); |
|
391 | + // don't load admin only questions on the frontend |
|
392 | + if (! $this->checkout->admin_request) { |
|
393 | + $query_params['QST_admin_only'] = array('!=', true); |
|
394 | + } |
|
395 | + $questions = $question_group->get_many_related( |
|
396 | + 'Question', |
|
397 | + apply_filters( |
|
398 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__related_questions_query_params', |
|
399 | + array( |
|
400 | + $query_params, |
|
401 | + 'order_by' => array( |
|
402 | + 'Question_Group_Question.QGQ_order' => 'ASC', |
|
403 | + ), |
|
404 | + ), |
|
405 | + $question_group, |
|
406 | + $registration, |
|
407 | + $this |
|
408 | + ) |
|
409 | + ); |
|
410 | + // filter for additional content before questions |
|
411 | + $form_args['subsections']['reg_form_questions_before'] = new EE_Form_Section_HTML( |
|
412 | + apply_filters( |
|
413 | + 'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', |
|
414 | + '', |
|
415 | + $registration, |
|
416 | + $question_group, |
|
417 | + $this |
|
418 | + ) |
|
419 | + ); |
|
420 | + // loop thru questions |
|
421 | + foreach ($questions as $question) { |
|
422 | + if ($question instanceof EE_Question) { |
|
423 | + $identifier = $question->is_system_question() |
|
424 | + ? $question->system_ID() |
|
425 | + : $question->ID(); |
|
426 | + $form_args['subsections'][ $identifier ] = $this->reg_form_question($registration, $question); |
|
427 | + } |
|
428 | + } |
|
429 | + $form_args['subsections'] = apply_filters( |
|
430 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__question_group_reg_form__subsections_array', |
|
431 | + $form_args['subsections'], |
|
432 | + $registration, |
|
433 | + $question_group, |
|
434 | + $this |
|
435 | + ); |
|
436 | + // filter for additional content after questions |
|
437 | + $form_args['subsections']['reg_form_questions_after'] = new EE_Form_Section_HTML( |
|
438 | + apply_filters( |
|
439 | + 'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', |
|
440 | + '', |
|
441 | + $registration, |
|
442 | + $question_group, |
|
443 | + $this |
|
444 | + ) |
|
445 | + ); |
|
446 | + // d($form_args); |
|
447 | + $question_group_reg_form = new EE_Form_Section_Proper($form_args); |
|
448 | + return apply_filters( |
|
449 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form', |
|
450 | + $question_group_reg_form, |
|
451 | + $registration, |
|
452 | + $question_group, |
|
453 | + $this |
|
454 | + ); |
|
455 | + } |
|
456 | + |
|
457 | + |
|
458 | + /** |
|
459 | + * @param EE_Question_Group $question_group |
|
460 | + * @return EE_Form_Section_HTML |
|
461 | + */ |
|
462 | + private function _question_group_header(EE_Question_Group $question_group) |
|
463 | + { |
|
464 | + $html = ''; |
|
465 | + // group_name |
|
466 | + if ($question_group->show_group_name() && $question_group->name() !== '') { |
|
467 | + if ($this->checkout->admin_request) { |
|
468 | + $html .= EEH_HTML::br(); |
|
469 | + $html .= EEH_HTML::h3( |
|
470 | + $question_group->name(), |
|
471 | + '', |
|
472 | + 'ee-reg-form-qstn-grp-title title', |
|
473 | + 'font-size: 1.3em; padding-left:0;' |
|
474 | + ); |
|
475 | + } else { |
|
476 | + $html .= EEH_HTML::h4( |
|
477 | + $question_group->name(), |
|
478 | + '', |
|
479 | + 'ee-reg-form-qstn-grp-title section-title' |
|
480 | + ); |
|
481 | + } |
|
482 | + } |
|
483 | + // group_desc |
|
484 | + if ($question_group->show_group_desc() && $question_group->desc() !== '') { |
|
485 | + $html .= EEH_HTML::p( |
|
486 | + $question_group->desc(), |
|
487 | + '', |
|
488 | + $this->checkout->admin_request |
|
489 | + ? 'ee-reg-form-qstn-grp-desc-pg' |
|
490 | + : 'ee-reg-form-qstn-grp-desc-pg small-text lt-grey-text' |
|
491 | + ); |
|
492 | + } |
|
493 | + return new EE_Form_Section_HTML($html); |
|
494 | + } |
|
495 | + |
|
496 | + |
|
497 | + /** |
|
498 | + * @return EE_Form_Section_Proper |
|
499 | + * @throws EE_Error |
|
500 | + * @throws InvalidArgumentException |
|
501 | + * @throws ReflectionException |
|
502 | + * @throws InvalidDataTypeException |
|
503 | + * @throws InvalidInterfaceException |
|
504 | + */ |
|
505 | + private function _copy_attendee_info_form() |
|
506 | + { |
|
507 | + // array of params to pass to parent constructor |
|
508 | + return new EE_Form_Section_Proper( |
|
509 | + array( |
|
510 | + 'subsections' => $this->_copy_attendee_info_inputs(), |
|
511 | + 'layout_strategy' => new EE_Template_Layout( |
|
512 | + array( |
|
513 | + 'layout_template_file' => SPCO_REG_STEPS_PATH |
|
514 | + . $this->_slug |
|
515 | + . DS |
|
516 | + . 'copy_attendee_info.template.php', |
|
517 | + 'begin_template_file' => null, |
|
518 | + 'input_template_file' => null, |
|
519 | + 'subsection_template_file' => null, |
|
520 | + 'end_template_file' => null, |
|
521 | + ) |
|
522 | + ), |
|
523 | + ) |
|
524 | + ); |
|
525 | + } |
|
526 | + |
|
527 | + |
|
528 | + /** |
|
529 | + * @return EE_Form_Section_HTML |
|
530 | + * @throws DomainException |
|
531 | + * @throws InvalidArgumentException |
|
532 | + * @throws InvalidDataTypeException |
|
533 | + * @throws InvalidInterfaceException |
|
534 | + */ |
|
535 | + private function _auto_copy_attendee_info() |
|
536 | + { |
|
537 | + return new EE_Form_Section_HTML( |
|
538 | + EEH_Template::locate_template( |
|
539 | + SPCO_REG_STEPS_PATH . $this->_slug . DS . '_auto_copy_attendee_info.template.php', |
|
540 | + apply_filters( |
|
541 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__auto_copy_attendee_info__template_args', |
|
542 | + array() |
|
543 | + ), |
|
544 | + true, |
|
545 | + true |
|
546 | + ) |
|
547 | + ); |
|
548 | + } |
|
549 | + |
|
550 | + |
|
551 | + /** |
|
552 | + * @return array |
|
553 | + * @throws EE_Error |
|
554 | + * @throws InvalidArgumentException |
|
555 | + * @throws ReflectionException |
|
556 | + * @throws InvalidDataTypeException |
|
557 | + * @throws InvalidInterfaceException |
|
558 | + */ |
|
559 | + private function _copy_attendee_info_inputs() |
|
560 | + { |
|
561 | + $copy_attendee_info_inputs = array(); |
|
562 | + $prev_ticket = null; |
|
563 | + // grab the saved registrations from the transaction |
|
564 | + $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
565 | + foreach ($registrations as $registration) { |
|
566 | + // for all attendees other than the primary attendee |
|
567 | + if ($registration instanceof EE_Registration && ! $registration->is_primary_registrant()) { |
|
568 | + // if this is a new ticket OR if this is the very first additional attendee after the primary attendee |
|
569 | + if ($registration->ticket()->ID() !== $prev_ticket) { |
|
570 | + $item_name = $registration->ticket()->name(); |
|
571 | + $item_name .= $registration->ticket()->description() !== '' |
|
572 | + ? ' - ' . $registration->ticket()->description() |
|
573 | + : ''; |
|
574 | + $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[ticket-' . $registration->ticket()->ID( |
|
575 | + ) . ']' ] = |
|
576 | + new EE_Form_Section_HTML( |
|
577 | + '<h6 class="spco-copy-attendee-event-hdr">' . $item_name . '</h6>' |
|
578 | + ); |
|
579 | + $prev_ticket = $registration->ticket()->ID(); |
|
580 | + } |
|
581 | + |
|
582 | + $copy_attendee_info_inputs[ 'spco_copy_attendee_chk[' . $registration->ID() . ']' ] = |
|
583 | + new EE_Checkbox_Multi_Input( |
|
584 | + array( |
|
585 | + $registration->ID() => sprintf( |
|
586 | + esc_html_x('Attendee #%s', 'Attendee #123', 'event_espresso'), |
|
587 | + $registration->count() |
|
588 | + ), |
|
589 | + ), |
|
590 | + array( |
|
591 | + 'html_id' => 'spco-copy-attendee-chk-' . $registration->reg_url_link(), |
|
592 | + 'html_class' => 'spco-copy-attendee-chk ee-do-not-validate', |
|
593 | + 'display_html_label_text' => false, |
|
594 | + ) |
|
595 | + ); |
|
596 | + } |
|
597 | + } |
|
598 | + return $copy_attendee_info_inputs; |
|
599 | + } |
|
600 | + |
|
601 | + |
|
602 | + /** |
|
603 | + * @param EE_Registration $registration |
|
604 | + * @return EE_Form_Input_Base |
|
605 | + * @throws EE_Error |
|
606 | + */ |
|
607 | + private function _additional_primary_registrant_inputs(EE_Registration $registration) |
|
608 | + { |
|
609 | + // generate hidden input |
|
610 | + return new EE_Hidden_Input( |
|
611 | + array( |
|
612 | + 'html_id' => 'primary_registrant', |
|
613 | + 'default' => $registration->reg_url_link(), |
|
614 | + ) |
|
615 | + ); |
|
616 | + } |
|
617 | + |
|
618 | + |
|
619 | + /** |
|
620 | + * @param EE_Registration $registration |
|
621 | + * @param EE_Question $question |
|
622 | + * @return EE_Form_Input_Base |
|
623 | + * @throws EE_Error |
|
624 | + * @throws InvalidArgumentException |
|
625 | + * @throws InvalidDataTypeException |
|
626 | + * @throws InvalidInterfaceException |
|
627 | + * @throws ReflectionException |
|
628 | + */ |
|
629 | + public function reg_form_question(EE_Registration $registration, EE_Question $question) |
|
630 | + { |
|
631 | + |
|
632 | + // if this question was for an attendee detail, then check for that answer |
|
633 | + $answer_value = EEM_Answer::instance()->get_attendee_property_answer_value( |
|
634 | + $registration, |
|
635 | + $question->system_ID() |
|
636 | + ); |
|
637 | + $answer = $answer_value === null |
|
638 | + ? EEM_Answer::instance()->get_one( |
|
639 | + array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID())) |
|
640 | + ) |
|
641 | + : null; |
|
642 | + // if NOT returning to edit an existing registration |
|
643 | + // OR if this question is for an attendee property |
|
644 | + // OR we still don't have an EE_Answer object |
|
645 | + if ($answer_value || ! $answer instanceof EE_Answer || ! $registration->reg_url_link()) { |
|
646 | + // create an EE_Answer object for storing everything in |
|
647 | + $answer = EE_Answer::new_instance( |
|
648 | + array( |
|
649 | + 'QST_ID' => $question->ID(), |
|
650 | + 'REG_ID' => $registration->ID(), |
|
651 | + ) |
|
652 | + ); |
|
653 | + } |
|
654 | + // verify instance |
|
655 | + if ($answer instanceof EE_Answer) { |
|
656 | + if (! empty($answer_value)) { |
|
657 | + $answer->set('ANS_value', $answer_value); |
|
658 | + } |
|
659 | + $answer->cache('Question', $question); |
|
660 | + // remember system ID had a bug where sometimes it could be null |
|
661 | + $answer_cache_id = $question->is_system_question() |
|
662 | + ? $question->system_ID() . '-' . $registration->reg_url_link() |
|
663 | + : $question->ID() . '-' . $registration->reg_url_link(); |
|
664 | + $registration->cache('Answer', $answer, $answer_cache_id); |
|
665 | + } |
|
666 | + return $this->_generate_question_input($registration, $question, $answer); |
|
667 | + } |
|
668 | + |
|
669 | + |
|
670 | + /** |
|
671 | + * @param EE_Registration $registration |
|
672 | + * @param EE_Question $question |
|
673 | + * @param $answer |
|
674 | + * @return EE_Form_Input_Base |
|
675 | + * @throws EE_Error |
|
676 | + * @throws InvalidArgumentException |
|
677 | + * @throws ReflectionException |
|
678 | + * @throws InvalidDataTypeException |
|
679 | + * @throws InvalidInterfaceException |
|
680 | + */ |
|
681 | + private function _generate_question_input(EE_Registration $registration, EE_Question $question, $answer) |
|
682 | + { |
|
683 | + $identifier = $question->is_system_question() |
|
684 | + ? $question->system_ID() |
|
685 | + : $question->ID(); |
|
686 | + $this->_required_questions[ $identifier ] = $question->required() ? true : false; |
|
687 | + add_filter( |
|
688 | + 'FHEE__EE_Question__generate_form_input__country_options', |
|
689 | + array($this, 'use_cached_countries_for_form_input'), |
|
690 | + 10, |
|
691 | + 4 |
|
692 | + ); |
|
693 | + add_filter( |
|
694 | + 'FHEE__EE_Question__generate_form_input__state_options', |
|
695 | + array($this, 'use_cached_states_for_form_input'), |
|
696 | + 10, |
|
697 | + 4 |
|
698 | + ); |
|
699 | + $input_constructor_args = array( |
|
700 | + 'html_name' => 'ee_reg_qstn[' . $registration->ID() . '][' . $identifier . ']', |
|
701 | + 'html_id' => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier, |
|
702 | + 'html_class' => 'ee-reg-qstn ee-reg-qstn-' . $identifier, |
|
703 | + 'html_label_id' => 'ee_reg_qstn-' . $registration->ID() . '-' . $identifier, |
|
704 | + 'html_label_class' => 'ee-reg-qstn', |
|
705 | + ); |
|
706 | + $input_constructor_args['html_label_id'] .= '-lbl'; |
|
707 | + if ($answer instanceof EE_Answer && $answer->ID()) { |
|
708 | + $input_constructor_args['html_name'] .= '[' . $answer->ID() . ']'; |
|
709 | + $input_constructor_args['html_id'] .= '-' . $answer->ID(); |
|
710 | + $input_constructor_args['html_label_id'] .= '-' . $answer->ID(); |
|
711 | + } |
|
712 | + $form_input = $question->generate_form_input( |
|
713 | + $registration, |
|
714 | + $answer, |
|
715 | + $input_constructor_args |
|
716 | + ); |
|
717 | + remove_filter( |
|
718 | + 'FHEE__EE_Question__generate_form_input__country_options', |
|
719 | + array($this, 'use_cached_countries_for_form_input') |
|
720 | + ); |
|
721 | + remove_filter( |
|
722 | + 'FHEE__EE_Question__generate_form_input__state_options', |
|
723 | + array($this, 'use_cached_states_for_form_input') |
|
724 | + ); |
|
725 | + return $form_input; |
|
726 | + } |
|
727 | + |
|
728 | + |
|
729 | + /** |
|
730 | + * Gets the list of countries for the form input |
|
731 | + * |
|
732 | + * @param array|null $countries_list |
|
733 | + * @param EE_Question $question |
|
734 | + * @param EE_Registration $registration |
|
735 | + * @param EE_Answer $answer |
|
736 | + * @return array 2d keys are country IDs, values are their names |
|
737 | + * @throws EE_Error |
|
738 | + * @throws InvalidArgumentException |
|
739 | + * @throws InvalidDataTypeException |
|
740 | + * @throws InvalidInterfaceException |
|
741 | + * @throws ReflectionException |
|
742 | + */ |
|
743 | + public function use_cached_countries_for_form_input( |
|
744 | + $countries_list, |
|
745 | + EE_Question $question = null, |
|
746 | + EE_Registration $registration = null, |
|
747 | + EE_Answer $answer = null |
|
748 | + ) { |
|
749 | + $country_options = array('' => ''); |
|
750 | + // get possibly cached list of countries |
|
751 | + $countries = $this->checkout->action === 'process_reg_step' |
|
752 | + ? EEM_Country::instance()->get_all_countries() |
|
753 | + : EEM_Country::instance()->get_all_active_countries(); |
|
754 | + if (! empty($countries)) { |
|
755 | + foreach ($countries as $country) { |
|
756 | + if ($country instanceof EE_Country) { |
|
757 | + $country_options[ $country->ID() ] = $country->name(); |
|
758 | + } |
|
759 | + } |
|
760 | + } |
|
761 | + if ($question instanceof EE_Question && $registration instanceof EE_Registration) { |
|
762 | + $answer = EEM_Answer::instance()->get_one( |
|
763 | + array(array('QST_ID' => $question->ID(), 'REG_ID' => $registration->ID())) |
|
764 | + ); |
|
765 | + } else { |
|
766 | + $answer = EE_Answer::new_instance(); |
|
767 | + } |
|
768 | + $country_options = apply_filters( |
|
769 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options', |
|
770 | + $country_options, |
|
771 | + $this, |
|
772 | + $registration, |
|
773 | + $question, |
|
774 | + $answer |
|
775 | + ); |
|
776 | + return $country_options; |
|
777 | + } |
|
778 | + |
|
779 | + |
|
780 | + /** |
|
781 | + * Gets the list of states for the form input |
|
782 | + * |
|
783 | + * @param array|null $states_list |
|
784 | + * @param EE_Question $question |
|
785 | + * @param EE_Registration $registration |
|
786 | + * @param EE_Answer $answer |
|
787 | + * @return array 2d keys are state IDs, values are their names |
|
788 | + * @throws EE_Error |
|
789 | + * @throws InvalidArgumentException |
|
790 | + * @throws InvalidDataTypeException |
|
791 | + * @throws InvalidInterfaceException |
|
792 | + * @throws ReflectionException |
|
793 | + */ |
|
794 | + public function use_cached_states_for_form_input( |
|
795 | + $states_list, |
|
796 | + EE_Question $question = null, |
|
797 | + EE_Registration $registration = null, |
|
798 | + EE_Answer $answer = null |
|
799 | + ) { |
|
800 | + $state_options = array('' => array('' => '')); |
|
801 | + $states = $this->checkout->action === 'process_reg_step' |
|
802 | + ? EEM_State::instance()->get_all_states() |
|
803 | + : EEM_State::instance()->get_all_active_states(); |
|
804 | + if (! empty($states)) { |
|
805 | + foreach ($states as $state) { |
|
806 | + if ($state instanceof EE_State) { |
|
807 | + $state_options[ $state->country()->name() ][ $state->ID() ] = $state->name(); |
|
808 | + } |
|
809 | + } |
|
810 | + } |
|
811 | + $state_options = apply_filters( |
|
812 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options', |
|
813 | + $state_options, |
|
814 | + $this, |
|
815 | + $registration, |
|
816 | + $question, |
|
817 | + $answer |
|
818 | + ); |
|
819 | + return $state_options; |
|
820 | + } |
|
821 | + |
|
822 | + |
|
823 | + /********************************************************************************************************/ |
|
824 | + /**************************************** PROCESS REG STEP ****************************************/ |
|
825 | + /********************************************************************************************************/ |
|
826 | + |
|
827 | + |
|
828 | + /** |
|
829 | + * @return bool |
|
830 | + * @throws EE_Error |
|
831 | + * @throws InvalidArgumentException |
|
832 | + * @throws ReflectionException |
|
833 | + * @throws RuntimeException |
|
834 | + * @throws InvalidDataTypeException |
|
835 | + * @throws InvalidInterfaceException |
|
836 | + */ |
|
837 | + public function process_reg_step() |
|
838 | + { |
|
839 | + do_action('AHEE_log', __FILE__, __FUNCTION__, ''); |
|
840 | + // grab validated data from form |
|
841 | + $valid_data = $this->checkout->current_step->valid_data(); |
|
842 | + // EEH_Debug_Tools::printr( $_REQUEST, '$_REQUEST', __FILE__, __LINE__ ); |
|
843 | + // EEH_Debug_Tools::printr( $valid_data, '$valid_data', __FILE__, __LINE__ ); |
|
844 | + // if we don't have any $valid_data then something went TERRIBLY WRONG !!! |
|
845 | + if (empty($valid_data)) { |
|
846 | + EE_Error::add_error( |
|
847 | + esc_html__('No valid question responses were received.', 'event_espresso'), |
|
848 | + __FILE__, |
|
849 | + __FUNCTION__, |
|
850 | + __LINE__ |
|
851 | + ); |
|
852 | + return false; |
|
853 | + } |
|
854 | + if (! $this->checkout->transaction instanceof EE_Transaction || ! $this->checkout->continue_reg) { |
|
855 | + EE_Error::add_error( |
|
856 | + esc_html__( |
|
857 | + 'A valid transaction could not be initiated for processing your registrations.', |
|
858 | + 'event_espresso' |
|
859 | + ), |
|
860 | + __FILE__, |
|
861 | + __FUNCTION__, |
|
862 | + __LINE__ |
|
863 | + ); |
|
864 | + return false; |
|
865 | + } |
|
866 | + // get cached registrations |
|
867 | + $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
868 | + // verify we got the goods |
|
869 | + if (empty($registrations)) { |
|
870 | + // combine the old translated string with a new one, in order to not break translations |
|
871 | + $error_message = esc_html__( |
|
872 | + 'Your form data could not be applied to any valid registrations.', |
|
873 | + 'event_espresso' |
|
874 | + ) |
|
875 | + . sprintf( |
|
876 | + esc_html_x( |
|
877 | + '%3$sThis can sometimes happen if too much time has been taken to complete the registration process.%3$sPlease return to the %1$sEvent List%2$s and reselect your tickets. If the problem continues, please contact the site administrator.', |
|
878 | + '(line break)This can sometimes happen if too much time has been taken to complete the registration process.(line break)Please return to the (link)Event List(end link) and reselect your tickets. If the problem continues, please contact the site administrator.', |
|
879 | + 'event_espresso' |
|
880 | + ), |
|
881 | + '<a href="' . get_post_type_archive_link('espresso_events') . '" >', |
|
882 | + '</a>', |
|
883 | + '<br />' |
|
884 | + ); |
|
885 | + EE_Error::add_error( |
|
886 | + $error_message, |
|
887 | + __FILE__, |
|
888 | + __FUNCTION__, |
|
889 | + __LINE__ |
|
890 | + ); |
|
891 | + return false; |
|
892 | + } |
|
893 | + // extract attendee info from form data and save to model objects |
|
894 | + $registrations_processed = $this->_process_registrations($registrations, $valid_data); |
|
895 | + // if first pass thru SPCO, |
|
896 | + // then let's check processed registrations against the total number of tickets in the cart |
|
897 | + if ($registrations_processed === false) { |
|
898 | + // but return immediately if the previous step exited early due to errors |
|
899 | + return false; |
|
900 | + } |
|
901 | + if (! $this->checkout->revisit && $registrations_processed !== $this->checkout->total_ticket_count) { |
|
902 | + // generate a correctly translated string for all possible singular/plural combinations |
|
903 | + if ($this->checkout->total_ticket_count === 1 && $registrations_processed !== 1) { |
|
904 | + $error_msg = sprintf( |
|
905 | + esc_html_x( |
|
906 | + 'There was %1$d ticket in the Event Queue, but %2$ds registrations were processed', |
|
907 | + 'There was 1 ticket in the Event Queue, but 2 registrations were processed', |
|
908 | + 'event_espresso' |
|
909 | + ), |
|
910 | + $this->checkout->total_ticket_count, |
|
911 | + $registrations_processed |
|
912 | + ); |
|
913 | + } elseif ($this->checkout->total_ticket_count !== 1 && $registrations_processed === 1) { |
|
914 | + $error_msg = sprintf( |
|
915 | + esc_html_x( |
|
916 | + 'There was a total of %1$d tickets in the Event Queue, but only %2$ds registration was processed', |
|
917 | + 'There was a total of 2 tickets in the Event Queue, but only 1 registration was processed', |
|
918 | + 'event_espresso' |
|
919 | + ), |
|
920 | + $this->checkout->total_ticket_count, |
|
921 | + $registrations_processed |
|
922 | + ); |
|
923 | + } else { |
|
924 | + $error_msg = sprintf( |
|
925 | + esc_html__( |
|
926 | + 'There was a total of 2 tickets in the Event Queue, but 2 registrations were processed', |
|
927 | + 'event_espresso' |
|
928 | + ), |
|
929 | + $this->checkout->total_ticket_count, |
|
930 | + $registrations_processed |
|
931 | + ); |
|
932 | + } |
|
933 | + EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__); |
|
934 | + return false; |
|
935 | + } |
|
936 | + // mark this reg step as completed |
|
937 | + $this->set_completed(); |
|
938 | + $this->_set_success_message( |
|
939 | + esc_html__('The Attendee Information Step has been successfully completed.', 'event_espresso') |
|
940 | + ); |
|
941 | + // do action in case a plugin wants to do something with the data submitted in step 1. |
|
942 | + // passes EE_Single_Page_Checkout, and it's posted data |
|
943 | + do_action('AHEE__EE_Single_Page_Checkout__process_attendee_information__end', $this, $valid_data); |
|
944 | + return true; |
|
945 | + } |
|
946 | + |
|
947 | + |
|
948 | + /** |
|
949 | + * _process_registrations |
|
950 | + * |
|
951 | + * @param EE_Registration[] $registrations |
|
952 | + * @param array[][] $valid_data |
|
953 | + * @return bool|int |
|
954 | + * @throws EntityNotFoundException |
|
955 | + * @throws EE_Error |
|
956 | + * @throws InvalidArgumentException |
|
957 | + * @throws ReflectionException |
|
958 | + * @throws RuntimeException |
|
959 | + * @throws InvalidDataTypeException |
|
960 | + * @throws InvalidInterfaceException |
|
961 | + */ |
|
962 | + private function _process_registrations($registrations = array(), $valid_data = array()) |
|
963 | + { |
|
964 | + // load resources and set some defaults |
|
965 | + EE_Registry::instance()->load_model('Attendee'); |
|
966 | + // holder for primary registrant attendee object |
|
967 | + $this->checkout->primary_attendee_obj = null; |
|
968 | + // array for tracking reg form data for the primary registrant |
|
969 | + $primary_registrant = array( |
|
970 | + 'line_item_id' => null, |
|
971 | + ); |
|
972 | + $copy_primary = false; |
|
973 | + // reg form sections that do not contain inputs |
|
974 | + $non_input_form_sections = array( |
|
975 | + 'primary_registrant', |
|
976 | + 'additional_attendee_reg_info', |
|
977 | + 'spco_copy_attendee_chk', |
|
978 | + ); |
|
979 | + // attendee counter |
|
980 | + $att_nmbr = 0; |
|
981 | + // grab the saved registrations from the transaction |
|
982 | + foreach ($registrations as $registration) { |
|
983 | + // verify EE_Registration object |
|
984 | + if (! $registration instanceof EE_Registration) { |
|
985 | + EE_Error::add_error( |
|
986 | + esc_html__( |
|
987 | + 'An invalid Registration object was discovered when attempting to process your registration information.', |
|
988 | + 'event_espresso' |
|
989 | + ), |
|
990 | + __FILE__, |
|
991 | + __FUNCTION__, |
|
992 | + __LINE__ |
|
993 | + ); |
|
994 | + return false; |
|
995 | + } |
|
996 | + /** @var string $reg_url_link */ |
|
997 | + $reg_url_link = $registration->reg_url_link(); |
|
998 | + // reg_url_link exists ? |
|
999 | + if (! empty($reg_url_link)) { |
|
1000 | + // should this registration be processed during this visit ? |
|
1001 | + if ($this->checkout->visit_allows_processing_of_this_registration($registration)) { |
|
1002 | + // if NOT revisiting, then let's save the registration now, |
|
1003 | + // so that we have a REG_ID to use when generating other objects |
|
1004 | + if (! $this->checkout->revisit) { |
|
1005 | + $registration->save(); |
|
1006 | + } |
|
1007 | + /** |
|
1008 | + * This allows plugins to trigger a fail on processing of a |
|
1009 | + * registration for any conditions they may have for it to pass. |
|
1010 | + * |
|
1011 | + * @var bool if true is returned by the plugin then the |
|
1012 | + * registration processing is halted. |
|
1013 | + */ |
|
1014 | + if (apply_filters( |
|
1015 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___process_registrations__pre_registration_process', |
|
1016 | + false, |
|
1017 | + $att_nmbr, |
|
1018 | + $registration, |
|
1019 | + $registrations, |
|
1020 | + $valid_data, |
|
1021 | + $this |
|
1022 | + )) { |
|
1023 | + return false; |
|
1024 | + } |
|
1025 | + |
|
1026 | + // Houston, we have a registration! |
|
1027 | + $att_nmbr++; |
|
1028 | + $this->_attendee_data[ $reg_url_link ] = array(); |
|
1029 | + // grab any existing related answer objects |
|
1030 | + $this->_registration_answers = $registration->answers(); |
|
1031 | + // unset( $valid_data[ $reg_url_link ]['additional_attendee_reg_info'] ); |
|
1032 | + if (isset($valid_data[ $reg_url_link ])) { |
|
1033 | + // do we need to copy basic info from primary attendee ? |
|
1034 | + $copy_primary = isset($valid_data[ $reg_url_link ]['additional_attendee_reg_info']) |
|
1035 | + && absint($valid_data[ $reg_url_link ]['additional_attendee_reg_info']) === 0; |
|
1036 | + // filter form input data for this registration |
|
1037 | + $valid_data[ $reg_url_link ] = (array) apply_filters( |
|
1038 | + 'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item', |
|
1039 | + $valid_data[ $reg_url_link ] |
|
1040 | + ); |
|
1041 | + if (isset($valid_data['primary_attendee'])) { |
|
1042 | + $primary_registrant['line_item_id'] = ! empty($valid_data['primary_attendee']) |
|
1043 | + ? $valid_data['primary_attendee'] |
|
1044 | + : false; |
|
1045 | + unset($valid_data['primary_attendee']); |
|
1046 | + } |
|
1047 | + // now loop through our array of valid post data && process attendee reg forms |
|
1048 | + foreach ($valid_data[ $reg_url_link ] as $form_section => $form_inputs) { |
|
1049 | + if (! in_array($form_section, $non_input_form_sections, true)) { |
|
1050 | + foreach ($form_inputs as $form_input => $input_value) { |
|
1051 | + // \EEH_Debug_Tools::printr( $input_value, $form_input, __FILE__, __LINE__ ); |
|
1052 | + // check for critical inputs |
|
1053 | + if (! $this->_verify_critical_attendee_details_are_set_and_validate_email( |
|
1054 | + $form_input, |
|
1055 | + $input_value |
|
1056 | + ) |
|
1057 | + ) { |
|
1058 | + return false; |
|
1059 | + } |
|
1060 | + // store a bit of data about the primary attendee |
|
1061 | + if ($att_nmbr === 1 |
|
1062 | + && ! empty($input_value) |
|
1063 | + && $reg_url_link === $primary_registrant['line_item_id'] |
|
1064 | + ) { |
|
1065 | + $primary_registrant[ $form_input ] = $input_value; |
|
1066 | + } elseif ($copy_primary |
|
1067 | + && $input_value === null |
|
1068 | + && isset($primary_registrant[ $form_input ]) |
|
1069 | + ) { |
|
1070 | + $input_value = $primary_registrant[ $form_input ]; |
|
1071 | + } |
|
1072 | + // now attempt to save the input data |
|
1073 | + if (! $this->_save_registration_form_input( |
|
1074 | + $registration, |
|
1075 | + $form_input, |
|
1076 | + $input_value |
|
1077 | + ) |
|
1078 | + ) { |
|
1079 | + EE_Error::add_error( |
|
1080 | + sprintf( |
|
1081 | + esc_html_x( |
|
1082 | + 'Unable to save registration form data for the form input: "%1$s" with the submitted value: "%2$s"', |
|
1083 | + 'Unable to save registration form data for the form input: "form input name" with the submitted value: "form input value"', |
|
1084 | + 'event_espresso' |
|
1085 | + ), |
|
1086 | + $form_input, |
|
1087 | + $input_value |
|
1088 | + ), |
|
1089 | + __FILE__, |
|
1090 | + __FUNCTION__, |
|
1091 | + __LINE__ |
|
1092 | + ); |
|
1093 | + return false; |
|
1094 | + } |
|
1095 | + } |
|
1096 | + } |
|
1097 | + } // end of foreach ( $valid_data[ $reg_url_link ] as $form_section => $form_inputs ) |
|
1098 | + } |
|
1099 | + // EEH_Debug_Tools::printr( $this->_attendee_data, '$this->_attendee_data', __FILE__, __LINE__ ); |
|
1100 | + // this registration does not require additional attendee information ? |
|
1101 | + if ($copy_primary |
|
1102 | + && $att_nmbr > 1 |
|
1103 | + && $this->checkout->primary_attendee_obj instanceof EE_Attendee |
|
1104 | + ) { |
|
1105 | + // just copy the primary registrant |
|
1106 | + $attendee = $this->checkout->primary_attendee_obj; |
|
1107 | + } else { |
|
1108 | + // ensure critical details are set for additional attendees |
|
1109 | + $this->_attendee_data[ $reg_url_link ] = $att_nmbr > 1 |
|
1110 | + ? $this->_copy_critical_attendee_details_from_primary_registrant( |
|
1111 | + $this->_attendee_data[ $reg_url_link ] |
|
1112 | + ) |
|
1113 | + : $this->_attendee_data[ $reg_url_link ]; |
|
1114 | + // execute create attendee command (which may return an existing attendee) |
|
1115 | + $attendee = EE_Registry::instance()->BUS->execute( |
|
1116 | + new CreateAttendeeCommand( |
|
1117 | + $this->_attendee_data[ $reg_url_link ], |
|
1118 | + $registration |
|
1119 | + ) |
|
1120 | + ); |
|
1121 | + // who's #1 ? |
|
1122 | + if ($att_nmbr === 1) { |
|
1123 | + $this->checkout->primary_attendee_obj = $attendee; |
|
1124 | + } |
|
1125 | + } |
|
1126 | + // EEH_Debug_Tools::printr( $attendee, '$attendee', __FILE__, __LINE__ ); |
|
1127 | + // add relation to registration, set attendee ID, and cache attendee |
|
1128 | + $this->_associate_attendee_with_registration($registration, $attendee); |
|
1129 | + // \EEH_Debug_Tools::printr( $registration, '$registration', __FILE__, __LINE__ ); |
|
1130 | + if (! $registration->attendee() instanceof EE_Attendee) { |
|
1131 | + EE_Error::add_error( |
|
1132 | + sprintf( |
|
1133 | + esc_html_x( |
|
1134 | + 'Registration %s has an invalid or missing Attendee object.', |
|
1135 | + 'Registration 123-456-789 has an invalid or missing Attendee object.', |
|
1136 | + 'event_espresso' |
|
1137 | + ), |
|
1138 | + $reg_url_link |
|
1139 | + ), |
|
1140 | + __FILE__, |
|
1141 | + __FUNCTION__, |
|
1142 | + __LINE__ |
|
1143 | + ); |
|
1144 | + return false; |
|
1145 | + } |
|
1146 | + /** @type EE_Registration_Processor $registration_processor */ |
|
1147 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
1148 | + // at this point, we should have enough details about the registrant to consider the registration |
|
1149 | + // NOT incomplete |
|
1150 | + $registration_processor->toggle_incomplete_registration_status_to_default( |
|
1151 | + $registration, |
|
1152 | + false, |
|
1153 | + new Context( |
|
1154 | + 'spco_reg_step_attendee_information_process_registrations', |
|
1155 | + esc_html__( |
|
1156 | + 'Finished populating registration with details from the registration form after submitting the Attendee Information Reg Step.', |
|
1157 | + 'event_espresso' |
|
1158 | + ) |
|
1159 | + ) |
|
1160 | + ); |
|
1161 | + // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to |
|
1162 | + // abandoned |
|
1163 | + $this->checkout->transaction->toggle_failed_transaction_status(); |
|
1164 | + // if we've gotten this far, then let's save what we have |
|
1165 | + $registration->save(); |
|
1166 | + // add relation between TXN and registration |
|
1167 | + $this->_associate_registration_with_transaction($registration); |
|
1168 | + } |
|
1169 | + } else { |
|
1170 | + EE_Error::add_error( |
|
1171 | + esc_html__( |
|
1172 | + 'An invalid or missing line item ID was encountered while attempting to process the registration form.', |
|
1173 | + 'event_espresso' |
|
1174 | + ), |
|
1175 | + __FILE__, |
|
1176 | + __FUNCTION__, |
|
1177 | + __LINE__ |
|
1178 | + ); |
|
1179 | + // remove malformed data |
|
1180 | + unset($valid_data[ $reg_url_link ]); |
|
1181 | + return false; |
|
1182 | + } |
|
1183 | + } // end of foreach ( $this->checkout->transaction->registrations() as $registration ) |
|
1184 | + return $att_nmbr; |
|
1185 | + } |
|
1186 | + |
|
1187 | + |
|
1188 | + /** |
|
1189 | + * _save_registration_form_input |
|
1190 | + * |
|
1191 | + * @param EE_Registration $registration |
|
1192 | + * @param string $form_input |
|
1193 | + * @param string $input_value |
|
1194 | + * @return bool |
|
1195 | + * @throws EE_Error |
|
1196 | + * @throws InvalidArgumentException |
|
1197 | + * @throws InvalidDataTypeException |
|
1198 | + * @throws InvalidInterfaceException |
|
1199 | + * @throws ReflectionException |
|
1200 | + */ |
|
1201 | + private function _save_registration_form_input( |
|
1202 | + EE_Registration $registration, |
|
1203 | + $form_input = '', |
|
1204 | + $input_value = '' |
|
1205 | + ) { |
|
1206 | + // \EEH_Debug_Tools::printr( __FUNCTION__, __CLASS__, __FILE__, __LINE__, 2 ); |
|
1207 | + // \EEH_Debug_Tools::printr( $form_input, '$form_input', __FILE__, __LINE__ ); |
|
1208 | + // \EEH_Debug_Tools::printr( $input_value, '$input_value', __FILE__, __LINE__ ); |
|
1209 | + // allow for plugins to hook in and do their own processing of the form input. |
|
1210 | + // For plugins to bypass normal processing here, they just need to return a boolean value. |
|
1211 | + if (apply_filters( |
|
1212 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input', |
|
1213 | + false, |
|
1214 | + $registration, |
|
1215 | + $form_input, |
|
1216 | + $input_value, |
|
1217 | + $this |
|
1218 | + )) { |
|
1219 | + return true; |
|
1220 | + } |
|
1221 | + /* |
|
1222 | 1222 | * $answer_cache_id is the key used to find the EE_Answer we want |
1223 | 1223 | * @see https://events.codebasehq.com/projects/event-espresso/tickets/10477 |
1224 | 1224 | */ |
1225 | - $answer_cache_id = $this->checkout->reg_url_link |
|
1226 | - ? $form_input . '-' . $registration->reg_url_link() |
|
1227 | - : $form_input; |
|
1228 | - $answer_is_obj = isset($this->_registration_answers[ $answer_cache_id ]) |
|
1229 | - && $this->_registration_answers[ $answer_cache_id ] instanceof EE_Answer; |
|
1230 | - // rename form_inputs if they are EE_Attendee properties |
|
1231 | - switch ((string) $form_input) { |
|
1232 | - case 'state': |
|
1233 | - case 'STA_ID': |
|
1234 | - $attendee_property = true; |
|
1235 | - $form_input = 'STA_ID'; |
|
1236 | - break; |
|
1237 | - |
|
1238 | - case 'country': |
|
1239 | - case 'CNT_ISO': |
|
1240 | - $attendee_property = true; |
|
1241 | - $form_input = 'CNT_ISO'; |
|
1242 | - break; |
|
1243 | - |
|
1244 | - default: |
|
1245 | - $ATT_input = 'ATT_' . $form_input; |
|
1246 | - // EEH_Debug_Tools::printr( $ATT_input, '$ATT_input', __FILE__, __LINE__ ); |
|
1247 | - $attendee_property = EEM_Attendee::instance()->has_field($ATT_input) ? true : false; |
|
1248 | - $form_input = $attendee_property ? 'ATT_' . $form_input : $form_input; |
|
1249 | - } |
|
1250 | - // EEH_Debug_Tools::printr( $answer_cache_id, '$answer_cache_id', __FILE__, __LINE__ ); |
|
1251 | - // EEH_Debug_Tools::printr( $attendee_property, '$attendee_property', __FILE__, __LINE__ ); |
|
1252 | - // EEH_Debug_Tools::printr( $answer_is_obj, '$answer_is_obj', __FILE__, __LINE__ ); |
|
1253 | - // if this form input has a corresponding attendee property |
|
1254 | - if ($attendee_property) { |
|
1255 | - $this->_attendee_data[ $registration->reg_url_link() ][ $form_input ] = $input_value; |
|
1256 | - if ($answer_is_obj) { |
|
1257 | - // and delete the corresponding answer since we won't be storing this data in that object |
|
1258 | - $registration->_remove_relation_to($this->_registration_answers[ $answer_cache_id ], 'Answer'); |
|
1259 | - $this->_registration_answers[ $answer_cache_id ]->delete_permanently(); |
|
1260 | - } |
|
1261 | - return true; |
|
1262 | - } |
|
1263 | - if ($answer_is_obj) { |
|
1264 | - // save this data to the answer object |
|
1265 | - $this->_registration_answers[ $answer_cache_id ]->set_value($input_value); |
|
1266 | - $result = $this->_registration_answers[ $answer_cache_id ]->save(); |
|
1267 | - return $result !== false; |
|
1268 | - } |
|
1269 | - foreach ($this->_registration_answers as $answer) { |
|
1270 | - if ($answer instanceof EE_Answer && $answer->question_ID() === $answer_cache_id) { |
|
1271 | - $answer->set_value($input_value); |
|
1272 | - $result = $answer->save(); |
|
1273 | - return $result !== false; |
|
1274 | - } |
|
1275 | - } |
|
1276 | - return false; |
|
1277 | - } |
|
1278 | - |
|
1279 | - |
|
1280 | - /** |
|
1281 | - * _verify_critical_attendee_details_are_set |
|
1282 | - * |
|
1283 | - * @param string $form_input |
|
1284 | - * @param string $input_value |
|
1285 | - * @return boolean |
|
1286 | - */ |
|
1287 | - private function _verify_critical_attendee_details_are_set_and_validate_email( |
|
1288 | - $form_input = '', |
|
1289 | - $input_value = '' |
|
1290 | - ) { |
|
1291 | - if (empty($input_value)) { |
|
1292 | - // if the form input isn't marked as being required, then just return |
|
1293 | - if (! isset($this->_required_questions[ $form_input ]) || ! $this->_required_questions[ $form_input ]) { |
|
1294 | - return true; |
|
1295 | - } |
|
1296 | - switch ($form_input) { |
|
1297 | - case 'fname': |
|
1298 | - EE_Error::add_error( |
|
1299 | - esc_html__('First Name is a required value.', 'event_espresso'), |
|
1300 | - __FILE__, |
|
1301 | - __FUNCTION__, |
|
1302 | - __LINE__ |
|
1303 | - ); |
|
1304 | - return false; |
|
1305 | - break; |
|
1306 | - case 'lname': |
|
1307 | - EE_Error::add_error( |
|
1308 | - esc_html__('Last Name is a required value.', 'event_espresso'), |
|
1309 | - __FILE__, |
|
1310 | - __FUNCTION__, |
|
1311 | - __LINE__ |
|
1312 | - ); |
|
1313 | - return false; |
|
1314 | - break; |
|
1315 | - case 'email': |
|
1316 | - EE_Error::add_error( |
|
1317 | - esc_html__('Please enter a valid email address.', 'event_espresso'), |
|
1318 | - __FILE__, |
|
1319 | - __FUNCTION__, |
|
1320 | - __LINE__ |
|
1321 | - ); |
|
1322 | - return false; |
|
1323 | - break; |
|
1324 | - } |
|
1325 | - } |
|
1326 | - return true; |
|
1327 | - } |
|
1328 | - |
|
1329 | - |
|
1330 | - /** |
|
1331 | - * _associate_attendee_with_registration |
|
1332 | - * |
|
1333 | - * @param EE_Registration $registration |
|
1334 | - * @param EE_Attendee $attendee |
|
1335 | - * @return void |
|
1336 | - * @throws EE_Error |
|
1337 | - * @throws InvalidArgumentException |
|
1338 | - * @throws ReflectionException |
|
1339 | - * @throws RuntimeException |
|
1340 | - * @throws InvalidDataTypeException |
|
1341 | - * @throws InvalidInterfaceException |
|
1342 | - */ |
|
1343 | - private function _associate_attendee_with_registration(EE_Registration $registration, EE_Attendee $attendee) |
|
1344 | - { |
|
1345 | - // add relation to attendee |
|
1346 | - $registration->_add_relation_to($attendee, 'Attendee'); |
|
1347 | - $registration->set_attendee_id($attendee->ID()); |
|
1348 | - $registration->update_cache_after_object_save('Attendee', $attendee); |
|
1349 | - } |
|
1350 | - |
|
1351 | - |
|
1352 | - /** |
|
1353 | - * _associate_registration_with_transaction |
|
1354 | - * |
|
1355 | - * @param EE_Registration $registration |
|
1356 | - * @return void |
|
1357 | - * @throws EE_Error |
|
1358 | - * @throws InvalidArgumentException |
|
1359 | - * @throws ReflectionException |
|
1360 | - * @throws InvalidDataTypeException |
|
1361 | - * @throws InvalidInterfaceException |
|
1362 | - */ |
|
1363 | - private function _associate_registration_with_transaction(EE_Registration $registration) |
|
1364 | - { |
|
1365 | - // add relation to registration |
|
1366 | - $this->checkout->transaction->_add_relation_to($registration, 'Registration'); |
|
1367 | - $this->checkout->transaction->update_cache_after_object_save('Registration', $registration); |
|
1368 | - } |
|
1369 | - |
|
1370 | - |
|
1371 | - /** |
|
1372 | - * _copy_critical_attendee_details_from_primary_registrant |
|
1373 | - * ensures that all attendees at least have data for first name, last name, and email address |
|
1374 | - * |
|
1375 | - * @param array $attendee_data |
|
1376 | - * @return array |
|
1377 | - * @throws EE_Error |
|
1378 | - * @throws InvalidArgumentException |
|
1379 | - * @throws ReflectionException |
|
1380 | - * @throws InvalidDataTypeException |
|
1381 | - * @throws InvalidInterfaceException |
|
1382 | - */ |
|
1383 | - private function _copy_critical_attendee_details_from_primary_registrant($attendee_data = array()) |
|
1384 | - { |
|
1385 | - // bare minimum critical details include first name, last name, email address |
|
1386 | - $critical_attendee_details = array('ATT_fname', 'ATT_lname', 'ATT_email'); |
|
1387 | - // add address info to critical details? |
|
1388 | - if (apply_filters( |
|
1389 | - 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details', |
|
1390 | - false |
|
1391 | - )) { |
|
1392 | - $address_details = array( |
|
1393 | - 'ATT_address', |
|
1394 | - 'ATT_address2', |
|
1395 | - 'ATT_city', |
|
1396 | - 'STA_ID', |
|
1397 | - 'CNT_ISO', |
|
1398 | - 'ATT_zip', |
|
1399 | - 'ATT_phone', |
|
1400 | - ); |
|
1401 | - $critical_attendee_details = array_merge($critical_attendee_details, $address_details); |
|
1402 | - } |
|
1403 | - foreach ($critical_attendee_details as $critical_attendee_detail) { |
|
1404 | - if (! isset($attendee_data[ $critical_attendee_detail ]) |
|
1405 | - || empty($attendee_data[ $critical_attendee_detail ]) |
|
1406 | - ) { |
|
1407 | - $attendee_data[ $critical_attendee_detail ] = $this->checkout->primary_attendee_obj->get( |
|
1408 | - $critical_attendee_detail |
|
1409 | - ); |
|
1410 | - } |
|
1411 | - } |
|
1412 | - return $attendee_data; |
|
1413 | - } |
|
1414 | - |
|
1415 | - |
|
1416 | - /** |
|
1417 | - * update_reg_step |
|
1418 | - * this is the final step after a user revisits the site to edit their attendee information |
|
1419 | - * this gets called AFTER the process_reg_step() method above |
|
1420 | - * |
|
1421 | - * @return bool |
|
1422 | - * @throws EE_Error |
|
1423 | - * @throws InvalidArgumentException |
|
1424 | - * @throws ReflectionException |
|
1425 | - * @throws RuntimeException |
|
1426 | - * @throws InvalidDataTypeException |
|
1427 | - * @throws InvalidInterfaceException |
|
1428 | - */ |
|
1429 | - public function update_reg_step() |
|
1430 | - { |
|
1431 | - // save everything |
|
1432 | - if ($this->process_reg_step()) { |
|
1433 | - $this->checkout->redirect = true; |
|
1434 | - $this->checkout->redirect_url = add_query_arg( |
|
1435 | - array( |
|
1436 | - 'e_reg_url_link' => $this->checkout->reg_url_link, |
|
1437 | - 'revisit' => true, |
|
1438 | - ), |
|
1439 | - $this->checkout->thank_you_page_url |
|
1440 | - ); |
|
1441 | - $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url); |
|
1442 | - return true; |
|
1443 | - } |
|
1444 | - return false; |
|
1445 | - } |
|
1225 | + $answer_cache_id = $this->checkout->reg_url_link |
|
1226 | + ? $form_input . '-' . $registration->reg_url_link() |
|
1227 | + : $form_input; |
|
1228 | + $answer_is_obj = isset($this->_registration_answers[ $answer_cache_id ]) |
|
1229 | + && $this->_registration_answers[ $answer_cache_id ] instanceof EE_Answer; |
|
1230 | + // rename form_inputs if they are EE_Attendee properties |
|
1231 | + switch ((string) $form_input) { |
|
1232 | + case 'state': |
|
1233 | + case 'STA_ID': |
|
1234 | + $attendee_property = true; |
|
1235 | + $form_input = 'STA_ID'; |
|
1236 | + break; |
|
1237 | + |
|
1238 | + case 'country': |
|
1239 | + case 'CNT_ISO': |
|
1240 | + $attendee_property = true; |
|
1241 | + $form_input = 'CNT_ISO'; |
|
1242 | + break; |
|
1243 | + |
|
1244 | + default: |
|
1245 | + $ATT_input = 'ATT_' . $form_input; |
|
1246 | + // EEH_Debug_Tools::printr( $ATT_input, '$ATT_input', __FILE__, __LINE__ ); |
|
1247 | + $attendee_property = EEM_Attendee::instance()->has_field($ATT_input) ? true : false; |
|
1248 | + $form_input = $attendee_property ? 'ATT_' . $form_input : $form_input; |
|
1249 | + } |
|
1250 | + // EEH_Debug_Tools::printr( $answer_cache_id, '$answer_cache_id', __FILE__, __LINE__ ); |
|
1251 | + // EEH_Debug_Tools::printr( $attendee_property, '$attendee_property', __FILE__, __LINE__ ); |
|
1252 | + // EEH_Debug_Tools::printr( $answer_is_obj, '$answer_is_obj', __FILE__, __LINE__ ); |
|
1253 | + // if this form input has a corresponding attendee property |
|
1254 | + if ($attendee_property) { |
|
1255 | + $this->_attendee_data[ $registration->reg_url_link() ][ $form_input ] = $input_value; |
|
1256 | + if ($answer_is_obj) { |
|
1257 | + // and delete the corresponding answer since we won't be storing this data in that object |
|
1258 | + $registration->_remove_relation_to($this->_registration_answers[ $answer_cache_id ], 'Answer'); |
|
1259 | + $this->_registration_answers[ $answer_cache_id ]->delete_permanently(); |
|
1260 | + } |
|
1261 | + return true; |
|
1262 | + } |
|
1263 | + if ($answer_is_obj) { |
|
1264 | + // save this data to the answer object |
|
1265 | + $this->_registration_answers[ $answer_cache_id ]->set_value($input_value); |
|
1266 | + $result = $this->_registration_answers[ $answer_cache_id ]->save(); |
|
1267 | + return $result !== false; |
|
1268 | + } |
|
1269 | + foreach ($this->_registration_answers as $answer) { |
|
1270 | + if ($answer instanceof EE_Answer && $answer->question_ID() === $answer_cache_id) { |
|
1271 | + $answer->set_value($input_value); |
|
1272 | + $result = $answer->save(); |
|
1273 | + return $result !== false; |
|
1274 | + } |
|
1275 | + } |
|
1276 | + return false; |
|
1277 | + } |
|
1278 | + |
|
1279 | + |
|
1280 | + /** |
|
1281 | + * _verify_critical_attendee_details_are_set |
|
1282 | + * |
|
1283 | + * @param string $form_input |
|
1284 | + * @param string $input_value |
|
1285 | + * @return boolean |
|
1286 | + */ |
|
1287 | + private function _verify_critical_attendee_details_are_set_and_validate_email( |
|
1288 | + $form_input = '', |
|
1289 | + $input_value = '' |
|
1290 | + ) { |
|
1291 | + if (empty($input_value)) { |
|
1292 | + // if the form input isn't marked as being required, then just return |
|
1293 | + if (! isset($this->_required_questions[ $form_input ]) || ! $this->_required_questions[ $form_input ]) { |
|
1294 | + return true; |
|
1295 | + } |
|
1296 | + switch ($form_input) { |
|
1297 | + case 'fname': |
|
1298 | + EE_Error::add_error( |
|
1299 | + esc_html__('First Name is a required value.', 'event_espresso'), |
|
1300 | + __FILE__, |
|
1301 | + __FUNCTION__, |
|
1302 | + __LINE__ |
|
1303 | + ); |
|
1304 | + return false; |
|
1305 | + break; |
|
1306 | + case 'lname': |
|
1307 | + EE_Error::add_error( |
|
1308 | + esc_html__('Last Name is a required value.', 'event_espresso'), |
|
1309 | + __FILE__, |
|
1310 | + __FUNCTION__, |
|
1311 | + __LINE__ |
|
1312 | + ); |
|
1313 | + return false; |
|
1314 | + break; |
|
1315 | + case 'email': |
|
1316 | + EE_Error::add_error( |
|
1317 | + esc_html__('Please enter a valid email address.', 'event_espresso'), |
|
1318 | + __FILE__, |
|
1319 | + __FUNCTION__, |
|
1320 | + __LINE__ |
|
1321 | + ); |
|
1322 | + return false; |
|
1323 | + break; |
|
1324 | + } |
|
1325 | + } |
|
1326 | + return true; |
|
1327 | + } |
|
1328 | + |
|
1329 | + |
|
1330 | + /** |
|
1331 | + * _associate_attendee_with_registration |
|
1332 | + * |
|
1333 | + * @param EE_Registration $registration |
|
1334 | + * @param EE_Attendee $attendee |
|
1335 | + * @return void |
|
1336 | + * @throws EE_Error |
|
1337 | + * @throws InvalidArgumentException |
|
1338 | + * @throws ReflectionException |
|
1339 | + * @throws RuntimeException |
|
1340 | + * @throws InvalidDataTypeException |
|
1341 | + * @throws InvalidInterfaceException |
|
1342 | + */ |
|
1343 | + private function _associate_attendee_with_registration(EE_Registration $registration, EE_Attendee $attendee) |
|
1344 | + { |
|
1345 | + // add relation to attendee |
|
1346 | + $registration->_add_relation_to($attendee, 'Attendee'); |
|
1347 | + $registration->set_attendee_id($attendee->ID()); |
|
1348 | + $registration->update_cache_after_object_save('Attendee', $attendee); |
|
1349 | + } |
|
1350 | + |
|
1351 | + |
|
1352 | + /** |
|
1353 | + * _associate_registration_with_transaction |
|
1354 | + * |
|
1355 | + * @param EE_Registration $registration |
|
1356 | + * @return void |
|
1357 | + * @throws EE_Error |
|
1358 | + * @throws InvalidArgumentException |
|
1359 | + * @throws ReflectionException |
|
1360 | + * @throws InvalidDataTypeException |
|
1361 | + * @throws InvalidInterfaceException |
|
1362 | + */ |
|
1363 | + private function _associate_registration_with_transaction(EE_Registration $registration) |
|
1364 | + { |
|
1365 | + // add relation to registration |
|
1366 | + $this->checkout->transaction->_add_relation_to($registration, 'Registration'); |
|
1367 | + $this->checkout->transaction->update_cache_after_object_save('Registration', $registration); |
|
1368 | + } |
|
1369 | + |
|
1370 | + |
|
1371 | + /** |
|
1372 | + * _copy_critical_attendee_details_from_primary_registrant |
|
1373 | + * ensures that all attendees at least have data for first name, last name, and email address |
|
1374 | + * |
|
1375 | + * @param array $attendee_data |
|
1376 | + * @return array |
|
1377 | + * @throws EE_Error |
|
1378 | + * @throws InvalidArgumentException |
|
1379 | + * @throws ReflectionException |
|
1380 | + * @throws InvalidDataTypeException |
|
1381 | + * @throws InvalidInterfaceException |
|
1382 | + */ |
|
1383 | + private function _copy_critical_attendee_details_from_primary_registrant($attendee_data = array()) |
|
1384 | + { |
|
1385 | + // bare minimum critical details include first name, last name, email address |
|
1386 | + $critical_attendee_details = array('ATT_fname', 'ATT_lname', 'ATT_email'); |
|
1387 | + // add address info to critical details? |
|
1388 | + if (apply_filters( |
|
1389 | + 'FHEE__EE_SPCO_Reg_Step_Attendee_Information__merge_address_details_with_critical_attendee_details', |
|
1390 | + false |
|
1391 | + )) { |
|
1392 | + $address_details = array( |
|
1393 | + 'ATT_address', |
|
1394 | + 'ATT_address2', |
|
1395 | + 'ATT_city', |
|
1396 | + 'STA_ID', |
|
1397 | + 'CNT_ISO', |
|
1398 | + 'ATT_zip', |
|
1399 | + 'ATT_phone', |
|
1400 | + ); |
|
1401 | + $critical_attendee_details = array_merge($critical_attendee_details, $address_details); |
|
1402 | + } |
|
1403 | + foreach ($critical_attendee_details as $critical_attendee_detail) { |
|
1404 | + if (! isset($attendee_data[ $critical_attendee_detail ]) |
|
1405 | + || empty($attendee_data[ $critical_attendee_detail ]) |
|
1406 | + ) { |
|
1407 | + $attendee_data[ $critical_attendee_detail ] = $this->checkout->primary_attendee_obj->get( |
|
1408 | + $critical_attendee_detail |
|
1409 | + ); |
|
1410 | + } |
|
1411 | + } |
|
1412 | + return $attendee_data; |
|
1413 | + } |
|
1414 | + |
|
1415 | + |
|
1416 | + /** |
|
1417 | + * update_reg_step |
|
1418 | + * this is the final step after a user revisits the site to edit their attendee information |
|
1419 | + * this gets called AFTER the process_reg_step() method above |
|
1420 | + * |
|
1421 | + * @return bool |
|
1422 | + * @throws EE_Error |
|
1423 | + * @throws InvalidArgumentException |
|
1424 | + * @throws ReflectionException |
|
1425 | + * @throws RuntimeException |
|
1426 | + * @throws InvalidDataTypeException |
|
1427 | + * @throws InvalidInterfaceException |
|
1428 | + */ |
|
1429 | + public function update_reg_step() |
|
1430 | + { |
|
1431 | + // save everything |
|
1432 | + if ($this->process_reg_step()) { |
|
1433 | + $this->checkout->redirect = true; |
|
1434 | + $this->checkout->redirect_url = add_query_arg( |
|
1435 | + array( |
|
1436 | + 'e_reg_url_link' => $this->checkout->reg_url_link, |
|
1437 | + 'revisit' => true, |
|
1438 | + ), |
|
1439 | + $this->checkout->thank_you_page_url |
|
1440 | + ); |
|
1441 | + $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url); |
|
1442 | + return true; |
|
1443 | + } |
|
1444 | + return false; |
|
1445 | + } |
|
1446 | 1446 | } |
@@ -18,179 +18,179 @@ |
||
18 | 18 | */ |
19 | 19 | class EE_Registration_Custom_Questions_Form extends EE_Form_Section_Proper |
20 | 20 | { |
21 | - /** |
|
22 | - * |
|
23 | - * @var EE_Registration |
|
24 | - */ |
|
25 | - protected $_registration = null; |
|
21 | + /** |
|
22 | + * |
|
23 | + * @var EE_Registration |
|
24 | + */ |
|
25 | + protected $_registration = null; |
|
26 | 26 | |
27 | - /** |
|
28 | - * |
|
29 | - * @param EE_Registration $reg |
|
30 | - * @param array $options |
|
31 | - */ |
|
32 | - public function __construct(EE_Registration $reg, $options = array()) |
|
33 | - { |
|
34 | - $this->_registration = $reg; |
|
35 | - if (! isset($options['layout_strategy'])) { |
|
36 | - $options['layout_strategy'] = new EE_Admin_Two_Column_Layout(); |
|
37 | - } |
|
38 | - if (! isset($options['html_id'])) { |
|
39 | - $options['html_id'] = 'reg-admin-attendee-questions-frm'; |
|
40 | - } |
|
41 | - $this->build_form_from_registration(); |
|
42 | - parent::__construct($options); |
|
43 | - } |
|
27 | + /** |
|
28 | + * |
|
29 | + * @param EE_Registration $reg |
|
30 | + * @param array $options |
|
31 | + */ |
|
32 | + public function __construct(EE_Registration $reg, $options = array()) |
|
33 | + { |
|
34 | + $this->_registration = $reg; |
|
35 | + if (! isset($options['layout_strategy'])) { |
|
36 | + $options['layout_strategy'] = new EE_Admin_Two_Column_Layout(); |
|
37 | + } |
|
38 | + if (! isset($options['html_id'])) { |
|
39 | + $options['html_id'] = 'reg-admin-attendee-questions-frm'; |
|
40 | + } |
|
41 | + $this->build_form_from_registration(); |
|
42 | + parent::__construct($options); |
|
43 | + } |
|
44 | 44 | |
45 | 45 | |
46 | - /** |
|
47 | - * Gets the registration object this form is about |
|
48 | - * @return EE_Registration |
|
49 | - */ |
|
50 | - public function get_registration() |
|
51 | - { |
|
52 | - return $this->_registration; |
|
53 | - } |
|
46 | + /** |
|
47 | + * Gets the registration object this form is about |
|
48 | + * @return EE_Registration |
|
49 | + */ |
|
50 | + public function get_registration() |
|
51 | + { |
|
52 | + return $this->_registration; |
|
53 | + } |
|
54 | 54 | |
55 | - /** |
|
56 | - * @since $VID:$ |
|
57 | - * @throws EE_Error |
|
58 | - * @throws InvalidArgumentException |
|
59 | - * @throws ReflectionException |
|
60 | - * @throws InvalidDataTypeException |
|
61 | - * @throws InvalidInterfaceException |
|
62 | - */ |
|
63 | - public function build_form_from_registration() |
|
64 | - { |
|
65 | - $reg = $this->get_registration(); |
|
66 | - if (! $reg instanceof EE_Registration) { |
|
67 | - throw new EE_Error(__('We cannot build the registration custom questions form because there is no registration set on it yet', 'event_espresso')); |
|
68 | - } |
|
69 | - // we want to get all their question groups |
|
70 | - $question_groups = EEM_Question_Group::instance()->get_all( |
|
71 | - [ |
|
72 | - [ |
|
73 | - 'Event_Question_Group.EVT_ID' => $reg->event_ID(), |
|
74 | - 'OR' => [ |
|
75 | - 'Question.QST_system*blank' => '', |
|
76 | - 'Question.QST_system*null' => ['IS_NULL'] |
|
77 | - ], |
|
78 | - 'Event_Question_Group.' |
|
79 | - . EEM_Event_Question_Group::instance()->fieldNameForContext( |
|
80 | - $reg->is_primary_registrant() |
|
81 | - ) => true |
|
82 | - ], |
|
83 | - 'order_by' => ['QSG_order' => 'ASC'] |
|
84 | - ] |
|
85 | - ); |
|
86 | - // get each question groups questions |
|
87 | - foreach ($question_groups as $question_group) { |
|
88 | - if ($question_group instanceof EE_Question_Group) { |
|
89 | - $this->_subsections[ $question_group->ID() ] = $this->build_subform_from_question_group( |
|
90 | - $question_group, |
|
91 | - $reg |
|
92 | - ); |
|
93 | - } |
|
94 | - } |
|
95 | - } |
|
55 | + /** |
|
56 | + * @since $VID:$ |
|
57 | + * @throws EE_Error |
|
58 | + * @throws InvalidArgumentException |
|
59 | + * @throws ReflectionException |
|
60 | + * @throws InvalidDataTypeException |
|
61 | + * @throws InvalidInterfaceException |
|
62 | + */ |
|
63 | + public function build_form_from_registration() |
|
64 | + { |
|
65 | + $reg = $this->get_registration(); |
|
66 | + if (! $reg instanceof EE_Registration) { |
|
67 | + throw new EE_Error(__('We cannot build the registration custom questions form because there is no registration set on it yet', 'event_espresso')); |
|
68 | + } |
|
69 | + // we want to get all their question groups |
|
70 | + $question_groups = EEM_Question_Group::instance()->get_all( |
|
71 | + [ |
|
72 | + [ |
|
73 | + 'Event_Question_Group.EVT_ID' => $reg->event_ID(), |
|
74 | + 'OR' => [ |
|
75 | + 'Question.QST_system*blank' => '', |
|
76 | + 'Question.QST_system*null' => ['IS_NULL'] |
|
77 | + ], |
|
78 | + 'Event_Question_Group.' |
|
79 | + . EEM_Event_Question_Group::instance()->fieldNameForContext( |
|
80 | + $reg->is_primary_registrant() |
|
81 | + ) => true |
|
82 | + ], |
|
83 | + 'order_by' => ['QSG_order' => 'ASC'] |
|
84 | + ] |
|
85 | + ); |
|
86 | + // get each question groups questions |
|
87 | + foreach ($question_groups as $question_group) { |
|
88 | + if ($question_group instanceof EE_Question_Group) { |
|
89 | + $this->_subsections[ $question_group->ID() ] = $this->build_subform_from_question_group( |
|
90 | + $question_group, |
|
91 | + $reg |
|
92 | + ); |
|
93 | + } |
|
94 | + } |
|
95 | + } |
|
96 | 96 | |
97 | 97 | |
98 | 98 | |
99 | - /** |
|
100 | - * |
|
101 | - * @param EE_Question_Group $question_group |
|
102 | - * @param EE_Registration $registration |
|
103 | - * @return \EE_Form_Section_Proper |
|
104 | - * @throws \EE_Error |
|
105 | - */ |
|
106 | - public function build_subform_from_question_group($question_group, $registration) |
|
107 | - { |
|
108 | - if (! $question_group instanceof EE_Question_Group || |
|
109 | - ! $registration instanceof EE_Registration) { |
|
110 | - throw new EE_Error(__('A valid question group and registration must be passed to EE_Registration_Custom_Question_Form', 'event_espresso')); |
|
111 | - } |
|
112 | - $parts_of_subsection = array( |
|
113 | - 'title' => new EE_Form_Section_HTML( |
|
114 | - EEH_HTML::h5( |
|
115 | - $question_group->name(), |
|
116 | - $question_group->identifier(), |
|
117 | - 'espresso-question-group-title-h5 section-title' |
|
118 | - ) |
|
119 | - ) |
|
120 | - ); |
|
121 | - $questions = $question_group->questions( |
|
122 | - array( |
|
123 | - array( |
|
124 | - 'OR' => array( |
|
125 | - 'QST_system*blank' => '', |
|
126 | - 'QST_system*null' => array( 'IS_NULL' ) |
|
127 | - ) |
|
128 | - ) |
|
129 | - ) |
|
130 | - ); |
|
131 | - foreach ($questions as $question) { |
|
132 | - $parts_of_subsection[ $question->ID() ] = $question->generate_form_input($registration); |
|
133 | - } |
|
134 | - if (EE_Registry::instance()->CAP->current_user_can( |
|
135 | - 'ee_edit_registration', |
|
136 | - 'edit-reg-questions-mbox', |
|
137 | - $this->_registration->ID() |
|
138 | - )) { |
|
139 | - $parts_of_subsection['edit_link'] = new EE_Form_Section_HTML( |
|
140 | - '<tr><th/><td class="reg-admin-edit-attendee-question-td"><a class="reg-admin-edit-attendee-question-lnk" href="#" title="' . esc_attr__('click to edit question', 'event_espresso') . '"> |
|
99 | + /** |
|
100 | + * |
|
101 | + * @param EE_Question_Group $question_group |
|
102 | + * @param EE_Registration $registration |
|
103 | + * @return \EE_Form_Section_Proper |
|
104 | + * @throws \EE_Error |
|
105 | + */ |
|
106 | + public function build_subform_from_question_group($question_group, $registration) |
|
107 | + { |
|
108 | + if (! $question_group instanceof EE_Question_Group || |
|
109 | + ! $registration instanceof EE_Registration) { |
|
110 | + throw new EE_Error(__('A valid question group and registration must be passed to EE_Registration_Custom_Question_Form', 'event_espresso')); |
|
111 | + } |
|
112 | + $parts_of_subsection = array( |
|
113 | + 'title' => new EE_Form_Section_HTML( |
|
114 | + EEH_HTML::h5( |
|
115 | + $question_group->name(), |
|
116 | + $question_group->identifier(), |
|
117 | + 'espresso-question-group-title-h5 section-title' |
|
118 | + ) |
|
119 | + ) |
|
120 | + ); |
|
121 | + $questions = $question_group->questions( |
|
122 | + array( |
|
123 | + array( |
|
124 | + 'OR' => array( |
|
125 | + 'QST_system*blank' => '', |
|
126 | + 'QST_system*null' => array( 'IS_NULL' ) |
|
127 | + ) |
|
128 | + ) |
|
129 | + ) |
|
130 | + ); |
|
131 | + foreach ($questions as $question) { |
|
132 | + $parts_of_subsection[ $question->ID() ] = $question->generate_form_input($registration); |
|
133 | + } |
|
134 | + if (EE_Registry::instance()->CAP->current_user_can( |
|
135 | + 'ee_edit_registration', |
|
136 | + 'edit-reg-questions-mbox', |
|
137 | + $this->_registration->ID() |
|
138 | + )) { |
|
139 | + $parts_of_subsection['edit_link'] = new EE_Form_Section_HTML( |
|
140 | + '<tr><th/><td class="reg-admin-edit-attendee-question-td"><a class="reg-admin-edit-attendee-question-lnk" href="#" title="' . esc_attr__('click to edit question', 'event_espresso') . '"> |
|
141 | 141 | <span class="reg-admin-edit-question-group-spn lt-grey-txt">' . __('edit the above question group', 'event_espresso') . '</span> |
142 | 142 | <div class="dashicons dashicons-edit"></div> |
143 | 143 | </a></td></tr>' |
144 | - ); |
|
145 | - } |
|
146 | - return new EE_Form_Section_Proper( |
|
147 | - array( |
|
148 | - 'subsections' => $parts_of_subsection, |
|
149 | - 'html_class' => 'question-group-questions', |
|
150 | - ) |
|
151 | - ); |
|
152 | - } |
|
144 | + ); |
|
145 | + } |
|
146 | + return new EE_Form_Section_Proper( |
|
147 | + array( |
|
148 | + 'subsections' => $parts_of_subsection, |
|
149 | + 'html_class' => 'question-group-questions', |
|
150 | + ) |
|
151 | + ); |
|
152 | + } |
|
153 | 153 | |
154 | - /** |
|
155 | - * Overrides parent so if inputs were disabled, we leave those with their defaults |
|
156 | - * from the answers in the DB |
|
157 | - * @param array $req_data like $_POST |
|
158 | - * @return void |
|
159 | - */ |
|
160 | - protected function _normalize($req_data) |
|
161 | - { |
|
162 | - $this->_received_submission = true; |
|
163 | - $this->_validation_errors = array(); |
|
164 | - foreach ($this->get_validatable_subsections() as $subsection) { |
|
165 | - if ($subsection->form_data_present_in($req_data)) { |
|
166 | - try { |
|
167 | - $subsection->_normalize($req_data); |
|
168 | - } catch (EE_Validation_Error $e) { |
|
169 | - $subsection->add_validation_error($e); |
|
170 | - } |
|
171 | - } |
|
172 | - } |
|
173 | - } |
|
154 | + /** |
|
155 | + * Overrides parent so if inputs were disabled, we leave those with their defaults |
|
156 | + * from the answers in the DB |
|
157 | + * @param array $req_data like $_POST |
|
158 | + * @return void |
|
159 | + */ |
|
160 | + protected function _normalize($req_data) |
|
161 | + { |
|
162 | + $this->_received_submission = true; |
|
163 | + $this->_validation_errors = array(); |
|
164 | + foreach ($this->get_validatable_subsections() as $subsection) { |
|
165 | + if ($subsection->form_data_present_in($req_data)) { |
|
166 | + try { |
|
167 | + $subsection->_normalize($req_data); |
|
168 | + } catch (EE_Validation_Error $e) { |
|
169 | + $subsection->add_validation_error($e); |
|
170 | + } |
|
171 | + } |
|
172 | + } |
|
173 | + } |
|
174 | 174 | |
175 | 175 | |
176 | 176 | |
177 | - /** |
|
178 | - * Performs validation on this form section and its subsections. For each subsection, |
|
179 | - * calls _validate_{subsection_name} on THIS form (if the function exists) and passes it the subsection, then calls _validate on that subsection. |
|
180 | - * If you need to perform validation on the form as a whole (considering multiple) you would be best to override this _validate method, |
|
181 | - * calling parent::_validate() first. |
|
182 | - */ |
|
183 | - protected function _validate() |
|
184 | - { |
|
185 | - foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) { |
|
186 | - if ($subsection->form_data_present_in(array_merge($_GET, $_POST))) { |
|
187 | - if (method_exists($this, '_validate_'.$subsection_name)) { |
|
188 | - call_user_func_array(array($this,'_validate_'.$subsection_name), array($subsection)); |
|
189 | - } |
|
190 | - $subsection->_validate(); |
|
191 | - } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
192 | - $subsection->_received_submission = true; |
|
193 | - } |
|
194 | - } |
|
195 | - } |
|
177 | + /** |
|
178 | + * Performs validation on this form section and its subsections. For each subsection, |
|
179 | + * calls _validate_{subsection_name} on THIS form (if the function exists) and passes it the subsection, then calls _validate on that subsection. |
|
180 | + * If you need to perform validation on the form as a whole (considering multiple) you would be best to override this _validate method, |
|
181 | + * calling parent::_validate() first. |
|
182 | + */ |
|
183 | + protected function _validate() |
|
184 | + { |
|
185 | + foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) { |
|
186 | + if ($subsection->form_data_present_in(array_merge($_GET, $_POST))) { |
|
187 | + if (method_exists($this, '_validate_'.$subsection_name)) { |
|
188 | + call_user_func_array(array($this,'_validate_'.$subsection_name), array($subsection)); |
|
189 | + } |
|
190 | + $subsection->_validate(); |
|
191 | + } elseif ($subsection instanceof EE_Form_Section_Proper) { |
|
192 | + $subsection->_received_submission = true; |
|
193 | + } |
|
194 | + } |
|
195 | + } |
|
196 | 196 | } |