@@ -181,14 +181,14 @@ discard block |
||
181 | 181 | */ |
182 | 182 | public function setActiveTickets(array $active_tickets = array()) |
183 | 183 | { |
184 | - if (! empty($active_tickets)) { |
|
184 | + if ( ! empty($active_tickets)) { |
|
185 | 185 | foreach ($active_tickets as $active_ticket) { |
186 | 186 | $this->validateTicket($active_ticket); |
187 | 187 | } |
188 | 188 | // sort incoming array by ticket quantity (asc) |
189 | 189 | usort( |
190 | 190 | $active_tickets, |
191 | - function (EE_Ticket $a, EE_Ticket $b) { |
|
191 | + function(EE_Ticket $a, EE_Ticket $b) { |
|
192 | 192 | if ($a->qty() === $b->qty()) { |
193 | 193 | return 0; |
194 | 194 | } |
@@ -210,7 +210,7 @@ discard block |
||
210 | 210 | */ |
211 | 211 | private function validateTicket($ticket) |
212 | 212 | { |
213 | - if (! $ticket instanceof EE_Ticket) { |
|
213 | + if ( ! $ticket instanceof EE_Ticket) { |
|
214 | 214 | throw new DomainException( |
215 | 215 | esc_html__( |
216 | 216 | 'Invalid Ticket. Only EE_Ticket objects can be used to calculate event space availability.', |
@@ -261,7 +261,7 @@ discard block |
||
261 | 261 | ) |
262 | 262 | ); |
263 | 263 | } |
264 | - $this->datetimes[ $datetime->ID() ] = $datetime; |
|
264 | + $this->datetimes[$datetime->ID()] = $datetime; |
|
265 | 265 | } |
266 | 266 | |
267 | 267 | |
@@ -340,7 +340,7 @@ discard block |
||
340 | 340 | $this->tickets_sold = array(); |
341 | 341 | $this->total_spaces = array(); |
342 | 342 | $active_tickets = $this->getActiveTickets(); |
343 | - if (! empty($active_tickets)) { |
|
343 | + if ( ! empty($active_tickets)) { |
|
344 | 344 | foreach ($active_tickets as $ticket) { |
345 | 345 | $this->validateTicket($ticket); |
346 | 346 | // we need to index our data arrays using strings for the purpose of sorting, |
@@ -362,16 +362,16 @@ discard block |
||
362 | 362 | // we are going to move all of our data into the following arrays: |
363 | 363 | // datetime spaces initially represents the reg limit for each datetime, |
364 | 364 | // but this will get adjusted as tickets are accounted for |
365 | - $this->datetime_spaces[ $datetime_identifier ] = $reg_limit; |
|
365 | + $this->datetime_spaces[$datetime_identifier] = $reg_limit; |
|
366 | 366 | // just an array of ticket IDs grouped by datetime |
367 | - $this->datetime_tickets[ $datetime_identifier ][] = $ticket_identifier; |
|
367 | + $this->datetime_tickets[$datetime_identifier][] = $ticket_identifier; |
|
368 | 368 | // and an array of datetime IDs grouped by ticket |
369 | - $this->ticket_datetimes[ $ticket_identifier ][] = $datetime_identifier; |
|
369 | + $this->ticket_datetimes[$ticket_identifier][] = $datetime_identifier; |
|
370 | 370 | } |
371 | 371 | // total quantity of sold and reserved for each ticket |
372 | - $this->tickets_sold[ $ticket_identifier ] = $ticket->sold() + $ticket->reserved(); |
|
372 | + $this->tickets_sold[$ticket_identifier] = $ticket->sold() + $ticket->reserved(); |
|
373 | 373 | // and the maximum ticket quantities for each ticket (adjusted for reg limit) |
374 | - $this->ticket_quantities[ $ticket_identifier ] = $max_tickets; |
|
374 | + $this->ticket_quantities[$ticket_identifier] = $max_tickets; |
|
375 | 375 | } |
376 | 376 | } |
377 | 377 | // sort datetime spaces by reg limit, but maintain our string indexes |
@@ -430,11 +430,11 @@ discard block |
||
430 | 430 | \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2); |
431 | 431 | } |
432 | 432 | foreach ($this->tickets_sold as $ticket_identifier => $tickets_sold) { |
433 | - if (isset($this->ticket_quantities[ $ticket_identifier ])) { |
|
434 | - $this->ticket_quantities[ $ticket_identifier ] -= $tickets_sold; |
|
433 | + if (isset($this->ticket_quantities[$ticket_identifier])) { |
|
434 | + $this->ticket_quantities[$ticket_identifier] -= $tickets_sold; |
|
435 | 435 | // don't let values go below zero |
436 | - $this->ticket_quantities[ $ticket_identifier ] = max( |
|
437 | - $this->ticket_quantities[ $ticket_identifier ], |
|
436 | + $this->ticket_quantities[$ticket_identifier] = max( |
|
437 | + $this->ticket_quantities[$ticket_identifier], |
|
438 | 438 | 0 |
439 | 439 | ); |
440 | 440 | if ($this->debug) { |
@@ -447,15 +447,15 @@ discard block |
||
447 | 447 | } |
448 | 448 | } |
449 | 449 | if ( |
450 | - isset($this->ticket_datetimes[ $ticket_identifier ]) |
|
451 | - && is_array($this->ticket_datetimes[ $ticket_identifier ]) |
|
450 | + isset($this->ticket_datetimes[$ticket_identifier]) |
|
451 | + && is_array($this->ticket_datetimes[$ticket_identifier]) |
|
452 | 452 | ) { |
453 | - foreach ($this->ticket_datetimes[ $ticket_identifier ] as $ticket_datetime) { |
|
454 | - if (isset($this->ticket_quantities[ $ticket_identifier ])) { |
|
455 | - $this->datetime_spaces[ $ticket_datetime ] -= $tickets_sold; |
|
453 | + foreach ($this->ticket_datetimes[$ticket_identifier] as $ticket_datetime) { |
|
454 | + if (isset($this->ticket_quantities[$ticket_identifier])) { |
|
455 | + $this->datetime_spaces[$ticket_datetime] -= $tickets_sold; |
|
456 | 456 | // don't let values go below zero |
457 | - $this->datetime_spaces[ $ticket_datetime ] = max( |
|
458 | - $this->datetime_spaces[ $ticket_datetime ], |
|
457 | + $this->datetime_spaces[$ticket_datetime] = max( |
|
458 | + $this->datetime_spaces[$ticket_datetime], |
|
459 | 459 | 0 |
460 | 460 | ); |
461 | 461 | if ($this->debug) { |
@@ -480,11 +480,11 @@ discard block |
||
480 | 480 | private function trackAvailableSpacesForDatetimes($datetime_identifier, array $tickets) |
481 | 481 | { |
482 | 482 | // make sure a reg limit is set for the datetime |
483 | - $reg_limit = isset($this->datetime_spaces[ $datetime_identifier ]) |
|
484 | - ? $this->datetime_spaces[ $datetime_identifier ] |
|
483 | + $reg_limit = isset($this->datetime_spaces[$datetime_identifier]) |
|
484 | + ? $this->datetime_spaces[$datetime_identifier] |
|
485 | 485 | : 0; |
486 | 486 | // and bail if it is not |
487 | - if (! $reg_limit) { |
|
487 | + if ( ! $reg_limit) { |
|
488 | 488 | if ($this->debug) { |
489 | 489 | \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__); |
490 | 490 | } |
@@ -501,7 +501,7 @@ discard block |
||
501 | 501 | } |
502 | 502 | // number of allocated spaces always starts at zero |
503 | 503 | $spaces_allocated = 0; |
504 | - $this->total_spaces[ $datetime_identifier ] = 0; |
|
504 | + $this->total_spaces[$datetime_identifier] = 0; |
|
505 | 505 | foreach ($tickets as $ticket_identifier) { |
506 | 506 | $spaces_allocated = $this->calculateAvailableSpacesForTicket( |
507 | 507 | $datetime_identifier, |
@@ -514,7 +514,7 @@ discard block |
||
514 | 514 | $spaces_allocated = max($spaces_allocated, 0); |
515 | 515 | if ($spaces_allocated) { |
516 | 516 | // track any non-zero values |
517 | - $this->total_spaces[ $datetime_identifier ] += $spaces_allocated; |
|
517 | + $this->total_spaces[$datetime_identifier] += $spaces_allocated; |
|
518 | 518 | if ($this->debug) { |
519 | 519 | \EEH_Debug_Tools::printr((string) $spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__); |
520 | 520 | } |
@@ -525,7 +525,7 @@ discard block |
||
525 | 525 | } |
526 | 526 | if ($this->debug) { |
527 | 527 | \EEH_Debug_Tools::printr( |
528 | - $this->total_spaces[ $datetime_identifier ], |
|
528 | + $this->total_spaces[$datetime_identifier], |
|
529 | 529 | '$total_spaces', |
530 | 530 | __FILE__, |
531 | 531 | __LINE__ |
@@ -550,8 +550,8 @@ discard block |
||
550 | 550 | $spaces_allocated |
551 | 551 | ) { |
552 | 552 | // make sure ticket quantity is set |
553 | - $ticket_quantity = isset($this->ticket_quantities[ $ticket_identifier ]) |
|
554 | - ? $this->ticket_quantities[ $ticket_identifier ] |
|
553 | + $ticket_quantity = isset($this->ticket_quantities[$ticket_identifier]) |
|
554 | + ? $this->ticket_quantities[$ticket_identifier] |
|
555 | 555 | : 0; |
556 | 556 | if ($this->debug) { |
557 | 557 | \EEH_Debug_Tools::printr("{$spaces_allocated}", '$spaces_allocated', __FILE__, __LINE__); |
@@ -581,7 +581,7 @@ discard block |
||
581 | 581 | // or the maximum ticket quantity |
582 | 582 | $ticket_quantity = min($reg_limit - $spaces_allocated, $ticket_quantity); |
583 | 583 | // adjust the available quantity in our tracking array |
584 | - $this->ticket_quantities[ $ticket_identifier ] -= $ticket_quantity; |
|
584 | + $this->ticket_quantities[$ticket_identifier] -= $ticket_quantity; |
|
585 | 585 | // and increment spaces allocated for this datetime |
586 | 586 | $spaces_allocated += $ticket_quantity; |
587 | 587 | $at_capacity = $spaces_allocated >= $reg_limit; |
@@ -638,15 +638,15 @@ discard block |
||
638 | 638 | $ticket_quantity |
639 | 639 | ); |
640 | 640 | // skip to next ticket if nothing changed |
641 | - if (! ($adjusted || $at_capacity)) { |
|
641 | + if ( ! ($adjusted || $at_capacity)) { |
|
642 | 642 | continue; |
643 | 643 | } |
644 | 644 | // then all of it's tickets are now unavailable |
645 | 645 | foreach ($datetime_tickets as $datetime_ticket) { |
646 | 646 | if ( |
647 | 647 | ($ticket_identifier === $datetime_ticket || $at_capacity) |
648 | - && isset($this->ticket_quantities[ $datetime_ticket ]) |
|
649 | - && $this->ticket_quantities[ $datetime_ticket ] > 0 |
|
648 | + && isset($this->ticket_quantities[$datetime_ticket]) |
|
649 | + && $this->ticket_quantities[$datetime_ticket] > 0 |
|
650 | 650 | ) { |
651 | 651 | if ($this->debug) { |
652 | 652 | \EEH_Debug_Tools::printr( |
@@ -660,14 +660,14 @@ discard block |
||
660 | 660 | // otherwise just subtract the ticket quantity |
661 | 661 | $new_quantity = $at_capacity |
662 | 662 | ? 0 |
663 | - : $this->ticket_quantities[ $datetime_ticket ] - $ticket_quantity; |
|
663 | + : $this->ticket_quantities[$datetime_ticket] - $ticket_quantity; |
|
664 | 664 | // don't let ticket quantity go below zero |
665 | - $this->ticket_quantities[ $datetime_ticket ] = max($new_quantity, 0); |
|
665 | + $this->ticket_quantities[$datetime_ticket] = max($new_quantity, 0); |
|
666 | 666 | if ($this->debug) { |
667 | 667 | \EEH_Debug_Tools::printr( |
668 | 668 | $at_capacity |
669 | 669 | ? "0 because Datetime {$datetime_identifier} is at capacity" |
670 | - : "{$this->ticket_quantities[ $datetime_ticket ]}", |
|
670 | + : "{$this->ticket_quantities[$datetime_ticket]}", |
|
671 | 671 | " . . . . {$datetime_ticket} quantity set to ", |
672 | 672 | __FILE__, |
673 | 673 | __LINE__ |
@@ -677,8 +677,8 @@ discard block |
||
677 | 677 | // but we also need to adjust spaces for any other datetimes this ticket has access to |
678 | 678 | if ($datetime_ticket === $ticket_identifier) { |
679 | 679 | if ( |
680 | - isset($this->ticket_datetimes[ $datetime_ticket ]) |
|
681 | - && is_array($this->ticket_datetimes[ $datetime_ticket ]) |
|
680 | + isset($this->ticket_datetimes[$datetime_ticket]) |
|
681 | + && is_array($this->ticket_datetimes[$datetime_ticket]) |
|
682 | 682 | ) { |
683 | 683 | if ($this->debug) { |
684 | 684 | \EEH_Debug_Tools::printr( |
@@ -688,7 +688,7 @@ discard block |
||
688 | 688 | __LINE__ |
689 | 689 | ); |
690 | 690 | } |
691 | - foreach ($this->ticket_datetimes[ $datetime_ticket ] as $datetime) { |
|
691 | + foreach ($this->ticket_datetimes[$datetime_ticket] as $datetime) { |
|
692 | 692 | // don't adjust the current datetime twice |
693 | 693 | if ($datetime !== $datetime_identifier) { |
694 | 694 | $this->adjustDatetimeSpaces( |
@@ -709,24 +709,24 @@ discard block |
||
709 | 709 | // does datetime have spaces available? |
710 | 710 | // and does the supplied ticket have access to this datetime ? |
711 | 711 | if ( |
712 | - $this->datetime_spaces[ $datetime_identifier ] > 0 |
|
713 | - && isset($this->datetime_spaces[ $datetime_identifier ], $this->datetime_tickets[ $datetime_identifier ]) |
|
714 | - && in_array($ticket_identifier, $this->datetime_tickets[ $datetime_identifier ], true) |
|
712 | + $this->datetime_spaces[$datetime_identifier] > 0 |
|
713 | + && isset($this->datetime_spaces[$datetime_identifier], $this->datetime_tickets[$datetime_identifier]) |
|
714 | + && in_array($ticket_identifier, $this->datetime_tickets[$datetime_identifier], true) |
|
715 | 715 | ) { |
716 | 716 | if ($this->debug) { |
717 | 717 | \EEH_Debug_Tools::printr($datetime_identifier, ' . . adjust Datetime Spaces for', __FILE__, __LINE__); |
718 | 718 | \EEH_Debug_Tools::printr( |
719 | - "{$this->datetime_spaces[ $datetime_identifier ]}", |
|
719 | + "{$this->datetime_spaces[$datetime_identifier]}", |
|
720 | 720 | " . . current {$datetime_identifier} spaces available", |
721 | 721 | __FILE__, |
722 | 722 | __LINE__ |
723 | 723 | ); |
724 | 724 | } |
725 | 725 | // then decrement the available spaces for the datetime |
726 | - $this->datetime_spaces[ $datetime_identifier ] -= $ticket_quantity; |
|
726 | + $this->datetime_spaces[$datetime_identifier] -= $ticket_quantity; |
|
727 | 727 | // but don't let quantities go below zero |
728 | - $this->datetime_spaces[ $datetime_identifier ] = max( |
|
729 | - $this->datetime_spaces[ $datetime_identifier ], |
|
728 | + $this->datetime_spaces[$datetime_identifier] = max( |
|
729 | + $this->datetime_spaces[$datetime_identifier], |
|
730 | 730 | 0 |
731 | 731 | ); |
732 | 732 | if ($this->debug) { |
@@ -25,719 +25,719 @@ |
||
25 | 25 | */ |
26 | 26 | class EventSpacesCalculator |
27 | 27 | { |
28 | - /** |
|
29 | - * @var EE_Event $event |
|
30 | - */ |
|
31 | - private $event; |
|
32 | - |
|
33 | - /** |
|
34 | - * @var array $datetime_query_params |
|
35 | - */ |
|
36 | - private $datetime_query_params; |
|
37 | - |
|
38 | - /** |
|
39 | - * @var EE_Ticket[] $active_tickets |
|
40 | - */ |
|
41 | - private $active_tickets = array(); |
|
42 | - |
|
43 | - /** |
|
44 | - * @var EE_Datetime[] $datetimes |
|
45 | - */ |
|
46 | - private $datetimes = array(); |
|
47 | - |
|
48 | - /** |
|
49 | - * Array of Ticket IDs grouped by Datetime |
|
50 | - * |
|
51 | - * @var array $datetimes |
|
52 | - */ |
|
53 | - private $datetime_tickets = array(); |
|
54 | - |
|
55 | - /** |
|
56 | - * Max spaces for each Datetime (reg limit - previous sold) |
|
57 | - * |
|
58 | - * @var array $datetime_spaces |
|
59 | - */ |
|
60 | - private $datetime_spaces = array(); |
|
61 | - |
|
62 | - /** |
|
63 | - * Array of Datetime IDs grouped by Ticket |
|
64 | - * |
|
65 | - * @var array[] $ticket_datetimes |
|
66 | - */ |
|
67 | - private $ticket_datetimes = array(); |
|
68 | - |
|
69 | - /** |
|
70 | - * maximum ticket quantities for each ticket (adjusted for reg limit) |
|
71 | - * |
|
72 | - * @var array $ticket_quantities |
|
73 | - */ |
|
74 | - private $ticket_quantities = array(); |
|
75 | - |
|
76 | - /** |
|
77 | - * total quantity of sold and reserved for each ticket |
|
78 | - * |
|
79 | - * @var array $tickets_sold |
|
80 | - */ |
|
81 | - private $tickets_sold = array(); |
|
82 | - |
|
83 | - /** |
|
84 | - * total spaces available across all datetimes |
|
85 | - * |
|
86 | - * @var array $total_spaces |
|
87 | - */ |
|
88 | - private $total_spaces = array(); |
|
89 | - |
|
90 | - /** |
|
91 | - * @var boolean $debug |
|
92 | - */ |
|
93 | - private $debug = false; // true false |
|
94 | - |
|
95 | - /** |
|
96 | - * @var null|int $spaces_remaining |
|
97 | - */ |
|
98 | - private $spaces_remaining; |
|
99 | - |
|
100 | - /** |
|
101 | - * @var null|int $total_spaces_available |
|
102 | - */ |
|
103 | - private $total_spaces_available; |
|
104 | - |
|
105 | - |
|
106 | - /** |
|
107 | - * EventSpacesCalculator constructor. |
|
108 | - * |
|
109 | - * @param EE_Event $event |
|
110 | - * @param array $datetime_query_params |
|
111 | - * @throws EE_Error |
|
112 | - */ |
|
113 | - public function __construct(EE_Event $event, array $datetime_query_params = array()) |
|
114 | - { |
|
115 | - if ($this->debug) { |
|
116 | - \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 1); |
|
117 | - \EEH_Debug_Tools::printr((string) $event->ID(), 'For event', __FILE__, __LINE__); |
|
118 | - } |
|
119 | - $this->event = $event; |
|
120 | - $this->datetime_query_params = $datetime_query_params + array('order_by' => array('DTT_reg_limit' => 'ASC')); |
|
121 | - $this->setHooks(); |
|
122 | - } |
|
123 | - |
|
124 | - |
|
125 | - /** |
|
126 | - * @return void |
|
127 | - */ |
|
128 | - private function setHooks() |
|
129 | - { |
|
130 | - add_action('AHEE__EE_Ticket__increase_sold', array($this, 'clearResults')); |
|
131 | - add_action('AHEE__EE_Ticket__decrease_sold', array($this, 'clearResults')); |
|
132 | - add_action('AHEE__EE_Datetime__increase_sold', array($this, 'clearResults')); |
|
133 | - add_action('AHEE__EE_Datetime__decrease_sold', array($this, 'clearResults')); |
|
134 | - add_action('AHEE__EE_Ticket__increase_reserved', array($this, 'clearResults')); |
|
135 | - add_action('AHEE__EE_Ticket__decrease_reserved', array($this, 'clearResults')); |
|
136 | - add_action('AHEE__EE_Datetime__increase_reserved', array($this, 'clearResults')); |
|
137 | - add_action('AHEE__EE_Datetime__decrease_reserved', array($this, 'clearResults')); |
|
138 | - } |
|
139 | - |
|
140 | - |
|
141 | - /** |
|
142 | - * @return void |
|
143 | - */ |
|
144 | - public function clearResults() |
|
145 | - { |
|
146 | - if ($this->debug) { |
|
147 | - \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 1); |
|
148 | - } |
|
149 | - $this->spaces_remaining = null; |
|
150 | - $this->total_spaces_available = null; |
|
151 | - } |
|
152 | - |
|
153 | - |
|
154 | - /** |
|
155 | - * @return EE_Ticket[] |
|
156 | - * @throws EE_Error |
|
157 | - * @throws InvalidDataTypeException |
|
158 | - * @throws InvalidInterfaceException |
|
159 | - * @throws InvalidArgumentException |
|
160 | - */ |
|
161 | - public function getActiveTickets() |
|
162 | - { |
|
163 | - if (empty($this->active_tickets)) { |
|
164 | - $this->active_tickets = $this->event->tickets( |
|
165 | - array( |
|
166 | - array('TKT_deleted' => false), |
|
167 | - 'order_by' => array('TKT_qty' => 'ASC'), |
|
168 | - ) |
|
169 | - ); |
|
170 | - } |
|
171 | - return $this->active_tickets; |
|
172 | - } |
|
173 | - |
|
174 | - |
|
175 | - /** |
|
176 | - * @param EE_Ticket[] $active_tickets |
|
177 | - * @throws EE_Error |
|
178 | - * @throws DomainException |
|
179 | - * @throws UnexpectedEntityException |
|
180 | - */ |
|
181 | - public function setActiveTickets(array $active_tickets = array()) |
|
182 | - { |
|
183 | - if (! empty($active_tickets)) { |
|
184 | - foreach ($active_tickets as $active_ticket) { |
|
185 | - $this->validateTicket($active_ticket); |
|
186 | - } |
|
187 | - // sort incoming array by ticket quantity (asc) |
|
188 | - usort( |
|
189 | - $active_tickets, |
|
190 | - function (EE_Ticket $a, EE_Ticket $b) { |
|
191 | - if ($a->qty() === $b->qty()) { |
|
192 | - return 0; |
|
193 | - } |
|
194 | - return ($a->qty() < $b->qty()) |
|
195 | - ? -1 |
|
196 | - : 1; |
|
197 | - } |
|
198 | - ); |
|
199 | - } |
|
200 | - $this->active_tickets = $active_tickets; |
|
201 | - } |
|
202 | - |
|
203 | - |
|
204 | - /** |
|
205 | - * @param $ticket |
|
206 | - * @throws DomainException |
|
207 | - * @throws EE_Error |
|
208 | - * @throws UnexpectedEntityException |
|
209 | - */ |
|
210 | - private function validateTicket($ticket) |
|
211 | - { |
|
212 | - if (! $ticket instanceof EE_Ticket) { |
|
213 | - throw new DomainException( |
|
214 | - esc_html__( |
|
215 | - 'Invalid Ticket. Only EE_Ticket objects can be used to calculate event space availability.', |
|
216 | - 'event_espresso' |
|
217 | - ) |
|
218 | - ); |
|
219 | - } |
|
220 | - if ($ticket->get_event_ID() !== $this->event->ID()) { |
|
221 | - throw new DomainException( |
|
222 | - sprintf( |
|
223 | - esc_html__( |
|
224 | - 'An EE_Ticket for Event %1$d was supplied while calculating event space availability for Event %2$d.', |
|
225 | - 'event_espresso' |
|
226 | - ), |
|
227 | - $ticket->get_event_ID(), |
|
228 | - $this->event->ID() |
|
229 | - ) |
|
230 | - ); |
|
231 | - } |
|
232 | - } |
|
233 | - |
|
234 | - |
|
235 | - /** |
|
236 | - * @return EE_Datetime[] |
|
237 | - */ |
|
238 | - public function getDatetimes() |
|
239 | - { |
|
240 | - return $this->datetimes; |
|
241 | - } |
|
242 | - |
|
243 | - |
|
244 | - /** |
|
245 | - * @param EE_Datetime $datetime |
|
246 | - * @throws EE_Error |
|
247 | - * @throws DomainException |
|
248 | - */ |
|
249 | - public function setDatetime(EE_Datetime $datetime) |
|
250 | - { |
|
251 | - if ($datetime->event()->ID() !== $this->event->ID()) { |
|
252 | - throw new DomainException( |
|
253 | - sprintf( |
|
254 | - esc_html__( |
|
255 | - 'An EE_Datetime for Event %1$d was supplied while calculating event space availability for Event %2$d.', |
|
256 | - 'event_espresso' |
|
257 | - ), |
|
258 | - $datetime->event()->ID(), |
|
259 | - $this->event->ID() |
|
260 | - ) |
|
261 | - ); |
|
262 | - } |
|
263 | - $this->datetimes[ $datetime->ID() ] = $datetime; |
|
264 | - } |
|
265 | - |
|
266 | - |
|
267 | - /** |
|
268 | - * calculate spaces remaining based on "saleable" tickets |
|
269 | - * |
|
270 | - * @return float|int |
|
271 | - * @throws EE_Error |
|
272 | - * @throws DomainException |
|
273 | - * @throws UnexpectedEntityException |
|
274 | - * @throws InvalidDataTypeException |
|
275 | - * @throws InvalidInterfaceException |
|
276 | - * @throws InvalidArgumentException |
|
277 | - */ |
|
278 | - public function spacesRemaining() |
|
279 | - { |
|
280 | - if ($this->debug) { |
|
281 | - \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2); |
|
282 | - } |
|
283 | - if ($this->spaces_remaining === null) { |
|
284 | - $this->initialize(); |
|
285 | - $this->spaces_remaining = $this->calculate(); |
|
286 | - } |
|
287 | - return $this->spaces_remaining; |
|
288 | - } |
|
289 | - |
|
290 | - |
|
291 | - /** |
|
292 | - * calculates total available spaces for an event with no regard for sold tickets |
|
293 | - * |
|
294 | - * @return int|float |
|
295 | - * @throws EE_Error |
|
296 | - * @throws DomainException |
|
297 | - * @throws UnexpectedEntityException |
|
298 | - * @throws InvalidDataTypeException |
|
299 | - * @throws InvalidInterfaceException |
|
300 | - * @throws InvalidArgumentException |
|
301 | - */ |
|
302 | - public function totalSpacesAvailable() |
|
303 | - { |
|
304 | - if ($this->debug) { |
|
305 | - \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2); |
|
306 | - } |
|
307 | - if ($this->total_spaces_available === null) { |
|
308 | - $this->initialize(); |
|
309 | - $this->total_spaces_available = $this->calculate(false); |
|
310 | - } |
|
311 | - return $this->total_spaces_available; |
|
312 | - } |
|
313 | - |
|
314 | - |
|
315 | - /** |
|
316 | - * Loops through the active tickets for the event |
|
317 | - * and builds a series of data arrays that will be used for calculating |
|
318 | - * the total maximum available spaces, as well as the spaces remaining. |
|
319 | - * Because ticket quantities affect datetime spaces and vice versa, |
|
320 | - * we need to be constantly updating these data arrays as things change, |
|
321 | - * which is the entire reason for their existence. |
|
322 | - * |
|
323 | - * @throws EE_Error |
|
324 | - * @throws DomainException |
|
325 | - * @throws UnexpectedEntityException |
|
326 | - * @throws InvalidDataTypeException |
|
327 | - * @throws InvalidInterfaceException |
|
328 | - * @throws InvalidArgumentException |
|
329 | - */ |
|
330 | - private function initialize() |
|
331 | - { |
|
332 | - if ($this->debug) { |
|
333 | - \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2); |
|
334 | - } |
|
335 | - $this->datetime_tickets = array(); |
|
336 | - $this->datetime_spaces = array(); |
|
337 | - $this->ticket_datetimes = array(); |
|
338 | - $this->ticket_quantities = array(); |
|
339 | - $this->tickets_sold = array(); |
|
340 | - $this->total_spaces = array(); |
|
341 | - $active_tickets = $this->getActiveTickets(); |
|
342 | - if (! empty($active_tickets)) { |
|
343 | - foreach ($active_tickets as $ticket) { |
|
344 | - $this->validateTicket($ticket); |
|
345 | - // we need to index our data arrays using strings for the purpose of sorting, |
|
346 | - // but we also need them to be unique, so we'll just prepend a letter T to the ID |
|
347 | - $ticket_identifier = "T{$ticket->ID()}"; |
|
348 | - // to start, we'll just consider the raw qty to be the maximum availability for this ticket, |
|
349 | - // unless the ticket is past its "sell until" date, in which case the qty will be 0 |
|
350 | - $max_tickets = $ticket->is_expired() ? 0 : $ticket->qty(); |
|
351 | - // but we'll adjust that after looping over each datetime for the ticket and checking reg limits |
|
352 | - $ticket_datetimes = $ticket->datetimes($this->datetime_query_params); |
|
353 | - foreach ($ticket_datetimes as $datetime) { |
|
354 | - // save all datetimes |
|
355 | - $this->setDatetime($datetime); |
|
356 | - $datetime_identifier = "D{$datetime->ID()}"; |
|
357 | - $reg_limit = $datetime->reg_limit(); |
|
358 | - // ticket quantity can not exceed datetime reg limit |
|
359 | - $max_tickets = min($max_tickets, $reg_limit); |
|
360 | - // as described earlier, because we need to be able to constantly adjust numbers for things, |
|
361 | - // we are going to move all of our data into the following arrays: |
|
362 | - // datetime spaces initially represents the reg limit for each datetime, |
|
363 | - // but this will get adjusted as tickets are accounted for |
|
364 | - $this->datetime_spaces[ $datetime_identifier ] = $reg_limit; |
|
365 | - // just an array of ticket IDs grouped by datetime |
|
366 | - $this->datetime_tickets[ $datetime_identifier ][] = $ticket_identifier; |
|
367 | - // and an array of datetime IDs grouped by ticket |
|
368 | - $this->ticket_datetimes[ $ticket_identifier ][] = $datetime_identifier; |
|
369 | - } |
|
370 | - // total quantity of sold and reserved for each ticket |
|
371 | - $this->tickets_sold[ $ticket_identifier ] = $ticket->sold() + $ticket->reserved(); |
|
372 | - // and the maximum ticket quantities for each ticket (adjusted for reg limit) |
|
373 | - $this->ticket_quantities[ $ticket_identifier ] = $max_tickets; |
|
374 | - } |
|
375 | - } |
|
376 | - // sort datetime spaces by reg limit, but maintain our string indexes |
|
377 | - asort($this->datetime_spaces, SORT_NUMERIC); |
|
378 | - // datetime tickets need to be sorted in the SAME order as the above array... |
|
379 | - // so we'll just use array_merge() to take the structure of datetime_spaces |
|
380 | - // but overwrite all of the data with that from datetime_tickets |
|
381 | - $this->datetime_tickets = array_merge( |
|
382 | - $this->datetime_spaces, |
|
383 | - $this->datetime_tickets |
|
384 | - ); |
|
385 | - if ($this->debug) { |
|
386 | - \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__); |
|
387 | - \EEH_Debug_Tools::printr($this->datetime_tickets, 'datetime_tickets', __FILE__, __LINE__); |
|
388 | - \EEH_Debug_Tools::printr($this->ticket_quantities, 'ticket_quantities', __FILE__, __LINE__); |
|
389 | - } |
|
390 | - } |
|
391 | - |
|
392 | - |
|
393 | - /** |
|
394 | - * performs calculations on initialized data |
|
395 | - * |
|
396 | - * @param bool $consider_sold |
|
397 | - * @return int|float |
|
398 | - */ |
|
399 | - private function calculate($consider_sold = true) |
|
400 | - { |
|
401 | - if ($this->debug) { |
|
402 | - \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2); |
|
403 | - \EEH_Debug_Tools::printr($consider_sold, '$consider_sold', __FILE__, __LINE__); |
|
404 | - } |
|
405 | - if ($consider_sold) { |
|
406 | - // subtract amounts sold from all ticket quantities and datetime spaces |
|
407 | - $this->adjustTicketQuantitiesDueToSales(); |
|
408 | - } |
|
409 | - foreach ($this->datetime_tickets as $datetime_identifier => $tickets) { |
|
410 | - $this->trackAvailableSpacesForDatetimes($datetime_identifier, $tickets); |
|
411 | - } |
|
412 | - // total spaces available is just the sum of the spaces available for each datetime |
|
413 | - $spaces_remaining = array_sum($this->total_spaces); |
|
414 | - if ($this->debug) { |
|
415 | - \EEH_Debug_Tools::printr($this->total_spaces, '$this->total_spaces', __FILE__, __LINE__); |
|
416 | - \EEH_Debug_Tools::printr($this->tickets_sold, '$this->tickets_sold', __FILE__, __LINE__); |
|
417 | - \EEH_Debug_Tools::printr($spaces_remaining, '$spaces_remaining', __FILE__, __LINE__); |
|
418 | - } |
|
419 | - return $spaces_remaining; |
|
420 | - } |
|
421 | - |
|
422 | - |
|
423 | - /** |
|
424 | - * subtracts amount of tickets sold from ticket quantities and datetime spaces |
|
425 | - */ |
|
426 | - private function adjustTicketQuantitiesDueToSales() |
|
427 | - { |
|
428 | - if ($this->debug) { |
|
429 | - \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2); |
|
430 | - } |
|
431 | - foreach ($this->tickets_sold as $ticket_identifier => $tickets_sold) { |
|
432 | - if (isset($this->ticket_quantities[ $ticket_identifier ])) { |
|
433 | - $this->ticket_quantities[ $ticket_identifier ] -= $tickets_sold; |
|
434 | - // don't let values go below zero |
|
435 | - $this->ticket_quantities[ $ticket_identifier ] = max( |
|
436 | - $this->ticket_quantities[ $ticket_identifier ], |
|
437 | - 0 |
|
438 | - ); |
|
439 | - if ($this->debug) { |
|
440 | - \EEH_Debug_Tools::printr( |
|
441 | - "{$tickets_sold} sales for ticket {$ticket_identifier} ", |
|
442 | - 'subtracting', |
|
443 | - __FILE__, |
|
444 | - __LINE__ |
|
445 | - ); |
|
446 | - } |
|
447 | - } |
|
448 | - if ( |
|
449 | - isset($this->ticket_datetimes[ $ticket_identifier ]) |
|
450 | - && is_array($this->ticket_datetimes[ $ticket_identifier ]) |
|
451 | - ) { |
|
452 | - foreach ($this->ticket_datetimes[ $ticket_identifier ] as $ticket_datetime) { |
|
453 | - if (isset($this->ticket_quantities[ $ticket_identifier ])) { |
|
454 | - $this->datetime_spaces[ $ticket_datetime ] -= $tickets_sold; |
|
455 | - // don't let values go below zero |
|
456 | - $this->datetime_spaces[ $ticket_datetime ] = max( |
|
457 | - $this->datetime_spaces[ $ticket_datetime ], |
|
458 | - 0 |
|
459 | - ); |
|
460 | - if ($this->debug) { |
|
461 | - \EEH_Debug_Tools::printr( |
|
462 | - "{$tickets_sold} sales for datetime {$ticket_datetime} ", |
|
463 | - 'subtracting', |
|
464 | - __FILE__, |
|
465 | - __LINE__ |
|
466 | - ); |
|
467 | - } |
|
468 | - } |
|
469 | - } |
|
470 | - } |
|
471 | - } |
|
472 | - } |
|
473 | - |
|
474 | - |
|
475 | - /** |
|
476 | - * @param string $datetime_identifier |
|
477 | - * @param array $tickets |
|
478 | - */ |
|
479 | - private function trackAvailableSpacesForDatetimes($datetime_identifier, array $tickets) |
|
480 | - { |
|
481 | - // make sure a reg limit is set for the datetime |
|
482 | - $reg_limit = isset($this->datetime_spaces[ $datetime_identifier ]) |
|
483 | - ? $this->datetime_spaces[ $datetime_identifier ] |
|
484 | - : 0; |
|
485 | - // and bail if it is not |
|
486 | - if (! $reg_limit) { |
|
487 | - if ($this->debug) { |
|
488 | - \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__); |
|
489 | - } |
|
490 | - return; |
|
491 | - } |
|
492 | - if ($this->debug) { |
|
493 | - \EEH_Debug_Tools::printr($datetime_identifier, '* $datetime_identifier', __FILE__, __LINE__, 1); |
|
494 | - \EEH_Debug_Tools::printr( |
|
495 | - "{$reg_limit}", |
|
496 | - 'REG LIMIT', |
|
497 | - __FILE__, |
|
498 | - __LINE__ |
|
499 | - ); |
|
500 | - } |
|
501 | - // number of allocated spaces always starts at zero |
|
502 | - $spaces_allocated = 0; |
|
503 | - $this->total_spaces[ $datetime_identifier ] = 0; |
|
504 | - foreach ($tickets as $ticket_identifier) { |
|
505 | - $spaces_allocated = $this->calculateAvailableSpacesForTicket( |
|
506 | - $datetime_identifier, |
|
507 | - $reg_limit, |
|
508 | - $ticket_identifier, |
|
509 | - $spaces_allocated |
|
510 | - ); |
|
511 | - } |
|
512 | - // spaces can't be negative |
|
513 | - $spaces_allocated = max($spaces_allocated, 0); |
|
514 | - if ($spaces_allocated) { |
|
515 | - // track any non-zero values |
|
516 | - $this->total_spaces[ $datetime_identifier ] += $spaces_allocated; |
|
517 | - if ($this->debug) { |
|
518 | - \EEH_Debug_Tools::printr((string) $spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__); |
|
519 | - } |
|
520 | - } else { |
|
521 | - if ($this->debug) { |
|
522 | - \EEH_Debug_Tools::printr(' ', ' . NO TICKETS AVAILABLE FOR DATETIME', __FILE__, __LINE__); |
|
523 | - } |
|
524 | - } |
|
525 | - if ($this->debug) { |
|
526 | - \EEH_Debug_Tools::printr( |
|
527 | - $this->total_spaces[ $datetime_identifier ], |
|
528 | - '$total_spaces', |
|
529 | - __FILE__, |
|
530 | - __LINE__ |
|
531 | - ); |
|
532 | - \EEH_Debug_Tools::printr($this->ticket_quantities, '$ticket_quantities', __FILE__, __LINE__); |
|
533 | - \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__); |
|
534 | - } |
|
535 | - } |
|
536 | - |
|
537 | - |
|
538 | - /** |
|
539 | - * @param string $datetime_identifier |
|
540 | - * @param int $reg_limit |
|
541 | - * @param string $ticket_identifier |
|
542 | - * @param int $spaces_allocated |
|
543 | - * @return int |
|
544 | - */ |
|
545 | - private function calculateAvailableSpacesForTicket( |
|
546 | - $datetime_identifier, |
|
547 | - $reg_limit, |
|
548 | - $ticket_identifier, |
|
549 | - $spaces_allocated |
|
550 | - ) { |
|
551 | - // make sure ticket quantity is set |
|
552 | - $ticket_quantity = isset($this->ticket_quantities[ $ticket_identifier ]) |
|
553 | - ? $this->ticket_quantities[ $ticket_identifier ] |
|
554 | - : 0; |
|
555 | - if ($this->debug) { |
|
556 | - \EEH_Debug_Tools::printr("{$spaces_allocated}", '$spaces_allocated', __FILE__, __LINE__); |
|
557 | - \EEH_Debug_Tools::printr( |
|
558 | - "{$ticket_quantity}", |
|
559 | - "ticket $ticket_identifier quantity: ", |
|
560 | - __FILE__, |
|
561 | - __LINE__, |
|
562 | - 2 |
|
563 | - ); |
|
564 | - } |
|
565 | - if ($ticket_quantity) { |
|
566 | - if ($this->debug) { |
|
567 | - \EEH_Debug_Tools::printr( |
|
568 | - ($spaces_allocated <= $reg_limit) |
|
569 | - ? 'true' |
|
570 | - : 'false', |
|
571 | - ' . spaces_allocated <= reg_limit = ', |
|
572 | - __FILE__, |
|
573 | - __LINE__ |
|
574 | - ); |
|
575 | - } |
|
576 | - // if the datetime is NOT at full capacity yet |
|
577 | - if ($spaces_allocated <= $reg_limit) { |
|
578 | - // then the maximum ticket quantity we can allocate is the lowest value of either: |
|
579 | - // the number of remaining spaces for the datetime, which is the limit - spaces already taken |
|
580 | - // or the maximum ticket quantity |
|
581 | - $ticket_quantity = min($reg_limit - $spaces_allocated, $ticket_quantity); |
|
582 | - // adjust the available quantity in our tracking array |
|
583 | - $this->ticket_quantities[ $ticket_identifier ] -= $ticket_quantity; |
|
584 | - // and increment spaces allocated for this datetime |
|
585 | - $spaces_allocated += $ticket_quantity; |
|
586 | - $at_capacity = $spaces_allocated >= $reg_limit; |
|
587 | - if ($this->debug) { |
|
588 | - \EEH_Debug_Tools::printr( |
|
589 | - "{$ticket_quantity} {$ticket_identifier} tickets", |
|
590 | - ' > > allocate ', |
|
591 | - __FILE__, |
|
592 | - __LINE__, |
|
593 | - 3 |
|
594 | - ); |
|
595 | - if ($at_capacity) { |
|
596 | - \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__, 3); |
|
597 | - } |
|
598 | - } |
|
599 | - // now adjust all other datetimes that allow access to this ticket |
|
600 | - $this->adjustDatetimes( |
|
601 | - $datetime_identifier, |
|
602 | - $ticket_identifier, |
|
603 | - $ticket_quantity, |
|
604 | - $at_capacity |
|
605 | - ); |
|
606 | - } |
|
607 | - } |
|
608 | - return $spaces_allocated; |
|
609 | - } |
|
610 | - |
|
611 | - |
|
612 | - /** |
|
613 | - * subtracts ticket amounts from all datetime reg limits |
|
614 | - * that allow access to the ticket specified, |
|
615 | - * because that ticket could be used |
|
616 | - * to attend any of the datetimes it has access to |
|
617 | - * |
|
618 | - * @param string $datetime_identifier |
|
619 | - * @param string $ticket_identifier |
|
620 | - * @param bool $at_capacity |
|
621 | - * @param int $ticket_quantity |
|
622 | - */ |
|
623 | - private function adjustDatetimes( |
|
624 | - $datetime_identifier, |
|
625 | - $ticket_identifier, |
|
626 | - $ticket_quantity, |
|
627 | - $at_capacity |
|
628 | - ) { |
|
629 | - /** @var array $datetime_tickets */ |
|
630 | - foreach ($this->datetime_tickets as $datetime_ID => $datetime_tickets) { |
|
631 | - if ($datetime_ID !== $datetime_identifier || ! is_array($datetime_tickets)) { |
|
632 | - continue; |
|
633 | - } |
|
634 | - $adjusted = $this->adjustDatetimeSpaces( |
|
635 | - $datetime_ID, |
|
636 | - $ticket_identifier, |
|
637 | - $ticket_quantity |
|
638 | - ); |
|
639 | - // skip to next ticket if nothing changed |
|
640 | - if (! ($adjusted || $at_capacity)) { |
|
641 | - continue; |
|
642 | - } |
|
643 | - // then all of it's tickets are now unavailable |
|
644 | - foreach ($datetime_tickets as $datetime_ticket) { |
|
645 | - if ( |
|
646 | - ($ticket_identifier === $datetime_ticket || $at_capacity) |
|
647 | - && isset($this->ticket_quantities[ $datetime_ticket ]) |
|
648 | - && $this->ticket_quantities[ $datetime_ticket ] > 0 |
|
649 | - ) { |
|
650 | - if ($this->debug) { |
|
651 | - \EEH_Debug_Tools::printr( |
|
652 | - $datetime_ticket, |
|
653 | - ' . . . adjust ticket quantities for', |
|
654 | - __FILE__, |
|
655 | - __LINE__ |
|
656 | - ); |
|
657 | - } |
|
658 | - // if this datetime is at full capacity, set any tracked available quantities to zero |
|
659 | - // otherwise just subtract the ticket quantity |
|
660 | - $new_quantity = $at_capacity |
|
661 | - ? 0 |
|
662 | - : $this->ticket_quantities[ $datetime_ticket ] - $ticket_quantity; |
|
663 | - // don't let ticket quantity go below zero |
|
664 | - $this->ticket_quantities[ $datetime_ticket ] = max($new_quantity, 0); |
|
665 | - if ($this->debug) { |
|
666 | - \EEH_Debug_Tools::printr( |
|
667 | - $at_capacity |
|
668 | - ? "0 because Datetime {$datetime_identifier} is at capacity" |
|
669 | - : "{$this->ticket_quantities[ $datetime_ticket ]}", |
|
670 | - " . . . . {$datetime_ticket} quantity set to ", |
|
671 | - __FILE__, |
|
672 | - __LINE__ |
|
673 | - ); |
|
674 | - } |
|
675 | - } |
|
676 | - // but we also need to adjust spaces for any other datetimes this ticket has access to |
|
677 | - if ($datetime_ticket === $ticket_identifier) { |
|
678 | - if ( |
|
679 | - isset($this->ticket_datetimes[ $datetime_ticket ]) |
|
680 | - && is_array($this->ticket_datetimes[ $datetime_ticket ]) |
|
681 | - ) { |
|
682 | - if ($this->debug) { |
|
683 | - \EEH_Debug_Tools::printr( |
|
684 | - $datetime_ticket, |
|
685 | - ' . . adjust other Datetimes for', |
|
686 | - __FILE__, |
|
687 | - __LINE__ |
|
688 | - ); |
|
689 | - } |
|
690 | - foreach ($this->ticket_datetimes[ $datetime_ticket ] as $datetime) { |
|
691 | - // don't adjust the current datetime twice |
|
692 | - if ($datetime !== $datetime_identifier) { |
|
693 | - $this->adjustDatetimeSpaces( |
|
694 | - $datetime, |
|
695 | - $datetime_ticket, |
|
696 | - $ticket_quantity |
|
697 | - ); |
|
698 | - } |
|
699 | - } |
|
700 | - } |
|
701 | - } |
|
702 | - } |
|
703 | - } |
|
704 | - } |
|
705 | - |
|
706 | - private function adjustDatetimeSpaces($datetime_identifier, $ticket_identifier, $ticket_quantity = 0) |
|
707 | - { |
|
708 | - // does datetime have spaces available? |
|
709 | - // and does the supplied ticket have access to this datetime ? |
|
710 | - if ( |
|
711 | - $this->datetime_spaces[ $datetime_identifier ] > 0 |
|
712 | - && isset($this->datetime_spaces[ $datetime_identifier ], $this->datetime_tickets[ $datetime_identifier ]) |
|
713 | - && in_array($ticket_identifier, $this->datetime_tickets[ $datetime_identifier ], true) |
|
714 | - ) { |
|
715 | - if ($this->debug) { |
|
716 | - \EEH_Debug_Tools::printr($datetime_identifier, ' . . adjust Datetime Spaces for', __FILE__, __LINE__); |
|
717 | - \EEH_Debug_Tools::printr( |
|
718 | - "{$this->datetime_spaces[ $datetime_identifier ]}", |
|
719 | - " . . current {$datetime_identifier} spaces available", |
|
720 | - __FILE__, |
|
721 | - __LINE__ |
|
722 | - ); |
|
723 | - } |
|
724 | - // then decrement the available spaces for the datetime |
|
725 | - $this->datetime_spaces[ $datetime_identifier ] -= $ticket_quantity; |
|
726 | - // but don't let quantities go below zero |
|
727 | - $this->datetime_spaces[ $datetime_identifier ] = max( |
|
728 | - $this->datetime_spaces[ $datetime_identifier ], |
|
729 | - 0 |
|
730 | - ); |
|
731 | - if ($this->debug) { |
|
732 | - \EEH_Debug_Tools::printr( |
|
733 | - "{$ticket_quantity}", |
|
734 | - " . . . {$datetime_identifier} capacity reduced by", |
|
735 | - __FILE__, |
|
736 | - __LINE__ |
|
737 | - ); |
|
738 | - } |
|
739 | - return true; |
|
740 | - } |
|
741 | - return false; |
|
742 | - } |
|
28 | + /** |
|
29 | + * @var EE_Event $event |
|
30 | + */ |
|
31 | + private $event; |
|
32 | + |
|
33 | + /** |
|
34 | + * @var array $datetime_query_params |
|
35 | + */ |
|
36 | + private $datetime_query_params; |
|
37 | + |
|
38 | + /** |
|
39 | + * @var EE_Ticket[] $active_tickets |
|
40 | + */ |
|
41 | + private $active_tickets = array(); |
|
42 | + |
|
43 | + /** |
|
44 | + * @var EE_Datetime[] $datetimes |
|
45 | + */ |
|
46 | + private $datetimes = array(); |
|
47 | + |
|
48 | + /** |
|
49 | + * Array of Ticket IDs grouped by Datetime |
|
50 | + * |
|
51 | + * @var array $datetimes |
|
52 | + */ |
|
53 | + private $datetime_tickets = array(); |
|
54 | + |
|
55 | + /** |
|
56 | + * Max spaces for each Datetime (reg limit - previous sold) |
|
57 | + * |
|
58 | + * @var array $datetime_spaces |
|
59 | + */ |
|
60 | + private $datetime_spaces = array(); |
|
61 | + |
|
62 | + /** |
|
63 | + * Array of Datetime IDs grouped by Ticket |
|
64 | + * |
|
65 | + * @var array[] $ticket_datetimes |
|
66 | + */ |
|
67 | + private $ticket_datetimes = array(); |
|
68 | + |
|
69 | + /** |
|
70 | + * maximum ticket quantities for each ticket (adjusted for reg limit) |
|
71 | + * |
|
72 | + * @var array $ticket_quantities |
|
73 | + */ |
|
74 | + private $ticket_quantities = array(); |
|
75 | + |
|
76 | + /** |
|
77 | + * total quantity of sold and reserved for each ticket |
|
78 | + * |
|
79 | + * @var array $tickets_sold |
|
80 | + */ |
|
81 | + private $tickets_sold = array(); |
|
82 | + |
|
83 | + /** |
|
84 | + * total spaces available across all datetimes |
|
85 | + * |
|
86 | + * @var array $total_spaces |
|
87 | + */ |
|
88 | + private $total_spaces = array(); |
|
89 | + |
|
90 | + /** |
|
91 | + * @var boolean $debug |
|
92 | + */ |
|
93 | + private $debug = false; // true false |
|
94 | + |
|
95 | + /** |
|
96 | + * @var null|int $spaces_remaining |
|
97 | + */ |
|
98 | + private $spaces_remaining; |
|
99 | + |
|
100 | + /** |
|
101 | + * @var null|int $total_spaces_available |
|
102 | + */ |
|
103 | + private $total_spaces_available; |
|
104 | + |
|
105 | + |
|
106 | + /** |
|
107 | + * EventSpacesCalculator constructor. |
|
108 | + * |
|
109 | + * @param EE_Event $event |
|
110 | + * @param array $datetime_query_params |
|
111 | + * @throws EE_Error |
|
112 | + */ |
|
113 | + public function __construct(EE_Event $event, array $datetime_query_params = array()) |
|
114 | + { |
|
115 | + if ($this->debug) { |
|
116 | + \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 1); |
|
117 | + \EEH_Debug_Tools::printr((string) $event->ID(), 'For event', __FILE__, __LINE__); |
|
118 | + } |
|
119 | + $this->event = $event; |
|
120 | + $this->datetime_query_params = $datetime_query_params + array('order_by' => array('DTT_reg_limit' => 'ASC')); |
|
121 | + $this->setHooks(); |
|
122 | + } |
|
123 | + |
|
124 | + |
|
125 | + /** |
|
126 | + * @return void |
|
127 | + */ |
|
128 | + private function setHooks() |
|
129 | + { |
|
130 | + add_action('AHEE__EE_Ticket__increase_sold', array($this, 'clearResults')); |
|
131 | + add_action('AHEE__EE_Ticket__decrease_sold', array($this, 'clearResults')); |
|
132 | + add_action('AHEE__EE_Datetime__increase_sold', array($this, 'clearResults')); |
|
133 | + add_action('AHEE__EE_Datetime__decrease_sold', array($this, 'clearResults')); |
|
134 | + add_action('AHEE__EE_Ticket__increase_reserved', array($this, 'clearResults')); |
|
135 | + add_action('AHEE__EE_Ticket__decrease_reserved', array($this, 'clearResults')); |
|
136 | + add_action('AHEE__EE_Datetime__increase_reserved', array($this, 'clearResults')); |
|
137 | + add_action('AHEE__EE_Datetime__decrease_reserved', array($this, 'clearResults')); |
|
138 | + } |
|
139 | + |
|
140 | + |
|
141 | + /** |
|
142 | + * @return void |
|
143 | + */ |
|
144 | + public function clearResults() |
|
145 | + { |
|
146 | + if ($this->debug) { |
|
147 | + \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 1); |
|
148 | + } |
|
149 | + $this->spaces_remaining = null; |
|
150 | + $this->total_spaces_available = null; |
|
151 | + } |
|
152 | + |
|
153 | + |
|
154 | + /** |
|
155 | + * @return EE_Ticket[] |
|
156 | + * @throws EE_Error |
|
157 | + * @throws InvalidDataTypeException |
|
158 | + * @throws InvalidInterfaceException |
|
159 | + * @throws InvalidArgumentException |
|
160 | + */ |
|
161 | + public function getActiveTickets() |
|
162 | + { |
|
163 | + if (empty($this->active_tickets)) { |
|
164 | + $this->active_tickets = $this->event->tickets( |
|
165 | + array( |
|
166 | + array('TKT_deleted' => false), |
|
167 | + 'order_by' => array('TKT_qty' => 'ASC'), |
|
168 | + ) |
|
169 | + ); |
|
170 | + } |
|
171 | + return $this->active_tickets; |
|
172 | + } |
|
173 | + |
|
174 | + |
|
175 | + /** |
|
176 | + * @param EE_Ticket[] $active_tickets |
|
177 | + * @throws EE_Error |
|
178 | + * @throws DomainException |
|
179 | + * @throws UnexpectedEntityException |
|
180 | + */ |
|
181 | + public function setActiveTickets(array $active_tickets = array()) |
|
182 | + { |
|
183 | + if (! empty($active_tickets)) { |
|
184 | + foreach ($active_tickets as $active_ticket) { |
|
185 | + $this->validateTicket($active_ticket); |
|
186 | + } |
|
187 | + // sort incoming array by ticket quantity (asc) |
|
188 | + usort( |
|
189 | + $active_tickets, |
|
190 | + function (EE_Ticket $a, EE_Ticket $b) { |
|
191 | + if ($a->qty() === $b->qty()) { |
|
192 | + return 0; |
|
193 | + } |
|
194 | + return ($a->qty() < $b->qty()) |
|
195 | + ? -1 |
|
196 | + : 1; |
|
197 | + } |
|
198 | + ); |
|
199 | + } |
|
200 | + $this->active_tickets = $active_tickets; |
|
201 | + } |
|
202 | + |
|
203 | + |
|
204 | + /** |
|
205 | + * @param $ticket |
|
206 | + * @throws DomainException |
|
207 | + * @throws EE_Error |
|
208 | + * @throws UnexpectedEntityException |
|
209 | + */ |
|
210 | + private function validateTicket($ticket) |
|
211 | + { |
|
212 | + if (! $ticket instanceof EE_Ticket) { |
|
213 | + throw new DomainException( |
|
214 | + esc_html__( |
|
215 | + 'Invalid Ticket. Only EE_Ticket objects can be used to calculate event space availability.', |
|
216 | + 'event_espresso' |
|
217 | + ) |
|
218 | + ); |
|
219 | + } |
|
220 | + if ($ticket->get_event_ID() !== $this->event->ID()) { |
|
221 | + throw new DomainException( |
|
222 | + sprintf( |
|
223 | + esc_html__( |
|
224 | + 'An EE_Ticket for Event %1$d was supplied while calculating event space availability for Event %2$d.', |
|
225 | + 'event_espresso' |
|
226 | + ), |
|
227 | + $ticket->get_event_ID(), |
|
228 | + $this->event->ID() |
|
229 | + ) |
|
230 | + ); |
|
231 | + } |
|
232 | + } |
|
233 | + |
|
234 | + |
|
235 | + /** |
|
236 | + * @return EE_Datetime[] |
|
237 | + */ |
|
238 | + public function getDatetimes() |
|
239 | + { |
|
240 | + return $this->datetimes; |
|
241 | + } |
|
242 | + |
|
243 | + |
|
244 | + /** |
|
245 | + * @param EE_Datetime $datetime |
|
246 | + * @throws EE_Error |
|
247 | + * @throws DomainException |
|
248 | + */ |
|
249 | + public function setDatetime(EE_Datetime $datetime) |
|
250 | + { |
|
251 | + if ($datetime->event()->ID() !== $this->event->ID()) { |
|
252 | + throw new DomainException( |
|
253 | + sprintf( |
|
254 | + esc_html__( |
|
255 | + 'An EE_Datetime for Event %1$d was supplied while calculating event space availability for Event %2$d.', |
|
256 | + 'event_espresso' |
|
257 | + ), |
|
258 | + $datetime->event()->ID(), |
|
259 | + $this->event->ID() |
|
260 | + ) |
|
261 | + ); |
|
262 | + } |
|
263 | + $this->datetimes[ $datetime->ID() ] = $datetime; |
|
264 | + } |
|
265 | + |
|
266 | + |
|
267 | + /** |
|
268 | + * calculate spaces remaining based on "saleable" tickets |
|
269 | + * |
|
270 | + * @return float|int |
|
271 | + * @throws EE_Error |
|
272 | + * @throws DomainException |
|
273 | + * @throws UnexpectedEntityException |
|
274 | + * @throws InvalidDataTypeException |
|
275 | + * @throws InvalidInterfaceException |
|
276 | + * @throws InvalidArgumentException |
|
277 | + */ |
|
278 | + public function spacesRemaining() |
|
279 | + { |
|
280 | + if ($this->debug) { |
|
281 | + \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2); |
|
282 | + } |
|
283 | + if ($this->spaces_remaining === null) { |
|
284 | + $this->initialize(); |
|
285 | + $this->spaces_remaining = $this->calculate(); |
|
286 | + } |
|
287 | + return $this->spaces_remaining; |
|
288 | + } |
|
289 | + |
|
290 | + |
|
291 | + /** |
|
292 | + * calculates total available spaces for an event with no regard for sold tickets |
|
293 | + * |
|
294 | + * @return int|float |
|
295 | + * @throws EE_Error |
|
296 | + * @throws DomainException |
|
297 | + * @throws UnexpectedEntityException |
|
298 | + * @throws InvalidDataTypeException |
|
299 | + * @throws InvalidInterfaceException |
|
300 | + * @throws InvalidArgumentException |
|
301 | + */ |
|
302 | + public function totalSpacesAvailable() |
|
303 | + { |
|
304 | + if ($this->debug) { |
|
305 | + \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2); |
|
306 | + } |
|
307 | + if ($this->total_spaces_available === null) { |
|
308 | + $this->initialize(); |
|
309 | + $this->total_spaces_available = $this->calculate(false); |
|
310 | + } |
|
311 | + return $this->total_spaces_available; |
|
312 | + } |
|
313 | + |
|
314 | + |
|
315 | + /** |
|
316 | + * Loops through the active tickets for the event |
|
317 | + * and builds a series of data arrays that will be used for calculating |
|
318 | + * the total maximum available spaces, as well as the spaces remaining. |
|
319 | + * Because ticket quantities affect datetime spaces and vice versa, |
|
320 | + * we need to be constantly updating these data arrays as things change, |
|
321 | + * which is the entire reason for their existence. |
|
322 | + * |
|
323 | + * @throws EE_Error |
|
324 | + * @throws DomainException |
|
325 | + * @throws UnexpectedEntityException |
|
326 | + * @throws InvalidDataTypeException |
|
327 | + * @throws InvalidInterfaceException |
|
328 | + * @throws InvalidArgumentException |
|
329 | + */ |
|
330 | + private function initialize() |
|
331 | + { |
|
332 | + if ($this->debug) { |
|
333 | + \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2); |
|
334 | + } |
|
335 | + $this->datetime_tickets = array(); |
|
336 | + $this->datetime_spaces = array(); |
|
337 | + $this->ticket_datetimes = array(); |
|
338 | + $this->ticket_quantities = array(); |
|
339 | + $this->tickets_sold = array(); |
|
340 | + $this->total_spaces = array(); |
|
341 | + $active_tickets = $this->getActiveTickets(); |
|
342 | + if (! empty($active_tickets)) { |
|
343 | + foreach ($active_tickets as $ticket) { |
|
344 | + $this->validateTicket($ticket); |
|
345 | + // we need to index our data arrays using strings for the purpose of sorting, |
|
346 | + // but we also need them to be unique, so we'll just prepend a letter T to the ID |
|
347 | + $ticket_identifier = "T{$ticket->ID()}"; |
|
348 | + // to start, we'll just consider the raw qty to be the maximum availability for this ticket, |
|
349 | + // unless the ticket is past its "sell until" date, in which case the qty will be 0 |
|
350 | + $max_tickets = $ticket->is_expired() ? 0 : $ticket->qty(); |
|
351 | + // but we'll adjust that after looping over each datetime for the ticket and checking reg limits |
|
352 | + $ticket_datetimes = $ticket->datetimes($this->datetime_query_params); |
|
353 | + foreach ($ticket_datetimes as $datetime) { |
|
354 | + // save all datetimes |
|
355 | + $this->setDatetime($datetime); |
|
356 | + $datetime_identifier = "D{$datetime->ID()}"; |
|
357 | + $reg_limit = $datetime->reg_limit(); |
|
358 | + // ticket quantity can not exceed datetime reg limit |
|
359 | + $max_tickets = min($max_tickets, $reg_limit); |
|
360 | + // as described earlier, because we need to be able to constantly adjust numbers for things, |
|
361 | + // we are going to move all of our data into the following arrays: |
|
362 | + // datetime spaces initially represents the reg limit for each datetime, |
|
363 | + // but this will get adjusted as tickets are accounted for |
|
364 | + $this->datetime_spaces[ $datetime_identifier ] = $reg_limit; |
|
365 | + // just an array of ticket IDs grouped by datetime |
|
366 | + $this->datetime_tickets[ $datetime_identifier ][] = $ticket_identifier; |
|
367 | + // and an array of datetime IDs grouped by ticket |
|
368 | + $this->ticket_datetimes[ $ticket_identifier ][] = $datetime_identifier; |
|
369 | + } |
|
370 | + // total quantity of sold and reserved for each ticket |
|
371 | + $this->tickets_sold[ $ticket_identifier ] = $ticket->sold() + $ticket->reserved(); |
|
372 | + // and the maximum ticket quantities for each ticket (adjusted for reg limit) |
|
373 | + $this->ticket_quantities[ $ticket_identifier ] = $max_tickets; |
|
374 | + } |
|
375 | + } |
|
376 | + // sort datetime spaces by reg limit, but maintain our string indexes |
|
377 | + asort($this->datetime_spaces, SORT_NUMERIC); |
|
378 | + // datetime tickets need to be sorted in the SAME order as the above array... |
|
379 | + // so we'll just use array_merge() to take the structure of datetime_spaces |
|
380 | + // but overwrite all of the data with that from datetime_tickets |
|
381 | + $this->datetime_tickets = array_merge( |
|
382 | + $this->datetime_spaces, |
|
383 | + $this->datetime_tickets |
|
384 | + ); |
|
385 | + if ($this->debug) { |
|
386 | + \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__); |
|
387 | + \EEH_Debug_Tools::printr($this->datetime_tickets, 'datetime_tickets', __FILE__, __LINE__); |
|
388 | + \EEH_Debug_Tools::printr($this->ticket_quantities, 'ticket_quantities', __FILE__, __LINE__); |
|
389 | + } |
|
390 | + } |
|
391 | + |
|
392 | + |
|
393 | + /** |
|
394 | + * performs calculations on initialized data |
|
395 | + * |
|
396 | + * @param bool $consider_sold |
|
397 | + * @return int|float |
|
398 | + */ |
|
399 | + private function calculate($consider_sold = true) |
|
400 | + { |
|
401 | + if ($this->debug) { |
|
402 | + \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2); |
|
403 | + \EEH_Debug_Tools::printr($consider_sold, '$consider_sold', __FILE__, __LINE__); |
|
404 | + } |
|
405 | + if ($consider_sold) { |
|
406 | + // subtract amounts sold from all ticket quantities and datetime spaces |
|
407 | + $this->adjustTicketQuantitiesDueToSales(); |
|
408 | + } |
|
409 | + foreach ($this->datetime_tickets as $datetime_identifier => $tickets) { |
|
410 | + $this->trackAvailableSpacesForDatetimes($datetime_identifier, $tickets); |
|
411 | + } |
|
412 | + // total spaces available is just the sum of the spaces available for each datetime |
|
413 | + $spaces_remaining = array_sum($this->total_spaces); |
|
414 | + if ($this->debug) { |
|
415 | + \EEH_Debug_Tools::printr($this->total_spaces, '$this->total_spaces', __FILE__, __LINE__); |
|
416 | + \EEH_Debug_Tools::printr($this->tickets_sold, '$this->tickets_sold', __FILE__, __LINE__); |
|
417 | + \EEH_Debug_Tools::printr($spaces_remaining, '$spaces_remaining', __FILE__, __LINE__); |
|
418 | + } |
|
419 | + return $spaces_remaining; |
|
420 | + } |
|
421 | + |
|
422 | + |
|
423 | + /** |
|
424 | + * subtracts amount of tickets sold from ticket quantities and datetime spaces |
|
425 | + */ |
|
426 | + private function adjustTicketQuantitiesDueToSales() |
|
427 | + { |
|
428 | + if ($this->debug) { |
|
429 | + \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2); |
|
430 | + } |
|
431 | + foreach ($this->tickets_sold as $ticket_identifier => $tickets_sold) { |
|
432 | + if (isset($this->ticket_quantities[ $ticket_identifier ])) { |
|
433 | + $this->ticket_quantities[ $ticket_identifier ] -= $tickets_sold; |
|
434 | + // don't let values go below zero |
|
435 | + $this->ticket_quantities[ $ticket_identifier ] = max( |
|
436 | + $this->ticket_quantities[ $ticket_identifier ], |
|
437 | + 0 |
|
438 | + ); |
|
439 | + if ($this->debug) { |
|
440 | + \EEH_Debug_Tools::printr( |
|
441 | + "{$tickets_sold} sales for ticket {$ticket_identifier} ", |
|
442 | + 'subtracting', |
|
443 | + __FILE__, |
|
444 | + __LINE__ |
|
445 | + ); |
|
446 | + } |
|
447 | + } |
|
448 | + if ( |
|
449 | + isset($this->ticket_datetimes[ $ticket_identifier ]) |
|
450 | + && is_array($this->ticket_datetimes[ $ticket_identifier ]) |
|
451 | + ) { |
|
452 | + foreach ($this->ticket_datetimes[ $ticket_identifier ] as $ticket_datetime) { |
|
453 | + if (isset($this->ticket_quantities[ $ticket_identifier ])) { |
|
454 | + $this->datetime_spaces[ $ticket_datetime ] -= $tickets_sold; |
|
455 | + // don't let values go below zero |
|
456 | + $this->datetime_spaces[ $ticket_datetime ] = max( |
|
457 | + $this->datetime_spaces[ $ticket_datetime ], |
|
458 | + 0 |
|
459 | + ); |
|
460 | + if ($this->debug) { |
|
461 | + \EEH_Debug_Tools::printr( |
|
462 | + "{$tickets_sold} sales for datetime {$ticket_datetime} ", |
|
463 | + 'subtracting', |
|
464 | + __FILE__, |
|
465 | + __LINE__ |
|
466 | + ); |
|
467 | + } |
|
468 | + } |
|
469 | + } |
|
470 | + } |
|
471 | + } |
|
472 | + } |
|
473 | + |
|
474 | + |
|
475 | + /** |
|
476 | + * @param string $datetime_identifier |
|
477 | + * @param array $tickets |
|
478 | + */ |
|
479 | + private function trackAvailableSpacesForDatetimes($datetime_identifier, array $tickets) |
|
480 | + { |
|
481 | + // make sure a reg limit is set for the datetime |
|
482 | + $reg_limit = isset($this->datetime_spaces[ $datetime_identifier ]) |
|
483 | + ? $this->datetime_spaces[ $datetime_identifier ] |
|
484 | + : 0; |
|
485 | + // and bail if it is not |
|
486 | + if (! $reg_limit) { |
|
487 | + if ($this->debug) { |
|
488 | + \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__); |
|
489 | + } |
|
490 | + return; |
|
491 | + } |
|
492 | + if ($this->debug) { |
|
493 | + \EEH_Debug_Tools::printr($datetime_identifier, '* $datetime_identifier', __FILE__, __LINE__, 1); |
|
494 | + \EEH_Debug_Tools::printr( |
|
495 | + "{$reg_limit}", |
|
496 | + 'REG LIMIT', |
|
497 | + __FILE__, |
|
498 | + __LINE__ |
|
499 | + ); |
|
500 | + } |
|
501 | + // number of allocated spaces always starts at zero |
|
502 | + $spaces_allocated = 0; |
|
503 | + $this->total_spaces[ $datetime_identifier ] = 0; |
|
504 | + foreach ($tickets as $ticket_identifier) { |
|
505 | + $spaces_allocated = $this->calculateAvailableSpacesForTicket( |
|
506 | + $datetime_identifier, |
|
507 | + $reg_limit, |
|
508 | + $ticket_identifier, |
|
509 | + $spaces_allocated |
|
510 | + ); |
|
511 | + } |
|
512 | + // spaces can't be negative |
|
513 | + $spaces_allocated = max($spaces_allocated, 0); |
|
514 | + if ($spaces_allocated) { |
|
515 | + // track any non-zero values |
|
516 | + $this->total_spaces[ $datetime_identifier ] += $spaces_allocated; |
|
517 | + if ($this->debug) { |
|
518 | + \EEH_Debug_Tools::printr((string) $spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__); |
|
519 | + } |
|
520 | + } else { |
|
521 | + if ($this->debug) { |
|
522 | + \EEH_Debug_Tools::printr(' ', ' . NO TICKETS AVAILABLE FOR DATETIME', __FILE__, __LINE__); |
|
523 | + } |
|
524 | + } |
|
525 | + if ($this->debug) { |
|
526 | + \EEH_Debug_Tools::printr( |
|
527 | + $this->total_spaces[ $datetime_identifier ], |
|
528 | + '$total_spaces', |
|
529 | + __FILE__, |
|
530 | + __LINE__ |
|
531 | + ); |
|
532 | + \EEH_Debug_Tools::printr($this->ticket_quantities, '$ticket_quantities', __FILE__, __LINE__); |
|
533 | + \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__); |
|
534 | + } |
|
535 | + } |
|
536 | + |
|
537 | + |
|
538 | + /** |
|
539 | + * @param string $datetime_identifier |
|
540 | + * @param int $reg_limit |
|
541 | + * @param string $ticket_identifier |
|
542 | + * @param int $spaces_allocated |
|
543 | + * @return int |
|
544 | + */ |
|
545 | + private function calculateAvailableSpacesForTicket( |
|
546 | + $datetime_identifier, |
|
547 | + $reg_limit, |
|
548 | + $ticket_identifier, |
|
549 | + $spaces_allocated |
|
550 | + ) { |
|
551 | + // make sure ticket quantity is set |
|
552 | + $ticket_quantity = isset($this->ticket_quantities[ $ticket_identifier ]) |
|
553 | + ? $this->ticket_quantities[ $ticket_identifier ] |
|
554 | + : 0; |
|
555 | + if ($this->debug) { |
|
556 | + \EEH_Debug_Tools::printr("{$spaces_allocated}", '$spaces_allocated', __FILE__, __LINE__); |
|
557 | + \EEH_Debug_Tools::printr( |
|
558 | + "{$ticket_quantity}", |
|
559 | + "ticket $ticket_identifier quantity: ", |
|
560 | + __FILE__, |
|
561 | + __LINE__, |
|
562 | + 2 |
|
563 | + ); |
|
564 | + } |
|
565 | + if ($ticket_quantity) { |
|
566 | + if ($this->debug) { |
|
567 | + \EEH_Debug_Tools::printr( |
|
568 | + ($spaces_allocated <= $reg_limit) |
|
569 | + ? 'true' |
|
570 | + : 'false', |
|
571 | + ' . spaces_allocated <= reg_limit = ', |
|
572 | + __FILE__, |
|
573 | + __LINE__ |
|
574 | + ); |
|
575 | + } |
|
576 | + // if the datetime is NOT at full capacity yet |
|
577 | + if ($spaces_allocated <= $reg_limit) { |
|
578 | + // then the maximum ticket quantity we can allocate is the lowest value of either: |
|
579 | + // the number of remaining spaces for the datetime, which is the limit - spaces already taken |
|
580 | + // or the maximum ticket quantity |
|
581 | + $ticket_quantity = min($reg_limit - $spaces_allocated, $ticket_quantity); |
|
582 | + // adjust the available quantity in our tracking array |
|
583 | + $this->ticket_quantities[ $ticket_identifier ] -= $ticket_quantity; |
|
584 | + // and increment spaces allocated for this datetime |
|
585 | + $spaces_allocated += $ticket_quantity; |
|
586 | + $at_capacity = $spaces_allocated >= $reg_limit; |
|
587 | + if ($this->debug) { |
|
588 | + \EEH_Debug_Tools::printr( |
|
589 | + "{$ticket_quantity} {$ticket_identifier} tickets", |
|
590 | + ' > > allocate ', |
|
591 | + __FILE__, |
|
592 | + __LINE__, |
|
593 | + 3 |
|
594 | + ); |
|
595 | + if ($at_capacity) { |
|
596 | + \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__, 3); |
|
597 | + } |
|
598 | + } |
|
599 | + // now adjust all other datetimes that allow access to this ticket |
|
600 | + $this->adjustDatetimes( |
|
601 | + $datetime_identifier, |
|
602 | + $ticket_identifier, |
|
603 | + $ticket_quantity, |
|
604 | + $at_capacity |
|
605 | + ); |
|
606 | + } |
|
607 | + } |
|
608 | + return $spaces_allocated; |
|
609 | + } |
|
610 | + |
|
611 | + |
|
612 | + /** |
|
613 | + * subtracts ticket amounts from all datetime reg limits |
|
614 | + * that allow access to the ticket specified, |
|
615 | + * because that ticket could be used |
|
616 | + * to attend any of the datetimes it has access to |
|
617 | + * |
|
618 | + * @param string $datetime_identifier |
|
619 | + * @param string $ticket_identifier |
|
620 | + * @param bool $at_capacity |
|
621 | + * @param int $ticket_quantity |
|
622 | + */ |
|
623 | + private function adjustDatetimes( |
|
624 | + $datetime_identifier, |
|
625 | + $ticket_identifier, |
|
626 | + $ticket_quantity, |
|
627 | + $at_capacity |
|
628 | + ) { |
|
629 | + /** @var array $datetime_tickets */ |
|
630 | + foreach ($this->datetime_tickets as $datetime_ID => $datetime_tickets) { |
|
631 | + if ($datetime_ID !== $datetime_identifier || ! is_array($datetime_tickets)) { |
|
632 | + continue; |
|
633 | + } |
|
634 | + $adjusted = $this->adjustDatetimeSpaces( |
|
635 | + $datetime_ID, |
|
636 | + $ticket_identifier, |
|
637 | + $ticket_quantity |
|
638 | + ); |
|
639 | + // skip to next ticket if nothing changed |
|
640 | + if (! ($adjusted || $at_capacity)) { |
|
641 | + continue; |
|
642 | + } |
|
643 | + // then all of it's tickets are now unavailable |
|
644 | + foreach ($datetime_tickets as $datetime_ticket) { |
|
645 | + if ( |
|
646 | + ($ticket_identifier === $datetime_ticket || $at_capacity) |
|
647 | + && isset($this->ticket_quantities[ $datetime_ticket ]) |
|
648 | + && $this->ticket_quantities[ $datetime_ticket ] > 0 |
|
649 | + ) { |
|
650 | + if ($this->debug) { |
|
651 | + \EEH_Debug_Tools::printr( |
|
652 | + $datetime_ticket, |
|
653 | + ' . . . adjust ticket quantities for', |
|
654 | + __FILE__, |
|
655 | + __LINE__ |
|
656 | + ); |
|
657 | + } |
|
658 | + // if this datetime is at full capacity, set any tracked available quantities to zero |
|
659 | + // otherwise just subtract the ticket quantity |
|
660 | + $new_quantity = $at_capacity |
|
661 | + ? 0 |
|
662 | + : $this->ticket_quantities[ $datetime_ticket ] - $ticket_quantity; |
|
663 | + // don't let ticket quantity go below zero |
|
664 | + $this->ticket_quantities[ $datetime_ticket ] = max($new_quantity, 0); |
|
665 | + if ($this->debug) { |
|
666 | + \EEH_Debug_Tools::printr( |
|
667 | + $at_capacity |
|
668 | + ? "0 because Datetime {$datetime_identifier} is at capacity" |
|
669 | + : "{$this->ticket_quantities[ $datetime_ticket ]}", |
|
670 | + " . . . . {$datetime_ticket} quantity set to ", |
|
671 | + __FILE__, |
|
672 | + __LINE__ |
|
673 | + ); |
|
674 | + } |
|
675 | + } |
|
676 | + // but we also need to adjust spaces for any other datetimes this ticket has access to |
|
677 | + if ($datetime_ticket === $ticket_identifier) { |
|
678 | + if ( |
|
679 | + isset($this->ticket_datetimes[ $datetime_ticket ]) |
|
680 | + && is_array($this->ticket_datetimes[ $datetime_ticket ]) |
|
681 | + ) { |
|
682 | + if ($this->debug) { |
|
683 | + \EEH_Debug_Tools::printr( |
|
684 | + $datetime_ticket, |
|
685 | + ' . . adjust other Datetimes for', |
|
686 | + __FILE__, |
|
687 | + __LINE__ |
|
688 | + ); |
|
689 | + } |
|
690 | + foreach ($this->ticket_datetimes[ $datetime_ticket ] as $datetime) { |
|
691 | + // don't adjust the current datetime twice |
|
692 | + if ($datetime !== $datetime_identifier) { |
|
693 | + $this->adjustDatetimeSpaces( |
|
694 | + $datetime, |
|
695 | + $datetime_ticket, |
|
696 | + $ticket_quantity |
|
697 | + ); |
|
698 | + } |
|
699 | + } |
|
700 | + } |
|
701 | + } |
|
702 | + } |
|
703 | + } |
|
704 | + } |
|
705 | + |
|
706 | + private function adjustDatetimeSpaces($datetime_identifier, $ticket_identifier, $ticket_quantity = 0) |
|
707 | + { |
|
708 | + // does datetime have spaces available? |
|
709 | + // and does the supplied ticket have access to this datetime ? |
|
710 | + if ( |
|
711 | + $this->datetime_spaces[ $datetime_identifier ] > 0 |
|
712 | + && isset($this->datetime_spaces[ $datetime_identifier ], $this->datetime_tickets[ $datetime_identifier ]) |
|
713 | + && in_array($ticket_identifier, $this->datetime_tickets[ $datetime_identifier ], true) |
|
714 | + ) { |
|
715 | + if ($this->debug) { |
|
716 | + \EEH_Debug_Tools::printr($datetime_identifier, ' . . adjust Datetime Spaces for', __FILE__, __LINE__); |
|
717 | + \EEH_Debug_Tools::printr( |
|
718 | + "{$this->datetime_spaces[ $datetime_identifier ]}", |
|
719 | + " . . current {$datetime_identifier} spaces available", |
|
720 | + __FILE__, |
|
721 | + __LINE__ |
|
722 | + ); |
|
723 | + } |
|
724 | + // then decrement the available spaces for the datetime |
|
725 | + $this->datetime_spaces[ $datetime_identifier ] -= $ticket_quantity; |
|
726 | + // but don't let quantities go below zero |
|
727 | + $this->datetime_spaces[ $datetime_identifier ] = max( |
|
728 | + $this->datetime_spaces[ $datetime_identifier ], |
|
729 | + 0 |
|
730 | + ); |
|
731 | + if ($this->debug) { |
|
732 | + \EEH_Debug_Tools::printr( |
|
733 | + "{$ticket_quantity}", |
|
734 | + " . . . {$datetime_identifier} capacity reduced by", |
|
735 | + __FILE__, |
|
736 | + __LINE__ |
|
737 | + ); |
|
738 | + } |
|
739 | + return true; |
|
740 | + } |
|
741 | + return false; |
|
742 | + } |
|
743 | 743 | } |
@@ -116,7 +116,7 @@ discard block |
||
116 | 116 | $attributes['limit'] = (int) $attributes['limit']; |
117 | 117 | $display_on_archives = filter_var($attributes['display_on_archives'], FILTER_VALIDATE_BOOLEAN); |
118 | 118 | // don't display on archives unless 'display_on_archives' is true |
119 | - if ($attributes['limit'] === 0 || (! $display_on_archives && is_archive())) { |
|
119 | + if ($attributes['limit'] === 0 || ( ! $display_on_archives && is_archive())) { |
|
120 | 120 | return ''; |
121 | 121 | } |
122 | 122 | try { |
@@ -317,7 +317,7 @@ discard block |
||
317 | 317 | */ |
318 | 318 | private function getDatetime(array $attributes) |
319 | 319 | { |
320 | - if (! empty($attributes['datetime_id'])) { |
|
320 | + if ( ! empty($attributes['datetime_id'])) { |
|
321 | 321 | $datetime = EEM_Datetime::instance()->get_one_by_ID($attributes['datetime_id']); |
322 | 322 | if ($datetime instanceof EE_Datetime) { |
323 | 323 | return $datetime; |
@@ -337,7 +337,7 @@ discard block |
||
337 | 337 | */ |
338 | 338 | private function getTicket(array $attributes) |
339 | 339 | { |
340 | - if (! empty($attributes['ticket_id'])) { |
|
340 | + if ( ! empty($attributes['ticket_id'])) { |
|
341 | 341 | $ticket = EEM_Ticket::instance()->get_one_by_ID($attributes['ticket_id']); |
342 | 342 | if ($ticket instanceof EE_Ticket) { |
343 | 343 | return $ticket; |
@@ -354,7 +354,7 @@ discard block |
||
354 | 354 | private function setAdditionalQueryParams(array $attributes) |
355 | 355 | { |
356 | 356 | $reg_status_array = EEM_Registration::reg_status_array(); |
357 | - if (isset($reg_status_array[ $attributes['status'] ])) { |
|
357 | + if (isset($reg_status_array[$attributes['status']])) { |
|
358 | 358 | $this->query_params[0]['Registration.STS_ID'] = $attributes['status']; |
359 | 359 | } |
360 | 360 | if (absint($attributes['limit'])) { |
@@ -30,339 +30,339 @@ |
||
30 | 30 | */ |
31 | 31 | class EspressoEventAttendees extends EspressoShortcode |
32 | 32 | { |
33 | - private $query_params = array( |
|
34 | - 0 => array(), |
|
35 | - ); |
|
33 | + private $query_params = array( |
|
34 | + 0 => array(), |
|
35 | + ); |
|
36 | 36 | |
37 | - private $template_args = array( |
|
38 | - 'contacts' => array(), |
|
39 | - 'event' => null, |
|
40 | - 'datetime' => null, |
|
41 | - 'ticket' => null, |
|
42 | - ); |
|
37 | + private $template_args = array( |
|
38 | + 'contacts' => array(), |
|
39 | + 'event' => null, |
|
40 | + 'datetime' => null, |
|
41 | + 'ticket' => null, |
|
42 | + ); |
|
43 | 43 | |
44 | - /** |
|
45 | - * the actual shortcode tag that gets registered with WordPress |
|
46 | - * |
|
47 | - * @return string |
|
48 | - */ |
|
49 | - public function getTag() |
|
50 | - { |
|
51 | - return 'ESPRESSO_EVENT_ATTENDEES'; |
|
52 | - } |
|
44 | + /** |
|
45 | + * the actual shortcode tag that gets registered with WordPress |
|
46 | + * |
|
47 | + * @return string |
|
48 | + */ |
|
49 | + public function getTag() |
|
50 | + { |
|
51 | + return 'ESPRESSO_EVENT_ATTENDEES'; |
|
52 | + } |
|
53 | 53 | |
54 | 54 | |
55 | - /** |
|
56 | - * the time in seconds to cache the results of the processShortcode() method |
|
57 | - * 0 means the processShortcode() results will NOT be cached at all |
|
58 | - * |
|
59 | - * @return int |
|
60 | - */ |
|
61 | - public function cacheExpiration() |
|
62 | - { |
|
63 | - return 0; |
|
64 | - } |
|
55 | + /** |
|
56 | + * the time in seconds to cache the results of the processShortcode() method |
|
57 | + * 0 means the processShortcode() results will NOT be cached at all |
|
58 | + * |
|
59 | + * @return int |
|
60 | + */ |
|
61 | + public function cacheExpiration() |
|
62 | + { |
|
63 | + return 0; |
|
64 | + } |
|
65 | 65 | |
66 | 66 | |
67 | - /** |
|
68 | - * a place for adding any initialization code that needs to run prior to wp_header(). |
|
69 | - * this may be required for shortcodes that utilize a corresponding module, |
|
70 | - * and need to enqueue assets for that module |
|
71 | - * |
|
72 | - * @return void |
|
73 | - */ |
|
74 | - public function initializeShortcode() |
|
75 | - { |
|
76 | - $this->shortcodeHasBeenInitialized(); |
|
77 | - } |
|
67 | + /** |
|
68 | + * a place for adding any initialization code that needs to run prior to wp_header(). |
|
69 | + * this may be required for shortcodes that utilize a corresponding module, |
|
70 | + * and need to enqueue assets for that module |
|
71 | + * |
|
72 | + * @return void |
|
73 | + */ |
|
74 | + public function initializeShortcode() |
|
75 | + { |
|
76 | + $this->shortcodeHasBeenInitialized(); |
|
77 | + } |
|
78 | 78 | |
79 | 79 | |
80 | - /** |
|
81 | - * process_shortcode - ESPRESSO_EVENT_ATTENDEES - Returns a list of attendees to an event. |
|
82 | - * [ESPRESSO_EVENT_ATTENDEES] |
|
83 | - * - defaults to attendees for earliest active event, or earliest upcoming event. |
|
84 | - * [ESPRESSO_EVENT_ATTENDEES event_id=123] |
|
85 | - * - attendees for specific event. |
|
86 | - * [ESPRESSO_EVENT_ATTENDEES datetime_id=245] |
|
87 | - * - attendees for a specific datetime. |
|
88 | - * [ESPRESSO_EVENT_ATTENDEES ticket_id=123] |
|
89 | - * - attendees for a specific ticket. |
|
90 | - * [ESPRESSO_EVENT_ATTENDEES status=all] |
|
91 | - * - specific registration status (use status id) or all for all attendees regardless of status. |
|
92 | - * Note default is to only return approved attendees |
|
93 | - * [ESPRESSO_EVENT_ATTENDEES show_gravatar=true] |
|
94 | - * - default is to not return gravatar. Otherwise if this is set then return gravatar for email address given. |
|
95 | - * [ESPRESSO_EVENT_ATTENDEES display_on_archives=true] |
|
96 | - * - default is to not display attendees list on archive pages. |
|
97 | - * Note: because of the relationship between event_id, ticket_id, and datetime_id: |
|
98 | - * If more than one of those params is included, then preference is given to the following: |
|
99 | - * - event_id is used whenever its present and any others are ignored. |
|
100 | - * - if no event_id then datetime is used whenever its present and any others are ignored. |
|
101 | - * - otherwise ticket_id is used if present. |
|
102 | - * |
|
103 | - * @param array $attributes |
|
104 | - * @return string |
|
105 | - * @throws EE_Error |
|
106 | - * @throws InvalidDataTypeException |
|
107 | - * @throws InvalidInterfaceException |
|
108 | - * @throws InvalidArgumentException |
|
109 | - * @throws DomainException |
|
110 | - */ |
|
111 | - public function processShortcode($attributes = array()) |
|
112 | - { |
|
113 | - // grab attributes and merge with defaults |
|
114 | - $attributes = $this->getAttributes((array) $attributes); |
|
115 | - $attributes['limit'] = (int) $attributes['limit']; |
|
116 | - $display_on_archives = filter_var($attributes['display_on_archives'], FILTER_VALIDATE_BOOLEAN); |
|
117 | - // don't display on archives unless 'display_on_archives' is true |
|
118 | - if ($attributes['limit'] === 0 || (! $display_on_archives && is_archive())) { |
|
119 | - return ''; |
|
120 | - } |
|
121 | - try { |
|
122 | - $this->setBaseTemplateArguments($attributes); |
|
123 | - $this->validateEntities($attributes); |
|
124 | - $this->setBaseQueryParams(); |
|
125 | - } catch (EntityNotFoundException $e) { |
|
126 | - if (WP_DEBUG) { |
|
127 | - return '<div class="important-notice ee-error">' |
|
128 | - . $e->getMessage() |
|
129 | - . '</div>'; |
|
130 | - } |
|
131 | - return ''; |
|
132 | - } |
|
133 | - $this->setAdditionalQueryParams($attributes); |
|
134 | - // get contacts! |
|
135 | - $this->template_args['contacts'] = EEM_Attendee::instance()->get_all($this->query_params); |
|
136 | - // all set let's load up the template and return. |
|
137 | - return EEH_Template::locate_template( |
|
138 | - 'loop-espresso_event_attendees.php', |
|
139 | - $this->template_args |
|
140 | - ); |
|
141 | - } |
|
80 | + /** |
|
81 | + * process_shortcode - ESPRESSO_EVENT_ATTENDEES - Returns a list of attendees to an event. |
|
82 | + * [ESPRESSO_EVENT_ATTENDEES] |
|
83 | + * - defaults to attendees for earliest active event, or earliest upcoming event. |
|
84 | + * [ESPRESSO_EVENT_ATTENDEES event_id=123] |
|
85 | + * - attendees for specific event. |
|
86 | + * [ESPRESSO_EVENT_ATTENDEES datetime_id=245] |
|
87 | + * - attendees for a specific datetime. |
|
88 | + * [ESPRESSO_EVENT_ATTENDEES ticket_id=123] |
|
89 | + * - attendees for a specific ticket. |
|
90 | + * [ESPRESSO_EVENT_ATTENDEES status=all] |
|
91 | + * - specific registration status (use status id) or all for all attendees regardless of status. |
|
92 | + * Note default is to only return approved attendees |
|
93 | + * [ESPRESSO_EVENT_ATTENDEES show_gravatar=true] |
|
94 | + * - default is to not return gravatar. Otherwise if this is set then return gravatar for email address given. |
|
95 | + * [ESPRESSO_EVENT_ATTENDEES display_on_archives=true] |
|
96 | + * - default is to not display attendees list on archive pages. |
|
97 | + * Note: because of the relationship between event_id, ticket_id, and datetime_id: |
|
98 | + * If more than one of those params is included, then preference is given to the following: |
|
99 | + * - event_id is used whenever its present and any others are ignored. |
|
100 | + * - if no event_id then datetime is used whenever its present and any others are ignored. |
|
101 | + * - otherwise ticket_id is used if present. |
|
102 | + * |
|
103 | + * @param array $attributes |
|
104 | + * @return string |
|
105 | + * @throws EE_Error |
|
106 | + * @throws InvalidDataTypeException |
|
107 | + * @throws InvalidInterfaceException |
|
108 | + * @throws InvalidArgumentException |
|
109 | + * @throws DomainException |
|
110 | + */ |
|
111 | + public function processShortcode($attributes = array()) |
|
112 | + { |
|
113 | + // grab attributes and merge with defaults |
|
114 | + $attributes = $this->getAttributes((array) $attributes); |
|
115 | + $attributes['limit'] = (int) $attributes['limit']; |
|
116 | + $display_on_archives = filter_var($attributes['display_on_archives'], FILTER_VALIDATE_BOOLEAN); |
|
117 | + // don't display on archives unless 'display_on_archives' is true |
|
118 | + if ($attributes['limit'] === 0 || (! $display_on_archives && is_archive())) { |
|
119 | + return ''; |
|
120 | + } |
|
121 | + try { |
|
122 | + $this->setBaseTemplateArguments($attributes); |
|
123 | + $this->validateEntities($attributes); |
|
124 | + $this->setBaseQueryParams(); |
|
125 | + } catch (EntityNotFoundException $e) { |
|
126 | + if (WP_DEBUG) { |
|
127 | + return '<div class="important-notice ee-error">' |
|
128 | + . $e->getMessage() |
|
129 | + . '</div>'; |
|
130 | + } |
|
131 | + return ''; |
|
132 | + } |
|
133 | + $this->setAdditionalQueryParams($attributes); |
|
134 | + // get contacts! |
|
135 | + $this->template_args['contacts'] = EEM_Attendee::instance()->get_all($this->query_params); |
|
136 | + // all set let's load up the template and return. |
|
137 | + return EEH_Template::locate_template( |
|
138 | + 'loop-espresso_event_attendees.php', |
|
139 | + $this->template_args |
|
140 | + ); |
|
141 | + } |
|
142 | 142 | |
143 | 143 | |
144 | - /** |
|
145 | - * merge incoming attributes with filtered defaults |
|
146 | - * |
|
147 | - * @param array $attributes |
|
148 | - * @return array |
|
149 | - */ |
|
150 | - private function getAttributes(array $attributes) |
|
151 | - { |
|
152 | - return (array) apply_filters( |
|
153 | - 'EES_Espresso_Event_Attendees__process_shortcode__default_shortcode_atts', |
|
154 | - $attributes + array( |
|
155 | - 'event_id' => null, |
|
156 | - 'datetime_id' => null, |
|
157 | - 'ticket_id' => null, |
|
158 | - 'status' => EEM_Registration::status_id_approved, |
|
159 | - 'show_gravatar' => false, |
|
160 | - 'display_on_archives' => false, |
|
161 | - 'limit' => 999, |
|
162 | - ) |
|
163 | - ); |
|
164 | - } |
|
144 | + /** |
|
145 | + * merge incoming attributes with filtered defaults |
|
146 | + * |
|
147 | + * @param array $attributes |
|
148 | + * @return array |
|
149 | + */ |
|
150 | + private function getAttributes(array $attributes) |
|
151 | + { |
|
152 | + return (array) apply_filters( |
|
153 | + 'EES_Espresso_Event_Attendees__process_shortcode__default_shortcode_atts', |
|
154 | + $attributes + array( |
|
155 | + 'event_id' => null, |
|
156 | + 'datetime_id' => null, |
|
157 | + 'ticket_id' => null, |
|
158 | + 'status' => EEM_Registration::status_id_approved, |
|
159 | + 'show_gravatar' => false, |
|
160 | + 'display_on_archives' => false, |
|
161 | + 'limit' => 999, |
|
162 | + ) |
|
163 | + ); |
|
164 | + } |
|
165 | 165 | |
166 | 166 | |
167 | - /** |
|
168 | - * Set all the base template arguments from the incoming attributes. |
|
169 | - * * Note: because of the relationship between event_id, ticket_id, and datetime_id: |
|
170 | - * If more than one of those params is included, then preference is given to the following: |
|
171 | - * - event_id is used whenever its present and any others are ignored. |
|
172 | - * - if no event_id then datetime is used whenever its present and any others are ignored. |
|
173 | - * - otherwise ticket_id is used if present. |
|
174 | - * |
|
175 | - * @param array $attributes |
|
176 | - * @throws EE_Error |
|
177 | - * @throws InvalidDataTypeException |
|
178 | - * @throws InvalidInterfaceException |
|
179 | - * @throws InvalidArgumentException |
|
180 | - */ |
|
181 | - private function setBaseTemplateArguments(array $attributes) |
|
182 | - { |
|
183 | - $this->template_args['show_gravatar'] = $attributes['show_gravatar']; |
|
184 | - $this->template_args['event'] = $this->getEvent($attributes); |
|
185 | - $this->template_args['datetime'] = empty($attributes['event_id']) |
|
186 | - ? $this->getDatetime($attributes) |
|
187 | - : null; |
|
188 | - $this->template_args['ticket'] = empty($attributes['datetime_id']) && empty($attributes['event_id']) |
|
189 | - ? $this->getTicket($attributes) |
|
190 | - : null; |
|
191 | - } |
|
167 | + /** |
|
168 | + * Set all the base template arguments from the incoming attributes. |
|
169 | + * * Note: because of the relationship between event_id, ticket_id, and datetime_id: |
|
170 | + * If more than one of those params is included, then preference is given to the following: |
|
171 | + * - event_id is used whenever its present and any others are ignored. |
|
172 | + * - if no event_id then datetime is used whenever its present and any others are ignored. |
|
173 | + * - otherwise ticket_id is used if present. |
|
174 | + * |
|
175 | + * @param array $attributes |
|
176 | + * @throws EE_Error |
|
177 | + * @throws InvalidDataTypeException |
|
178 | + * @throws InvalidInterfaceException |
|
179 | + * @throws InvalidArgumentException |
|
180 | + */ |
|
181 | + private function setBaseTemplateArguments(array $attributes) |
|
182 | + { |
|
183 | + $this->template_args['show_gravatar'] = $attributes['show_gravatar']; |
|
184 | + $this->template_args['event'] = $this->getEvent($attributes); |
|
185 | + $this->template_args['datetime'] = empty($attributes['event_id']) |
|
186 | + ? $this->getDatetime($attributes) |
|
187 | + : null; |
|
188 | + $this->template_args['ticket'] = empty($attributes['datetime_id']) && empty($attributes['event_id']) |
|
189 | + ? $this->getTicket($attributes) |
|
190 | + : null; |
|
191 | + } |
|
192 | 192 | |
193 | 193 | |
194 | - /** |
|
195 | - * Validates the presence of entities for the given attribute values. |
|
196 | - * |
|
197 | - * @param array $attributes |
|
198 | - * @throws EntityNotFoundException |
|
199 | - */ |
|
200 | - private function validateEntities(array $attributes) |
|
201 | - { |
|
202 | - if ( |
|
203 | - ! $this->template_args['event'] instanceof EE_Event |
|
204 | - || ( |
|
205 | - empty($attributes['event_id']) |
|
206 | - && $attributes['datetime_id'] |
|
207 | - && ! $this->template_args['datetime'] instanceof EE_Datetime |
|
208 | - ) |
|
209 | - || ( |
|
210 | - empty($attributes['event_id']) |
|
211 | - && empty($attributes['datetime_id']) |
|
212 | - && $attributes['ticket_id'] |
|
213 | - && ! $this->template_args['ticket'] instanceof EE_Ticket |
|
214 | - ) |
|
215 | - ) { |
|
216 | - throw new EntityNotFoundException( |
|
217 | - '', |
|
218 | - '', |
|
219 | - esc_html__( |
|
220 | - 'The [ESPRESSO_EVENT_ATTENDEES] shortcode has been used incorrectly. Please double check the arguments you used for any typos. In the case of ID type arguments, its possible the given ID does not correspond to existing data in the database.', |
|
221 | - 'event_espresso' |
|
222 | - ) |
|
223 | - ); |
|
224 | - } |
|
225 | - } |
|
194 | + /** |
|
195 | + * Validates the presence of entities for the given attribute values. |
|
196 | + * |
|
197 | + * @param array $attributes |
|
198 | + * @throws EntityNotFoundException |
|
199 | + */ |
|
200 | + private function validateEntities(array $attributes) |
|
201 | + { |
|
202 | + if ( |
|
203 | + ! $this->template_args['event'] instanceof EE_Event |
|
204 | + || ( |
|
205 | + empty($attributes['event_id']) |
|
206 | + && $attributes['datetime_id'] |
|
207 | + && ! $this->template_args['datetime'] instanceof EE_Datetime |
|
208 | + ) |
|
209 | + || ( |
|
210 | + empty($attributes['event_id']) |
|
211 | + && empty($attributes['datetime_id']) |
|
212 | + && $attributes['ticket_id'] |
|
213 | + && ! $this->template_args['ticket'] instanceof EE_Ticket |
|
214 | + ) |
|
215 | + ) { |
|
216 | + throw new EntityNotFoundException( |
|
217 | + '', |
|
218 | + '', |
|
219 | + esc_html__( |
|
220 | + 'The [ESPRESSO_EVENT_ATTENDEES] shortcode has been used incorrectly. Please double check the arguments you used for any typos. In the case of ID type arguments, its possible the given ID does not correspond to existing data in the database.', |
|
221 | + 'event_espresso' |
|
222 | + ) |
|
223 | + ); |
|
224 | + } |
|
225 | + } |
|
226 | 226 | |
227 | 227 | |
228 | - /** |
|
229 | - * Sets the query params for the base query elements. |
|
230 | - */ |
|
231 | - private function setBaseQueryParams() |
|
232 | - { |
|
233 | - switch (true) { |
|
234 | - case $this->template_args['datetime'] instanceof EE_Datetime: |
|
235 | - $this->query_params = array( |
|
236 | - 0 => array( |
|
237 | - 'Registration.Ticket.Datetime.DTT_ID' => $this->template_args['datetime']->ID(), |
|
238 | - ), |
|
239 | - 'default_where_conditions' => 'this_model_only', |
|
240 | - ); |
|
241 | - break; |
|
242 | - case $this->template_args['ticket'] instanceof EE_Ticket: |
|
243 | - $this->query_params[0] = array( |
|
244 | - 'Registration.TKT_ID' => $this->template_args['ticket']->ID(), |
|
245 | - ); |
|
246 | - break; |
|
247 | - case $this->template_args['event'] instanceof EE_Event: |
|
248 | - $this->query_params[0] = array( |
|
249 | - 'Registration.EVT_ID' => $this->template_args['event']->ID(), |
|
250 | - ); |
|
251 | - break; |
|
252 | - } |
|
253 | - } |
|
228 | + /** |
|
229 | + * Sets the query params for the base query elements. |
|
230 | + */ |
|
231 | + private function setBaseQueryParams() |
|
232 | + { |
|
233 | + switch (true) { |
|
234 | + case $this->template_args['datetime'] instanceof EE_Datetime: |
|
235 | + $this->query_params = array( |
|
236 | + 0 => array( |
|
237 | + 'Registration.Ticket.Datetime.DTT_ID' => $this->template_args['datetime']->ID(), |
|
238 | + ), |
|
239 | + 'default_where_conditions' => 'this_model_only', |
|
240 | + ); |
|
241 | + break; |
|
242 | + case $this->template_args['ticket'] instanceof EE_Ticket: |
|
243 | + $this->query_params[0] = array( |
|
244 | + 'Registration.TKT_ID' => $this->template_args['ticket']->ID(), |
|
245 | + ); |
|
246 | + break; |
|
247 | + case $this->template_args['event'] instanceof EE_Event: |
|
248 | + $this->query_params[0] = array( |
|
249 | + 'Registration.EVT_ID' => $this->template_args['event']->ID(), |
|
250 | + ); |
|
251 | + break; |
|
252 | + } |
|
253 | + } |
|
254 | 254 | |
255 | 255 | |
256 | - /** |
|
257 | - * @param array $attributes |
|
258 | - * @return EE_Event|null |
|
259 | - * @throws EE_Error |
|
260 | - * @throws InvalidDataTypeException |
|
261 | - * @throws InvalidInterfaceException |
|
262 | - * @throws InvalidArgumentException |
|
263 | - */ |
|
264 | - private function getEvent(array $attributes) |
|
265 | - { |
|
266 | - switch (true) { |
|
267 | - case ! empty($attributes['event_id']): |
|
268 | - $event = EEM_Event::instance()->get_one_by_ID($attributes['event_id']); |
|
269 | - break; |
|
270 | - case ! empty($attributes['datetime_id']): |
|
271 | - $event = EEM_Event::instance()->get_one(array( |
|
272 | - array( |
|
273 | - 'Datetime.DTT_ID' => $attributes['datetime_id'], |
|
274 | - ), |
|
275 | - )); |
|
276 | - break; |
|
277 | - case ! empty($attributes['ticket_id']): |
|
278 | - $event = EEM_Event::instance()->get_one(array( |
|
279 | - array( |
|
280 | - 'Datetime.Ticket.TKT_ID' => $attributes['ticket_id'], |
|
281 | - ), |
|
282 | - 'default_where_conditions' => 'none' |
|
283 | - )); |
|
284 | - break; |
|
285 | - case is_espresso_event(): |
|
286 | - $event = EEH_Event_View::get_event(); |
|
287 | - break; |
|
288 | - default: |
|
289 | - // one last shot... |
|
290 | - // try getting the earliest active event |
|
291 | - $events = EEM_Event::instance()->get_active_events(array( |
|
292 | - 'limit' => 1, |
|
293 | - 'order_by' => array('Datetime.DTT_EVT_start' => 'ASC'), |
|
294 | - )); |
|
295 | - // if none then get the next upcoming |
|
296 | - $events = empty($events) |
|
297 | - ? EEM_Event::instance()->get_upcoming_events(array( |
|
298 | - 'limit' => 1, |
|
299 | - 'order_by' => array('Datetime.DTT_EVT_start' => 'ASC'), |
|
300 | - )) |
|
301 | - : $events; |
|
302 | - $event = reset($events); |
|
303 | - } |
|
256 | + /** |
|
257 | + * @param array $attributes |
|
258 | + * @return EE_Event|null |
|
259 | + * @throws EE_Error |
|
260 | + * @throws InvalidDataTypeException |
|
261 | + * @throws InvalidInterfaceException |
|
262 | + * @throws InvalidArgumentException |
|
263 | + */ |
|
264 | + private function getEvent(array $attributes) |
|
265 | + { |
|
266 | + switch (true) { |
|
267 | + case ! empty($attributes['event_id']): |
|
268 | + $event = EEM_Event::instance()->get_one_by_ID($attributes['event_id']); |
|
269 | + break; |
|
270 | + case ! empty($attributes['datetime_id']): |
|
271 | + $event = EEM_Event::instance()->get_one(array( |
|
272 | + array( |
|
273 | + 'Datetime.DTT_ID' => $attributes['datetime_id'], |
|
274 | + ), |
|
275 | + )); |
|
276 | + break; |
|
277 | + case ! empty($attributes['ticket_id']): |
|
278 | + $event = EEM_Event::instance()->get_one(array( |
|
279 | + array( |
|
280 | + 'Datetime.Ticket.TKT_ID' => $attributes['ticket_id'], |
|
281 | + ), |
|
282 | + 'default_where_conditions' => 'none' |
|
283 | + )); |
|
284 | + break; |
|
285 | + case is_espresso_event(): |
|
286 | + $event = EEH_Event_View::get_event(); |
|
287 | + break; |
|
288 | + default: |
|
289 | + // one last shot... |
|
290 | + // try getting the earliest active event |
|
291 | + $events = EEM_Event::instance()->get_active_events(array( |
|
292 | + 'limit' => 1, |
|
293 | + 'order_by' => array('Datetime.DTT_EVT_start' => 'ASC'), |
|
294 | + )); |
|
295 | + // if none then get the next upcoming |
|
296 | + $events = empty($events) |
|
297 | + ? EEM_Event::instance()->get_upcoming_events(array( |
|
298 | + 'limit' => 1, |
|
299 | + 'order_by' => array('Datetime.DTT_EVT_start' => 'ASC'), |
|
300 | + )) |
|
301 | + : $events; |
|
302 | + $event = reset($events); |
|
303 | + } |
|
304 | 304 | |
305 | - return $event instanceof EE_Event ? $event : null; |
|
306 | - } |
|
305 | + return $event instanceof EE_Event ? $event : null; |
|
306 | + } |
|
307 | 307 | |
308 | 308 | |
309 | - /** |
|
310 | - * @param array $attributes |
|
311 | - * @return EE_Datetime|null |
|
312 | - * @throws EE_Error |
|
313 | - * @throws InvalidDataTypeException |
|
314 | - * @throws InvalidInterfaceException |
|
315 | - * @throws InvalidArgumentException |
|
316 | - */ |
|
317 | - private function getDatetime(array $attributes) |
|
318 | - { |
|
319 | - if (! empty($attributes['datetime_id'])) { |
|
320 | - $datetime = EEM_Datetime::instance()->get_one_by_ID($attributes['datetime_id']); |
|
321 | - if ($datetime instanceof EE_Datetime) { |
|
322 | - return $datetime; |
|
323 | - } |
|
324 | - } |
|
325 | - return null; |
|
326 | - } |
|
309 | + /** |
|
310 | + * @param array $attributes |
|
311 | + * @return EE_Datetime|null |
|
312 | + * @throws EE_Error |
|
313 | + * @throws InvalidDataTypeException |
|
314 | + * @throws InvalidInterfaceException |
|
315 | + * @throws InvalidArgumentException |
|
316 | + */ |
|
317 | + private function getDatetime(array $attributes) |
|
318 | + { |
|
319 | + if (! empty($attributes['datetime_id'])) { |
|
320 | + $datetime = EEM_Datetime::instance()->get_one_by_ID($attributes['datetime_id']); |
|
321 | + if ($datetime instanceof EE_Datetime) { |
|
322 | + return $datetime; |
|
323 | + } |
|
324 | + } |
|
325 | + return null; |
|
326 | + } |
|
327 | 327 | |
328 | 328 | |
329 | - /** |
|
330 | - * @param array $attributes |
|
331 | - * @return \EE_Base_Class|EE_Ticket|null |
|
332 | - * @throws EE_Error |
|
333 | - * @throws InvalidDataTypeException |
|
334 | - * @throws InvalidInterfaceException |
|
335 | - * @throws InvalidArgumentException |
|
336 | - */ |
|
337 | - private function getTicket(array $attributes) |
|
338 | - { |
|
339 | - if (! empty($attributes['ticket_id'])) { |
|
340 | - $ticket = EEM_Ticket::instance()->get_one_by_ID($attributes['ticket_id']); |
|
341 | - if ($ticket instanceof EE_Ticket) { |
|
342 | - return $ticket; |
|
343 | - } |
|
344 | - } |
|
345 | - return null; |
|
346 | - } |
|
329 | + /** |
|
330 | + * @param array $attributes |
|
331 | + * @return \EE_Base_Class|EE_Ticket|null |
|
332 | + * @throws EE_Error |
|
333 | + * @throws InvalidDataTypeException |
|
334 | + * @throws InvalidInterfaceException |
|
335 | + * @throws InvalidArgumentException |
|
336 | + */ |
|
337 | + private function getTicket(array $attributes) |
|
338 | + { |
|
339 | + if (! empty($attributes['ticket_id'])) { |
|
340 | + $ticket = EEM_Ticket::instance()->get_one_by_ID($attributes['ticket_id']); |
|
341 | + if ($ticket instanceof EE_Ticket) { |
|
342 | + return $ticket; |
|
343 | + } |
|
344 | + } |
|
345 | + return null; |
|
346 | + } |
|
347 | 347 | |
348 | 348 | |
349 | - /** |
|
350 | - * @param array $attributes |
|
351 | - * @throws EE_Error |
|
352 | - */ |
|
353 | - private function setAdditionalQueryParams(array $attributes) |
|
354 | - { |
|
355 | - $reg_status_array = EEM_Registration::reg_status_array(); |
|
356 | - if (isset($reg_status_array[ $attributes['status'] ])) { |
|
357 | - $this->query_params[0]['Registration.STS_ID'] = $attributes['status']; |
|
358 | - } |
|
359 | - if (absint($attributes['limit'])) { |
|
360 | - $this->query_params['limit'] = $attributes['limit']; |
|
361 | - } |
|
362 | - $this->query_params['group_by'] = array('ATT_ID'); |
|
363 | - $this->query_params['order_by'] = (array) apply_filters( |
|
364 | - 'FHEE__EES_Espresso_Event_Attendees__process_shortcode__order_by', |
|
365 | - array('ATT_lname' => 'ASC', 'ATT_fname' => 'ASC') |
|
366 | - ); |
|
367 | - } |
|
349 | + /** |
|
350 | + * @param array $attributes |
|
351 | + * @throws EE_Error |
|
352 | + */ |
|
353 | + private function setAdditionalQueryParams(array $attributes) |
|
354 | + { |
|
355 | + $reg_status_array = EEM_Registration::reg_status_array(); |
|
356 | + if (isset($reg_status_array[ $attributes['status'] ])) { |
|
357 | + $this->query_params[0]['Registration.STS_ID'] = $attributes['status']; |
|
358 | + } |
|
359 | + if (absint($attributes['limit'])) { |
|
360 | + $this->query_params['limit'] = $attributes['limit']; |
|
361 | + } |
|
362 | + $this->query_params['group_by'] = array('ATT_ID'); |
|
363 | + $this->query_params['order_by'] = (array) apply_filters( |
|
364 | + 'FHEE__EES_Espresso_Event_Attendees__process_shortcode__order_by', |
|
365 | + array('ATT_lname' => 'ASC', 'ATT_fname' => 'ASC') |
|
366 | + ); |
|
367 | + } |
|
368 | 368 | } |
@@ -128,7 +128,7 @@ discard block |
||
128 | 128 | if (is_array($this->_CPTs)) { |
129 | 129 | foreach ($this->_CPTs as $CPT_type => $CPT) { |
130 | 130 | if (isset($CPT['plural_slug'])) { |
131 | - $_CPT_endpoints [ (string) $CPT['plural_slug'] ] = $CPT_type; |
|
131 | + $_CPT_endpoints [(string) $CPT['plural_slug']] = $CPT_type; |
|
132 | 132 | } |
133 | 133 | } |
134 | 134 | } |
@@ -151,7 +151,7 @@ discard block |
||
151 | 151 | public function pre_get_posts($WP_Query) |
152 | 152 | { |
153 | 153 | // check that post-type is set |
154 | - if (! $WP_Query instanceof WP_Query) { |
|
154 | + if ( ! $WP_Query instanceof WP_Query) { |
|
155 | 155 | return; |
156 | 156 | } |
157 | 157 | // add our conditionals |
@@ -195,7 +195,7 @@ discard block |
||
195 | 195 | $terms = EEM_Term::instance()->get_all_CPT_post_tags(); |
196 | 196 | foreach ($terms as $term) { |
197 | 197 | if ($term instanceof EE_Term) { |
198 | - $this->_CPT_terms[ $term->slug() ] = $term; |
|
198 | + $this->_CPT_terms[$term->slug()] = $term; |
|
199 | 199 | } |
200 | 200 | } |
201 | 201 | } |
@@ -260,7 +260,7 @@ discard block |
||
260 | 260 | // loop thru our taxonomies |
261 | 261 | foreach ($this->_CPT_taxonomies as $CPT_taxonomy => $CPT_taxonomy_details) { |
262 | 262 | // check if one of our taxonomies is set as a query var |
263 | - if (isset($WP_Query->query[ $CPT_taxonomy ])) { |
|
263 | + if (isset($WP_Query->query[$CPT_taxonomy])) { |
|
264 | 264 | // but which CPT does that correspond to??? hmmm... guess we gotta go looping |
265 | 265 | foreach ($this->_CPTs as $post_type => $CPT) { |
266 | 266 | // verify our CPT has args, is public and has taxonomies set |
@@ -284,7 +284,7 @@ discard block |
||
284 | 284 | break; |
285 | 285 | default: |
286 | 286 | do_action( |
287 | - 'AHEE__EE_CPT_Strategy___set_CPT_taxonomies_on_WP_Query__for_' . $post_type . '_post_type', |
|
287 | + 'AHEE__EE_CPT_Strategy___set_CPT_taxonomies_on_WP_Query__for_'.$post_type.'_post_type', |
|
288 | 288 | $WP_Query, |
289 | 289 | $this |
290 | 290 | ); |
@@ -309,11 +309,11 @@ discard block |
||
309 | 309 | // loop thru post_types as array |
310 | 310 | foreach ((array) $WP_Query->query_vars['post_type'] as $post_type) { |
311 | 311 | // is current query for an EE CPT ? |
312 | - if (isset($this->_CPTs[ $post_type ])) { |
|
312 | + if (isset($this->_CPTs[$post_type])) { |
|
313 | 313 | // is EE on or off ? |
314 | 314 | if (EE_Maintenance_Mode::instance()->level()) { |
315 | 315 | // reroute CPT template view to maintenance_mode.template.php |
316 | - if (! has_filter('template_include', array('EE_Maintenance_Mode', 'template_include'))) { |
|
316 | + if ( ! has_filter('template_include', array('EE_Maintenance_Mode', 'template_include'))) { |
|
317 | 317 | add_filter('template_include', array('EE_Maintenance_Mode', 'template_include'), 99999); |
318 | 318 | } |
319 | 319 | if (has_filter('the_content', array(EE_Maintenance_Mode::instance(), 'the_content'))) { |
@@ -341,7 +341,7 @@ discard block |
||
341 | 341 | 'EventEspresso\core\CPTs\CptQueryModifier', |
342 | 342 | array( |
343 | 343 | $post_type, |
344 | - $this->_CPTs[ $post_type ], |
|
344 | + $this->_CPTs[$post_type], |
|
345 | 345 | $WP_Query, |
346 | 346 | ) |
347 | 347 | ); |
@@ -15,449 +15,449 @@ |
||
15 | 15 | */ |
16 | 16 | class EE_CPT_Strategy extends EE_Base |
17 | 17 | { |
18 | - /** |
|
19 | - * @var EE_CPT_Strategy $_instance |
|
20 | - */ |
|
21 | - private static $_instance; |
|
22 | - |
|
23 | - /** |
|
24 | - * the current page, if it utilizes CPTs |
|
25 | - * |
|
26 | - * @var array $CPT |
|
27 | - */ |
|
28 | - protected $CPT; |
|
29 | - |
|
30 | - /** |
|
31 | - * return value from CustomPostTypeDefinitions::getDefinitions() |
|
32 | - * |
|
33 | - * @var array $_CPTs |
|
34 | - */ |
|
35 | - protected $_CPTs = array(); |
|
36 | - |
|
37 | - /** |
|
38 | - * @var array $_CPT_taxonomies |
|
39 | - */ |
|
40 | - protected $_CPT_taxonomies = array(); |
|
41 | - |
|
42 | - /** |
|
43 | - * @var array $_CPT_terms |
|
44 | - */ |
|
45 | - protected $_CPT_terms = array(); |
|
46 | - |
|
47 | - /** |
|
48 | - * @var array $_CPT_endpoints |
|
49 | - */ |
|
50 | - protected $_CPT_endpoints = array(); |
|
51 | - |
|
52 | - /** |
|
53 | - * @var EEM_Base $CPT_model |
|
54 | - */ |
|
55 | - protected $CPT_model; |
|
56 | - |
|
57 | - /** |
|
58 | - * @var EventEspresso\Core\CPTs\CptQueryModifier $query_modifier |
|
59 | - */ |
|
60 | - protected $query_modifier; |
|
61 | - |
|
62 | - |
|
63 | - /** |
|
64 | - * @singleton method used to instantiate class object |
|
65 | - * @param CustomPostTypeDefinitions|null $custom_post_types |
|
66 | - * @param CustomTaxonomyDefinitions|null $taxonomies |
|
67 | - * @return EE_CPT_Strategy |
|
68 | - */ |
|
69 | - public static function instance( |
|
70 | - CustomPostTypeDefinitions $custom_post_types = null, |
|
71 | - CustomTaxonomyDefinitions $taxonomies = null |
|
72 | - ) { |
|
73 | - // check if class object is instantiated |
|
74 | - if ( |
|
75 | - ! self::$_instance instanceof EE_CPT_Strategy |
|
76 | - && $custom_post_types instanceof CustomPostTypeDefinitions |
|
77 | - && $taxonomies instanceof CustomTaxonomyDefinitions |
|
78 | - ) { |
|
79 | - self::$_instance = new self($custom_post_types, $taxonomies); |
|
80 | - } |
|
81 | - return self::$_instance; |
|
82 | - } |
|
83 | - |
|
84 | - |
|
85 | - /** |
|
86 | - * @param CustomPostTypeDefinitions $custom_post_types |
|
87 | - * @param CustomTaxonomyDefinitions $taxonomies |
|
88 | - */ |
|
89 | - protected function __construct( |
|
90 | - CustomPostTypeDefinitions $custom_post_types, |
|
91 | - CustomTaxonomyDefinitions $taxonomies |
|
92 | - ) { |
|
93 | - // get CPT data |
|
94 | - $this->_CPTs = $custom_post_types->getDefinitions(); |
|
95 | - $this->_CPT_endpoints = $this->_set_CPT_endpoints(); |
|
96 | - $this->_CPT_taxonomies = $taxonomies->getCustomTaxonomyDefinitions(); |
|
97 | - add_action('pre_get_posts', array($this, 'pre_get_posts'), 5); |
|
98 | - } |
|
99 | - |
|
100 | - |
|
101 | - /** |
|
102 | - * @return array |
|
103 | - */ |
|
104 | - public function get_CPT_endpoints() |
|
105 | - { |
|
106 | - return $this->_CPT_endpoints; |
|
107 | - } |
|
108 | - |
|
109 | - |
|
110 | - /** |
|
111 | - * @return array |
|
112 | - */ |
|
113 | - public function get_CPT_taxonomies() |
|
114 | - { |
|
115 | - return $this->_CPT_taxonomies; |
|
116 | - } |
|
117 | - |
|
118 | - |
|
119 | - /** |
|
120 | - * add CPT "slugs" to array of default espresso "pages" |
|
121 | - * |
|
122 | - * @return array |
|
123 | - */ |
|
124 | - private function _set_CPT_endpoints() |
|
125 | - { |
|
126 | - $_CPT_endpoints = array(); |
|
127 | - if (is_array($this->_CPTs)) { |
|
128 | - foreach ($this->_CPTs as $CPT_type => $CPT) { |
|
129 | - if (isset($CPT['plural_slug'])) { |
|
130 | - $_CPT_endpoints [ (string) $CPT['plural_slug'] ] = $CPT_type; |
|
131 | - } |
|
132 | - } |
|
133 | - } |
|
134 | - return $_CPT_endpoints; |
|
135 | - } |
|
136 | - |
|
137 | - |
|
138 | - /** |
|
139 | - * If this query (not just "main" queries (ie, for WP's infamous "loop")) is for an EE CPT, then we want to |
|
140 | - * supercharge the get_posts query to add our EE stuff (like joining to our tables, selecting extra columns, and |
|
141 | - * adding EE objects to the post to facilitate further querying of related data etc) |
|
142 | - * |
|
143 | - * @param WP_Query $WP_Query |
|
144 | - * @return void |
|
145 | - * @throws \EE_Error |
|
146 | - * @throws \InvalidArgumentException |
|
147 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
148 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
149 | - */ |
|
150 | - public function pre_get_posts($WP_Query) |
|
151 | - { |
|
152 | - // check that post-type is set |
|
153 | - if (! $WP_Query instanceof WP_Query) { |
|
154 | - return; |
|
155 | - } |
|
156 | - // add our conditionals |
|
157 | - $this->_set_EE_tags_on_WP_Query($WP_Query); |
|
158 | - // check for terms |
|
159 | - $this->_set_post_type_for_terms($WP_Query); |
|
160 | - // make sure paging is always set |
|
161 | - $this->_set_paging($WP_Query); |
|
162 | - // is a taxonomy set ? |
|
163 | - $this->_set_CPT_taxonomies_on_WP_Query($WP_Query); |
|
164 | - // loop thru post_types if set |
|
165 | - $this->_process_WP_Query_post_types($WP_Query); |
|
166 | - } |
|
167 | - |
|
168 | - |
|
169 | - /** |
|
170 | - * @param WP_Query $WP_Query |
|
171 | - * @return void |
|
172 | - */ |
|
173 | - private function _set_EE_tags_on_WP_Query(WP_Query $WP_Query) |
|
174 | - { |
|
175 | - $WP_Query->is_espresso_event_single = false; |
|
176 | - $WP_Query->is_espresso_event_archive = false; |
|
177 | - $WP_Query->is_espresso_event_taxonomy = false; |
|
178 | - $WP_Query->is_espresso_venue_single = false; |
|
179 | - $WP_Query->is_espresso_venue_archive = false; |
|
180 | - $WP_Query->is_espresso_venue_taxonomy = false; |
|
181 | - } |
|
182 | - |
|
183 | - |
|
184 | - /** |
|
185 | - * @return void |
|
186 | - * @throws EE_Error |
|
187 | - * @throws InvalidArgumentException |
|
188 | - * @throws InvalidDataTypeException |
|
189 | - * @throws InvalidInterfaceException |
|
190 | - */ |
|
191 | - private function _set_CPT_terms() |
|
192 | - { |
|
193 | - if (empty($this->_CPT_terms)) { |
|
194 | - $terms = EEM_Term::instance()->get_all_CPT_post_tags(); |
|
195 | - foreach ($terms as $term) { |
|
196 | - if ($term instanceof EE_Term) { |
|
197 | - $this->_CPT_terms[ $term->slug() ] = $term; |
|
198 | - } |
|
199 | - } |
|
200 | - } |
|
201 | - } |
|
202 | - |
|
203 | - |
|
204 | - /** |
|
205 | - * @param WP_Query $WP_Query |
|
206 | - * @return void |
|
207 | - * @throws EE_Error |
|
208 | - * @throws InvalidArgumentException |
|
209 | - * @throws InvalidDataTypeException |
|
210 | - * @throws InvalidInterfaceException |
|
211 | - */ |
|
212 | - private function _set_post_type_for_terms(WP_Query $WP_Query) |
|
213 | - { |
|
214 | - // is a tag set ? |
|
215 | - if (isset($WP_Query->query['tag'])) { |
|
216 | - // get term for tag |
|
217 | - $term = EEM_Term::instance()->get_post_tag_for_event_or_venue($WP_Query->query['tag']); |
|
218 | - // verify the term |
|
219 | - if ($term instanceof EE_Term) { |
|
220 | - $term->post_type = array_merge(array('post', 'page'), (array) $term->post_type); |
|
221 | - $term->post_type = apply_filters( |
|
222 | - 'FHEE__EE_CPT_Strategy___set_post_type_for_terms__term_post_type', |
|
223 | - $term->post_type, |
|
224 | - $term |
|
225 | - ); |
|
226 | - // if a post type is already set |
|
227 | - if (isset($WP_Query->query_vars['post_type'])) { |
|
228 | - // add to existing array |
|
229 | - $term->post_type = array_merge((array) $WP_Query->query_vars['post_type'], $term->post_type); |
|
230 | - } |
|
231 | - // just set post_type to our CPT |
|
232 | - $WP_Query->set('post_type', array_unique($term->post_type)); |
|
233 | - } |
|
234 | - } |
|
235 | - } |
|
236 | - |
|
237 | - |
|
238 | - /** |
|
239 | - * @param WP_Query $WP_Query |
|
240 | - * @return void |
|
241 | - */ |
|
242 | - public function _set_paging($WP_Query) |
|
243 | - { |
|
244 | - if ($WP_Query->is_main_query() && apply_filters('FHEE__EE_CPT_Strategy___set_paging', true)) { |
|
245 | - $page = get_query_var('page') ? get_query_var('page') : null; |
|
246 | - $paged = get_query_var('paged') ? get_query_var('paged') : $page; |
|
247 | - $WP_Query->set('paged', $paged); |
|
248 | - } |
|
249 | - } |
|
250 | - |
|
251 | - |
|
252 | - /** |
|
253 | - * @param \WP_Query $WP_Query |
|
254 | - */ |
|
255 | - protected function _set_CPT_taxonomies_on_WP_Query(WP_Query $WP_Query) |
|
256 | - { |
|
257 | - // is a taxonomy set ? |
|
258 | - if ($WP_Query->is_tax) { |
|
259 | - // loop thru our taxonomies |
|
260 | - foreach ($this->_CPT_taxonomies as $CPT_taxonomy => $CPT_taxonomy_details) { |
|
261 | - // check if one of our taxonomies is set as a query var |
|
262 | - if (isset($WP_Query->query[ $CPT_taxonomy ])) { |
|
263 | - // but which CPT does that correspond to??? hmmm... guess we gotta go looping |
|
264 | - foreach ($this->_CPTs as $post_type => $CPT) { |
|
265 | - // verify our CPT has args, is public and has taxonomies set |
|
266 | - if ( |
|
267 | - isset($CPT['args']['public']) |
|
268 | - && $CPT['args']['public'] |
|
269 | - && ! empty($CPT['args']['taxonomies']) |
|
270 | - && in_array($CPT_taxonomy, $CPT['args']['taxonomies'], true) |
|
271 | - ) { |
|
272 | - // if so, then add this CPT post_type to the current query's array of post_types' |
|
273 | - $WP_Query->query_vars['post_type'] = isset($WP_Query->query_vars['post_type']) |
|
274 | - ? (array) $WP_Query->query_vars['post_type'] |
|
275 | - : array(); |
|
276 | - $WP_Query->query_vars['post_type'][] = $post_type; |
|
277 | - switch ($post_type) { |
|
278 | - case 'espresso_events': |
|
279 | - $WP_Query->is_espresso_event_taxonomy = true; |
|
280 | - break; |
|
281 | - case 'espresso_venues': |
|
282 | - $WP_Query->is_espresso_venue_taxonomy = true; |
|
283 | - break; |
|
284 | - default: |
|
285 | - do_action( |
|
286 | - 'AHEE__EE_CPT_Strategy___set_CPT_taxonomies_on_WP_Query__for_' . $post_type . '_post_type', |
|
287 | - $WP_Query, |
|
288 | - $this |
|
289 | - ); |
|
290 | - } |
|
291 | - } |
|
292 | - } |
|
293 | - } |
|
294 | - } |
|
295 | - } |
|
296 | - } |
|
297 | - |
|
298 | - |
|
299 | - /** |
|
300 | - * @param \WP_Query $WP_Query |
|
301 | - * @throws InvalidArgumentException |
|
302 | - * @throws InvalidDataTypeException |
|
303 | - * @throws InvalidInterfaceException |
|
304 | - */ |
|
305 | - protected function _process_WP_Query_post_types(WP_Query $WP_Query) |
|
306 | - { |
|
307 | - if (isset($WP_Query->query_vars['post_type'])) { |
|
308 | - // loop thru post_types as array |
|
309 | - foreach ((array) $WP_Query->query_vars['post_type'] as $post_type) { |
|
310 | - // is current query for an EE CPT ? |
|
311 | - if (isset($this->_CPTs[ $post_type ])) { |
|
312 | - // is EE on or off ? |
|
313 | - if (EE_Maintenance_Mode::instance()->level()) { |
|
314 | - // reroute CPT template view to maintenance_mode.template.php |
|
315 | - if (! has_filter('template_include', array('EE_Maintenance_Mode', 'template_include'))) { |
|
316 | - add_filter('template_include', array('EE_Maintenance_Mode', 'template_include'), 99999); |
|
317 | - } |
|
318 | - if (has_filter('the_content', array(EE_Maintenance_Mode::instance(), 'the_content'))) { |
|
319 | - add_filter('the_content', array($this, 'inject_EE_shortcode_placeholder'), 1); |
|
320 | - } |
|
321 | - return; |
|
322 | - } |
|
323 | - $this->_generate_CptQueryModifier($WP_Query, $post_type); |
|
324 | - } |
|
325 | - } |
|
326 | - } |
|
327 | - } |
|
328 | - |
|
329 | - |
|
330 | - /** |
|
331 | - * @param \WP_Query $WP_Query |
|
332 | - * @param string $post_type |
|
333 | - * @throws InvalidArgumentException |
|
334 | - * @throws InvalidDataTypeException |
|
335 | - * @throws InvalidInterfaceException |
|
336 | - */ |
|
337 | - protected function _generate_CptQueryModifier(WP_Query $WP_Query, $post_type) |
|
338 | - { |
|
339 | - $this->query_modifier = LoaderFactory::getLoader()->getShared( |
|
340 | - 'EventEspresso\core\CPTs\CptQueryModifier', |
|
341 | - array( |
|
342 | - $post_type, |
|
343 | - $this->_CPTs[ $post_type ], |
|
344 | - $WP_Query, |
|
345 | - ) |
|
346 | - ); |
|
347 | - $this->_CPT_taxonomies = $this->query_modifier->taxonomies(); |
|
348 | - } |
|
349 | - |
|
350 | - |
|
351 | - /** |
|
352 | - * inject_EE_shortcode_placeholder |
|
353 | - * in order to display the M-Mode notice on our CPT routes, |
|
354 | - * we need to first inject what looks like one of our shortcodes, |
|
355 | - * so that it can be replaced with the actual M-Mode notice |
|
356 | - * |
|
357 | - * @return string |
|
358 | - */ |
|
359 | - public function inject_EE_shortcode_placeholder() |
|
360 | - { |
|
361 | - return '[ESPRESSO_'; |
|
362 | - } |
|
363 | - |
|
364 | - |
|
365 | - /** |
|
366 | - * @deprecated |
|
367 | - * @since 4.8.41 |
|
368 | - * @return void |
|
369 | - */ |
|
370 | - public function _possibly_set_ee_request_var() |
|
371 | - { |
|
372 | - $this->query_modifier->setRequestVarsIfCpt(); |
|
373 | - } |
|
374 | - |
|
375 | - |
|
376 | - /** |
|
377 | - * @deprecated |
|
378 | - * @since 4.8.41 |
|
379 | - * @param $SQL |
|
380 | - * @return string |
|
381 | - */ |
|
382 | - public function posts_fields($SQL) |
|
383 | - { |
|
384 | - if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) { |
|
385 | - return $this->query_modifier->postsFields($SQL); |
|
386 | - } |
|
387 | - return $SQL; |
|
388 | - } |
|
389 | - |
|
390 | - |
|
391 | - /** |
|
392 | - * @deprecated |
|
393 | - * @since 4.8.41 |
|
394 | - * @param $SQL |
|
395 | - * @return string |
|
396 | - */ |
|
397 | - public function posts_join($SQL) |
|
398 | - { |
|
399 | - if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) { |
|
400 | - return $this->query_modifier->postsJoin($SQL); |
|
401 | - } |
|
402 | - return $SQL; |
|
403 | - } |
|
404 | - |
|
405 | - |
|
406 | - /** |
|
407 | - * @deprecated |
|
408 | - * @since 4.8.41 |
|
409 | - * @param \WP_Post[] $posts |
|
410 | - * @return \WP_Post[] |
|
411 | - */ |
|
412 | - public function the_posts($posts) |
|
413 | - { |
|
414 | - if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) { |
|
415 | - $this->query_modifier->thePosts($posts); |
|
416 | - } |
|
417 | - return $posts; |
|
418 | - } |
|
419 | - |
|
420 | - |
|
421 | - /** |
|
422 | - * @deprecated |
|
423 | - * @since 4.8.41 |
|
424 | - * @param $url |
|
425 | - * @param $ID |
|
426 | - * @return string |
|
427 | - */ |
|
428 | - public function get_edit_post_link($url, $ID) |
|
429 | - { |
|
430 | - if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) { |
|
431 | - return $this->query_modifier->getEditPostLink($url, $ID); |
|
432 | - } |
|
433 | - return ''; |
|
434 | - } |
|
435 | - |
|
436 | - |
|
437 | - /** |
|
438 | - * @deprecated |
|
439 | - * @since 4.8.41 |
|
440 | - * @param null $WP_Query |
|
441 | - */ |
|
442 | - protected function _do_template_filters($WP_Query = null) |
|
443 | - { |
|
444 | - if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) { |
|
445 | - $this->query_modifier->addTemplateFilters(); |
|
446 | - } |
|
447 | - } |
|
448 | - |
|
449 | - |
|
450 | - /** |
|
451 | - * @deprecated |
|
452 | - * @since 4.8.41 |
|
453 | - * @param string $current_template Existing default template path derived for this page call. |
|
454 | - * @return string the path to the full template file. |
|
455 | - */ |
|
456 | - public function single_cpt_template($current_template) |
|
457 | - { |
|
458 | - if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) { |
|
459 | - return $this->query_modifier->singleCptTemplate($current_template); |
|
460 | - } |
|
461 | - return $current_template; |
|
462 | - } |
|
18 | + /** |
|
19 | + * @var EE_CPT_Strategy $_instance |
|
20 | + */ |
|
21 | + private static $_instance; |
|
22 | + |
|
23 | + /** |
|
24 | + * the current page, if it utilizes CPTs |
|
25 | + * |
|
26 | + * @var array $CPT |
|
27 | + */ |
|
28 | + protected $CPT; |
|
29 | + |
|
30 | + /** |
|
31 | + * return value from CustomPostTypeDefinitions::getDefinitions() |
|
32 | + * |
|
33 | + * @var array $_CPTs |
|
34 | + */ |
|
35 | + protected $_CPTs = array(); |
|
36 | + |
|
37 | + /** |
|
38 | + * @var array $_CPT_taxonomies |
|
39 | + */ |
|
40 | + protected $_CPT_taxonomies = array(); |
|
41 | + |
|
42 | + /** |
|
43 | + * @var array $_CPT_terms |
|
44 | + */ |
|
45 | + protected $_CPT_terms = array(); |
|
46 | + |
|
47 | + /** |
|
48 | + * @var array $_CPT_endpoints |
|
49 | + */ |
|
50 | + protected $_CPT_endpoints = array(); |
|
51 | + |
|
52 | + /** |
|
53 | + * @var EEM_Base $CPT_model |
|
54 | + */ |
|
55 | + protected $CPT_model; |
|
56 | + |
|
57 | + /** |
|
58 | + * @var EventEspresso\Core\CPTs\CptQueryModifier $query_modifier |
|
59 | + */ |
|
60 | + protected $query_modifier; |
|
61 | + |
|
62 | + |
|
63 | + /** |
|
64 | + * @singleton method used to instantiate class object |
|
65 | + * @param CustomPostTypeDefinitions|null $custom_post_types |
|
66 | + * @param CustomTaxonomyDefinitions|null $taxonomies |
|
67 | + * @return EE_CPT_Strategy |
|
68 | + */ |
|
69 | + public static function instance( |
|
70 | + CustomPostTypeDefinitions $custom_post_types = null, |
|
71 | + CustomTaxonomyDefinitions $taxonomies = null |
|
72 | + ) { |
|
73 | + // check if class object is instantiated |
|
74 | + if ( |
|
75 | + ! self::$_instance instanceof EE_CPT_Strategy |
|
76 | + && $custom_post_types instanceof CustomPostTypeDefinitions |
|
77 | + && $taxonomies instanceof CustomTaxonomyDefinitions |
|
78 | + ) { |
|
79 | + self::$_instance = new self($custom_post_types, $taxonomies); |
|
80 | + } |
|
81 | + return self::$_instance; |
|
82 | + } |
|
83 | + |
|
84 | + |
|
85 | + /** |
|
86 | + * @param CustomPostTypeDefinitions $custom_post_types |
|
87 | + * @param CustomTaxonomyDefinitions $taxonomies |
|
88 | + */ |
|
89 | + protected function __construct( |
|
90 | + CustomPostTypeDefinitions $custom_post_types, |
|
91 | + CustomTaxonomyDefinitions $taxonomies |
|
92 | + ) { |
|
93 | + // get CPT data |
|
94 | + $this->_CPTs = $custom_post_types->getDefinitions(); |
|
95 | + $this->_CPT_endpoints = $this->_set_CPT_endpoints(); |
|
96 | + $this->_CPT_taxonomies = $taxonomies->getCustomTaxonomyDefinitions(); |
|
97 | + add_action('pre_get_posts', array($this, 'pre_get_posts'), 5); |
|
98 | + } |
|
99 | + |
|
100 | + |
|
101 | + /** |
|
102 | + * @return array |
|
103 | + */ |
|
104 | + public function get_CPT_endpoints() |
|
105 | + { |
|
106 | + return $this->_CPT_endpoints; |
|
107 | + } |
|
108 | + |
|
109 | + |
|
110 | + /** |
|
111 | + * @return array |
|
112 | + */ |
|
113 | + public function get_CPT_taxonomies() |
|
114 | + { |
|
115 | + return $this->_CPT_taxonomies; |
|
116 | + } |
|
117 | + |
|
118 | + |
|
119 | + /** |
|
120 | + * add CPT "slugs" to array of default espresso "pages" |
|
121 | + * |
|
122 | + * @return array |
|
123 | + */ |
|
124 | + private function _set_CPT_endpoints() |
|
125 | + { |
|
126 | + $_CPT_endpoints = array(); |
|
127 | + if (is_array($this->_CPTs)) { |
|
128 | + foreach ($this->_CPTs as $CPT_type => $CPT) { |
|
129 | + if (isset($CPT['plural_slug'])) { |
|
130 | + $_CPT_endpoints [ (string) $CPT['plural_slug'] ] = $CPT_type; |
|
131 | + } |
|
132 | + } |
|
133 | + } |
|
134 | + return $_CPT_endpoints; |
|
135 | + } |
|
136 | + |
|
137 | + |
|
138 | + /** |
|
139 | + * If this query (not just "main" queries (ie, for WP's infamous "loop")) is for an EE CPT, then we want to |
|
140 | + * supercharge the get_posts query to add our EE stuff (like joining to our tables, selecting extra columns, and |
|
141 | + * adding EE objects to the post to facilitate further querying of related data etc) |
|
142 | + * |
|
143 | + * @param WP_Query $WP_Query |
|
144 | + * @return void |
|
145 | + * @throws \EE_Error |
|
146 | + * @throws \InvalidArgumentException |
|
147 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
148 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
149 | + */ |
|
150 | + public function pre_get_posts($WP_Query) |
|
151 | + { |
|
152 | + // check that post-type is set |
|
153 | + if (! $WP_Query instanceof WP_Query) { |
|
154 | + return; |
|
155 | + } |
|
156 | + // add our conditionals |
|
157 | + $this->_set_EE_tags_on_WP_Query($WP_Query); |
|
158 | + // check for terms |
|
159 | + $this->_set_post_type_for_terms($WP_Query); |
|
160 | + // make sure paging is always set |
|
161 | + $this->_set_paging($WP_Query); |
|
162 | + // is a taxonomy set ? |
|
163 | + $this->_set_CPT_taxonomies_on_WP_Query($WP_Query); |
|
164 | + // loop thru post_types if set |
|
165 | + $this->_process_WP_Query_post_types($WP_Query); |
|
166 | + } |
|
167 | + |
|
168 | + |
|
169 | + /** |
|
170 | + * @param WP_Query $WP_Query |
|
171 | + * @return void |
|
172 | + */ |
|
173 | + private function _set_EE_tags_on_WP_Query(WP_Query $WP_Query) |
|
174 | + { |
|
175 | + $WP_Query->is_espresso_event_single = false; |
|
176 | + $WP_Query->is_espresso_event_archive = false; |
|
177 | + $WP_Query->is_espresso_event_taxonomy = false; |
|
178 | + $WP_Query->is_espresso_venue_single = false; |
|
179 | + $WP_Query->is_espresso_venue_archive = false; |
|
180 | + $WP_Query->is_espresso_venue_taxonomy = false; |
|
181 | + } |
|
182 | + |
|
183 | + |
|
184 | + /** |
|
185 | + * @return void |
|
186 | + * @throws EE_Error |
|
187 | + * @throws InvalidArgumentException |
|
188 | + * @throws InvalidDataTypeException |
|
189 | + * @throws InvalidInterfaceException |
|
190 | + */ |
|
191 | + private function _set_CPT_terms() |
|
192 | + { |
|
193 | + if (empty($this->_CPT_terms)) { |
|
194 | + $terms = EEM_Term::instance()->get_all_CPT_post_tags(); |
|
195 | + foreach ($terms as $term) { |
|
196 | + if ($term instanceof EE_Term) { |
|
197 | + $this->_CPT_terms[ $term->slug() ] = $term; |
|
198 | + } |
|
199 | + } |
|
200 | + } |
|
201 | + } |
|
202 | + |
|
203 | + |
|
204 | + /** |
|
205 | + * @param WP_Query $WP_Query |
|
206 | + * @return void |
|
207 | + * @throws EE_Error |
|
208 | + * @throws InvalidArgumentException |
|
209 | + * @throws InvalidDataTypeException |
|
210 | + * @throws InvalidInterfaceException |
|
211 | + */ |
|
212 | + private function _set_post_type_for_terms(WP_Query $WP_Query) |
|
213 | + { |
|
214 | + // is a tag set ? |
|
215 | + if (isset($WP_Query->query['tag'])) { |
|
216 | + // get term for tag |
|
217 | + $term = EEM_Term::instance()->get_post_tag_for_event_or_venue($WP_Query->query['tag']); |
|
218 | + // verify the term |
|
219 | + if ($term instanceof EE_Term) { |
|
220 | + $term->post_type = array_merge(array('post', 'page'), (array) $term->post_type); |
|
221 | + $term->post_type = apply_filters( |
|
222 | + 'FHEE__EE_CPT_Strategy___set_post_type_for_terms__term_post_type', |
|
223 | + $term->post_type, |
|
224 | + $term |
|
225 | + ); |
|
226 | + // if a post type is already set |
|
227 | + if (isset($WP_Query->query_vars['post_type'])) { |
|
228 | + // add to existing array |
|
229 | + $term->post_type = array_merge((array) $WP_Query->query_vars['post_type'], $term->post_type); |
|
230 | + } |
|
231 | + // just set post_type to our CPT |
|
232 | + $WP_Query->set('post_type', array_unique($term->post_type)); |
|
233 | + } |
|
234 | + } |
|
235 | + } |
|
236 | + |
|
237 | + |
|
238 | + /** |
|
239 | + * @param WP_Query $WP_Query |
|
240 | + * @return void |
|
241 | + */ |
|
242 | + public function _set_paging($WP_Query) |
|
243 | + { |
|
244 | + if ($WP_Query->is_main_query() && apply_filters('FHEE__EE_CPT_Strategy___set_paging', true)) { |
|
245 | + $page = get_query_var('page') ? get_query_var('page') : null; |
|
246 | + $paged = get_query_var('paged') ? get_query_var('paged') : $page; |
|
247 | + $WP_Query->set('paged', $paged); |
|
248 | + } |
|
249 | + } |
|
250 | + |
|
251 | + |
|
252 | + /** |
|
253 | + * @param \WP_Query $WP_Query |
|
254 | + */ |
|
255 | + protected function _set_CPT_taxonomies_on_WP_Query(WP_Query $WP_Query) |
|
256 | + { |
|
257 | + // is a taxonomy set ? |
|
258 | + if ($WP_Query->is_tax) { |
|
259 | + // loop thru our taxonomies |
|
260 | + foreach ($this->_CPT_taxonomies as $CPT_taxonomy => $CPT_taxonomy_details) { |
|
261 | + // check if one of our taxonomies is set as a query var |
|
262 | + if (isset($WP_Query->query[ $CPT_taxonomy ])) { |
|
263 | + // but which CPT does that correspond to??? hmmm... guess we gotta go looping |
|
264 | + foreach ($this->_CPTs as $post_type => $CPT) { |
|
265 | + // verify our CPT has args, is public and has taxonomies set |
|
266 | + if ( |
|
267 | + isset($CPT['args']['public']) |
|
268 | + && $CPT['args']['public'] |
|
269 | + && ! empty($CPT['args']['taxonomies']) |
|
270 | + && in_array($CPT_taxonomy, $CPT['args']['taxonomies'], true) |
|
271 | + ) { |
|
272 | + // if so, then add this CPT post_type to the current query's array of post_types' |
|
273 | + $WP_Query->query_vars['post_type'] = isset($WP_Query->query_vars['post_type']) |
|
274 | + ? (array) $WP_Query->query_vars['post_type'] |
|
275 | + : array(); |
|
276 | + $WP_Query->query_vars['post_type'][] = $post_type; |
|
277 | + switch ($post_type) { |
|
278 | + case 'espresso_events': |
|
279 | + $WP_Query->is_espresso_event_taxonomy = true; |
|
280 | + break; |
|
281 | + case 'espresso_venues': |
|
282 | + $WP_Query->is_espresso_venue_taxonomy = true; |
|
283 | + break; |
|
284 | + default: |
|
285 | + do_action( |
|
286 | + 'AHEE__EE_CPT_Strategy___set_CPT_taxonomies_on_WP_Query__for_' . $post_type . '_post_type', |
|
287 | + $WP_Query, |
|
288 | + $this |
|
289 | + ); |
|
290 | + } |
|
291 | + } |
|
292 | + } |
|
293 | + } |
|
294 | + } |
|
295 | + } |
|
296 | + } |
|
297 | + |
|
298 | + |
|
299 | + /** |
|
300 | + * @param \WP_Query $WP_Query |
|
301 | + * @throws InvalidArgumentException |
|
302 | + * @throws InvalidDataTypeException |
|
303 | + * @throws InvalidInterfaceException |
|
304 | + */ |
|
305 | + protected function _process_WP_Query_post_types(WP_Query $WP_Query) |
|
306 | + { |
|
307 | + if (isset($WP_Query->query_vars['post_type'])) { |
|
308 | + // loop thru post_types as array |
|
309 | + foreach ((array) $WP_Query->query_vars['post_type'] as $post_type) { |
|
310 | + // is current query for an EE CPT ? |
|
311 | + if (isset($this->_CPTs[ $post_type ])) { |
|
312 | + // is EE on or off ? |
|
313 | + if (EE_Maintenance_Mode::instance()->level()) { |
|
314 | + // reroute CPT template view to maintenance_mode.template.php |
|
315 | + if (! has_filter('template_include', array('EE_Maintenance_Mode', 'template_include'))) { |
|
316 | + add_filter('template_include', array('EE_Maintenance_Mode', 'template_include'), 99999); |
|
317 | + } |
|
318 | + if (has_filter('the_content', array(EE_Maintenance_Mode::instance(), 'the_content'))) { |
|
319 | + add_filter('the_content', array($this, 'inject_EE_shortcode_placeholder'), 1); |
|
320 | + } |
|
321 | + return; |
|
322 | + } |
|
323 | + $this->_generate_CptQueryModifier($WP_Query, $post_type); |
|
324 | + } |
|
325 | + } |
|
326 | + } |
|
327 | + } |
|
328 | + |
|
329 | + |
|
330 | + /** |
|
331 | + * @param \WP_Query $WP_Query |
|
332 | + * @param string $post_type |
|
333 | + * @throws InvalidArgumentException |
|
334 | + * @throws InvalidDataTypeException |
|
335 | + * @throws InvalidInterfaceException |
|
336 | + */ |
|
337 | + protected function _generate_CptQueryModifier(WP_Query $WP_Query, $post_type) |
|
338 | + { |
|
339 | + $this->query_modifier = LoaderFactory::getLoader()->getShared( |
|
340 | + 'EventEspresso\core\CPTs\CptQueryModifier', |
|
341 | + array( |
|
342 | + $post_type, |
|
343 | + $this->_CPTs[ $post_type ], |
|
344 | + $WP_Query, |
|
345 | + ) |
|
346 | + ); |
|
347 | + $this->_CPT_taxonomies = $this->query_modifier->taxonomies(); |
|
348 | + } |
|
349 | + |
|
350 | + |
|
351 | + /** |
|
352 | + * inject_EE_shortcode_placeholder |
|
353 | + * in order to display the M-Mode notice on our CPT routes, |
|
354 | + * we need to first inject what looks like one of our shortcodes, |
|
355 | + * so that it can be replaced with the actual M-Mode notice |
|
356 | + * |
|
357 | + * @return string |
|
358 | + */ |
|
359 | + public function inject_EE_shortcode_placeholder() |
|
360 | + { |
|
361 | + return '[ESPRESSO_'; |
|
362 | + } |
|
363 | + |
|
364 | + |
|
365 | + /** |
|
366 | + * @deprecated |
|
367 | + * @since 4.8.41 |
|
368 | + * @return void |
|
369 | + */ |
|
370 | + public function _possibly_set_ee_request_var() |
|
371 | + { |
|
372 | + $this->query_modifier->setRequestVarsIfCpt(); |
|
373 | + } |
|
374 | + |
|
375 | + |
|
376 | + /** |
|
377 | + * @deprecated |
|
378 | + * @since 4.8.41 |
|
379 | + * @param $SQL |
|
380 | + * @return string |
|
381 | + */ |
|
382 | + public function posts_fields($SQL) |
|
383 | + { |
|
384 | + if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) { |
|
385 | + return $this->query_modifier->postsFields($SQL); |
|
386 | + } |
|
387 | + return $SQL; |
|
388 | + } |
|
389 | + |
|
390 | + |
|
391 | + /** |
|
392 | + * @deprecated |
|
393 | + * @since 4.8.41 |
|
394 | + * @param $SQL |
|
395 | + * @return string |
|
396 | + */ |
|
397 | + public function posts_join($SQL) |
|
398 | + { |
|
399 | + if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) { |
|
400 | + return $this->query_modifier->postsJoin($SQL); |
|
401 | + } |
|
402 | + return $SQL; |
|
403 | + } |
|
404 | + |
|
405 | + |
|
406 | + /** |
|
407 | + * @deprecated |
|
408 | + * @since 4.8.41 |
|
409 | + * @param \WP_Post[] $posts |
|
410 | + * @return \WP_Post[] |
|
411 | + */ |
|
412 | + public function the_posts($posts) |
|
413 | + { |
|
414 | + if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) { |
|
415 | + $this->query_modifier->thePosts($posts); |
|
416 | + } |
|
417 | + return $posts; |
|
418 | + } |
|
419 | + |
|
420 | + |
|
421 | + /** |
|
422 | + * @deprecated |
|
423 | + * @since 4.8.41 |
|
424 | + * @param $url |
|
425 | + * @param $ID |
|
426 | + * @return string |
|
427 | + */ |
|
428 | + public function get_edit_post_link($url, $ID) |
|
429 | + { |
|
430 | + if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) { |
|
431 | + return $this->query_modifier->getEditPostLink($url, $ID); |
|
432 | + } |
|
433 | + return ''; |
|
434 | + } |
|
435 | + |
|
436 | + |
|
437 | + /** |
|
438 | + * @deprecated |
|
439 | + * @since 4.8.41 |
|
440 | + * @param null $WP_Query |
|
441 | + */ |
|
442 | + protected function _do_template_filters($WP_Query = null) |
|
443 | + { |
|
444 | + if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) { |
|
445 | + $this->query_modifier->addTemplateFilters(); |
|
446 | + } |
|
447 | + } |
|
448 | + |
|
449 | + |
|
450 | + /** |
|
451 | + * @deprecated |
|
452 | + * @since 4.8.41 |
|
453 | + * @param string $current_template Existing default template path derived for this page call. |
|
454 | + * @return string the path to the full template file. |
|
455 | + */ |
|
456 | + public function single_cpt_template($current_template) |
|
457 | + { |
|
458 | + if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) { |
|
459 | + return $this->query_modifier->singleCptTemplate($current_template); |
|
460 | + } |
|
461 | + return $current_template; |
|
462 | + } |
|
463 | 463 | } |
@@ -122,13 +122,13 @@ discard block |
||
122 | 122 | ) |
123 | 123 | ) { |
124 | 124 | // adds something like ", wp_esp_datetime.* " to WP Query SELECT statement |
125 | - $SQL .= ', ' . EEM_Datetime::instance()->table() . '.* '; |
|
125 | + $SQL .= ', '.EEM_Datetime::instance()->table().'.* '; |
|
126 | 126 | if ($wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy) { |
127 | 127 | // because we only want to retrieve the next upcoming datetime for each event: |
128 | 128 | // add something like: |
129 | 129 | // ", MIN( wp_esp_datetime.DTT_EVT_start ) as event_start_date " |
130 | 130 | // to WP Query SELECT statement |
131 | - $SQL .= ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date '; |
|
131 | + $SQL .= ', MIN( '.EEM_Datetime::instance()->table().'.DTT_EVT_start ) as event_start_date '; |
|
132 | 132 | } |
133 | 133 | } |
134 | 134 | return $SQL; |
@@ -158,9 +158,9 @@ discard block |
||
158 | 158 | // adds something like: |
159 | 159 | // " LEFT JOIN wp_esp_datetime ON ( wp_esp_datetime.EVT_ID = wp_posts.ID ) " |
160 | 160 | // to WP Query JOIN statement |
161 | - $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . EEM_Event::instance()->table() |
|
162 | - . '.ID = ' . EEM_Datetime::instance()->table() . '.' |
|
163 | - . EEM_Event::instance()->primary_key_name() . ' ) '; |
|
161 | + $SQL .= ' INNER JOIN '.EEM_Datetime::instance()->table().' ON ( '.EEM_Event::instance()->table() |
|
162 | + . '.ID = '.EEM_Datetime::instance()->table().'.' |
|
163 | + . EEM_Event::instance()->primary_key_name().' ) '; |
|
164 | 164 | } |
165 | 165 | return $SQL; |
166 | 166 | } |
@@ -190,8 +190,8 @@ discard block |
||
190 | 190 | || ! isset(EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events) |
191 | 191 | || ! EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events |
192 | 192 | ) { |
193 | - $SQL .= ' AND ' . EEM_Datetime::instance()->table() . ".DTT_EVT_end > '" |
|
194 | - . current_time('mysql', true) . "' "; |
|
193 | + $SQL .= ' AND '.EEM_Datetime::instance()->table().".DTT_EVT_end > '" |
|
194 | + . current_time('mysql', true)."' "; |
|
195 | 195 | } |
196 | 196 | } |
197 | 197 | return $SQL; |
@@ -239,7 +239,7 @@ discard block |
||
239 | 239 | // but we want to only show each event only once |
240 | 240 | // (whereas if we didn't group them by the post's ID, then we would end up with many repeats) |
241 | 241 | global $wpdb; |
242 | - $SQL = $wpdb->posts . '.ID '; |
|
242 | + $SQL = $wpdb->posts.'.ID '; |
|
243 | 243 | } |
244 | 244 | return $SQL; |
245 | 245 | } |
@@ -12,258 +12,258 @@ |
||
12 | 12 | */ |
13 | 13 | class EE_CPT_Event_Strategy |
14 | 14 | { |
15 | - /** |
|
16 | - * the current page, if it utilizes CPTs |
|
17 | - * |
|
18 | - * @var object $CPT |
|
19 | - */ |
|
20 | - protected $CPT; |
|
15 | + /** |
|
16 | + * the current page, if it utilizes CPTs |
|
17 | + * |
|
18 | + * @var object $CPT |
|
19 | + */ |
|
20 | + protected $CPT; |
|
21 | 21 | |
22 | 22 | |
23 | - /** |
|
24 | - * @param WP_Query $wp_query |
|
25 | - * @param array $CPT |
|
26 | - */ |
|
27 | - public function __construct($wp_query, $CPT = array()) |
|
28 | - { |
|
29 | - if ($wp_query instanceof WP_Query) { |
|
30 | - $WP_Query = $wp_query; |
|
31 | - $this->CPT = $CPT; |
|
32 | - } else { |
|
33 | - $WP_Query = isset($wp_query['WP_Query']) ? $wp_query['WP_Query'] : null; |
|
34 | - $this->CPT = isset($wp_query['CPT']) ? $wp_query['CPT'] : null; |
|
35 | - } |
|
36 | - // !!!!!!!!!! IMPORTANT !!!!!!!!!!!! |
|
37 | - // here's the list of available filters in the WP_Query object |
|
38 | - // 'posts_where' |
|
39 | - // 'posts_where_paged' |
|
40 | - // 'posts_groupby' |
|
41 | - // 'posts_join_paged' |
|
42 | - // 'posts_orderby' |
|
43 | - // 'posts_distinct' |
|
44 | - // 'post_limits' |
|
45 | - // 'posts_fields' |
|
46 | - // 'posts_join' |
|
47 | - $this->_add_filters(); |
|
48 | - if ($WP_Query instanceof WP_Query) { |
|
49 | - $WP_Query->is_espresso_event_single = is_singular() |
|
50 | - && isset($WP_Query->query->post_type) |
|
51 | - && $WP_Query->query->post_type === 'espresso_events'; |
|
52 | - $WP_Query->is_espresso_event_archive = is_post_type_archive('espresso_events'); |
|
53 | - $WP_Query->is_espresso_event_taxonomy = is_tax('espresso_event_categories'); |
|
54 | - } |
|
55 | - } |
|
23 | + /** |
|
24 | + * @param WP_Query $wp_query |
|
25 | + * @param array $CPT |
|
26 | + */ |
|
27 | + public function __construct($wp_query, $CPT = array()) |
|
28 | + { |
|
29 | + if ($wp_query instanceof WP_Query) { |
|
30 | + $WP_Query = $wp_query; |
|
31 | + $this->CPT = $CPT; |
|
32 | + } else { |
|
33 | + $WP_Query = isset($wp_query['WP_Query']) ? $wp_query['WP_Query'] : null; |
|
34 | + $this->CPT = isset($wp_query['CPT']) ? $wp_query['CPT'] : null; |
|
35 | + } |
|
36 | + // !!!!!!!!!! IMPORTANT !!!!!!!!!!!! |
|
37 | + // here's the list of available filters in the WP_Query object |
|
38 | + // 'posts_where' |
|
39 | + // 'posts_where_paged' |
|
40 | + // 'posts_groupby' |
|
41 | + // 'posts_join_paged' |
|
42 | + // 'posts_orderby' |
|
43 | + // 'posts_distinct' |
|
44 | + // 'post_limits' |
|
45 | + // 'posts_fields' |
|
46 | + // 'posts_join' |
|
47 | + $this->_add_filters(); |
|
48 | + if ($WP_Query instanceof WP_Query) { |
|
49 | + $WP_Query->is_espresso_event_single = is_singular() |
|
50 | + && isset($WP_Query->query->post_type) |
|
51 | + && $WP_Query->query->post_type === 'espresso_events'; |
|
52 | + $WP_Query->is_espresso_event_archive = is_post_type_archive('espresso_events'); |
|
53 | + $WP_Query->is_espresso_event_taxonomy = is_tax('espresso_event_categories'); |
|
54 | + } |
|
55 | + } |
|
56 | 56 | |
57 | 57 | |
58 | - /** |
|
59 | - * When an instance of this class is created, we add our filters |
|
60 | - * (which will get removed in case the next call to get_posts ISN'T |
|
61 | - * for event CPTs) |
|
62 | - */ |
|
63 | - protected function _add_filters() |
|
64 | - { |
|
65 | - add_filter('posts_fields', array($this, 'posts_fields'), 1, 2); |
|
66 | - add_filter('posts_join', array($this, 'posts_join'), 1, 2); |
|
67 | - add_filter('posts_where', array($this, 'posts_where'), 10, 2); |
|
68 | - // add_filter( 'the_posts', array( $this, 'the_posts' ), 1, 2 ); |
|
69 | - add_filter('posts_orderby', array($this, 'posts_orderby'), 1, 2); |
|
70 | - add_filter('posts_groupby', array($this, 'posts_groupby'), 1, 2); |
|
71 | - add_action('posts_selection', array($this, 'remove_filters')); |
|
72 | - } |
|
58 | + /** |
|
59 | + * When an instance of this class is created, we add our filters |
|
60 | + * (which will get removed in case the next call to get_posts ISN'T |
|
61 | + * for event CPTs) |
|
62 | + */ |
|
63 | + protected function _add_filters() |
|
64 | + { |
|
65 | + add_filter('posts_fields', array($this, 'posts_fields'), 1, 2); |
|
66 | + add_filter('posts_join', array($this, 'posts_join'), 1, 2); |
|
67 | + add_filter('posts_where', array($this, 'posts_where'), 10, 2); |
|
68 | + // add_filter( 'the_posts', array( $this, 'the_posts' ), 1, 2 ); |
|
69 | + add_filter('posts_orderby', array($this, 'posts_orderby'), 1, 2); |
|
70 | + add_filter('posts_groupby', array($this, 'posts_groupby'), 1, 2); |
|
71 | + add_action('posts_selection', array($this, 'remove_filters')); |
|
72 | + } |
|
73 | 73 | |
74 | 74 | |
75 | - /** |
|
76 | - * public access to _remove_filters() |
|
77 | - * |
|
78 | - * @since 4.9.63.p |
|
79 | - */ |
|
80 | - public function remove_filters() |
|
81 | - { |
|
82 | - $this->_remove_filters(); |
|
83 | - } |
|
75 | + /** |
|
76 | + * public access to _remove_filters() |
|
77 | + * |
|
78 | + * @since 4.9.63.p |
|
79 | + */ |
|
80 | + public function remove_filters() |
|
81 | + { |
|
82 | + $this->_remove_filters(); |
|
83 | + } |
|
84 | 84 | |
85 | 85 | |
86 | - /** |
|
87 | - * Should eb called when the last filter or hook is fired for this CPT strategy. |
|
88 | - * This is to avoid applying this CPT strategy for other posts or CPTs (eg, |
|
89 | - * we don't want to join to the datetime table when querying for venues, do we!?) |
|
90 | - */ |
|
91 | - protected function _remove_filters() |
|
92 | - { |
|
93 | - remove_filter('posts_fields', array($this, 'posts_fields'), 1); |
|
94 | - remove_filter('posts_join', array($this, 'posts_join'), 1); |
|
95 | - remove_filter('posts_where', array($this, 'posts_where'), 10); |
|
96 | - // remove_filter( 'the_posts', array( $this, 'the_posts' ), 1 ); |
|
97 | - remove_filter('posts_orderby', array($this, 'posts_orderby'), 1); |
|
98 | - remove_filter('posts_groupby', array($this, 'posts_groupby'), 1); |
|
99 | - remove_action('posts_selection', array($this, 'remove_filters')); |
|
100 | - } |
|
86 | + /** |
|
87 | + * Should eb called when the last filter or hook is fired for this CPT strategy. |
|
88 | + * This is to avoid applying this CPT strategy for other posts or CPTs (eg, |
|
89 | + * we don't want to join to the datetime table when querying for venues, do we!?) |
|
90 | + */ |
|
91 | + protected function _remove_filters() |
|
92 | + { |
|
93 | + remove_filter('posts_fields', array($this, 'posts_fields'), 1); |
|
94 | + remove_filter('posts_join', array($this, 'posts_join'), 1); |
|
95 | + remove_filter('posts_where', array($this, 'posts_where'), 10); |
|
96 | + // remove_filter( 'the_posts', array( $this, 'the_posts' ), 1 ); |
|
97 | + remove_filter('posts_orderby', array($this, 'posts_orderby'), 1); |
|
98 | + remove_filter('posts_groupby', array($this, 'posts_groupby'), 1); |
|
99 | + remove_action('posts_selection', array($this, 'remove_filters')); |
|
100 | + } |
|
101 | 101 | |
102 | 102 | |
103 | - /** |
|
104 | - * @param string $SQL |
|
105 | - * @param WP_Query $wp_query |
|
106 | - * @return string |
|
107 | - * @throws EE_Error |
|
108 | - * @throws InvalidArgumentException |
|
109 | - * @throws InvalidDataTypeException |
|
110 | - * @throws InvalidInterfaceException |
|
111 | - */ |
|
112 | - public function posts_fields($SQL, WP_Query $wp_query) |
|
113 | - { |
|
114 | - if ( |
|
115 | - $wp_query instanceof WP_Query |
|
116 | - && |
|
117 | - ( |
|
118 | - $wp_query->is_espresso_event_single |
|
119 | - || $wp_query->is_espresso_event_archive |
|
120 | - || $wp_query->is_espresso_event_taxonomy |
|
121 | - ) |
|
122 | - ) { |
|
123 | - // adds something like ", wp_esp_datetime.* " to WP Query SELECT statement |
|
124 | - $SQL .= ', ' . EEM_Datetime::instance()->table() . '.* '; |
|
125 | - if ($wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy) { |
|
126 | - // because we only want to retrieve the next upcoming datetime for each event: |
|
127 | - // add something like: |
|
128 | - // ", MIN( wp_esp_datetime.DTT_EVT_start ) as event_start_date " |
|
129 | - // to WP Query SELECT statement |
|
130 | - $SQL .= ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date '; |
|
131 | - } |
|
132 | - } |
|
133 | - return $SQL; |
|
134 | - } |
|
103 | + /** |
|
104 | + * @param string $SQL |
|
105 | + * @param WP_Query $wp_query |
|
106 | + * @return string |
|
107 | + * @throws EE_Error |
|
108 | + * @throws InvalidArgumentException |
|
109 | + * @throws InvalidDataTypeException |
|
110 | + * @throws InvalidInterfaceException |
|
111 | + */ |
|
112 | + public function posts_fields($SQL, WP_Query $wp_query) |
|
113 | + { |
|
114 | + if ( |
|
115 | + $wp_query instanceof WP_Query |
|
116 | + && |
|
117 | + ( |
|
118 | + $wp_query->is_espresso_event_single |
|
119 | + || $wp_query->is_espresso_event_archive |
|
120 | + || $wp_query->is_espresso_event_taxonomy |
|
121 | + ) |
|
122 | + ) { |
|
123 | + // adds something like ", wp_esp_datetime.* " to WP Query SELECT statement |
|
124 | + $SQL .= ', ' . EEM_Datetime::instance()->table() . '.* '; |
|
125 | + if ($wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy) { |
|
126 | + // because we only want to retrieve the next upcoming datetime for each event: |
|
127 | + // add something like: |
|
128 | + // ", MIN( wp_esp_datetime.DTT_EVT_start ) as event_start_date " |
|
129 | + // to WP Query SELECT statement |
|
130 | + $SQL .= ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date '; |
|
131 | + } |
|
132 | + } |
|
133 | + return $SQL; |
|
134 | + } |
|
135 | 135 | |
136 | 136 | |
137 | - /** |
|
138 | - * @param string $SQL |
|
139 | - * @param WP_Query $wp_query |
|
140 | - * @return string |
|
141 | - * @throws EE_Error |
|
142 | - * @throws InvalidArgumentException |
|
143 | - * @throws InvalidDataTypeException |
|
144 | - * @throws InvalidInterfaceException |
|
145 | - */ |
|
146 | - public function posts_join($SQL, WP_Query $wp_query) |
|
147 | - { |
|
148 | - if ( |
|
149 | - $wp_query instanceof WP_Query |
|
150 | - && |
|
151 | - ( |
|
152 | - $wp_query->is_espresso_event_single |
|
153 | - || $wp_query->is_espresso_event_archive |
|
154 | - || $wp_query->is_espresso_event_taxonomy |
|
155 | - ) |
|
156 | - ) { |
|
157 | - // adds something like: |
|
158 | - // " LEFT JOIN wp_esp_datetime ON ( wp_esp_datetime.EVT_ID = wp_posts.ID ) " |
|
159 | - // to WP Query JOIN statement |
|
160 | - $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . EEM_Event::instance()->table() |
|
161 | - . '.ID = ' . EEM_Datetime::instance()->table() . '.' |
|
162 | - . EEM_Event::instance()->primary_key_name() . ' ) '; |
|
163 | - } |
|
164 | - return $SQL; |
|
165 | - } |
|
137 | + /** |
|
138 | + * @param string $SQL |
|
139 | + * @param WP_Query $wp_query |
|
140 | + * @return string |
|
141 | + * @throws EE_Error |
|
142 | + * @throws InvalidArgumentException |
|
143 | + * @throws InvalidDataTypeException |
|
144 | + * @throws InvalidInterfaceException |
|
145 | + */ |
|
146 | + public function posts_join($SQL, WP_Query $wp_query) |
|
147 | + { |
|
148 | + if ( |
|
149 | + $wp_query instanceof WP_Query |
|
150 | + && |
|
151 | + ( |
|
152 | + $wp_query->is_espresso_event_single |
|
153 | + || $wp_query->is_espresso_event_archive |
|
154 | + || $wp_query->is_espresso_event_taxonomy |
|
155 | + ) |
|
156 | + ) { |
|
157 | + // adds something like: |
|
158 | + // " LEFT JOIN wp_esp_datetime ON ( wp_esp_datetime.EVT_ID = wp_posts.ID ) " |
|
159 | + // to WP Query JOIN statement |
|
160 | + $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . EEM_Event::instance()->table() |
|
161 | + . '.ID = ' . EEM_Datetime::instance()->table() . '.' |
|
162 | + . EEM_Event::instance()->primary_key_name() . ' ) '; |
|
163 | + } |
|
164 | + return $SQL; |
|
165 | + } |
|
166 | 166 | |
167 | 167 | |
168 | - /** |
|
169 | - * @param string $SQL |
|
170 | - * @param WP_Query $wp_query |
|
171 | - * @return string |
|
172 | - * @throws EE_Error |
|
173 | - * @throws InvalidArgumentException |
|
174 | - * @throws InvalidDataTypeException |
|
175 | - * @throws InvalidInterfaceException |
|
176 | - */ |
|
177 | - public function posts_where($SQL, WP_Query $wp_query) |
|
178 | - { |
|
179 | - if ( |
|
180 | - $wp_query instanceof WP_Query |
|
181 | - && |
|
182 | - ( |
|
183 | - $wp_query->is_espresso_event_archive |
|
184 | - || $wp_query->is_espresso_event_taxonomy |
|
185 | - ) |
|
186 | - ) { |
|
187 | - if ( |
|
188 | - ! isset(EE_Registry::instance()->CFG->template_settings->EED_Events_Archive) |
|
189 | - || ! isset(EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events) |
|
190 | - || ! EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events |
|
191 | - ) { |
|
192 | - $SQL .= ' AND ' . EEM_Datetime::instance()->table() . ".DTT_EVT_end > '" |
|
193 | - . current_time('mysql', true) . "' "; |
|
194 | - } |
|
195 | - } |
|
196 | - return $SQL; |
|
197 | - } |
|
168 | + /** |
|
169 | + * @param string $SQL |
|
170 | + * @param WP_Query $wp_query |
|
171 | + * @return string |
|
172 | + * @throws EE_Error |
|
173 | + * @throws InvalidArgumentException |
|
174 | + * @throws InvalidDataTypeException |
|
175 | + * @throws InvalidInterfaceException |
|
176 | + */ |
|
177 | + public function posts_where($SQL, WP_Query $wp_query) |
|
178 | + { |
|
179 | + if ( |
|
180 | + $wp_query instanceof WP_Query |
|
181 | + && |
|
182 | + ( |
|
183 | + $wp_query->is_espresso_event_archive |
|
184 | + || $wp_query->is_espresso_event_taxonomy |
|
185 | + ) |
|
186 | + ) { |
|
187 | + if ( |
|
188 | + ! isset(EE_Registry::instance()->CFG->template_settings->EED_Events_Archive) |
|
189 | + || ! isset(EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events) |
|
190 | + || ! EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events |
|
191 | + ) { |
|
192 | + $SQL .= ' AND ' . EEM_Datetime::instance()->table() . ".DTT_EVT_end > '" |
|
193 | + . current_time('mysql', true) . "' "; |
|
194 | + } |
|
195 | + } |
|
196 | + return $SQL; |
|
197 | + } |
|
198 | 198 | |
199 | 199 | |
200 | - /** |
|
201 | - * @param string $SQL |
|
202 | - * @param WP_Query $wp_query |
|
203 | - * @return string |
|
204 | - */ |
|
205 | - public function posts_orderby($SQL, WP_Query $wp_query) |
|
206 | - { |
|
207 | - if ( |
|
208 | - $wp_query instanceof WP_Query |
|
209 | - && |
|
210 | - ( |
|
211 | - $wp_query->is_espresso_event_archive |
|
212 | - || $wp_query->is_espresso_event_taxonomy |
|
213 | - ) |
|
214 | - ) { |
|
215 | - $SQL = ' event_start_date ASC '; |
|
216 | - } |
|
217 | - return $SQL; |
|
218 | - } |
|
200 | + /** |
|
201 | + * @param string $SQL |
|
202 | + * @param WP_Query $wp_query |
|
203 | + * @return string |
|
204 | + */ |
|
205 | + public function posts_orderby($SQL, WP_Query $wp_query) |
|
206 | + { |
|
207 | + if ( |
|
208 | + $wp_query instanceof WP_Query |
|
209 | + && |
|
210 | + ( |
|
211 | + $wp_query->is_espresso_event_archive |
|
212 | + || $wp_query->is_espresso_event_taxonomy |
|
213 | + ) |
|
214 | + ) { |
|
215 | + $SQL = ' event_start_date ASC '; |
|
216 | + } |
|
217 | + return $SQL; |
|
218 | + } |
|
219 | 219 | |
220 | 220 | |
221 | - /** |
|
222 | - * @param string $SQL |
|
223 | - * @param WP_Query $wp_query |
|
224 | - * @return string |
|
225 | - */ |
|
226 | - public function posts_groupby($SQL, WP_Query $wp_query) |
|
227 | - { |
|
228 | - if ( |
|
229 | - $wp_query instanceof WP_Query |
|
230 | - && |
|
231 | - ( |
|
232 | - $wp_query->is_espresso_event_archive |
|
233 | - || $wp_query->is_espresso_event_taxonomy |
|
234 | - ) |
|
235 | - ) { |
|
236 | - // TODO: add event list option for displaying ALL datetimes in event list or only primary datetime (default) |
|
237 | - // we're joining to the datetimes table, where there can be MANY datetimes for a single event, |
|
238 | - // but we want to only show each event only once |
|
239 | - // (whereas if we didn't group them by the post's ID, then we would end up with many repeats) |
|
240 | - global $wpdb; |
|
241 | - $SQL = $wpdb->posts . '.ID '; |
|
242 | - } |
|
243 | - return $SQL; |
|
244 | - } |
|
221 | + /** |
|
222 | + * @param string $SQL |
|
223 | + * @param WP_Query $wp_query |
|
224 | + * @return string |
|
225 | + */ |
|
226 | + public function posts_groupby($SQL, WP_Query $wp_query) |
|
227 | + { |
|
228 | + if ( |
|
229 | + $wp_query instanceof WP_Query |
|
230 | + && |
|
231 | + ( |
|
232 | + $wp_query->is_espresso_event_archive |
|
233 | + || $wp_query->is_espresso_event_taxonomy |
|
234 | + ) |
|
235 | + ) { |
|
236 | + // TODO: add event list option for displaying ALL datetimes in event list or only primary datetime (default) |
|
237 | + // we're joining to the datetimes table, where there can be MANY datetimes for a single event, |
|
238 | + // but we want to only show each event only once |
|
239 | + // (whereas if we didn't group them by the post's ID, then we would end up with many repeats) |
|
240 | + global $wpdb; |
|
241 | + $SQL = $wpdb->posts . '.ID '; |
|
242 | + } |
|
243 | + return $SQL; |
|
244 | + } |
|
245 | 245 | |
246 | 246 | |
247 | - /** |
|
248 | - * @param array $posts |
|
249 | - * @param WP_Query $wp_query |
|
250 | - * @return array |
|
251 | - */ |
|
252 | - public function the_posts($posts, WP_Query $wp_query) |
|
253 | - { |
|
254 | - return $posts; |
|
255 | - } |
|
247 | + /** |
|
248 | + * @param array $posts |
|
249 | + * @param WP_Query $wp_query |
|
250 | + * @return array |
|
251 | + */ |
|
252 | + public function the_posts($posts, WP_Query $wp_query) |
|
253 | + { |
|
254 | + return $posts; |
|
255 | + } |
|
256 | 256 | |
257 | 257 | |
258 | - /** |
|
259 | - * @param null $meta_value |
|
260 | - * @param $post_id |
|
261 | - * @param $meta_key |
|
262 | - * @param $single |
|
263 | - * @return string |
|
264 | - */ |
|
265 | - public function get_EE_post_type_metadata($meta_value = null, $post_id, $meta_key, $single) |
|
266 | - { |
|
267 | - return $meta_value; |
|
268 | - } |
|
258 | + /** |
|
259 | + * @param null $meta_value |
|
260 | + * @param $post_id |
|
261 | + * @param $meta_key |
|
262 | + * @param $single |
|
263 | + * @return string |
|
264 | + */ |
|
265 | + public function get_EE_post_type_metadata($meta_value = null, $post_id, $meta_key, $single) |
|
266 | + { |
|
267 | + return $meta_value; |
|
268 | + } |
|
269 | 269 | } |
@@ -80,7 +80,7 @@ discard block |
||
80 | 80 | $data = []; |
81 | 81 | if (empty($this->countries)) { |
82 | 82 | $this->data_version = $this->getCountrySubRegionDataVersion(); |
83 | - $data = $this->retrieveJsonData(self::REPO_URL . 'countries.json'); |
|
83 | + $data = $this->retrieveJsonData(self::REPO_URL.'countries.json'); |
|
84 | 84 | } |
85 | 85 | if (empty($data)) { |
86 | 86 | EE_Error::add_error( |
@@ -144,7 +144,7 @@ discard block |
||
144 | 144 | */ |
145 | 145 | private function processCountryData($CNT_ISO, $countries = array()) |
146 | 146 | { |
147 | - if (! empty($countries)) { |
|
147 | + if ( ! empty($countries)) { |
|
148 | 148 | foreach ($countries as $key => $country) { |
149 | 149 | if ( |
150 | 150 | $country instanceof stdClass |
@@ -153,7 +153,7 @@ discard block |
||
153 | 153 | && ! empty($country->filename) |
154 | 154 | ) { |
155 | 155 | $country->sub_regions = $this->retrieveJsonData( |
156 | - self::REPO_URL . 'countries/' . $country->filename . '.json' |
|
156 | + self::REPO_URL.'countries/'.$country->filename.'.json' |
|
157 | 157 | ); |
158 | 158 | return $this->saveSubRegionData($country, $country->sub_regions); |
159 | 159 | } |
@@ -215,7 +215,7 @@ discard block |
||
215 | 215 | foreach ($sub_regions as $sub_region) { |
216 | 216 | // remove country code from sub region code |
217 | 217 | $abbrev = str_replace( |
218 | - $country->code . '-', |
|
218 | + $country->code.'-', |
|
219 | 219 | '', |
220 | 220 | sanitize_text_field($sub_region->code) |
221 | 221 | ); |
@@ -25,252 +25,252 @@ |
||
25 | 25 | */ |
26 | 26 | class CountrySubRegionDao |
27 | 27 | { |
28 | - const REPO_URL = 'https://raw.githubusercontent.com/eventespresso/countries-and-subregions/master/'; |
|
28 | + const REPO_URL = 'https://raw.githubusercontent.com/eventespresso/countries-and-subregions/master/'; |
|
29 | 29 | |
30 | - const OPTION_NAME_COUNTRY_DATA_VERSION = 'espresso-country-sub-region-data-version'; |
|
30 | + const OPTION_NAME_COUNTRY_DATA_VERSION = 'espresso-country-sub-region-data-version'; |
|
31 | 31 | |
32 | - /** |
|
33 | - * @var EEM_State $state_model |
|
34 | - */ |
|
35 | - private $state_model; |
|
32 | + /** |
|
33 | + * @var EEM_State $state_model |
|
34 | + */ |
|
35 | + private $state_model; |
|
36 | 36 | |
37 | - /** |
|
38 | - * @var JsonValidator $json_validator |
|
39 | - */ |
|
40 | - private $json_validator; |
|
37 | + /** |
|
38 | + * @var JsonValidator $json_validator |
|
39 | + */ |
|
40 | + private $json_validator; |
|
41 | 41 | |
42 | - /** |
|
43 | - * @var string $data_version |
|
44 | - */ |
|
45 | - private $data_version; |
|
42 | + /** |
|
43 | + * @var string $data_version |
|
44 | + */ |
|
45 | + private $data_version; |
|
46 | 46 | |
47 | - /** |
|
48 | - * @var array $countries |
|
49 | - */ |
|
50 | - private $countries = array(); |
|
47 | + /** |
|
48 | + * @var array $countries |
|
49 | + */ |
|
50 | + private $countries = array(); |
|
51 | 51 | |
52 | 52 | |
53 | - /** |
|
54 | - * CountrySubRegionDao constructor. |
|
55 | - * |
|
56 | - * @param EEM_State $state_model |
|
57 | - * @param JsonValidator $json_validator |
|
58 | - */ |
|
59 | - public function __construct(EEM_State $state_model, JsonValidator $json_validator) |
|
60 | - { |
|
61 | - $this->state_model = $state_model; |
|
62 | - $this->json_validator = $json_validator; |
|
63 | - } |
|
53 | + /** |
|
54 | + * CountrySubRegionDao constructor. |
|
55 | + * |
|
56 | + * @param EEM_State $state_model |
|
57 | + * @param JsonValidator $json_validator |
|
58 | + */ |
|
59 | + public function __construct(EEM_State $state_model, JsonValidator $json_validator) |
|
60 | + { |
|
61 | + $this->state_model = $state_model; |
|
62 | + $this->json_validator = $json_validator; |
|
63 | + } |
|
64 | 64 | |
65 | 65 | |
66 | - /** |
|
67 | - * @param EE_Country $country_object |
|
68 | - * @return bool |
|
69 | - * @throws EE_Error |
|
70 | - * @throws InvalidArgumentException |
|
71 | - * @throws InvalidDataTypeException |
|
72 | - * @throws InvalidInterfaceException |
|
73 | - * @throws ReflectionException |
|
74 | - */ |
|
75 | - public function saveCountrySubRegions(EE_Country $country_object) |
|
76 | - { |
|
77 | - $CNT_ISO = $country_object->ID(); |
|
78 | - $has_sub_regions = $this->state_model->count(array(array('Country.CNT_ISO' => $CNT_ISO))); |
|
79 | - $data = []; |
|
80 | - if (empty($this->countries)) { |
|
81 | - $this->data_version = $this->getCountrySubRegionDataVersion(); |
|
82 | - $data = $this->retrieveJsonData(self::REPO_URL . 'countries.json'); |
|
83 | - } |
|
84 | - if (empty($data)) { |
|
85 | - EE_Error::add_error( |
|
86 | - 'Country Subregion Data could not be retrieved', |
|
87 | - __FILE__, |
|
88 | - __METHOD__, |
|
89 | - __LINE__ |
|
90 | - ); |
|
91 | - } |
|
92 | - if ( |
|
93 | - ! $has_sub_regions |
|
94 | - || (isset($data->version) && version_compare($data->version, $this->data_version)) |
|
95 | - ) { |
|
96 | - if ( |
|
97 | - isset($data->countries) |
|
98 | - && $this->processCountryData($CNT_ISO, $data->countries) > 0 |
|
99 | - ) { |
|
100 | - $this->countries = $data->countries; |
|
101 | - $this->updateCountrySubRegionDataVersion($data->version); |
|
102 | - return true; |
|
103 | - } |
|
104 | - } |
|
105 | - return false; |
|
106 | - } |
|
66 | + /** |
|
67 | + * @param EE_Country $country_object |
|
68 | + * @return bool |
|
69 | + * @throws EE_Error |
|
70 | + * @throws InvalidArgumentException |
|
71 | + * @throws InvalidDataTypeException |
|
72 | + * @throws InvalidInterfaceException |
|
73 | + * @throws ReflectionException |
|
74 | + */ |
|
75 | + public function saveCountrySubRegions(EE_Country $country_object) |
|
76 | + { |
|
77 | + $CNT_ISO = $country_object->ID(); |
|
78 | + $has_sub_regions = $this->state_model->count(array(array('Country.CNT_ISO' => $CNT_ISO))); |
|
79 | + $data = []; |
|
80 | + if (empty($this->countries)) { |
|
81 | + $this->data_version = $this->getCountrySubRegionDataVersion(); |
|
82 | + $data = $this->retrieveJsonData(self::REPO_URL . 'countries.json'); |
|
83 | + } |
|
84 | + if (empty($data)) { |
|
85 | + EE_Error::add_error( |
|
86 | + 'Country Subregion Data could not be retrieved', |
|
87 | + __FILE__, |
|
88 | + __METHOD__, |
|
89 | + __LINE__ |
|
90 | + ); |
|
91 | + } |
|
92 | + if ( |
|
93 | + ! $has_sub_regions |
|
94 | + || (isset($data->version) && version_compare($data->version, $this->data_version)) |
|
95 | + ) { |
|
96 | + if ( |
|
97 | + isset($data->countries) |
|
98 | + && $this->processCountryData($CNT_ISO, $data->countries) > 0 |
|
99 | + ) { |
|
100 | + $this->countries = $data->countries; |
|
101 | + $this->updateCountrySubRegionDataVersion($data->version); |
|
102 | + return true; |
|
103 | + } |
|
104 | + } |
|
105 | + return false; |
|
106 | + } |
|
107 | 107 | |
108 | 108 | |
109 | - /** |
|
110 | - * @since 4.9.70.p |
|
111 | - * @return string |
|
112 | - */ |
|
113 | - private function getCountrySubRegionDataVersion() |
|
114 | - { |
|
115 | - return get_option(self::OPTION_NAME_COUNTRY_DATA_VERSION, null); |
|
116 | - } |
|
109 | + /** |
|
110 | + * @since 4.9.70.p |
|
111 | + * @return string |
|
112 | + */ |
|
113 | + private function getCountrySubRegionDataVersion() |
|
114 | + { |
|
115 | + return get_option(self::OPTION_NAME_COUNTRY_DATA_VERSION, null); |
|
116 | + } |
|
117 | 117 | |
118 | 118 | |
119 | - /** |
|
120 | - * @param string $version |
|
121 | - */ |
|
122 | - private function updateCountrySubRegionDataVersion($version = '') |
|
123 | - { |
|
124 | - // add version option if it has never been added before, or update existing |
|
125 | - if ($this->data_version === null) { |
|
126 | - add_option(self::OPTION_NAME_COUNTRY_DATA_VERSION, $version, '', false); |
|
127 | - } else { |
|
128 | - update_option(self::OPTION_NAME_COUNTRY_DATA_VERSION, $version); |
|
129 | - } |
|
130 | - } |
|
119 | + /** |
|
120 | + * @param string $version |
|
121 | + */ |
|
122 | + private function updateCountrySubRegionDataVersion($version = '') |
|
123 | + { |
|
124 | + // add version option if it has never been added before, or update existing |
|
125 | + if ($this->data_version === null) { |
|
126 | + add_option(self::OPTION_NAME_COUNTRY_DATA_VERSION, $version, '', false); |
|
127 | + } else { |
|
128 | + update_option(self::OPTION_NAME_COUNTRY_DATA_VERSION, $version); |
|
129 | + } |
|
130 | + } |
|
131 | 131 | |
132 | 132 | |
133 | - /** |
|
134 | - * @param string $CNT_ISO |
|
135 | - * @param array $countries |
|
136 | - * @return int |
|
137 | - * @throws EE_Error |
|
138 | - * @throws InvalidArgumentException |
|
139 | - * @throws InvalidDataTypeException |
|
140 | - * @throws InvalidInterfaceException |
|
141 | - * @throws ReflectionException |
|
142 | - * @since 4.9.70.p |
|
143 | - */ |
|
144 | - private function processCountryData($CNT_ISO, $countries = array()) |
|
145 | - { |
|
146 | - if (! empty($countries)) { |
|
147 | - foreach ($countries as $key => $country) { |
|
148 | - if ( |
|
149 | - $country instanceof stdClass |
|
150 | - && $country->code === $CNT_ISO |
|
151 | - && empty($country->sub_regions) |
|
152 | - && ! empty($country->filename) |
|
153 | - ) { |
|
154 | - $country->sub_regions = $this->retrieveJsonData( |
|
155 | - self::REPO_URL . 'countries/' . $country->filename . '.json' |
|
156 | - ); |
|
157 | - return $this->saveSubRegionData($country, $country->sub_regions); |
|
158 | - } |
|
159 | - } |
|
160 | - } |
|
161 | - return 0; |
|
162 | - } |
|
133 | + /** |
|
134 | + * @param string $CNT_ISO |
|
135 | + * @param array $countries |
|
136 | + * @return int |
|
137 | + * @throws EE_Error |
|
138 | + * @throws InvalidArgumentException |
|
139 | + * @throws InvalidDataTypeException |
|
140 | + * @throws InvalidInterfaceException |
|
141 | + * @throws ReflectionException |
|
142 | + * @since 4.9.70.p |
|
143 | + */ |
|
144 | + private function processCountryData($CNT_ISO, $countries = array()) |
|
145 | + { |
|
146 | + if (! empty($countries)) { |
|
147 | + foreach ($countries as $key => $country) { |
|
148 | + if ( |
|
149 | + $country instanceof stdClass |
|
150 | + && $country->code === $CNT_ISO |
|
151 | + && empty($country->sub_regions) |
|
152 | + && ! empty($country->filename) |
|
153 | + ) { |
|
154 | + $country->sub_regions = $this->retrieveJsonData( |
|
155 | + self::REPO_URL . 'countries/' . $country->filename . '.json' |
|
156 | + ); |
|
157 | + return $this->saveSubRegionData($country, $country->sub_regions); |
|
158 | + } |
|
159 | + } |
|
160 | + } |
|
161 | + return 0; |
|
162 | + } |
|
163 | 163 | |
164 | 164 | |
165 | - /** |
|
166 | - * @param string $url |
|
167 | - * @return array |
|
168 | - */ |
|
169 | - private function retrieveJsonData($url) |
|
170 | - { |
|
171 | - if (empty($url)) { |
|
172 | - EE_Error::add_error( |
|
173 | - 'No URL was provided!', |
|
174 | - __FILE__, |
|
175 | - __METHOD__, |
|
176 | - __LINE__ |
|
177 | - ); |
|
178 | - return array(); |
|
179 | - } |
|
180 | - $request = wp_safe_remote_get($url); |
|
181 | - if ($request instanceof WP_Error) { |
|
182 | - EE_Error::add_error( |
|
183 | - $request->get_error_message(), |
|
184 | - __FILE__, |
|
185 | - __METHOD__, |
|
186 | - __LINE__ |
|
187 | - ); |
|
188 | - return array(); |
|
189 | - } |
|
190 | - $body = wp_remote_retrieve_body($request); |
|
191 | - $json = json_decode($body); |
|
192 | - if ($this->json_validator->isValid(__FILE__, __METHOD__, __LINE__)) { |
|
193 | - return $json; |
|
194 | - } |
|
195 | - return array(); |
|
196 | - } |
|
165 | + /** |
|
166 | + * @param string $url |
|
167 | + * @return array |
|
168 | + */ |
|
169 | + private function retrieveJsonData($url) |
|
170 | + { |
|
171 | + if (empty($url)) { |
|
172 | + EE_Error::add_error( |
|
173 | + 'No URL was provided!', |
|
174 | + __FILE__, |
|
175 | + __METHOD__, |
|
176 | + __LINE__ |
|
177 | + ); |
|
178 | + return array(); |
|
179 | + } |
|
180 | + $request = wp_safe_remote_get($url); |
|
181 | + if ($request instanceof WP_Error) { |
|
182 | + EE_Error::add_error( |
|
183 | + $request->get_error_message(), |
|
184 | + __FILE__, |
|
185 | + __METHOD__, |
|
186 | + __LINE__ |
|
187 | + ); |
|
188 | + return array(); |
|
189 | + } |
|
190 | + $body = wp_remote_retrieve_body($request); |
|
191 | + $json = json_decode($body); |
|
192 | + if ($this->json_validator->isValid(__FILE__, __METHOD__, __LINE__)) { |
|
193 | + return $json; |
|
194 | + } |
|
195 | + return array(); |
|
196 | + } |
|
197 | 197 | |
198 | 198 | |
199 | - /** |
|
200 | - * @param stdClass $country |
|
201 | - * @param array $sub_regions |
|
202 | - * @return int |
|
203 | - * @throws EE_Error |
|
204 | - * @throws InvalidArgumentException |
|
205 | - * @throws InvalidDataTypeException |
|
206 | - * @throws InvalidInterfaceException |
|
207 | - * @throws ReflectionException |
|
208 | - */ |
|
209 | - private function saveSubRegionData(stdClass $country, $sub_regions = array()) |
|
210 | - { |
|
211 | - $results = 0; |
|
212 | - if (is_array($sub_regions)) { |
|
213 | - $existing_sub_regions = $this->getExistingStateAbbreviations($country->code); |
|
214 | - foreach ($sub_regions as $sub_region) { |
|
215 | - // remove country code from sub region code |
|
216 | - $abbrev = str_replace( |
|
217 | - $country->code . '-', |
|
218 | - '', |
|
219 | - sanitize_text_field($sub_region->code) |
|
220 | - ); |
|
221 | - // but NOT if sub region code results in only a number |
|
222 | - if (absint($abbrev) !== 0) { |
|
223 | - $abbrev = sanitize_text_field($sub_region->code); |
|
224 | - } |
|
225 | - if ( |
|
226 | - ! in_array($abbrev, $existing_sub_regions, true) |
|
227 | - && $this->state_model->insert( |
|
228 | - [ |
|
229 | - // STA_ID CNT_ISO STA_abbrev STA_name STA_active |
|
230 | - 'CNT_ISO' => $country->code, |
|
231 | - 'STA_abbrev' => $abbrev, |
|
232 | - 'STA_name' => sanitize_text_field($sub_region->name), |
|
233 | - 'STA_active' => 1, |
|
234 | - ] |
|
235 | - ) |
|
236 | - ) { |
|
237 | - $results++; |
|
238 | - } |
|
239 | - } |
|
240 | - } |
|
241 | - return $results; |
|
242 | - } |
|
199 | + /** |
|
200 | + * @param stdClass $country |
|
201 | + * @param array $sub_regions |
|
202 | + * @return int |
|
203 | + * @throws EE_Error |
|
204 | + * @throws InvalidArgumentException |
|
205 | + * @throws InvalidDataTypeException |
|
206 | + * @throws InvalidInterfaceException |
|
207 | + * @throws ReflectionException |
|
208 | + */ |
|
209 | + private function saveSubRegionData(stdClass $country, $sub_regions = array()) |
|
210 | + { |
|
211 | + $results = 0; |
|
212 | + if (is_array($sub_regions)) { |
|
213 | + $existing_sub_regions = $this->getExistingStateAbbreviations($country->code); |
|
214 | + foreach ($sub_regions as $sub_region) { |
|
215 | + // remove country code from sub region code |
|
216 | + $abbrev = str_replace( |
|
217 | + $country->code . '-', |
|
218 | + '', |
|
219 | + sanitize_text_field($sub_region->code) |
|
220 | + ); |
|
221 | + // but NOT if sub region code results in only a number |
|
222 | + if (absint($abbrev) !== 0) { |
|
223 | + $abbrev = sanitize_text_field($sub_region->code); |
|
224 | + } |
|
225 | + if ( |
|
226 | + ! in_array($abbrev, $existing_sub_regions, true) |
|
227 | + && $this->state_model->insert( |
|
228 | + [ |
|
229 | + // STA_ID CNT_ISO STA_abbrev STA_name STA_active |
|
230 | + 'CNT_ISO' => $country->code, |
|
231 | + 'STA_abbrev' => $abbrev, |
|
232 | + 'STA_name' => sanitize_text_field($sub_region->name), |
|
233 | + 'STA_active' => 1, |
|
234 | + ] |
|
235 | + ) |
|
236 | + ) { |
|
237 | + $results++; |
|
238 | + } |
|
239 | + } |
|
240 | + } |
|
241 | + return $results; |
|
242 | + } |
|
243 | 243 | |
244 | 244 | |
245 | - /** |
|
246 | - * @param string $CNT_ISO |
|
247 | - * @since 4.9.76.p |
|
248 | - * @return array |
|
249 | - * @throws EE_Error |
|
250 | - * @throws InvalidArgumentException |
|
251 | - * @throws InvalidDataTypeException |
|
252 | - * @throws InvalidInterfaceException |
|
253 | - * @throws ReflectionException |
|
254 | - */ |
|
255 | - private function getExistingStateAbbreviations($CNT_ISO) |
|
256 | - { |
|
257 | - $existing_sub_region_IDs = []; |
|
258 | - $existing_sub_regions = $this->state_model->get_all(array( |
|
259 | - array( |
|
260 | - 'Country.CNT_ISO' => array( |
|
261 | - 'IN', |
|
262 | - [$CNT_ISO] |
|
263 | - ) |
|
264 | - ), |
|
265 | - 'order_by' => array('Country.CNT_name' => 'ASC', 'STA_name' => 'ASC') |
|
266 | - )); |
|
267 | - if (is_array($existing_sub_regions)) { |
|
268 | - foreach ($existing_sub_regions as $existing_sub_region) { |
|
269 | - if ($existing_sub_region instanceof EE_State) { |
|
270 | - $existing_sub_region_IDs[] = $existing_sub_region->abbrev(); |
|
271 | - } |
|
272 | - } |
|
273 | - } |
|
274 | - return $existing_sub_region_IDs; |
|
275 | - } |
|
245 | + /** |
|
246 | + * @param string $CNT_ISO |
|
247 | + * @since 4.9.76.p |
|
248 | + * @return array |
|
249 | + * @throws EE_Error |
|
250 | + * @throws InvalidArgumentException |
|
251 | + * @throws InvalidDataTypeException |
|
252 | + * @throws InvalidInterfaceException |
|
253 | + * @throws ReflectionException |
|
254 | + */ |
|
255 | + private function getExistingStateAbbreviations($CNT_ISO) |
|
256 | + { |
|
257 | + $existing_sub_region_IDs = []; |
|
258 | + $existing_sub_regions = $this->state_model->get_all(array( |
|
259 | + array( |
|
260 | + 'Country.CNT_ISO' => array( |
|
261 | + 'IN', |
|
262 | + [$CNT_ISO] |
|
263 | + ) |
|
264 | + ), |
|
265 | + 'order_by' => array('Country.CNT_name' => 'ASC', 'STA_name' => 'ASC') |
|
266 | + )); |
|
267 | + if (is_array($existing_sub_regions)) { |
|
268 | + foreach ($existing_sub_regions as $existing_sub_region) { |
|
269 | + if ($existing_sub_region instanceof EE_State) { |
|
270 | + $existing_sub_region_IDs[] = $existing_sub_region->abbrev(); |
|
271 | + } |
|
272 | + } |
|
273 | + } |
|
274 | + return $existing_sub_region_IDs; |
|
275 | + } |
|
276 | 276 | } |
@@ -20,202 +20,202 @@ |
||
20 | 20 | */ |
21 | 21 | class PayPalSettingsForm extends EE_Payment_Method_Form |
22 | 22 | { |
23 | - /** |
|
24 | - * @var string of HTML being the help tab link |
|
25 | - */ |
|
26 | - protected $helpTabLink; |
|
23 | + /** |
|
24 | + * @var string of HTML being the help tab link |
|
25 | + */ |
|
26 | + protected $helpTabLink; |
|
27 | 27 | |
28 | - public function __construct(array $options_array = array(), $help_tab_link = '') |
|
29 | - { |
|
30 | - $this->helpTabLink = $help_tab_link; |
|
31 | - $options_array = array_replace_recursive( |
|
32 | - array( |
|
33 | - 'extra_meta_inputs' => array( |
|
34 | - 'api_username' => new EE_Text_Input( |
|
35 | - array( |
|
36 | - 'html_label_text' => sprintf( |
|
37 | - // translators: %s link to help doc |
|
38 | - esc_html__('API Username %s', 'event_espresso'), |
|
39 | - $help_tab_link |
|
40 | - ), |
|
41 | - 'required' => true, |
|
42 | - ) |
|
43 | - ), |
|
44 | - 'api_password' => new EE_Text_Input( |
|
45 | - array( |
|
46 | - 'html_label_text' => sprintf( |
|
47 | - // translators: %s link to help doc |
|
48 | - esc_html__('API Password %s', 'event_espresso'), |
|
49 | - $help_tab_link |
|
50 | - ), |
|
51 | - 'required' => true, |
|
52 | - ) |
|
53 | - ), |
|
54 | - 'api_signature' => new EE_Text_Input( |
|
55 | - array( |
|
56 | - 'html_label_text' => sprintf( |
|
57 | - // translators: %s link to help doc |
|
58 | - esc_html__('API Signature %s', 'event_espresso'), |
|
59 | - $help_tab_link |
|
60 | - ), |
|
61 | - 'required' => true, |
|
62 | - ) |
|
63 | - ), |
|
64 | - ) |
|
65 | - ), |
|
66 | - $options_array |
|
67 | - ); |
|
68 | - parent::__construct($options_array); |
|
69 | - } |
|
28 | + public function __construct(array $options_array = array(), $help_tab_link = '') |
|
29 | + { |
|
30 | + $this->helpTabLink = $help_tab_link; |
|
31 | + $options_array = array_replace_recursive( |
|
32 | + array( |
|
33 | + 'extra_meta_inputs' => array( |
|
34 | + 'api_username' => new EE_Text_Input( |
|
35 | + array( |
|
36 | + 'html_label_text' => sprintf( |
|
37 | + // translators: %s link to help doc |
|
38 | + esc_html__('API Username %s', 'event_espresso'), |
|
39 | + $help_tab_link |
|
40 | + ), |
|
41 | + 'required' => true, |
|
42 | + ) |
|
43 | + ), |
|
44 | + 'api_password' => new EE_Text_Input( |
|
45 | + array( |
|
46 | + 'html_label_text' => sprintf( |
|
47 | + // translators: %s link to help doc |
|
48 | + esc_html__('API Password %s', 'event_espresso'), |
|
49 | + $help_tab_link |
|
50 | + ), |
|
51 | + 'required' => true, |
|
52 | + ) |
|
53 | + ), |
|
54 | + 'api_signature' => new EE_Text_Input( |
|
55 | + array( |
|
56 | + 'html_label_text' => sprintf( |
|
57 | + // translators: %s link to help doc |
|
58 | + esc_html__('API Signature %s', 'event_espresso'), |
|
59 | + $help_tab_link |
|
60 | + ), |
|
61 | + 'required' => true, |
|
62 | + ) |
|
63 | + ), |
|
64 | + ) |
|
65 | + ), |
|
66 | + $options_array |
|
67 | + ); |
|
68 | + parent::__construct($options_array); |
|
69 | + } |
|
70 | 70 | |
71 | - /** |
|
72 | - * Tests the the PayPal API credentials work ok |
|
73 | - * @return string of an error using the credentials, otherwise, if the credentials work, returns a blank string |
|
74 | - * @throws EE_Error |
|
75 | - */ |
|
76 | - protected function checkForCredentialsErrors() |
|
77 | - { |
|
78 | - $request_params = array( |
|
79 | - 'METHOD' => 'GetBalance', |
|
80 | - 'VERSION' => '204.0', |
|
81 | - 'USER' => $this->get_input_value('api_username'), |
|
82 | - 'PWD' => $this->get_input_value('api_password'), |
|
83 | - 'SIGNATURE' => $this->get_input_value('api_signature'), |
|
84 | - ); |
|
85 | - $gateway_url = $this->get_input_value('PMD_debug_mode') |
|
86 | - ? 'https://api-3t.sandbox.paypal.com/nvp' |
|
87 | - : 'https://api-3t.paypal.com/nvp'; |
|
88 | - // Request Customer Details. |
|
89 | - $response = wp_remote_post( |
|
90 | - $gateway_url, |
|
91 | - array( |
|
92 | - 'method' => 'POST', |
|
93 | - 'timeout' => 45, |
|
94 | - 'httpversion' => '1.1', |
|
95 | - 'cookies' => array(), |
|
96 | - 'headers' => array(), |
|
97 | - 'body' => http_build_query($request_params, '', '&'), |
|
98 | - ) |
|
99 | - ); |
|
100 | - if (is_wp_error($response) || empty($response['body'])) { |
|
101 | - // If we got here then there was an error in this request. |
|
102 | - // maybe is turned off. We don't know the credentials are invalid |
|
103 | - EE_Error::add_error( |
|
104 | - sprintf( |
|
105 | - // translators: %1$s Error message received from PayPal |
|
106 | - esc_html__( |
|
107 | - // @codingStandardsIgnoreStart |
|
108 | - 'Your PayPal credentials could not be verified. The following error occurred while communicating with PayPal: %1$s', |
|
109 | - // @codingStandardsIgnoreEnd |
|
110 | - 'event_espresso' |
|
111 | - ), |
|
112 | - $response->get_error_message() |
|
113 | - ), |
|
114 | - __FILE__, |
|
115 | - __FUNCTION__, |
|
116 | - __LINE__ |
|
117 | - ); |
|
118 | - } |
|
119 | - $response_args = array(); |
|
120 | - parse_str(urldecode($response['body']), $response_args); |
|
71 | + /** |
|
72 | + * Tests the the PayPal API credentials work ok |
|
73 | + * @return string of an error using the credentials, otherwise, if the credentials work, returns a blank string |
|
74 | + * @throws EE_Error |
|
75 | + */ |
|
76 | + protected function checkForCredentialsErrors() |
|
77 | + { |
|
78 | + $request_params = array( |
|
79 | + 'METHOD' => 'GetBalance', |
|
80 | + 'VERSION' => '204.0', |
|
81 | + 'USER' => $this->get_input_value('api_username'), |
|
82 | + 'PWD' => $this->get_input_value('api_password'), |
|
83 | + 'SIGNATURE' => $this->get_input_value('api_signature'), |
|
84 | + ); |
|
85 | + $gateway_url = $this->get_input_value('PMD_debug_mode') |
|
86 | + ? 'https://api-3t.sandbox.paypal.com/nvp' |
|
87 | + : 'https://api-3t.paypal.com/nvp'; |
|
88 | + // Request Customer Details. |
|
89 | + $response = wp_remote_post( |
|
90 | + $gateway_url, |
|
91 | + array( |
|
92 | + 'method' => 'POST', |
|
93 | + 'timeout' => 45, |
|
94 | + 'httpversion' => '1.1', |
|
95 | + 'cookies' => array(), |
|
96 | + 'headers' => array(), |
|
97 | + 'body' => http_build_query($request_params, '', '&'), |
|
98 | + ) |
|
99 | + ); |
|
100 | + if (is_wp_error($response) || empty($response['body'])) { |
|
101 | + // If we got here then there was an error in this request. |
|
102 | + // maybe is turned off. We don't know the credentials are invalid |
|
103 | + EE_Error::add_error( |
|
104 | + sprintf( |
|
105 | + // translators: %1$s Error message received from PayPal |
|
106 | + esc_html__( |
|
107 | + // @codingStandardsIgnoreStart |
|
108 | + 'Your PayPal credentials could not be verified. The following error occurred while communicating with PayPal: %1$s', |
|
109 | + // @codingStandardsIgnoreEnd |
|
110 | + 'event_espresso' |
|
111 | + ), |
|
112 | + $response->get_error_message() |
|
113 | + ), |
|
114 | + __FILE__, |
|
115 | + __FUNCTION__, |
|
116 | + __LINE__ |
|
117 | + ); |
|
118 | + } |
|
119 | + $response_args = array(); |
|
120 | + parse_str(urldecode($response['body']), $response_args); |
|
121 | 121 | |
122 | - if (empty($response_args['ACK'])) { |
|
123 | - EE_Error::add_error( |
|
124 | - esc_html__( |
|
125 | - 'Your PayPal credentials could not be verified. Part of their response was missing.', |
|
126 | - 'event_espresso' |
|
127 | - ), |
|
128 | - __FILE__, |
|
129 | - __FUNCTION__, |
|
130 | - __LINE__ |
|
131 | - ); |
|
132 | - } |
|
133 | - if ( |
|
134 | - in_array( |
|
135 | - $response_args['ACK'], |
|
136 | - array( |
|
137 | - 'Success', |
|
138 | - 'SuccessWithWarning' |
|
139 | - ), |
|
140 | - true |
|
141 | - ) |
|
142 | - ) { |
|
143 | - return ''; |
|
144 | - } else { |
|
145 | - return sprintf( |
|
146 | - // translators: %1$s: PayPal response message, %2$s: PayPal response code |
|
147 | - esc_html__( |
|
148 | - // @codingStandardsIgnoreStart |
|
149 | - 'Your PayPal API credentials appear to be invalid. PayPal said "%1$s (%2$s)". Please see tips below.', |
|
150 | - // @codingStandardsIgnoreEnd |
|
151 | - 'event_espresso' |
|
152 | - ), |
|
153 | - isset($response_args['L_LONGMESSAGE0']) |
|
154 | - ? $response_args['L_LONGMESSAGE0'] |
|
155 | - : esc_html__('No error message received from PayPal', 'event_espresso'), |
|
156 | - isset($response_args['L_ERRORCODE0']) ? $response_args['L_ERRORCODE0'] : 0 |
|
157 | - ); |
|
158 | - } |
|
159 | - } |
|
122 | + if (empty($response_args['ACK'])) { |
|
123 | + EE_Error::add_error( |
|
124 | + esc_html__( |
|
125 | + 'Your PayPal credentials could not be verified. Part of their response was missing.', |
|
126 | + 'event_espresso' |
|
127 | + ), |
|
128 | + __FILE__, |
|
129 | + __FUNCTION__, |
|
130 | + __LINE__ |
|
131 | + ); |
|
132 | + } |
|
133 | + if ( |
|
134 | + in_array( |
|
135 | + $response_args['ACK'], |
|
136 | + array( |
|
137 | + 'Success', |
|
138 | + 'SuccessWithWarning' |
|
139 | + ), |
|
140 | + true |
|
141 | + ) |
|
142 | + ) { |
|
143 | + return ''; |
|
144 | + } else { |
|
145 | + return sprintf( |
|
146 | + // translators: %1$s: PayPal response message, %2$s: PayPal response code |
|
147 | + esc_html__( |
|
148 | + // @codingStandardsIgnoreStart |
|
149 | + 'Your PayPal API credentials appear to be invalid. PayPal said "%1$s (%2$s)". Please see tips below.', |
|
150 | + // @codingStandardsIgnoreEnd |
|
151 | + 'event_espresso' |
|
152 | + ), |
|
153 | + isset($response_args['L_LONGMESSAGE0']) |
|
154 | + ? $response_args['L_LONGMESSAGE0'] |
|
155 | + : esc_html__('No error message received from PayPal', 'event_espresso'), |
|
156 | + isset($response_args['L_ERRORCODE0']) ? $response_args['L_ERRORCODE0'] : 0 |
|
157 | + ); |
|
158 | + } |
|
159 | + } |
|
160 | 160 | |
161 | - /** |
|
162 | - * Gets the HTML to show the link to the help tab |
|
163 | - * @return string |
|
164 | - */ |
|
165 | - protected function helpTabLink() |
|
166 | - { |
|
167 | - return $this->helpTabLink; |
|
168 | - } |
|
161 | + /** |
|
162 | + * Gets the HTML to show the link to the help tab |
|
163 | + * @return string |
|
164 | + */ |
|
165 | + protected function helpTabLink() |
|
166 | + { |
|
167 | + return $this->helpTabLink; |
|
168 | + } |
|
169 | 169 | |
170 | - /** |
|
171 | - * Does the normal validation, but also verifies the PayPal API credentials work. |
|
172 | - * If they don't, sets a validation error on the entire form, and adds validation errors (which are really more |
|
173 | - * tips) on each of the inputs that could be the cause of the problem. |
|
174 | - * @throws EE_Error |
|
175 | - */ |
|
176 | - public function _validate() |
|
177 | - { |
|
178 | - parent::_validate(); |
|
179 | - $credentials_message = $this->checkForCredentialsErrors(); |
|
180 | - if ($credentials_message !== '') { |
|
181 | - $this->add_validation_error($credentials_message); |
|
182 | - $this->get_input('PMD_debug_mode')->add_validation_error( |
|
183 | - esc_html__( |
|
184 | - // @codingStandardsIgnoreStart |
|
185 | - 'If you are using PayPal Sandbox (test) credentials, Debug mode should be set to "Yes". Otherwise, if you are using live PayPal credentials, set this to "No".', |
|
186 | - // @codingStandardsIgnoreEnd |
|
187 | - 'event_espresso' |
|
188 | - ) |
|
189 | - ); |
|
190 | - $this->get_input('api_username')->add_validation_error( |
|
191 | - sprintf( |
|
192 | - // translators: $1$s HTML for a link to the help tab |
|
193 | - esc_html__( |
|
194 | - 'Are you sure this is your API username, not your login username? %1$s', |
|
195 | - 'event_espresso' |
|
196 | - ), |
|
197 | - $this->helpTabLink() |
|
198 | - ) |
|
199 | - ); |
|
200 | - $this->get_input('api_password')->add_validation_error( |
|
201 | - sprintf( |
|
202 | - // translators: $1$s HTML for a link to the help tab |
|
203 | - esc_html__( |
|
204 | - 'Are you sure this is your API password, not your login password? %1$s', |
|
205 | - 'event_espresso' |
|
206 | - ), |
|
207 | - $this->helpTabLink() |
|
208 | - ) |
|
209 | - ); |
|
210 | - $this->get_input('api_signature')->add_validation_error( |
|
211 | - sprintf( |
|
212 | - // translators: $1$s HTML for a link to the help tab |
|
213 | - esc_html__('Please verify your API signature is correct. %1$s', 'event_espresso'), |
|
214 | - $this->helpTabLink() |
|
215 | - ) |
|
216 | - ); |
|
217 | - } |
|
218 | - } |
|
170 | + /** |
|
171 | + * Does the normal validation, but also verifies the PayPal API credentials work. |
|
172 | + * If they don't, sets a validation error on the entire form, and adds validation errors (which are really more |
|
173 | + * tips) on each of the inputs that could be the cause of the problem. |
|
174 | + * @throws EE_Error |
|
175 | + */ |
|
176 | + public function _validate() |
|
177 | + { |
|
178 | + parent::_validate(); |
|
179 | + $credentials_message = $this->checkForCredentialsErrors(); |
|
180 | + if ($credentials_message !== '') { |
|
181 | + $this->add_validation_error($credentials_message); |
|
182 | + $this->get_input('PMD_debug_mode')->add_validation_error( |
|
183 | + esc_html__( |
|
184 | + // @codingStandardsIgnoreStart |
|
185 | + 'If you are using PayPal Sandbox (test) credentials, Debug mode should be set to "Yes". Otherwise, if you are using live PayPal credentials, set this to "No".', |
|
186 | + // @codingStandardsIgnoreEnd |
|
187 | + 'event_espresso' |
|
188 | + ) |
|
189 | + ); |
|
190 | + $this->get_input('api_username')->add_validation_error( |
|
191 | + sprintf( |
|
192 | + // translators: $1$s HTML for a link to the help tab |
|
193 | + esc_html__( |
|
194 | + 'Are you sure this is your API username, not your login username? %1$s', |
|
195 | + 'event_espresso' |
|
196 | + ), |
|
197 | + $this->helpTabLink() |
|
198 | + ) |
|
199 | + ); |
|
200 | + $this->get_input('api_password')->add_validation_error( |
|
201 | + sprintf( |
|
202 | + // translators: $1$s HTML for a link to the help tab |
|
203 | + esc_html__( |
|
204 | + 'Are you sure this is your API password, not your login password? %1$s', |
|
205 | + 'event_espresso' |
|
206 | + ), |
|
207 | + $this->helpTabLink() |
|
208 | + ) |
|
209 | + ); |
|
210 | + $this->get_input('api_signature')->add_validation_error( |
|
211 | + sprintf( |
|
212 | + // translators: $1$s HTML for a link to the help tab |
|
213 | + esc_html__('Please verify your API signature is correct. %1$s', 'event_espresso'), |
|
214 | + $this->helpTabLink() |
|
215 | + ) |
|
216 | + ); |
|
217 | + } |
|
218 | + } |
|
219 | 219 | } |
220 | 220 | // End of file PayPalSettingsForm.php |
221 | 221 | // Location: ${NAMESPACE}/PayPalSettingsForm.php |
@@ -193,7 +193,7 @@ discard block |
||
193 | 193 | */ |
194 | 194 | protected function setCollectionInterface($collection_interface) |
195 | 195 | { |
196 | - if (! (interface_exists($collection_interface) || class_exists($collection_interface))) { |
|
196 | + if ( ! (interface_exists($collection_interface) || class_exists($collection_interface))) { |
|
197 | 197 | throw new InvalidInterfaceException($collection_interface); |
198 | 198 | } |
199 | 199 | $this->collection_interface = $collection_interface; |
@@ -221,7 +221,7 @@ discard block |
||
221 | 221 | */ |
222 | 222 | protected function setCollectionName($collection_name) |
223 | 223 | { |
224 | - if (! is_string($collection_name)) { |
|
224 | + if ( ! is_string($collection_name)) { |
|
225 | 225 | throw new InvalidDataTypeException('$collection_name', $collection_name, 'string'); |
226 | 226 | } |
227 | 227 | $this->collection_name = str_replace( |
@@ -281,7 +281,7 @@ discard block |
||
281 | 281 | */ |
282 | 282 | protected function setIdentifierCallback($identifier_callback = 'identifier') |
283 | 283 | { |
284 | - if (! is_string($identifier_callback)) { |
|
284 | + if ( ! is_string($identifier_callback)) { |
|
285 | 285 | throw new InvalidDataTypeException('$identifier_callback', $identifier_callback, 'string'); |
286 | 286 | } |
287 | 287 | $this->identifier_callback = $identifier_callback; |
@@ -311,7 +311,7 @@ discard block |
||
311 | 311 | $this->file_mask = ! empty($file_mask) ? $file_mask : '*.php'; |
312 | 312 | // we know our default is a string, so if it's not a string now, |
313 | 313 | // then that means the incoming parameter was something else |
314 | - if (! is_string($this->file_mask)) { |
|
314 | + if ( ! is_string($this->file_mask)) { |
|
315 | 315 | throw new InvalidDataTypeException('$file_mask', $this->file_mask, 'string'); |
316 | 316 | } |
317 | 317 | } |
@@ -336,7 +336,7 @@ discard block |
||
336 | 336 | public function setCollectionFQCNs($collection_FQCNs) |
337 | 337 | { |
338 | 338 | foreach ((array) $collection_FQCNs as $collection_FQCN) { |
339 | - if (! empty($collection_FQCN)) { |
|
339 | + if ( ! empty($collection_FQCN)) { |
|
340 | 340 | if (class_exists($collection_FQCN)) { |
341 | 341 | $this->collection_FQCNs[] = $collection_FQCN; |
342 | 342 | } else { |
@@ -358,7 +358,7 @@ discard block |
||
358 | 358 | */ |
359 | 359 | protected function getFQCNsFromPartialNamespace($partial_FQCN) |
360 | 360 | { |
361 | - if (! $this->file_locator instanceof FqcnLocator) { |
|
361 | + if ( ! $this->file_locator instanceof FqcnLocator) { |
|
362 | 362 | $this->file_locator = new FqcnLocator(); |
363 | 363 | } |
364 | 364 | $this->file_locator->locate($partial_FQCN); |
@@ -384,8 +384,8 @@ discard block |
||
384 | 384 | public function setCollectionPaths($collection_paths) |
385 | 385 | { |
386 | 386 | foreach ((array) $collection_paths as $collection_path) { |
387 | - if (! empty($collection_path)) { |
|
388 | - if (! is_readable($collection_path)) { |
|
387 | + if ( ! empty($collection_path)) { |
|
388 | + if ( ! is_readable($collection_path)) { |
|
389 | 389 | throw new InvalidFilePathException($collection_path); |
390 | 390 | } |
391 | 391 | $this->collection_paths[] = $collection_path; |
@@ -42,353 +42,353 @@ |
||
42 | 42 | */ |
43 | 43 | class CollectionDetails implements CollectionDetailsInterface |
44 | 44 | { |
45 | - /** |
|
46 | - * if $identifier_type is set to this, |
|
47 | - * then the collection will use each object's spl_object_hash() as it's identifier |
|
48 | - */ |
|
49 | - const ID_OBJECT_HASH = 'identifier-uses-spl-object-hash'; |
|
50 | - |
|
51 | - /** |
|
52 | - * if $identifier_type is set to this, |
|
53 | - * then the collection will use each object's class name as it's identifier |
|
54 | - */ |
|
55 | - const ID_CLASS_NAME = 'identifier-uses-object-class-name'; |
|
56 | - |
|
57 | - /** |
|
58 | - * if $identifier_type is set to this, |
|
59 | - * then the collection will use the return value from a specified callback method on each object |
|
60 | - */ |
|
61 | - const ID_CALLBACK_METHOD = 'identifier-uses-callback-method'; |
|
62 | - |
|
63 | - /** |
|
64 | - * The interface used for controlling what gets added to the collection |
|
65 | - * |
|
66 | - * @var string $collection_interface |
|
67 | - */ |
|
68 | - protected $collection_interface = ''; |
|
69 | - |
|
70 | - /** |
|
71 | - * a unique name used to identify the collection in filter names |
|
72 | - * supplied value is run through sanitize_title_with_dashes(), |
|
73 | - * but then also converts dashes to underscores |
|
74 | - * |
|
75 | - * @var string $collection_name |
|
76 | - */ |
|
77 | - protected $collection_name = ''; |
|
78 | - |
|
79 | - /** |
|
80 | - * what the collection uses for the object identifier. |
|
81 | - * corresponds to one of the class constants above. |
|
82 | - * CollectionDetails::ID_OBJECT_HASH will use spl_object_hash( object ) for the identifier |
|
83 | - * CollectionDetails::ID_CLASS_NAME will use get_class( object ) for the identifier |
|
84 | - * CollectionDetails::ID_CALLBACK_METHOD will use a callback for the identifier |
|
85 | - * defaults to using spl_object_hash() so that multiple objects of the same class can be added |
|
86 | - * |
|
87 | - * @var string $identifier_type |
|
88 | - */ |
|
89 | - protected $identifier_type = CollectionDetails::ID_OBJECT_HASH; |
|
90 | - |
|
91 | - /** |
|
92 | - * the pattern applied to paths when searching for class files to add to the collection |
|
93 | - * ie: "My_Awesome_*.class.php" |
|
94 | - * defaults to "*.php" |
|
95 | - * |
|
96 | - * @var string $file_mask |
|
97 | - */ |
|
98 | - protected $file_mask = ''; |
|
99 | - |
|
100 | - /** |
|
101 | - * if the $identifier_type above is set to CollectionDetails::ID_CALLBACK_METHOD, |
|
102 | - * then this specifies the method to use on each entity. |
|
103 | - * If the callback method does not exist, then an exception will be thrown |
|
104 | - * |
|
105 | - * @var string $identifier_callback |
|
106 | - */ |
|
107 | - protected $identifier_callback = ''; |
|
108 | - |
|
109 | - /** |
|
110 | - * an array of Fully Qualified Class Names |
|
111 | - * for example: |
|
112 | - * $FQCNs = array( |
|
113 | - * '/Fully/Qualified/ClassNameA' |
|
114 | - * '/Fully/Qualified/Other/ClassNameB' |
|
115 | - * ); |
|
116 | - * |
|
117 | - * @var array $collection_FQCNs |
|
118 | - */ |
|
119 | - protected $collection_FQCNs = array(); |
|
120 | - |
|
121 | - /** |
|
122 | - * an array of full server paths to folders containing files to be loaded into collection |
|
123 | - * for example: |
|
124 | - * $paths = array( |
|
125 | - * '/full/server/path/to/ClassNameA.ext.php' // for class ClassNameA |
|
126 | - * '/full/server/path/to/other/ClassNameB.php' // for class ClassNameB |
|
127 | - * ); |
|
128 | - * |
|
129 | - * @var array $collection_paths |
|
130 | - */ |
|
131 | - protected $collection_paths = array(); |
|
132 | - |
|
133 | - /** |
|
134 | - * @var LocatorInterface $file_locator |
|
135 | - */ |
|
136 | - protected $file_locator; |
|
137 | - |
|
138 | - |
|
139 | - /** |
|
140 | - * CollectionDetails constructor. |
|
141 | - * |
|
142 | - * @access public |
|
143 | - * @param string $collection_name |
|
144 | - * @param string $collection_interface |
|
145 | - * @param array $collection_FQCNs |
|
146 | - * @param array $collection_paths |
|
147 | - * @param string $file_mask |
|
148 | - * @param string $identifier_type |
|
149 | - * @param string $identifier_callback |
|
150 | - * @param LocatorInterface $file_locator |
|
151 | - * @throws CollectionDetailsException |
|
152 | - */ |
|
153 | - public function __construct( |
|
154 | - $collection_name, |
|
155 | - $collection_interface, |
|
156 | - array $collection_FQCNs = array(), |
|
157 | - array $collection_paths = array(), |
|
158 | - $file_mask = '', |
|
159 | - $identifier_type = CollectionDetails::ID_OBJECT_HASH, |
|
160 | - $identifier_callback = '', |
|
161 | - LocatorInterface $file_locator = null |
|
162 | - ) { |
|
163 | - try { |
|
164 | - $this->setCollectionName($collection_name); |
|
165 | - $this->setCollectionInterface($collection_interface); |
|
166 | - $this->setCollectionFQCNs($collection_FQCNs); |
|
167 | - $this->setCollectionPaths($collection_paths); |
|
168 | - $this->setFileMasks($file_mask); |
|
169 | - $this->setIdentifierType($identifier_type); |
|
170 | - $this->setIdentifierCallback($identifier_callback); |
|
171 | - $this->file_locator = $file_locator; |
|
172 | - } catch (Exception $exception) { |
|
173 | - throw new CollectionDetailsException($exception); |
|
174 | - } |
|
175 | - } |
|
176 | - |
|
177 | - |
|
178 | - /** |
|
179 | - * @access public |
|
180 | - * @return mixed |
|
181 | - */ |
|
182 | - public function getCollectionInterface() |
|
183 | - { |
|
184 | - return $this->collection_interface; |
|
185 | - } |
|
186 | - |
|
187 | - |
|
188 | - /** |
|
189 | - * @access protected |
|
190 | - * @param string $collection_interface |
|
191 | - * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
192 | - */ |
|
193 | - protected function setCollectionInterface($collection_interface) |
|
194 | - { |
|
195 | - if (! (interface_exists($collection_interface) || class_exists($collection_interface))) { |
|
196 | - throw new InvalidInterfaceException($collection_interface); |
|
197 | - } |
|
198 | - $this->collection_interface = $collection_interface; |
|
199 | - } |
|
200 | - |
|
201 | - |
|
202 | - /** |
|
203 | - * the collection name will be used for creating dynamic filters |
|
204 | - * |
|
205 | - * @access public |
|
206 | - * @return string |
|
207 | - */ |
|
208 | - public function collectionName() |
|
209 | - { |
|
210 | - return $this->collection_name; |
|
211 | - } |
|
212 | - |
|
213 | - |
|
214 | - /** |
|
215 | - * sanitizes collection name and converts spaces and dashes to underscores |
|
216 | - * |
|
217 | - * @access protected |
|
218 | - * @param string $collection_name |
|
219 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
220 | - */ |
|
221 | - protected function setCollectionName($collection_name) |
|
222 | - { |
|
223 | - if (! is_string($collection_name)) { |
|
224 | - throw new InvalidDataTypeException('$collection_name', $collection_name, 'string'); |
|
225 | - } |
|
226 | - $this->collection_name = str_replace( |
|
227 | - '-', |
|
228 | - '_', |
|
229 | - sanitize_title_with_dashes($collection_name, '', 'save') |
|
230 | - ); |
|
231 | - } |
|
232 | - |
|
233 | - |
|
234 | - /** |
|
235 | - * @access public |
|
236 | - * @return string |
|
237 | - */ |
|
238 | - public function identifierType() |
|
239 | - { |
|
240 | - return $this->identifier_type; |
|
241 | - } |
|
242 | - |
|
243 | - |
|
244 | - /** |
|
245 | - * @access protected |
|
246 | - * @param string $identifier_type |
|
247 | - * @throws InvalidIdentifierException |
|
248 | - */ |
|
249 | - protected function setIdentifierType($identifier_type) |
|
250 | - { |
|
251 | - if ( |
|
252 | - ! ($identifier_type === CollectionDetails::ID_CLASS_NAME |
|
253 | - || $identifier_type === CollectionDetails::ID_OBJECT_HASH |
|
254 | - || $identifier_type === CollectionDetails::ID_CALLBACK_METHOD |
|
255 | - ) |
|
256 | - ) { |
|
257 | - throw new InvalidIdentifierException( |
|
258 | - $identifier_type, |
|
259 | - 'CollectionDetails::ID_CLASS_NAME or CollectionDetails::ID_OBJECT_HASH or CollectionDetails::ID_CALLBACK_METHOD' |
|
260 | - ); |
|
261 | - } |
|
262 | - $this->identifier_type = $identifier_type; |
|
263 | - } |
|
264 | - |
|
265 | - |
|
266 | - /** |
|
267 | - * @access public |
|
268 | - * @return string |
|
269 | - */ |
|
270 | - public function identifierCallback() |
|
271 | - { |
|
272 | - return $this->identifier_callback; |
|
273 | - } |
|
274 | - |
|
275 | - |
|
276 | - /** |
|
277 | - * @access protected |
|
278 | - * @param string $identifier_callback |
|
279 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
280 | - */ |
|
281 | - protected function setIdentifierCallback($identifier_callback = 'identifier') |
|
282 | - { |
|
283 | - if (! is_string($identifier_callback)) { |
|
284 | - throw new InvalidDataTypeException('$identifier_callback', $identifier_callback, 'string'); |
|
285 | - } |
|
286 | - $this->identifier_callback = $identifier_callback; |
|
287 | - } |
|
288 | - |
|
289 | - |
|
290 | - /** |
|
291 | - * @access public |
|
292 | - * @return string |
|
293 | - */ |
|
294 | - public function getFileMask() |
|
295 | - { |
|
296 | - return $this->file_mask; |
|
297 | - } |
|
298 | - |
|
299 | - |
|
300 | - /** |
|
301 | - * sets the file mask which is then used to filter what files get loaded |
|
302 | - * when searching for classes to add to the collection. Defaults to '*.php' |
|
303 | - * |
|
304 | - * @access protected |
|
305 | - * @param string $file_mask |
|
306 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
307 | - */ |
|
308 | - protected function setFileMasks($file_mask) |
|
309 | - { |
|
310 | - $this->file_mask = ! empty($file_mask) ? $file_mask : '*.php'; |
|
311 | - // we know our default is a string, so if it's not a string now, |
|
312 | - // then that means the incoming parameter was something else |
|
313 | - if (! is_string($this->file_mask)) { |
|
314 | - throw new InvalidDataTypeException('$file_mask', $this->file_mask, 'string'); |
|
315 | - } |
|
316 | - } |
|
317 | - |
|
318 | - |
|
319 | - /** |
|
320 | - * @access public |
|
321 | - * @return array |
|
322 | - */ |
|
323 | - public function getCollectionFQCNs() |
|
324 | - { |
|
325 | - return $this->collection_FQCNs; |
|
326 | - } |
|
327 | - |
|
328 | - |
|
329 | - /** |
|
330 | - * @access public |
|
331 | - * @param string|array $collection_FQCNs |
|
332 | - * @throws \EventEspresso\core\exceptions\InvalidClassException |
|
333 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
334 | - */ |
|
335 | - public function setCollectionFQCNs($collection_FQCNs) |
|
336 | - { |
|
337 | - foreach ((array) $collection_FQCNs as $collection_FQCN) { |
|
338 | - if (! empty($collection_FQCN)) { |
|
339 | - if (class_exists($collection_FQCN)) { |
|
340 | - $this->collection_FQCNs[] = $collection_FQCN; |
|
341 | - } else { |
|
342 | - foreach ($this->getFQCNsFromPartialNamespace($collection_FQCN) as $FQCN) { |
|
343 | - $this->collection_FQCNs[] = $FQCN; |
|
344 | - } |
|
345 | - } |
|
346 | - } |
|
347 | - } |
|
348 | - } |
|
349 | - |
|
350 | - |
|
351 | - /** |
|
352 | - * @access protected |
|
353 | - * @param string $partial_FQCN |
|
354 | - * @return array |
|
355 | - * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
356 | - * @throws \EventEspresso\core\exceptions\InvalidClassException |
|
357 | - */ |
|
358 | - protected function getFQCNsFromPartialNamespace($partial_FQCN) |
|
359 | - { |
|
360 | - if (! $this->file_locator instanceof FqcnLocator) { |
|
361 | - $this->file_locator = new FqcnLocator(); |
|
362 | - } |
|
363 | - $this->file_locator->locate($partial_FQCN); |
|
364 | - return $this->file_locator->getFQCNs(); |
|
365 | - } |
|
366 | - |
|
367 | - |
|
368 | - /** |
|
369 | - * @access public |
|
370 | - * @return array |
|
371 | - */ |
|
372 | - public function getCollectionPaths() |
|
373 | - { |
|
374 | - return $this->collection_paths; |
|
375 | - } |
|
376 | - |
|
377 | - |
|
378 | - /** |
|
379 | - * @access public |
|
380 | - * @param string|array $collection_paths |
|
381 | - * @throws \EventEspresso\core\exceptions\InvalidFilePathException |
|
382 | - */ |
|
383 | - public function setCollectionPaths($collection_paths) |
|
384 | - { |
|
385 | - foreach ((array) $collection_paths as $collection_path) { |
|
386 | - if (! empty($collection_path)) { |
|
387 | - if (! is_readable($collection_path)) { |
|
388 | - throw new InvalidFilePathException($collection_path); |
|
389 | - } |
|
390 | - $this->collection_paths[] = $collection_path; |
|
391 | - } |
|
392 | - } |
|
393 | - } |
|
45 | + /** |
|
46 | + * if $identifier_type is set to this, |
|
47 | + * then the collection will use each object's spl_object_hash() as it's identifier |
|
48 | + */ |
|
49 | + const ID_OBJECT_HASH = 'identifier-uses-spl-object-hash'; |
|
50 | + |
|
51 | + /** |
|
52 | + * if $identifier_type is set to this, |
|
53 | + * then the collection will use each object's class name as it's identifier |
|
54 | + */ |
|
55 | + const ID_CLASS_NAME = 'identifier-uses-object-class-name'; |
|
56 | + |
|
57 | + /** |
|
58 | + * if $identifier_type is set to this, |
|
59 | + * then the collection will use the return value from a specified callback method on each object |
|
60 | + */ |
|
61 | + const ID_CALLBACK_METHOD = 'identifier-uses-callback-method'; |
|
62 | + |
|
63 | + /** |
|
64 | + * The interface used for controlling what gets added to the collection |
|
65 | + * |
|
66 | + * @var string $collection_interface |
|
67 | + */ |
|
68 | + protected $collection_interface = ''; |
|
69 | + |
|
70 | + /** |
|
71 | + * a unique name used to identify the collection in filter names |
|
72 | + * supplied value is run through sanitize_title_with_dashes(), |
|
73 | + * but then also converts dashes to underscores |
|
74 | + * |
|
75 | + * @var string $collection_name |
|
76 | + */ |
|
77 | + protected $collection_name = ''; |
|
78 | + |
|
79 | + /** |
|
80 | + * what the collection uses for the object identifier. |
|
81 | + * corresponds to one of the class constants above. |
|
82 | + * CollectionDetails::ID_OBJECT_HASH will use spl_object_hash( object ) for the identifier |
|
83 | + * CollectionDetails::ID_CLASS_NAME will use get_class( object ) for the identifier |
|
84 | + * CollectionDetails::ID_CALLBACK_METHOD will use a callback for the identifier |
|
85 | + * defaults to using spl_object_hash() so that multiple objects of the same class can be added |
|
86 | + * |
|
87 | + * @var string $identifier_type |
|
88 | + */ |
|
89 | + protected $identifier_type = CollectionDetails::ID_OBJECT_HASH; |
|
90 | + |
|
91 | + /** |
|
92 | + * the pattern applied to paths when searching for class files to add to the collection |
|
93 | + * ie: "My_Awesome_*.class.php" |
|
94 | + * defaults to "*.php" |
|
95 | + * |
|
96 | + * @var string $file_mask |
|
97 | + */ |
|
98 | + protected $file_mask = ''; |
|
99 | + |
|
100 | + /** |
|
101 | + * if the $identifier_type above is set to CollectionDetails::ID_CALLBACK_METHOD, |
|
102 | + * then this specifies the method to use on each entity. |
|
103 | + * If the callback method does not exist, then an exception will be thrown |
|
104 | + * |
|
105 | + * @var string $identifier_callback |
|
106 | + */ |
|
107 | + protected $identifier_callback = ''; |
|
108 | + |
|
109 | + /** |
|
110 | + * an array of Fully Qualified Class Names |
|
111 | + * for example: |
|
112 | + * $FQCNs = array( |
|
113 | + * '/Fully/Qualified/ClassNameA' |
|
114 | + * '/Fully/Qualified/Other/ClassNameB' |
|
115 | + * ); |
|
116 | + * |
|
117 | + * @var array $collection_FQCNs |
|
118 | + */ |
|
119 | + protected $collection_FQCNs = array(); |
|
120 | + |
|
121 | + /** |
|
122 | + * an array of full server paths to folders containing files to be loaded into collection |
|
123 | + * for example: |
|
124 | + * $paths = array( |
|
125 | + * '/full/server/path/to/ClassNameA.ext.php' // for class ClassNameA |
|
126 | + * '/full/server/path/to/other/ClassNameB.php' // for class ClassNameB |
|
127 | + * ); |
|
128 | + * |
|
129 | + * @var array $collection_paths |
|
130 | + */ |
|
131 | + protected $collection_paths = array(); |
|
132 | + |
|
133 | + /** |
|
134 | + * @var LocatorInterface $file_locator |
|
135 | + */ |
|
136 | + protected $file_locator; |
|
137 | + |
|
138 | + |
|
139 | + /** |
|
140 | + * CollectionDetails constructor. |
|
141 | + * |
|
142 | + * @access public |
|
143 | + * @param string $collection_name |
|
144 | + * @param string $collection_interface |
|
145 | + * @param array $collection_FQCNs |
|
146 | + * @param array $collection_paths |
|
147 | + * @param string $file_mask |
|
148 | + * @param string $identifier_type |
|
149 | + * @param string $identifier_callback |
|
150 | + * @param LocatorInterface $file_locator |
|
151 | + * @throws CollectionDetailsException |
|
152 | + */ |
|
153 | + public function __construct( |
|
154 | + $collection_name, |
|
155 | + $collection_interface, |
|
156 | + array $collection_FQCNs = array(), |
|
157 | + array $collection_paths = array(), |
|
158 | + $file_mask = '', |
|
159 | + $identifier_type = CollectionDetails::ID_OBJECT_HASH, |
|
160 | + $identifier_callback = '', |
|
161 | + LocatorInterface $file_locator = null |
|
162 | + ) { |
|
163 | + try { |
|
164 | + $this->setCollectionName($collection_name); |
|
165 | + $this->setCollectionInterface($collection_interface); |
|
166 | + $this->setCollectionFQCNs($collection_FQCNs); |
|
167 | + $this->setCollectionPaths($collection_paths); |
|
168 | + $this->setFileMasks($file_mask); |
|
169 | + $this->setIdentifierType($identifier_type); |
|
170 | + $this->setIdentifierCallback($identifier_callback); |
|
171 | + $this->file_locator = $file_locator; |
|
172 | + } catch (Exception $exception) { |
|
173 | + throw new CollectionDetailsException($exception); |
|
174 | + } |
|
175 | + } |
|
176 | + |
|
177 | + |
|
178 | + /** |
|
179 | + * @access public |
|
180 | + * @return mixed |
|
181 | + */ |
|
182 | + public function getCollectionInterface() |
|
183 | + { |
|
184 | + return $this->collection_interface; |
|
185 | + } |
|
186 | + |
|
187 | + |
|
188 | + /** |
|
189 | + * @access protected |
|
190 | + * @param string $collection_interface |
|
191 | + * @throws \EventEspresso\core\exceptions\InvalidInterfaceException |
|
192 | + */ |
|
193 | + protected function setCollectionInterface($collection_interface) |
|
194 | + { |
|
195 | + if (! (interface_exists($collection_interface) || class_exists($collection_interface))) { |
|
196 | + throw new InvalidInterfaceException($collection_interface); |
|
197 | + } |
|
198 | + $this->collection_interface = $collection_interface; |
|
199 | + } |
|
200 | + |
|
201 | + |
|
202 | + /** |
|
203 | + * the collection name will be used for creating dynamic filters |
|
204 | + * |
|
205 | + * @access public |
|
206 | + * @return string |
|
207 | + */ |
|
208 | + public function collectionName() |
|
209 | + { |
|
210 | + return $this->collection_name; |
|
211 | + } |
|
212 | + |
|
213 | + |
|
214 | + /** |
|
215 | + * sanitizes collection name and converts spaces and dashes to underscores |
|
216 | + * |
|
217 | + * @access protected |
|
218 | + * @param string $collection_name |
|
219 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
220 | + */ |
|
221 | + protected function setCollectionName($collection_name) |
|
222 | + { |
|
223 | + if (! is_string($collection_name)) { |
|
224 | + throw new InvalidDataTypeException('$collection_name', $collection_name, 'string'); |
|
225 | + } |
|
226 | + $this->collection_name = str_replace( |
|
227 | + '-', |
|
228 | + '_', |
|
229 | + sanitize_title_with_dashes($collection_name, '', 'save') |
|
230 | + ); |
|
231 | + } |
|
232 | + |
|
233 | + |
|
234 | + /** |
|
235 | + * @access public |
|
236 | + * @return string |
|
237 | + */ |
|
238 | + public function identifierType() |
|
239 | + { |
|
240 | + return $this->identifier_type; |
|
241 | + } |
|
242 | + |
|
243 | + |
|
244 | + /** |
|
245 | + * @access protected |
|
246 | + * @param string $identifier_type |
|
247 | + * @throws InvalidIdentifierException |
|
248 | + */ |
|
249 | + protected function setIdentifierType($identifier_type) |
|
250 | + { |
|
251 | + if ( |
|
252 | + ! ($identifier_type === CollectionDetails::ID_CLASS_NAME |
|
253 | + || $identifier_type === CollectionDetails::ID_OBJECT_HASH |
|
254 | + || $identifier_type === CollectionDetails::ID_CALLBACK_METHOD |
|
255 | + ) |
|
256 | + ) { |
|
257 | + throw new InvalidIdentifierException( |
|
258 | + $identifier_type, |
|
259 | + 'CollectionDetails::ID_CLASS_NAME or CollectionDetails::ID_OBJECT_HASH or CollectionDetails::ID_CALLBACK_METHOD' |
|
260 | + ); |
|
261 | + } |
|
262 | + $this->identifier_type = $identifier_type; |
|
263 | + } |
|
264 | + |
|
265 | + |
|
266 | + /** |
|
267 | + * @access public |
|
268 | + * @return string |
|
269 | + */ |
|
270 | + public function identifierCallback() |
|
271 | + { |
|
272 | + return $this->identifier_callback; |
|
273 | + } |
|
274 | + |
|
275 | + |
|
276 | + /** |
|
277 | + * @access protected |
|
278 | + * @param string $identifier_callback |
|
279 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
280 | + */ |
|
281 | + protected function setIdentifierCallback($identifier_callback = 'identifier') |
|
282 | + { |
|
283 | + if (! is_string($identifier_callback)) { |
|
284 | + throw new InvalidDataTypeException('$identifier_callback', $identifier_callback, 'string'); |
|
285 | + } |
|
286 | + $this->identifier_callback = $identifier_callback; |
|
287 | + } |
|
288 | + |
|
289 | + |
|
290 | + /** |
|
291 | + * @access public |
|
292 | + * @return string |
|
293 | + */ |
|
294 | + public function getFileMask() |
|
295 | + { |
|
296 | + return $this->file_mask; |
|
297 | + } |
|
298 | + |
|
299 | + |
|
300 | + /** |
|
301 | + * sets the file mask which is then used to filter what files get loaded |
|
302 | + * when searching for classes to add to the collection. Defaults to '*.php' |
|
303 | + * |
|
304 | + * @access protected |
|
305 | + * @param string $file_mask |
|
306 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
307 | + */ |
|
308 | + protected function setFileMasks($file_mask) |
|
309 | + { |
|
310 | + $this->file_mask = ! empty($file_mask) ? $file_mask : '*.php'; |
|
311 | + // we know our default is a string, so if it's not a string now, |
|
312 | + // then that means the incoming parameter was something else |
|
313 | + if (! is_string($this->file_mask)) { |
|
314 | + throw new InvalidDataTypeException('$file_mask', $this->file_mask, 'string'); |
|
315 | + } |
|
316 | + } |
|
317 | + |
|
318 | + |
|
319 | + /** |
|
320 | + * @access public |
|
321 | + * @return array |
|
322 | + */ |
|
323 | + public function getCollectionFQCNs() |
|
324 | + { |
|
325 | + return $this->collection_FQCNs; |
|
326 | + } |
|
327 | + |
|
328 | + |
|
329 | + /** |
|
330 | + * @access public |
|
331 | + * @param string|array $collection_FQCNs |
|
332 | + * @throws \EventEspresso\core\exceptions\InvalidClassException |
|
333 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
334 | + */ |
|
335 | + public function setCollectionFQCNs($collection_FQCNs) |
|
336 | + { |
|
337 | + foreach ((array) $collection_FQCNs as $collection_FQCN) { |
|
338 | + if (! empty($collection_FQCN)) { |
|
339 | + if (class_exists($collection_FQCN)) { |
|
340 | + $this->collection_FQCNs[] = $collection_FQCN; |
|
341 | + } else { |
|
342 | + foreach ($this->getFQCNsFromPartialNamespace($collection_FQCN) as $FQCN) { |
|
343 | + $this->collection_FQCNs[] = $FQCN; |
|
344 | + } |
|
345 | + } |
|
346 | + } |
|
347 | + } |
|
348 | + } |
|
349 | + |
|
350 | + |
|
351 | + /** |
|
352 | + * @access protected |
|
353 | + * @param string $partial_FQCN |
|
354 | + * @return array |
|
355 | + * @throws \EventEspresso\core\exceptions\InvalidDataTypeException |
|
356 | + * @throws \EventEspresso\core\exceptions\InvalidClassException |
|
357 | + */ |
|
358 | + protected function getFQCNsFromPartialNamespace($partial_FQCN) |
|
359 | + { |
|
360 | + if (! $this->file_locator instanceof FqcnLocator) { |
|
361 | + $this->file_locator = new FqcnLocator(); |
|
362 | + } |
|
363 | + $this->file_locator->locate($partial_FQCN); |
|
364 | + return $this->file_locator->getFQCNs(); |
|
365 | + } |
|
366 | + |
|
367 | + |
|
368 | + /** |
|
369 | + * @access public |
|
370 | + * @return array |
|
371 | + */ |
|
372 | + public function getCollectionPaths() |
|
373 | + { |
|
374 | + return $this->collection_paths; |
|
375 | + } |
|
376 | + |
|
377 | + |
|
378 | + /** |
|
379 | + * @access public |
|
380 | + * @param string|array $collection_paths |
|
381 | + * @throws \EventEspresso\core\exceptions\InvalidFilePathException |
|
382 | + */ |
|
383 | + public function setCollectionPaths($collection_paths) |
|
384 | + { |
|
385 | + foreach ((array) $collection_paths as $collection_path) { |
|
386 | + if (! empty($collection_path)) { |
|
387 | + if (! is_readable($collection_path)) { |
|
388 | + throw new InvalidFilePathException($collection_path); |
|
389 | + } |
|
390 | + $this->collection_paths[] = $collection_path; |
|
391 | + } |
|
392 | + } |
|
393 | + } |
|
394 | 394 | } |
@@ -85,7 +85,7 @@ discard block |
||
85 | 85 | */ |
86 | 86 | public function setReturnUrl($return_url) |
87 | 87 | { |
88 | - if (! is_string($return_url)) { |
|
88 | + if ( ! is_string($return_url)) { |
|
89 | 89 | throw new InvalidDataTypeException('$return_url', $return_url, 'string'); |
90 | 90 | } |
91 | 91 | $this->return_url = $return_url; |
@@ -102,7 +102,7 @@ discard block |
||
102 | 102 | */ |
103 | 103 | protected function getPersistentAdminNoticeCollection() |
104 | 104 | { |
105 | - if (! $this->notice_collection instanceof Collection) { |
|
105 | + if ( ! $this->notice_collection instanceof Collection) { |
|
106 | 106 | $this->notice_collection = new Collection( |
107 | 107 | 'EventEspresso\core\domain\entities\notifications\PersistentAdminNotice' |
108 | 108 | ); |
@@ -125,7 +125,7 @@ discard block |
||
125 | 125 | protected function retrieveStoredNotices() |
126 | 126 | { |
127 | 127 | $persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array()); |
128 | - if (! empty($persistent_admin_notices)) { |
|
128 | + if ( ! empty($persistent_admin_notices)) { |
|
129 | 129 | foreach ($persistent_admin_notices as $name => $details) { |
130 | 130 | if (is_array($details)) { |
131 | 131 | if ( |
@@ -247,14 +247,14 @@ discard block |
||
247 | 247 | { |
248 | 248 | wp_register_script( |
249 | 249 | 'espresso_core', |
250 | - EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js', |
|
250 | + EE_GLOBAL_ASSETS_URL.'scripts/espresso_core.js', |
|
251 | 251 | array('jquery'), |
252 | 252 | EVENT_ESPRESSO_VERSION, |
253 | 253 | true |
254 | 254 | ); |
255 | 255 | wp_register_script( |
256 | 256 | 'ee_error_js', |
257 | - EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js', |
|
257 | + EE_GLOBAL_ASSETS_URL.'scripts/EE_Error.js', |
|
258 | 258 | array('espresso_core'), |
259 | 259 | EVENT_ESPRESSO_VERSION, |
260 | 260 | true |
@@ -285,7 +285,7 @@ discard block |
||
285 | 285 | // used in template |
286 | 286 | $persistent_admin_notice_name = $persistent_admin_notice->getName(); |
287 | 287 | $persistent_admin_notice_message = $persistent_admin_notice->getMessage(); |
288 | - require EE_TEMPLATES . '/notifications/persistent_admin_notice.template.php'; |
|
288 | + require EE_TEMPLATES.'/notifications/persistent_admin_notice.template.php'; |
|
289 | 289 | } |
290 | 290 | |
291 | 291 | |
@@ -310,7 +310,7 @@ discard block |
||
310 | 310 | { |
311 | 311 | $pan_name = $this->request->getRequestParam('ee_nag_notice', $pan_name); |
312 | 312 | $this->notice_collection = $this->getPersistentAdminNoticeCollection(); |
313 | - if (! empty($pan_name) && $this->notice_collection->has($pan_name)) { |
|
313 | + if ( ! empty($pan_name) && $this->notice_collection->has($pan_name)) { |
|
314 | 314 | /** @var PersistentAdminNotice $persistent_admin_notice */ |
315 | 315 | $persistent_admin_notice = $this->notice_collection->get($pan_name); |
316 | 316 | $persistent_admin_notice->setDismissed(true); |
@@ -360,10 +360,10 @@ discard block |
||
360 | 360 | foreach ($this->notice_collection as $persistent_admin_notice) { |
361 | 361 | // are we deleting this notice ? |
362 | 362 | if ($persistent_admin_notice->getPurge()) { |
363 | - unset($persistent_admin_notices[ $persistent_admin_notice->getName() ]); |
|
363 | + unset($persistent_admin_notices[$persistent_admin_notice->getName()]); |
|
364 | 364 | } else { |
365 | 365 | /** @var PersistentAdminNotice $persistent_admin_notice */ |
366 | - $persistent_admin_notices[ $persistent_admin_notice->getName() ] = array( |
|
366 | + $persistent_admin_notices[$persistent_admin_notice->getName()] = array( |
|
367 | 367 | 'message' => $persistent_admin_notice->getMessage(), |
368 | 368 | 'capability' => $persistent_admin_notice->getCapability(), |
369 | 369 | 'cap_context' => $persistent_admin_notice->getCapContext(), |
@@ -30,392 +30,392 @@ |
||
30 | 30 | */ |
31 | 31 | class PersistentAdminNoticeManager |
32 | 32 | { |
33 | - const WP_OPTION_KEY = 'ee_pers_admin_notices'; |
|
34 | - |
|
35 | - /** |
|
36 | - * @var Collection|PersistentAdminNotice[] $notice_collection |
|
37 | - */ |
|
38 | - private $notice_collection; |
|
39 | - |
|
40 | - /** |
|
41 | - * if AJAX is not enabled, then the return URL will be used for redirecting back to the admin page where the |
|
42 | - * persistent admin notice was displayed, and ultimately dismissed from. |
|
43 | - * |
|
44 | - * @var string $return_url |
|
45 | - */ |
|
46 | - private $return_url; |
|
47 | - |
|
48 | - /** |
|
49 | - * @var CapabilitiesChecker $capabilities_checker |
|
50 | - */ |
|
51 | - private $capabilities_checker; |
|
52 | - |
|
53 | - /** |
|
54 | - * @var RequestInterface $request |
|
55 | - */ |
|
56 | - private $request; |
|
57 | - |
|
58 | - |
|
59 | - /** |
|
60 | - * PersistentAdminNoticeManager constructor |
|
61 | - * |
|
62 | - * @param CapabilitiesChecker $capabilities_checker |
|
63 | - * @param RequestInterface $request |
|
64 | - * @param string $return_url where to redirect to after dismissing notices |
|
65 | - * @throws InvalidDataTypeException |
|
66 | - */ |
|
67 | - public function __construct( |
|
68 | - CapabilitiesChecker $capabilities_checker, |
|
69 | - RequestInterface $request, |
|
70 | - string $return_url = '' |
|
71 | - ) { |
|
72 | - $this->setReturnUrl($return_url); |
|
73 | - $this->capabilities_checker = $capabilities_checker; |
|
74 | - $this->request = $request; |
|
75 | - // setup up notices at priority 9 because `EE_Admin::display_admin_notices()` runs at priority 10, |
|
76 | - // and we want to retrieve and generate any nag notices at the last possible moment |
|
77 | - add_action('admin_notices', array($this, 'displayNotices'), 9); |
|
78 | - add_action('network_admin_notices', array($this, 'displayNotices'), 9); |
|
79 | - add_action('wp_ajax_dismiss_ee_nag_notice', array($this, 'dismissNotice')); |
|
80 | - add_action('shutdown', array($this, 'registerAndSaveNotices'), 998); |
|
81 | - } |
|
82 | - |
|
83 | - |
|
84 | - /** |
|
85 | - * @param string $return_url |
|
86 | - * @throws InvalidDataTypeException |
|
87 | - */ |
|
88 | - public function setReturnUrl($return_url) |
|
89 | - { |
|
90 | - if (! is_string($return_url)) { |
|
91 | - throw new InvalidDataTypeException('$return_url', $return_url, 'string'); |
|
92 | - } |
|
93 | - $this->return_url = $return_url; |
|
94 | - } |
|
95 | - |
|
96 | - |
|
97 | - /** |
|
98 | - * @return Collection |
|
99 | - * @throws InvalidEntityException |
|
100 | - * @throws InvalidInterfaceException |
|
101 | - * @throws InvalidDataTypeException |
|
102 | - * @throws DomainException |
|
103 | - * @throws DuplicateCollectionIdentifierException |
|
104 | - */ |
|
105 | - protected function getPersistentAdminNoticeCollection() |
|
106 | - { |
|
107 | - if (! $this->notice_collection instanceof Collection) { |
|
108 | - $this->notice_collection = new Collection( |
|
109 | - 'EventEspresso\core\domain\entities\notifications\PersistentAdminNotice' |
|
110 | - ); |
|
111 | - $this->retrieveStoredNotices(); |
|
112 | - $this->registerNotices(); |
|
113 | - } |
|
114 | - return $this->notice_collection; |
|
115 | - } |
|
116 | - |
|
117 | - |
|
118 | - /** |
|
119 | - * generates PersistentAdminNotice objects for all non-dismissed notices saved to the db |
|
120 | - * |
|
121 | - * @return void |
|
122 | - * @throws InvalidEntityException |
|
123 | - * @throws DomainException |
|
124 | - * @throws InvalidDataTypeException |
|
125 | - * @throws DuplicateCollectionIdentifierException |
|
126 | - */ |
|
127 | - protected function retrieveStoredNotices() |
|
128 | - { |
|
129 | - $persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array()); |
|
130 | - if (! empty($persistent_admin_notices)) { |
|
131 | - foreach ($persistent_admin_notices as $name => $details) { |
|
132 | - if (is_array($details)) { |
|
133 | - if ( |
|
134 | - ! isset( |
|
135 | - $details['message'], |
|
136 | - $details['capability'], |
|
137 | - $details['cap_context'], |
|
138 | - $details['dismissed'] |
|
139 | - ) |
|
140 | - ) { |
|
141 | - throw new DomainException( |
|
142 | - sprintf( |
|
143 | - esc_html__( |
|
144 | - 'The "%1$s" PersistentAdminNotice could not be retrieved from the database.', |
|
145 | - 'event_espresso' |
|
146 | - ), |
|
147 | - $name |
|
148 | - ) |
|
149 | - ); |
|
150 | - } |
|
151 | - // new format for nag notices |
|
152 | - $this->notice_collection->add( |
|
153 | - new PersistentAdminNotice( |
|
154 | - $name, |
|
155 | - $details['message'], |
|
156 | - false, |
|
157 | - $details['capability'], |
|
158 | - $details['cap_context'], |
|
159 | - $details['dismissed'] |
|
160 | - ), |
|
161 | - sanitize_key($name) |
|
162 | - ); |
|
163 | - } else { |
|
164 | - try { |
|
165 | - // old nag notices, that we want to convert to the new format |
|
166 | - $this->notice_collection->add( |
|
167 | - new PersistentAdminNotice( |
|
168 | - $name, |
|
169 | - (string) $details, |
|
170 | - false, |
|
171 | - '', |
|
172 | - '', |
|
173 | - empty($details) |
|
174 | - ), |
|
175 | - sanitize_key($name) |
|
176 | - ); |
|
177 | - } catch (Exception $e) { |
|
178 | - EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
179 | - } |
|
180 | - } |
|
181 | - // each notice will self register when the action hook in registerNotices is triggered |
|
182 | - } |
|
183 | - } |
|
184 | - } |
|
185 | - |
|
186 | - |
|
187 | - /** |
|
188 | - * exposes the Persistent Admin Notice Collection via an action |
|
189 | - * so that PersistentAdminNotice objects can be added and/or removed |
|
190 | - * without compromising the actual collection like a filter would |
|
191 | - */ |
|
192 | - protected function registerNotices() |
|
193 | - { |
|
194 | - do_action( |
|
195 | - 'AHEE__EventEspresso_core_services_notifications_PersistentAdminNoticeManager__registerNotices', |
|
196 | - $this->notice_collection |
|
197 | - ); |
|
198 | - } |
|
199 | - |
|
200 | - |
|
201 | - /** |
|
202 | - * @throws DomainException |
|
203 | - * @throws InvalidClassException |
|
204 | - * @throws InvalidDataTypeException |
|
205 | - * @throws InvalidInterfaceException |
|
206 | - * @throws InvalidEntityException |
|
207 | - * @throws DuplicateCollectionIdentifierException |
|
208 | - */ |
|
209 | - public function displayNotices() |
|
210 | - { |
|
211 | - $this->notice_collection = $this->getPersistentAdminNoticeCollection(); |
|
212 | - if ($this->notice_collection->hasObjects()) { |
|
213 | - $enqueue_assets = false; |
|
214 | - // and display notices |
|
215 | - foreach ($this->notice_collection as $persistent_admin_notice) { |
|
216 | - /** @var PersistentAdminNotice $persistent_admin_notice */ |
|
217 | - // don't display notices that have already been dismissed |
|
218 | - if ($persistent_admin_notice->getDismissed()) { |
|
219 | - continue; |
|
220 | - } |
|
221 | - try { |
|
222 | - $this->capabilities_checker->processCapCheck( |
|
223 | - $persistent_admin_notice->getCapCheck() |
|
224 | - ); |
|
225 | - } catch (InsufficientPermissionsException $e) { |
|
226 | - // user does not have required cap, so skip to next notice |
|
227 | - // and just eat the exception - nom nom nom nom |
|
228 | - continue; |
|
229 | - } |
|
230 | - if ($persistent_admin_notice->getMessage() === '') { |
|
231 | - continue; |
|
232 | - } |
|
233 | - $this->displayPersistentAdminNotice($persistent_admin_notice); |
|
234 | - $enqueue_assets = true; |
|
235 | - } |
|
236 | - if ($enqueue_assets) { |
|
237 | - $this->enqueueAssets(); |
|
238 | - } |
|
239 | - } |
|
240 | - } |
|
241 | - |
|
242 | - |
|
243 | - /** |
|
244 | - * does what it's named |
|
245 | - * |
|
246 | - * @return void |
|
247 | - */ |
|
248 | - public function enqueueAssets() |
|
249 | - { |
|
250 | - wp_register_script( |
|
251 | - 'espresso_core', |
|
252 | - EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js', |
|
253 | - array('jquery'), |
|
254 | - EVENT_ESPRESSO_VERSION, |
|
255 | - true |
|
256 | - ); |
|
257 | - wp_register_script( |
|
258 | - 'ee_error_js', |
|
259 | - EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js', |
|
260 | - array('espresso_core'), |
|
261 | - EVENT_ESPRESSO_VERSION, |
|
262 | - true |
|
263 | - ); |
|
264 | - wp_localize_script( |
|
265 | - 'ee_error_js', |
|
266 | - 'ee_dismiss', |
|
267 | - array( |
|
268 | - 'return_url' => urlencode($this->return_url), |
|
269 | - 'ajax_url' => WP_AJAX_URL, |
|
270 | - 'unknown_error' => wp_strip_all_tags( |
|
271 | - __( |
|
272 | - 'An unknown error has occurred on the server while attempting to dismiss this notice.', |
|
273 | - 'event_espresso' |
|
274 | - ) |
|
275 | - ), |
|
276 | - ) |
|
277 | - ); |
|
278 | - wp_enqueue_script('ee_error_js'); |
|
279 | - } |
|
280 | - |
|
281 | - |
|
282 | - /** |
|
283 | - * displayPersistentAdminNoticeHtml |
|
284 | - * |
|
285 | - * @param PersistentAdminNotice $persistent_admin_notice |
|
286 | - */ |
|
287 | - protected function displayPersistentAdminNotice(PersistentAdminNotice $persistent_admin_notice) |
|
288 | - { |
|
289 | - // used in template |
|
290 | - $persistent_admin_notice_name = $persistent_admin_notice->getName(); |
|
291 | - $persistent_admin_notice_message = $persistent_admin_notice->getMessage(); |
|
292 | - require EE_TEMPLATES . '/notifications/persistent_admin_notice.template.php'; |
|
293 | - } |
|
294 | - |
|
295 | - |
|
296 | - /** |
|
297 | - * dismissNotice |
|
298 | - * |
|
299 | - * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed |
|
300 | - * @param bool $purge if true, then delete it from the db |
|
301 | - * @param bool $return forget all of this AJAX or redirect nonsense, and just return |
|
302 | - * @return void |
|
303 | - * @throws InvalidEntityException |
|
304 | - * @throws InvalidInterfaceException |
|
305 | - * @throws InvalidDataTypeException |
|
306 | - * @throws DomainException |
|
307 | - * @throws InvalidArgumentException |
|
308 | - * @throws InvalidArgumentException |
|
309 | - * @throws InvalidArgumentException |
|
310 | - * @throws InvalidArgumentException |
|
311 | - * @throws DuplicateCollectionIdentifierException |
|
312 | - */ |
|
313 | - public function dismissNotice($pan_name = '', $purge = false, $return = false) |
|
314 | - { |
|
315 | - $pan_name = $this->request->getRequestParam('ee_nag_notice', $pan_name); |
|
316 | - $this->notice_collection = $this->getPersistentAdminNoticeCollection(); |
|
317 | - if (! empty($pan_name) && $this->notice_collection->has($pan_name)) { |
|
318 | - /** @var PersistentAdminNotice $persistent_admin_notice */ |
|
319 | - $persistent_admin_notice = $this->notice_collection->get($pan_name); |
|
320 | - $persistent_admin_notice->setDismissed(true); |
|
321 | - $persistent_admin_notice->setPurge($purge); |
|
322 | - $this->saveNotices(); |
|
323 | - } |
|
324 | - if ($return) { |
|
325 | - return; |
|
326 | - } |
|
327 | - if ($this->request->isAjax()) { |
|
328 | - // grab any notices and concatenate into string |
|
329 | - echo wp_json_encode( |
|
330 | - array( |
|
331 | - 'errors' => implode('<br />', EE_Error::get_notices(false)), |
|
332 | - ) |
|
333 | - ); |
|
334 | - exit(); |
|
335 | - } |
|
336 | - // save errors to a transient to be displayed on next request (after redirect) |
|
337 | - EE_Error::get_notices(false, true); |
|
338 | - wp_safe_redirect( |
|
339 | - urldecode( |
|
340 | - $this->request->getRequestParam('return_url', '') |
|
341 | - ) |
|
342 | - ); |
|
343 | - } |
|
344 | - |
|
345 | - |
|
346 | - /** |
|
347 | - * saveNotices |
|
348 | - * |
|
349 | - * @throws DomainException |
|
350 | - * @throws InvalidDataTypeException |
|
351 | - * @throws InvalidInterfaceException |
|
352 | - * @throws InvalidEntityException |
|
353 | - * @throws DuplicateCollectionIdentifierException |
|
354 | - */ |
|
355 | - public function saveNotices() |
|
356 | - { |
|
357 | - $this->notice_collection = $this->getPersistentAdminNoticeCollection(); |
|
358 | - if ($this->notice_collection->hasObjects()) { |
|
359 | - $persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array()); |
|
360 | - // maybe initialize persistent_admin_notices |
|
361 | - if (empty($persistent_admin_notices)) { |
|
362 | - add_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array(), '', 'no'); |
|
363 | - } |
|
364 | - foreach ($this->notice_collection as $persistent_admin_notice) { |
|
365 | - // are we deleting this notice ? |
|
366 | - if ($persistent_admin_notice->getPurge()) { |
|
367 | - unset($persistent_admin_notices[ $persistent_admin_notice->getName() ]); |
|
368 | - } else { |
|
369 | - /** @var PersistentAdminNotice $persistent_admin_notice */ |
|
370 | - $persistent_admin_notices[ $persistent_admin_notice->getName() ] = array( |
|
371 | - 'message' => $persistent_admin_notice->getMessage(), |
|
372 | - 'capability' => $persistent_admin_notice->getCapability(), |
|
373 | - 'cap_context' => $persistent_admin_notice->getCapContext(), |
|
374 | - 'dismissed' => $persistent_admin_notice->getDismissed(), |
|
375 | - ); |
|
376 | - } |
|
377 | - } |
|
378 | - update_option(PersistentAdminNoticeManager::WP_OPTION_KEY, $persistent_admin_notices); |
|
379 | - } |
|
380 | - } |
|
381 | - |
|
382 | - |
|
383 | - /** |
|
384 | - * @throws DomainException |
|
385 | - * @throws InvalidDataTypeException |
|
386 | - * @throws InvalidEntityException |
|
387 | - * @throws InvalidInterfaceException |
|
388 | - * @throws DuplicateCollectionIdentifierException |
|
389 | - */ |
|
390 | - public function registerAndSaveNotices() |
|
391 | - { |
|
392 | - $this->getPersistentAdminNoticeCollection(); |
|
393 | - $this->registerNotices(); |
|
394 | - $this->saveNotices(); |
|
395 | - add_filter( |
|
396 | - 'PersistentAdminNoticeManager__registerAndSaveNotices__complete', |
|
397 | - '__return_true' |
|
398 | - ); |
|
399 | - } |
|
400 | - |
|
401 | - |
|
402 | - /** |
|
403 | - * @throws DomainException |
|
404 | - * @throws InvalidDataTypeException |
|
405 | - * @throws InvalidEntityException |
|
406 | - * @throws InvalidInterfaceException |
|
407 | - * @throws InvalidArgumentException |
|
408 | - * @throws DuplicateCollectionIdentifierException |
|
409 | - */ |
|
410 | - public static function loadRegisterAndSaveNotices() |
|
411 | - { |
|
412 | - /** @var PersistentAdminNoticeManager $persistent_admin_notice_manager */ |
|
413 | - $persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared( |
|
414 | - 'EventEspresso\core\services\notifications\PersistentAdminNoticeManager' |
|
415 | - ); |
|
416 | - // if shutdown has already run, then call registerAndSaveNotices() manually |
|
417 | - if (did_action('shutdown')) { |
|
418 | - $persistent_admin_notice_manager->registerAndSaveNotices(); |
|
419 | - } |
|
420 | - } |
|
33 | + const WP_OPTION_KEY = 'ee_pers_admin_notices'; |
|
34 | + |
|
35 | + /** |
|
36 | + * @var Collection|PersistentAdminNotice[] $notice_collection |
|
37 | + */ |
|
38 | + private $notice_collection; |
|
39 | + |
|
40 | + /** |
|
41 | + * if AJAX is not enabled, then the return URL will be used for redirecting back to the admin page where the |
|
42 | + * persistent admin notice was displayed, and ultimately dismissed from. |
|
43 | + * |
|
44 | + * @var string $return_url |
|
45 | + */ |
|
46 | + private $return_url; |
|
47 | + |
|
48 | + /** |
|
49 | + * @var CapabilitiesChecker $capabilities_checker |
|
50 | + */ |
|
51 | + private $capabilities_checker; |
|
52 | + |
|
53 | + /** |
|
54 | + * @var RequestInterface $request |
|
55 | + */ |
|
56 | + private $request; |
|
57 | + |
|
58 | + |
|
59 | + /** |
|
60 | + * PersistentAdminNoticeManager constructor |
|
61 | + * |
|
62 | + * @param CapabilitiesChecker $capabilities_checker |
|
63 | + * @param RequestInterface $request |
|
64 | + * @param string $return_url where to redirect to after dismissing notices |
|
65 | + * @throws InvalidDataTypeException |
|
66 | + */ |
|
67 | + public function __construct( |
|
68 | + CapabilitiesChecker $capabilities_checker, |
|
69 | + RequestInterface $request, |
|
70 | + string $return_url = '' |
|
71 | + ) { |
|
72 | + $this->setReturnUrl($return_url); |
|
73 | + $this->capabilities_checker = $capabilities_checker; |
|
74 | + $this->request = $request; |
|
75 | + // setup up notices at priority 9 because `EE_Admin::display_admin_notices()` runs at priority 10, |
|
76 | + // and we want to retrieve and generate any nag notices at the last possible moment |
|
77 | + add_action('admin_notices', array($this, 'displayNotices'), 9); |
|
78 | + add_action('network_admin_notices', array($this, 'displayNotices'), 9); |
|
79 | + add_action('wp_ajax_dismiss_ee_nag_notice', array($this, 'dismissNotice')); |
|
80 | + add_action('shutdown', array($this, 'registerAndSaveNotices'), 998); |
|
81 | + } |
|
82 | + |
|
83 | + |
|
84 | + /** |
|
85 | + * @param string $return_url |
|
86 | + * @throws InvalidDataTypeException |
|
87 | + */ |
|
88 | + public function setReturnUrl($return_url) |
|
89 | + { |
|
90 | + if (! is_string($return_url)) { |
|
91 | + throw new InvalidDataTypeException('$return_url', $return_url, 'string'); |
|
92 | + } |
|
93 | + $this->return_url = $return_url; |
|
94 | + } |
|
95 | + |
|
96 | + |
|
97 | + /** |
|
98 | + * @return Collection |
|
99 | + * @throws InvalidEntityException |
|
100 | + * @throws InvalidInterfaceException |
|
101 | + * @throws InvalidDataTypeException |
|
102 | + * @throws DomainException |
|
103 | + * @throws DuplicateCollectionIdentifierException |
|
104 | + */ |
|
105 | + protected function getPersistentAdminNoticeCollection() |
|
106 | + { |
|
107 | + if (! $this->notice_collection instanceof Collection) { |
|
108 | + $this->notice_collection = new Collection( |
|
109 | + 'EventEspresso\core\domain\entities\notifications\PersistentAdminNotice' |
|
110 | + ); |
|
111 | + $this->retrieveStoredNotices(); |
|
112 | + $this->registerNotices(); |
|
113 | + } |
|
114 | + return $this->notice_collection; |
|
115 | + } |
|
116 | + |
|
117 | + |
|
118 | + /** |
|
119 | + * generates PersistentAdminNotice objects for all non-dismissed notices saved to the db |
|
120 | + * |
|
121 | + * @return void |
|
122 | + * @throws InvalidEntityException |
|
123 | + * @throws DomainException |
|
124 | + * @throws InvalidDataTypeException |
|
125 | + * @throws DuplicateCollectionIdentifierException |
|
126 | + */ |
|
127 | + protected function retrieveStoredNotices() |
|
128 | + { |
|
129 | + $persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array()); |
|
130 | + if (! empty($persistent_admin_notices)) { |
|
131 | + foreach ($persistent_admin_notices as $name => $details) { |
|
132 | + if (is_array($details)) { |
|
133 | + if ( |
|
134 | + ! isset( |
|
135 | + $details['message'], |
|
136 | + $details['capability'], |
|
137 | + $details['cap_context'], |
|
138 | + $details['dismissed'] |
|
139 | + ) |
|
140 | + ) { |
|
141 | + throw new DomainException( |
|
142 | + sprintf( |
|
143 | + esc_html__( |
|
144 | + 'The "%1$s" PersistentAdminNotice could not be retrieved from the database.', |
|
145 | + 'event_espresso' |
|
146 | + ), |
|
147 | + $name |
|
148 | + ) |
|
149 | + ); |
|
150 | + } |
|
151 | + // new format for nag notices |
|
152 | + $this->notice_collection->add( |
|
153 | + new PersistentAdminNotice( |
|
154 | + $name, |
|
155 | + $details['message'], |
|
156 | + false, |
|
157 | + $details['capability'], |
|
158 | + $details['cap_context'], |
|
159 | + $details['dismissed'] |
|
160 | + ), |
|
161 | + sanitize_key($name) |
|
162 | + ); |
|
163 | + } else { |
|
164 | + try { |
|
165 | + // old nag notices, that we want to convert to the new format |
|
166 | + $this->notice_collection->add( |
|
167 | + new PersistentAdminNotice( |
|
168 | + $name, |
|
169 | + (string) $details, |
|
170 | + false, |
|
171 | + '', |
|
172 | + '', |
|
173 | + empty($details) |
|
174 | + ), |
|
175 | + sanitize_key($name) |
|
176 | + ); |
|
177 | + } catch (Exception $e) { |
|
178 | + EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
179 | + } |
|
180 | + } |
|
181 | + // each notice will self register when the action hook in registerNotices is triggered |
|
182 | + } |
|
183 | + } |
|
184 | + } |
|
185 | + |
|
186 | + |
|
187 | + /** |
|
188 | + * exposes the Persistent Admin Notice Collection via an action |
|
189 | + * so that PersistentAdminNotice objects can be added and/or removed |
|
190 | + * without compromising the actual collection like a filter would |
|
191 | + */ |
|
192 | + protected function registerNotices() |
|
193 | + { |
|
194 | + do_action( |
|
195 | + 'AHEE__EventEspresso_core_services_notifications_PersistentAdminNoticeManager__registerNotices', |
|
196 | + $this->notice_collection |
|
197 | + ); |
|
198 | + } |
|
199 | + |
|
200 | + |
|
201 | + /** |
|
202 | + * @throws DomainException |
|
203 | + * @throws InvalidClassException |
|
204 | + * @throws InvalidDataTypeException |
|
205 | + * @throws InvalidInterfaceException |
|
206 | + * @throws InvalidEntityException |
|
207 | + * @throws DuplicateCollectionIdentifierException |
|
208 | + */ |
|
209 | + public function displayNotices() |
|
210 | + { |
|
211 | + $this->notice_collection = $this->getPersistentAdminNoticeCollection(); |
|
212 | + if ($this->notice_collection->hasObjects()) { |
|
213 | + $enqueue_assets = false; |
|
214 | + // and display notices |
|
215 | + foreach ($this->notice_collection as $persistent_admin_notice) { |
|
216 | + /** @var PersistentAdminNotice $persistent_admin_notice */ |
|
217 | + // don't display notices that have already been dismissed |
|
218 | + if ($persistent_admin_notice->getDismissed()) { |
|
219 | + continue; |
|
220 | + } |
|
221 | + try { |
|
222 | + $this->capabilities_checker->processCapCheck( |
|
223 | + $persistent_admin_notice->getCapCheck() |
|
224 | + ); |
|
225 | + } catch (InsufficientPermissionsException $e) { |
|
226 | + // user does not have required cap, so skip to next notice |
|
227 | + // and just eat the exception - nom nom nom nom |
|
228 | + continue; |
|
229 | + } |
|
230 | + if ($persistent_admin_notice->getMessage() === '') { |
|
231 | + continue; |
|
232 | + } |
|
233 | + $this->displayPersistentAdminNotice($persistent_admin_notice); |
|
234 | + $enqueue_assets = true; |
|
235 | + } |
|
236 | + if ($enqueue_assets) { |
|
237 | + $this->enqueueAssets(); |
|
238 | + } |
|
239 | + } |
|
240 | + } |
|
241 | + |
|
242 | + |
|
243 | + /** |
|
244 | + * does what it's named |
|
245 | + * |
|
246 | + * @return void |
|
247 | + */ |
|
248 | + public function enqueueAssets() |
|
249 | + { |
|
250 | + wp_register_script( |
|
251 | + 'espresso_core', |
|
252 | + EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js', |
|
253 | + array('jquery'), |
|
254 | + EVENT_ESPRESSO_VERSION, |
|
255 | + true |
|
256 | + ); |
|
257 | + wp_register_script( |
|
258 | + 'ee_error_js', |
|
259 | + EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js', |
|
260 | + array('espresso_core'), |
|
261 | + EVENT_ESPRESSO_VERSION, |
|
262 | + true |
|
263 | + ); |
|
264 | + wp_localize_script( |
|
265 | + 'ee_error_js', |
|
266 | + 'ee_dismiss', |
|
267 | + array( |
|
268 | + 'return_url' => urlencode($this->return_url), |
|
269 | + 'ajax_url' => WP_AJAX_URL, |
|
270 | + 'unknown_error' => wp_strip_all_tags( |
|
271 | + __( |
|
272 | + 'An unknown error has occurred on the server while attempting to dismiss this notice.', |
|
273 | + 'event_espresso' |
|
274 | + ) |
|
275 | + ), |
|
276 | + ) |
|
277 | + ); |
|
278 | + wp_enqueue_script('ee_error_js'); |
|
279 | + } |
|
280 | + |
|
281 | + |
|
282 | + /** |
|
283 | + * displayPersistentAdminNoticeHtml |
|
284 | + * |
|
285 | + * @param PersistentAdminNotice $persistent_admin_notice |
|
286 | + */ |
|
287 | + protected function displayPersistentAdminNotice(PersistentAdminNotice $persistent_admin_notice) |
|
288 | + { |
|
289 | + // used in template |
|
290 | + $persistent_admin_notice_name = $persistent_admin_notice->getName(); |
|
291 | + $persistent_admin_notice_message = $persistent_admin_notice->getMessage(); |
|
292 | + require EE_TEMPLATES . '/notifications/persistent_admin_notice.template.php'; |
|
293 | + } |
|
294 | + |
|
295 | + |
|
296 | + /** |
|
297 | + * dismissNotice |
|
298 | + * |
|
299 | + * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed |
|
300 | + * @param bool $purge if true, then delete it from the db |
|
301 | + * @param bool $return forget all of this AJAX or redirect nonsense, and just return |
|
302 | + * @return void |
|
303 | + * @throws InvalidEntityException |
|
304 | + * @throws InvalidInterfaceException |
|
305 | + * @throws InvalidDataTypeException |
|
306 | + * @throws DomainException |
|
307 | + * @throws InvalidArgumentException |
|
308 | + * @throws InvalidArgumentException |
|
309 | + * @throws InvalidArgumentException |
|
310 | + * @throws InvalidArgumentException |
|
311 | + * @throws DuplicateCollectionIdentifierException |
|
312 | + */ |
|
313 | + public function dismissNotice($pan_name = '', $purge = false, $return = false) |
|
314 | + { |
|
315 | + $pan_name = $this->request->getRequestParam('ee_nag_notice', $pan_name); |
|
316 | + $this->notice_collection = $this->getPersistentAdminNoticeCollection(); |
|
317 | + if (! empty($pan_name) && $this->notice_collection->has($pan_name)) { |
|
318 | + /** @var PersistentAdminNotice $persistent_admin_notice */ |
|
319 | + $persistent_admin_notice = $this->notice_collection->get($pan_name); |
|
320 | + $persistent_admin_notice->setDismissed(true); |
|
321 | + $persistent_admin_notice->setPurge($purge); |
|
322 | + $this->saveNotices(); |
|
323 | + } |
|
324 | + if ($return) { |
|
325 | + return; |
|
326 | + } |
|
327 | + if ($this->request->isAjax()) { |
|
328 | + // grab any notices and concatenate into string |
|
329 | + echo wp_json_encode( |
|
330 | + array( |
|
331 | + 'errors' => implode('<br />', EE_Error::get_notices(false)), |
|
332 | + ) |
|
333 | + ); |
|
334 | + exit(); |
|
335 | + } |
|
336 | + // save errors to a transient to be displayed on next request (after redirect) |
|
337 | + EE_Error::get_notices(false, true); |
|
338 | + wp_safe_redirect( |
|
339 | + urldecode( |
|
340 | + $this->request->getRequestParam('return_url', '') |
|
341 | + ) |
|
342 | + ); |
|
343 | + } |
|
344 | + |
|
345 | + |
|
346 | + /** |
|
347 | + * saveNotices |
|
348 | + * |
|
349 | + * @throws DomainException |
|
350 | + * @throws InvalidDataTypeException |
|
351 | + * @throws InvalidInterfaceException |
|
352 | + * @throws InvalidEntityException |
|
353 | + * @throws DuplicateCollectionIdentifierException |
|
354 | + */ |
|
355 | + public function saveNotices() |
|
356 | + { |
|
357 | + $this->notice_collection = $this->getPersistentAdminNoticeCollection(); |
|
358 | + if ($this->notice_collection->hasObjects()) { |
|
359 | + $persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array()); |
|
360 | + // maybe initialize persistent_admin_notices |
|
361 | + if (empty($persistent_admin_notices)) { |
|
362 | + add_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array(), '', 'no'); |
|
363 | + } |
|
364 | + foreach ($this->notice_collection as $persistent_admin_notice) { |
|
365 | + // are we deleting this notice ? |
|
366 | + if ($persistent_admin_notice->getPurge()) { |
|
367 | + unset($persistent_admin_notices[ $persistent_admin_notice->getName() ]); |
|
368 | + } else { |
|
369 | + /** @var PersistentAdminNotice $persistent_admin_notice */ |
|
370 | + $persistent_admin_notices[ $persistent_admin_notice->getName() ] = array( |
|
371 | + 'message' => $persistent_admin_notice->getMessage(), |
|
372 | + 'capability' => $persistent_admin_notice->getCapability(), |
|
373 | + 'cap_context' => $persistent_admin_notice->getCapContext(), |
|
374 | + 'dismissed' => $persistent_admin_notice->getDismissed(), |
|
375 | + ); |
|
376 | + } |
|
377 | + } |
|
378 | + update_option(PersistentAdminNoticeManager::WP_OPTION_KEY, $persistent_admin_notices); |
|
379 | + } |
|
380 | + } |
|
381 | + |
|
382 | + |
|
383 | + /** |
|
384 | + * @throws DomainException |
|
385 | + * @throws InvalidDataTypeException |
|
386 | + * @throws InvalidEntityException |
|
387 | + * @throws InvalidInterfaceException |
|
388 | + * @throws DuplicateCollectionIdentifierException |
|
389 | + */ |
|
390 | + public function registerAndSaveNotices() |
|
391 | + { |
|
392 | + $this->getPersistentAdminNoticeCollection(); |
|
393 | + $this->registerNotices(); |
|
394 | + $this->saveNotices(); |
|
395 | + add_filter( |
|
396 | + 'PersistentAdminNoticeManager__registerAndSaveNotices__complete', |
|
397 | + '__return_true' |
|
398 | + ); |
|
399 | + } |
|
400 | + |
|
401 | + |
|
402 | + /** |
|
403 | + * @throws DomainException |
|
404 | + * @throws InvalidDataTypeException |
|
405 | + * @throws InvalidEntityException |
|
406 | + * @throws InvalidInterfaceException |
|
407 | + * @throws InvalidArgumentException |
|
408 | + * @throws DuplicateCollectionIdentifierException |
|
409 | + */ |
|
410 | + public static function loadRegisterAndSaveNotices() |
|
411 | + { |
|
412 | + /** @var PersistentAdminNoticeManager $persistent_admin_notice_manager */ |
|
413 | + $persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared( |
|
414 | + 'EventEspresso\core\services\notifications\PersistentAdminNoticeManager' |
|
415 | + ); |
|
416 | + // if shutdown has already run, then call registerAndSaveNotices() manually |
|
417 | + if (did_action('shutdown')) { |
|
418 | + $persistent_admin_notice_manager->registerAndSaveNotices(); |
|
419 | + } |
|
420 | + } |
|
421 | 421 | } |
@@ -32,7 +32,7 @@ discard block |
||
32 | 32 | public function ensureTableNameHasPrefix($table_name) |
33 | 33 | { |
34 | 34 | global $wpdb; |
35 | - return strpos($table_name, $wpdb->base_prefix) === 0 ? $table_name : $wpdb->prefix . $table_name; |
|
35 | + return strpos($table_name, $wpdb->base_prefix) === 0 ? $table_name : $wpdb->prefix.$table_name; |
|
36 | 36 | } |
37 | 37 | |
38 | 38 | |
@@ -81,7 +81,7 @@ discard block |
||
81 | 81 | $wpdb->last_error = $old_error; |
82 | 82 | $EZSQL_ERROR = $ezsql_error_cache; |
83 | 83 | // if there was a table doesn't exist error |
84 | - if (! empty($new_error)) { |
|
84 | + if ( ! empty($new_error)) { |
|
85 | 85 | if ( |
86 | 86 | in_array( |
87 | 87 | \EEH_Activation::last_wpdb_error_code(), |
@@ -13,132 +13,132 @@ |
||
13 | 13 | */ |
14 | 14 | class TableAnalysis extends \EE_Base |
15 | 15 | { |
16 | - /** |
|
17 | - * The maximum number of characters that can be indexed on a column using utf8mb4 collation, |
|
18 | - * see https://events.codebasehq.com/redirect?https://make.wordpress.org/core/2015/04/02/the-utf8mb4-upgrade/ |
|
19 | - */ |
|
20 | - const INDEX_COLUMN_SIZE = 191; |
|
16 | + /** |
|
17 | + * The maximum number of characters that can be indexed on a column using utf8mb4 collation, |
|
18 | + * see https://events.codebasehq.com/redirect?https://make.wordpress.org/core/2015/04/02/the-utf8mb4-upgrade/ |
|
19 | + */ |
|
20 | + const INDEX_COLUMN_SIZE = 191; |
|
21 | 21 | |
22 | - /** |
|
23 | - * Returns the table name which will definitely have the wpdb prefix on the front, |
|
24 | - * except if it currently has the wpdb->base_prefix on the front, in which case |
|
25 | - * it will have the wpdb->base_prefix on it |
|
26 | - * |
|
27 | - * @global \wpdb $wpdb |
|
28 | - * @param string $table_name |
|
29 | - * @return string $tableName, having ensured it has the wpdb prefix on the front |
|
30 | - */ |
|
31 | - public function ensureTableNameHasPrefix($table_name) |
|
32 | - { |
|
33 | - global $wpdb; |
|
34 | - return strpos($table_name, $wpdb->base_prefix) === 0 ? $table_name : $wpdb->prefix . $table_name; |
|
35 | - } |
|
22 | + /** |
|
23 | + * Returns the table name which will definitely have the wpdb prefix on the front, |
|
24 | + * except if it currently has the wpdb->base_prefix on the front, in which case |
|
25 | + * it will have the wpdb->base_prefix on it |
|
26 | + * |
|
27 | + * @global \wpdb $wpdb |
|
28 | + * @param string $table_name |
|
29 | + * @return string $tableName, having ensured it has the wpdb prefix on the front |
|
30 | + */ |
|
31 | + public function ensureTableNameHasPrefix($table_name) |
|
32 | + { |
|
33 | + global $wpdb; |
|
34 | + return strpos($table_name, $wpdb->base_prefix) === 0 ? $table_name : $wpdb->prefix . $table_name; |
|
35 | + } |
|
36 | 36 | |
37 | 37 | |
38 | - /** |
|
39 | - * Indicates whether or not the table has any entries. $table_name can |
|
40 | - * optionally start with $wpdb->prefix or not |
|
41 | - * |
|
42 | - * @global \wpdb $wpdb |
|
43 | - * @param string $table_name |
|
44 | - * @return bool |
|
45 | - */ |
|
46 | - public function tableIsEmpty($table_name) |
|
47 | - { |
|
48 | - global $wpdb; |
|
49 | - $table_name = $this->ensureTableNameHasPrefix($table_name); |
|
50 | - if ($this->tableExists($table_name)) { |
|
51 | - $count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name"); |
|
52 | - return absint($count) === 0 ? true : false; |
|
53 | - } |
|
54 | - return false; |
|
55 | - } |
|
38 | + /** |
|
39 | + * Indicates whether or not the table has any entries. $table_name can |
|
40 | + * optionally start with $wpdb->prefix or not |
|
41 | + * |
|
42 | + * @global \wpdb $wpdb |
|
43 | + * @param string $table_name |
|
44 | + * @return bool |
|
45 | + */ |
|
46 | + public function tableIsEmpty($table_name) |
|
47 | + { |
|
48 | + global $wpdb; |
|
49 | + $table_name = $this->ensureTableNameHasPrefix($table_name); |
|
50 | + if ($this->tableExists($table_name)) { |
|
51 | + $count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name"); |
|
52 | + return absint($count) === 0 ? true : false; |
|
53 | + } |
|
54 | + return false; |
|
55 | + } |
|
56 | 56 | |
57 | 57 | |
58 | - /** |
|
59 | - * Indicates whether or not the table exists. $table_name can optionally |
|
60 | - * have the $wpdb->prefix on the beginning, or not. |
|
61 | - * |
|
62 | - * @global \wpdb $wpdb |
|
63 | - * @global array EZSQL_Error |
|
64 | - * @param $table_name |
|
65 | - * @return bool |
|
66 | - */ |
|
67 | - public function tableExists($table_name) |
|
68 | - { |
|
69 | - global $wpdb, $EZSQL_ERROR; |
|
70 | - $table_name = $this->ensureTableNameHasPrefix($table_name); |
|
71 | - // ignore if this causes an sql error |
|
72 | - $old_error = $wpdb->last_error; |
|
73 | - $old_suppress_errors = $wpdb->suppress_errors(); |
|
74 | - $old_show_errors_value = $wpdb->show_errors(false); |
|
75 | - $ezsql_error_cache = $EZSQL_ERROR; |
|
76 | - $wpdb->get_results("SELECT * from $table_name LIMIT 1"); |
|
77 | - $wpdb->show_errors($old_show_errors_value); |
|
78 | - $wpdb->suppress_errors($old_suppress_errors); |
|
79 | - $new_error = $wpdb->last_error; |
|
80 | - $wpdb->last_error = $old_error; |
|
81 | - $EZSQL_ERROR = $ezsql_error_cache; |
|
82 | - // if there was a table doesn't exist error |
|
83 | - if (! empty($new_error)) { |
|
84 | - if ( |
|
85 | - in_array( |
|
86 | - \EEH_Activation::last_wpdb_error_code(), |
|
87 | - array( |
|
88 | - 1051, // bad table |
|
89 | - 1109, // unknown table |
|
90 | - 117, // no such table |
|
91 | - ) |
|
92 | - ) |
|
93 | - || |
|
94 | - preg_match( |
|
95 | - '~^Table .* doesn\'t exist~', |
|
96 | - $new_error |
|
97 | - ) // in case not using mysql and error codes aren't reliable, just check for this error string |
|
98 | - ) { |
|
99 | - return false; |
|
100 | - } else { |
|
101 | - // log this because that's weird. Just use the normal PHP error log |
|
102 | - error_log( |
|
103 | - sprintf( |
|
104 | - esc_html__( |
|
105 | - 'Event Espresso error detected when checking if table existed: %1$s (it wasn\'t just that the table didn\'t exist either)', |
|
106 | - 'event_espresso' |
|
107 | - ), |
|
108 | - $new_error |
|
109 | - ) |
|
110 | - ); |
|
111 | - } |
|
112 | - } |
|
113 | - return true; |
|
114 | - } |
|
58 | + /** |
|
59 | + * Indicates whether or not the table exists. $table_name can optionally |
|
60 | + * have the $wpdb->prefix on the beginning, or not. |
|
61 | + * |
|
62 | + * @global \wpdb $wpdb |
|
63 | + * @global array EZSQL_Error |
|
64 | + * @param $table_name |
|
65 | + * @return bool |
|
66 | + */ |
|
67 | + public function tableExists($table_name) |
|
68 | + { |
|
69 | + global $wpdb, $EZSQL_ERROR; |
|
70 | + $table_name = $this->ensureTableNameHasPrefix($table_name); |
|
71 | + // ignore if this causes an sql error |
|
72 | + $old_error = $wpdb->last_error; |
|
73 | + $old_suppress_errors = $wpdb->suppress_errors(); |
|
74 | + $old_show_errors_value = $wpdb->show_errors(false); |
|
75 | + $ezsql_error_cache = $EZSQL_ERROR; |
|
76 | + $wpdb->get_results("SELECT * from $table_name LIMIT 1"); |
|
77 | + $wpdb->show_errors($old_show_errors_value); |
|
78 | + $wpdb->suppress_errors($old_suppress_errors); |
|
79 | + $new_error = $wpdb->last_error; |
|
80 | + $wpdb->last_error = $old_error; |
|
81 | + $EZSQL_ERROR = $ezsql_error_cache; |
|
82 | + // if there was a table doesn't exist error |
|
83 | + if (! empty($new_error)) { |
|
84 | + if ( |
|
85 | + in_array( |
|
86 | + \EEH_Activation::last_wpdb_error_code(), |
|
87 | + array( |
|
88 | + 1051, // bad table |
|
89 | + 1109, // unknown table |
|
90 | + 117, // no such table |
|
91 | + ) |
|
92 | + ) |
|
93 | + || |
|
94 | + preg_match( |
|
95 | + '~^Table .* doesn\'t exist~', |
|
96 | + $new_error |
|
97 | + ) // in case not using mysql and error codes aren't reliable, just check for this error string |
|
98 | + ) { |
|
99 | + return false; |
|
100 | + } else { |
|
101 | + // log this because that's weird. Just use the normal PHP error log |
|
102 | + error_log( |
|
103 | + sprintf( |
|
104 | + esc_html__( |
|
105 | + 'Event Espresso error detected when checking if table existed: %1$s (it wasn\'t just that the table didn\'t exist either)', |
|
106 | + 'event_espresso' |
|
107 | + ), |
|
108 | + $new_error |
|
109 | + ) |
|
110 | + ); |
|
111 | + } |
|
112 | + } |
|
113 | + return true; |
|
114 | + } |
|
115 | 115 | |
116 | 116 | |
117 | - /** |
|
118 | - * @param $table_name |
|
119 | - * @param $index_name |
|
120 | - * @return array of columns used on that index, Each entry is an object with the following properties { |
|
121 | - * @type string Table |
|
122 | - * @type string Non_unique "0" or "1" |
|
123 | - * @type string Key_name |
|
124 | - * @type string Seq_in_index |
|
125 | - * @type string Column_name |
|
126 | - * @type string Collation |
|
127 | - * @type string Cardinality |
|
128 | - * @type string Sub_part on a column, usually this is just the number of characters from this column to use in |
|
129 | - * indexing |
|
130 | - * @type string|null Packed |
|
131 | - * @type string Null |
|
132 | - * @type string Index_type |
|
133 | - * @type string Comment |
|
134 | - * @type string Index_comment |
|
135 | - * } |
|
136 | - */ |
|
137 | - public function showIndexes($table_name, $index_name) |
|
138 | - { |
|
139 | - global $wpdb; |
|
140 | - $table_name = $this->ensureTableNameHasPrefix($table_name); |
|
141 | - $index_exists_query = "SHOW INDEX FROM {$table_name} WHERE Key_name = '{$index_name}'"; |
|
142 | - return $wpdb->get_results($index_exists_query); |
|
143 | - } |
|
117 | + /** |
|
118 | + * @param $table_name |
|
119 | + * @param $index_name |
|
120 | + * @return array of columns used on that index, Each entry is an object with the following properties { |
|
121 | + * @type string Table |
|
122 | + * @type string Non_unique "0" or "1" |
|
123 | + * @type string Key_name |
|
124 | + * @type string Seq_in_index |
|
125 | + * @type string Column_name |
|
126 | + * @type string Collation |
|
127 | + * @type string Cardinality |
|
128 | + * @type string Sub_part on a column, usually this is just the number of characters from this column to use in |
|
129 | + * indexing |
|
130 | + * @type string|null Packed |
|
131 | + * @type string Null |
|
132 | + * @type string Index_type |
|
133 | + * @type string Comment |
|
134 | + * @type string Index_comment |
|
135 | + * } |
|
136 | + */ |
|
137 | + public function showIndexes($table_name, $index_name) |
|
138 | + { |
|
139 | + global $wpdb; |
|
140 | + $table_name = $this->ensureTableNameHasPrefix($table_name); |
|
141 | + $index_exists_query = "SHOW INDEX FROM {$table_name} WHERE Key_name = '{$index_name}'"; |
|
142 | + return $wpdb->get_results($index_exists_query); |
|
143 | + } |
|
144 | 144 | } |