Completed
Branch ENH/dipslay-error-on-iframe-ou... (eb5ff1)
by
unknown
31:09 queued 22:26
created

DisplayTicketSelector::handleMissingEvent()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 3
nop 0
dl 0
loc 33
rs 9.392
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\modules\ticket_selector;
4
5
use EE_Datetime;
6
use EE_Error;
7
use EE_Event;
8
use EE_Registry;
9
use EE_System;
10
use EE_Ticket_Selector_Config;
11
use EEH_Event_View;
12
use EEH_HTML;
13
use EEH_Template;
14
use EEH_URL;
15
use EEM_Event;
16
use EEM_Ticket;
17
use EventEspresso\core\exceptions\InvalidDataTypeException;
18
use EventEspresso\core\exceptions\InvalidInterfaceException;
19
use EventEspresso\core\exceptions\ExceptionStackTraceDisplay;
20
use InvalidArgumentException;
21
use WP_Post;
22
23
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
24
// phpcs:disable WordPress.WP.I18n.UnorderedPlaceholdersText
25
26
/**
27
 * Class DisplayTicketSelector
28
 * Description
29
 *
30
 * @package       Event Espresso
31
 * @subpackage    core
32
 * @author        Brent Christensen
33
 */
34
class DisplayTicketSelector
35
{
36
37
    /**
38
     * event that ticket selector is being generated for
39
     *
40
     * @access protected
41
     * @var EE_Event $event
42
     */
43
    protected $event;
44
45
    /**
46
     * Used to flag when the ticket selector is being called from an external iframe.
47
     *
48
     * @var bool $iframe
49
     */
50
    protected $iframe = false;
51
52
    /**
53
     * max attendees that can register for event at one time
54
     *
55
     * @var int $max_attendees
56
     */
57
    private $max_attendees = EE_INF;
58
59
    /**
60
     * @var string $date_format
61
     */
62
    private $date_format;
63
64
    /**
65
     * @var string $time_format
66
     */
67
    private $time_format;
68
69
    /**
70
     * @var boolean $display_full_ui
71
     */
72
    private $display_full_ui;
73
74
75
    /**
76
     * DisplayTicketSelector constructor.
77
     *
78
     * @param bool $iframe
79
     */
80
    public function __construct($iframe = false)
81
    {
82
        $this->iframe = $iframe;
83
        $this->date_format = apply_filters(
84
            'FHEE__EED_Ticket_Selector__display_ticket_selector__date_format',
85
            get_option('date_format')
86
        );
87
        $this->time_format = apply_filters(
88
            'FHEE__EED_Ticket_Selector__display_ticket_selector__time_format',
89
            get_option('time_format')
90
        );
91
    }
92
93
94
    /**
95
     * @return bool
96
     */
97
    public function isIframe()
98
    {
99
        return $this->iframe;
100
    }
101
102
103
    /**
104
     * @param boolean $iframe
105
     */
106
    public function setIframe($iframe = true)
107
    {
108
        $this->iframe = filter_var($iframe, FILTER_VALIDATE_BOOLEAN);
109
    }
110
111
112
    /**
113
     * finds and sets the \EE_Event object for use throughout class
114
     *
115
     * @param mixed $event
116
     * @return bool
117
     * @throws EE_Error
118
     * @throws InvalidDataTypeException
119
     * @throws InvalidInterfaceException
120
     * @throws InvalidArgumentException
121
     */
122
    protected function setEvent($event = null)
123
    {
124
        if ($event === null) {
125
            global $post;
126
            $event = $post;
127
        }
128
        if ($event instanceof EE_Event) {
129
            $this->event = $event;
130
        } elseif ($event instanceof WP_Post) {
0 ignored issues
show
Bug introduced by
The class WP_Post does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
131
            if (isset($event->EE_Event) && $event->EE_Event instanceof EE_Event) {
132
                $this->event = $event->EE_Event;
133
            } elseif ($event->post_type === 'espresso_events') {
134
                $event->EE_Event = EEM_Event::instance()->instantiate_class_from_post_object($event);
135
                $this->event = $event->EE_Event;
136
            }
137 View Code Duplication
        } else {
138
            $user_msg = __('No Event object or an invalid Event object was supplied.', 'event_espresso');
139
            $dev_msg = $user_msg . __(
140
                'In order to generate a ticket selector, please ensure you are passing either an EE_Event object or a WP_Post object of the post type "espresso_event" to the EE_Ticket_Selector class constructor.',
141
                'event_espresso'
142
            );
143
            EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
144
            return false;
145
        }
146
        return true;
147
    }
148
149
150
    /**
151
     * @return int
152
     */
153
    public function getMaxAttendees()
154
    {
155
        return $this->max_attendees;
156
    }
157
158
159
    /**
160
     * @param int $max_attendees
161
     */
162
    public function setMaxAttendees($max_attendees)
163
    {
164
        $this->max_attendees = absint(
165
            apply_filters(
166
                'FHEE__EE_Ticket_Selector__display_ticket_selector__max_tickets',
167
                $max_attendees
168
            )
169
        );
170
    }
171
172
173
    /**
174
     * Returns whether or not the full ticket selector should be shown or not.
175
     * Currently, it displays on the frontend (including ajax requests) but not the backend
176
     *
177
     * @return bool
178
     */
179
    private function display_full_ui()
180
    {
181
        if ($this->display_full_ui === null) {
182
            $this->display_full_ui = ! is_admin() || (defined('DOING_AJAX') && DOING_AJAX);
183
        }
184
        return $this->display_full_ui;
185
    }
186
187
188
    /**
189
     * creates buttons for selecting number of attendees for an event
190
     *
191
     * @param WP_Post|int $event
192
     * @param bool        $view_details
193
     * @return string
194
     * @throws EE_Error
195
     * @throws InvalidArgumentException
196
     * @throws InvalidDataTypeException
197
     * @throws InvalidInterfaceException
198
     */
199
    public function display($event = null, $view_details = false)
200
    {
201
        // reset filter for displaying submit button
202
        remove_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true');
203
        // poke and prod incoming event till it tells us what it is
204
        if (! $this->setEvent($event)) {
205
            return $this->handleMissingEvent();
206
        }
207
        // begin gathering template arguments by getting event status
208
        $template_args = array('event_status' => $this->event->get_active_status());
209
        if ($this->activeEventAndShowTicketSelector(
210
            $event,
211
            $template_args['event_status'],
212
            $view_details
213
        )) {
214
            return ! is_single() ? $this->displayViewDetailsButton() : '';
215
        }
216
        // filter the maximum qty that can appear in the Ticket Selector qty dropdowns
217
        $this->setMaxAttendees($this->event->additional_limit());
218
        if ($this->getMaxAttendees() < 1) {
219
            return $this->ticketSalesClosedMessage();
220
        }
221
        // is the event expired ?
222
        $template_args['event_is_expired'] = ! is_admin() ? $this->event->is_expired() : false;
223
        if ($template_args['event_is_expired']) {
224
            return $this->expiredEventMessage();
225
        }
226
        // get all tickets for this event ordered by the datetime
227
        $tickets = $this->getTickets();
228
        if (count($tickets) < 1) {
229
            return $this->noTicketAvailableMessage();
230
        }
231
        // redirecting to another site for registration ??
232
        $external_url = (string) $this->event->external_url()
233
            && $this->event->external_url() !== get_the_permalink()
234
            ? $this->event->external_url()
235
            : '';
236
        // if redirecting to another site for registration, then we don't load the TS
237
        $ticket_selector = $external_url
238
            ? $this->externalEventRegistration()
239
            : $this->loadTicketSelector($tickets, $template_args);
240
        // now set up the form (but not for the admin)
241
        $ticket_selector = $this->display_full_ui()
242
            ? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector
243
            : $ticket_selector;
244
        // submit button and form close tag
245
        $ticket_selector .= $this->display_full_ui() ? $this->displaySubmitButton($external_url) : '';
246
        return $ticket_selector;
247
    }
248
249
250
    /**
251
     * displayTicketSelector
252
     * examines the event properties and determines whether a Ticket Selector should be displayed
253
     *
254
     * @param WP_Post|int $event
255
     * @param string      $_event_active_status
256
     * @param bool        $view_details
257
     * @return bool
258
     * @throws EE_Error
259
     */
260
    protected function activeEventAndShowTicketSelector($event, $_event_active_status, $view_details)
261
    {
262
        $event_post = $this->event instanceof EE_Event ? $this->event->ID() : $event;
263
        return $this->display_full_ui()
264
               && (
265
                   ! $this->event->display_ticket_selector()
266
                   || $view_details
267
                   || post_password_required($event_post)
268
                   || (
269
                       $_event_active_status !== EE_Datetime::active
270
                       && $_event_active_status !== EE_Datetime::upcoming
271
                       && $_event_active_status !== EE_Datetime::sold_out
272
                       && ! (
273
                           $_event_active_status === EE_Datetime::inactive
274
                           && is_user_logged_in()
275
                       )
276
                   )
277
               );
278
    }
279
280
281
    /**
282
     * noTicketAvailableMessage
283
     * notice displayed if event is expired
284
     *
285
     * @return string
286
     * @throws EE_Error
287
     */
288
    protected function expiredEventMessage()
289
    {
290
        return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__(
291
            'We\'re sorry, but all tickets sales have ended because the event is expired.',
292
            'event_espresso'
293
        ) . '</span></div><!-- .ee-event-expired-notice -->';
294
    }
295
296
297
    /**
298
     * noTicketAvailableMessage
299
     * notice displayed if event has no more tickets available
300
     *
301
     * @return string
302
     * @throws EE_Error
303
     */
304 View Code Duplication
    protected function noTicketAvailableMessage()
305
    {
306
        $no_ticket_available_msg = esc_html__('We\'re sorry, but all ticket sales have ended.', 'event_espresso');
307
        if (current_user_can('edit_post', $this->event->ID())) {
308
            $no_ticket_available_msg .= sprintf(
309
                esc_html__(
310
                    '%1$sNote to Event Admin:%2$sNo tickets were found for this event. This effectively turns off ticket sales. Please ensure that at least one ticket is available for if you want people to be able to register.%3$s(click to edit this event)%4$s',
311
                    'event_espresso'
312
                ),
313
                '<div class="ee-attention" style="text-align: left;"><b>',
314
                '</b><br />',
315
                '<span class="edit-link"><a class="post-edit-link" href="'
316
                . get_edit_post_link($this->event->ID())
317
                . '">',
318
                '</a></span></div><!-- .ee-attention noTicketAvailableMessage -->'
319
            );
320
        }
321
        return '
322
            <div class="ee-event-expired-notice">
323
                <span class="important-notice">' . $no_ticket_available_msg . '</span>
324
            </div><!-- .ee-event-expired-notice -->';
325
    }
326
327
328
    /**
329
     * ticketSalesClosed
330
     * notice displayed if event ticket sales are turned off
331
     *
332
     * @return string
333
     * @throws EE_Error
334
     */
335 View Code Duplication
    protected function ticketSalesClosedMessage()
336
    {
337
        $sales_closed_msg = esc_html__(
338
            'We\'re sorry, but ticket sales have been closed at this time. Please check back again later.',
339
            'event_espresso'
340
        );
341
        if (current_user_can('edit_post', $this->event->ID())) {
342
            $sales_closed_msg .= sprintf(
343
                esc_html__(
344
                    '%sNote to Event Admin:%sThe "Maximum number of tickets allowed per order for this event" in the Event Registration Options has been set to "0". This effectively turns off ticket sales. %s(click to edit this event)%s',
345
                    'event_espresso'
346
                ),
347
                '<div class="ee-attention" style="text-align: left;"><b>',
348
                '</b><br />',
349
                '<span class="edit-link"><a class="post-edit-link" href="'
350
                . get_edit_post_link($this->event->ID())
351
                . '">',
352
                '</a></span></div><!-- .ee-attention ticketSalesClosedMessage -->'
353
            );
354
        }
355
        return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>';
356
    }
357
358
359
    /**
360
     * getTickets
361
     *
362
     * @return \EE_Base_Class[]|\EE_Ticket[]
363
     * @throws EE_Error
364
     * @throws InvalidDataTypeException
365
     * @throws InvalidInterfaceException
366
     * @throws InvalidArgumentException
367
     */
368
    protected function getTickets()
369
    {
370
        $show_expired_tickets = is_admin() || (
371
            EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config
372
            && EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector->show_expired_tickets
373
        );
374
375
        $ticket_query_args = array(
376
            array('Datetime.EVT_ID' => $this->event->ID()),
377
            'order_by' => array(
378
                'TKT_order'              => 'ASC',
379
                'TKT_required'           => 'DESC',
380
                'TKT_start_date'         => 'ASC',
381
                'TKT_end_date'           => 'ASC',
382
                'Datetime.DTT_EVT_start' => 'DESC',
383
            ),
384
        );
385
        if (! $show_expired_tickets) {
386
            // use the correct applicable time query depending on what version of core is being run.
387
            $current_time = method_exists('EEM_Datetime', 'current_time_for_query')
388
                ? time()
389
                : current_time('timestamp');
390
            $ticket_query_args[0]['TKT_end_date'] = array('>', $current_time);
391
        }
392
        return EEM_Ticket::instance()->get_all($ticket_query_args);
393
    }
394
395
396
    /**
397
     * loadTicketSelector
398
     * begins to assemble template arguments
399
     * and decides whether to load a "simple" ticket selector, or the standard
400
     *
401
     * @param \EE_Ticket[] $tickets
402
     * @param array        $template_args
403
     * @return string
404
     * @throws EE_Error
405
     */
406
    protected function loadTicketSelector(array $tickets, array $template_args)
407
    {
408
        $template_args['event'] = $this->event;
409
        $template_args['EVT_ID'] = $this->event->ID();
410
        $template_args['event_is_expired'] = $this->event->is_expired();
411
        $template_args['max_atndz'] = $this->getMaxAttendees();
412
        $template_args['date_format'] = $this->date_format;
413
        $template_args['time_format'] = $this->time_format;
414
        /**
415
         * Filters the anchor ID used when redirecting to the Ticket Selector if no quantity selected
416
         *
417
         * @since 4.9.13
418
         * @param     string  '#tkt-slctr-tbl-' . $EVT_ID The html ID to anchor to
419
         * @param int $EVT_ID The Event ID
420
         */
421
        $template_args['anchor_id'] = apply_filters(
422
            'FHEE__EE_Ticket_Selector__redirect_anchor_id',
423
            '#tkt-slctr-tbl-' . $this->event->ID(),
424
            $this->event->ID()
425
        );
426
        $template_args['tickets'] = $tickets;
427
        $template_args['ticket_count'] = count($tickets);
428
        $ticket_selector = $this->simpleTicketSelector($tickets, $template_args);
429
        return $ticket_selector instanceof TicketSelectorSimple
430
            ? $ticket_selector
431
            : new TicketSelectorStandard(
432
                $this->event,
433
                $tickets,
434
                $this->getMaxAttendees(),
435
                $template_args,
436
                $this->date_format,
437
                $this->time_format
438
            );
439
    }
440
441
442
    /**
443
     * simpleTicketSelector
444
     * there's one ticket, and max attendees is set to one,
445
     * so if the event is free, then this is a "simple" ticket selector
446
     * a.k.a. "Dude Where's my Ticket Selector?"
447
     *
448
     * @param \EE_Ticket[] $tickets
449
     * @param array        $template_args
450
     * @return string
451
     * @throws EE_Error
452
     */
453
    protected function simpleTicketSelector($tickets, array $template_args)
454
    {
455
        // if there is only ONE ticket with a max qty of ONE
456
        if (count($tickets) > 1 || $this->getMaxAttendees() !== 1) {
457
            return '';
458
        }
459
        /** @var \EE_Ticket $ticket */
460
        $ticket = reset($tickets);
461
        // if the ticket is free... then not much need for the ticket selector
462
        if (apply_filters(
463
            'FHEE__ticket_selector_chart_template__hide_ticket_selector',
464
            $ticket->is_free(),
465
            $this->event->ID()
466
        )) {
467
            return new TicketSelectorSimple(
468
                $this->event,
469
                $ticket,
470
                $this->getMaxAttendees(),
471
                $template_args
472
            );
473
        }
474
        return '';
475
    }
476
477
478
    /**
479
     * externalEventRegistration
480
     *
481
     * @return string
482
     */
483
    public function externalEventRegistration()
484
    {
485
        // if not we still need to trigger the display of the submit button
486
        add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true');
487
        // display notice to admin that registration is external
488
        return $this->display_full_ui()
489
            ? esc_html__(
490
                'Registration is at an external URL for this event.',
491
                'event_espresso'
492
            )
493
            : '';
494
    }
495
496
497
    /**
498
     * formOpen
499
     *
500
     * @param        int    $ID
501
     * @param        string $external_url
502
     * @return        string
503
     */
504
    public function formOpen($ID = 0, $external_url = '')
505
    {
506
        // if redirecting, we don't need any anything else
507
        if ($external_url) {
508
            $html = '<form method="GET" ';
509
            $html .= 'action="' . EEH_URL::refactor_url($external_url) . '" ';
510
            $html .= 'name="ticket-selector-form-' . $ID . '"';
511
            // open link in new window ?
512
            $html .= apply_filters(
513
                'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank',
514
                $this->isIframe(),
515
                $this
516
            )
517
                ? ' target="_blank"'
518
                : '';
519
            $html .= '>';
520
            $query_args = EEH_URL::get_query_string($external_url);
521
            foreach ((array) $query_args as $query_arg => $value) {
522
                $html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">';
523
            }
524
            return $html;
525
        }
526
        // if there is no submit button, then don't start building a form
527
        // because the "View Details" button will build its own form
528
        if (! apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) {
529
            return '';
530
        }
531
        $checkout_url = EEH_Event_View::event_link_url($ID);
532
        if (! $checkout_url) {
533
            EE_Error::add_error(
534
                esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'),
535
                __FILE__,
536
                __FUNCTION__,
537
                __LINE__
538
            );
539
        }
540
        // set no cache headers and constants
541
        EE_System::do_not_cache();
542
        $html = '<form method="POST" ';
543
        $html .= 'action="' . $checkout_url . '" ';
544
        $html .= 'name="ticket-selector-form-' . $ID . '"';
545
        $html .= $this->iframe ? ' target="_blank"' : '';
546
        $html .= '>';
547
        $html .= '<input type="hidden" name="ee" value="process_ticket_selections">';
548
        $html = apply_filters('FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event);
549
        return $html;
550
    }
551
552
553
    /**
554
     * displaySubmitButton
555
     *
556
     * @param  string $external_url
557
     * @return string
558
     * @throws EE_Error
559
     */
560
    public function displaySubmitButton($external_url = '')
561
    {
562
        $html = '';
563
        if ($this->display_full_ui()) {
564
            // standard TS displayed with submit button, ie: "Register Now"
565
            if (apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) {
566
                $html .= $this->displayRegisterNowButton();
567
                $html .= empty($external_url)
568
                    ? $this->ticketSelectorEndDiv()
569
                    : $this->clearTicketSelector();
570
                $html .= '<br/>' . $this->formClose();
571
            } elseif ($this->getMaxAttendees() === 1) {
572
                // its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1)
573
                if ($this->event->is_sold_out()) {
574
                    // then instead of a View Details or Submit button, just display a "Sold Out" message
575
                    $html .= apply_filters(
576
                        'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__sold_out_msg',
577
                        sprintf(
578
                            __(
579
                                '%1$s"%2$s" is currently sold out.%4$sPlease check back again later, as spots may become available.%3$s',
580
                                'event_espresso'
581
                            ),
582
                            '<p class="no-ticket-selector-msg clear-float">',
583
                            $this->event->name(),
584
                            '</p>',
585
                            '<br />'
586
                        ),
587
                        $this->event
588
                    );
589
                    if (apply_filters(
590
                        'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button',
591
                        false,
592
                        $this->event
593
                    )) {
594
                        $html .= $this->displayRegisterNowButton();
595
                    }
596
                    // sold out DWMTS event, no TS, no submit or view details button, but has additional content
597
                    $html .= $this->ticketSelectorEndDiv();
598
                } elseif (apply_filters('FHEE__EE_Ticket_Selector__hide_ticket_selector', false)
599
                          && ! is_single()
600
                ) {
601
                    // this is a "Dude Where's my Ticket Selector?" (DWMTS) type event,
602
                    // but no tickets are available, so display event's "View Details" button.
603
                    // it is being viewed via somewhere other than a single post
604
                    $html .= $this->displayViewDetailsButton(true);
605
                } else {
606
                    $html .= $this->ticketSelectorEndDiv();
607
                }
608
            } elseif (is_archive()) {
609
                // event list, no tickets available so display event's "View Details" button
610
                $html .= $this->ticketSelectorEndDiv();
611
                $html .= $this->displayViewDetailsButton();
612
            } else {
613
                if (apply_filters(
614
                    'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button',
615
                    false,
616
                    $this->event
617
                )) {
618
                    $html .= $this->displayRegisterNowButton();
619
                }
620
                // no submit or view details button, and no additional content
621
                $html .= $this->ticketSelectorEndDiv();
622
            }
623
            if (! $this->iframe && ! is_archive()) {
624
                $html .= EEH_Template::powered_by_event_espresso('', '', array('utm_content' => 'ticket_selector'));
625
            }
626
        }
627
        return apply_filters(
628
            'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displaySubmitButton__html',
629
            $html,
630
            $this->event,
631
            $this
632
        );
633
    }
634
635
636
    /**
637
     * @return string
638
     * @throws EE_Error
639
     */
640
    public function displayRegisterNowButton()
641
    {
642
        $btn_text = apply_filters(
643
            'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__btn_text',
644
            __('Register Now', 'event_espresso'),
645
            $this->event
646
        );
647
        $external_url = (string) $this->event->external_url()
648
            && $this->event->external_url() !== get_the_permalink()
649
            ? $this->event->external_url()
650
            : '';
651
        $html = EEH_HTML::div(
652
            '',
653
            'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap',
654
            'ticket-selector-submit-btn-wrap'
655
        );
656
        $html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"';
657
        $html .= ' class="ticket-selector-submit-btn ';
658
        $html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"';
659
        $html .= ' type="submit" value="' . $btn_text . '" data-ee-disable-after-recaptcha="true" />';
660
        $html .= EEH_HTML::divx() . '<!-- .ticket-selector-submit-btn-wrap -->';
661
        $html .= apply_filters(
662
            'FHEE__EE_Ticket_Selector__after_ticket_selector_submit',
663
            '',
664
            $this->event,
665
            $this->iframe
666
        );
667
        return $html;
668
    }
669
670
671
    /**
672
     * displayViewDetailsButton
673
     *
674
     * @param bool $DWMTS indicates a "Dude Where's my Ticket Selector?" (DWMTS) type event
675
     *                    (ie: $_max_atndz === 1) where there are no available tickets,
676
     *                    either because they are sold out, expired, or not yet on sale.
677
     *                    In this case, we need to close the form BEFORE adding any closing divs
678
     * @return string
679
     * @throws EE_Error
680
     */
681
    public function displayViewDetailsButton($DWMTS = false)
682
    {
683
        if (! $this->event->get_permalink()) {
684
            EE_Error::add_error(
685
                esc_html__('The URL for the Event Details page could not be retrieved.', 'event_espresso'),
686
                __FILE__,
687
                __FUNCTION__,
688
                __LINE__
689
            );
690
        }
691
        $view_details_btn = '<form method="GET" action="';
692
        $view_details_btn .= apply_filters(
693
            'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_url',
694
            $this->event->get_permalink(),
695
            $this->event
696
        );
697
        $view_details_btn .= '"';
698
        // open link in new window ?
699
        $view_details_btn .= apply_filters(
700
            'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displayViewDetailsButton__url_target_blank',
701
            $this->isIframe(),
702
            $this
703
        )
704
            ? ' target="_blank"'
705
            : '';
706
        $view_details_btn .= '>';
707
        $btn_text = apply_filters(
708
            'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text',
709
            esc_html__('View Details', 'event_espresso'),
710
            $this->event
711
        );
712
        $view_details_btn .= '<input id="ticket-selector-submit-'
713
                             . $this->event->ID()
714
                             . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="'
715
                             . $btn_text
716
                             . '" />';
717
        $view_details_btn .= apply_filters('FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event);
718
        if ($DWMTS) {
719
            $view_details_btn .= $this->formClose();
720
            $view_details_btn .= $this->ticketSelectorEndDiv();
721
            $view_details_btn .= '<br/>';
722
        } else {
723
            $view_details_btn .= $this->clearTicketSelector();
724
            $view_details_btn .= '<br/>';
725
            $view_details_btn .= $this->formClose();
726
        }
727
        return $view_details_btn;
728
    }
729
730
731
    /**
732
     * @return string
733
     */
734
    public function ticketSelectorEndDiv()
735
    {
736
        return $this->clearTicketSelector() . '</div><!-- ticketSelectorEndDiv -->';
737
    }
738
739
740
    /**
741
     * @return string
742
     */
743
    public function clearTicketSelector()
744
    {
745
        // standard TS displayed, appears after a "Register Now" or "view Details" button
746
        return '<div class="clear"></div><!-- clearTicketSelector -->';
747
    }
748
749
750
    /**
751
     * @access        public
752
     * @return        string
753
     */
754
    public function formClose()
755
    {
756
        return '</form>';
757
    }
758
759
760
    /**
761
     * handleMissingEvent
762
     * Returns either false or an error to display when no valid event is passed.
763
     *
764
     * @return mixed
765
     * @throws ExceptionStackTraceDisplay
766
     * @throws InvalidInterfaceException
767
     */
768
    protected function handleMissingEvent()
769
    {
770
        // If this is not an iFrame request, simply return false.
771
        if (! $this->isIframe()) {
772
            return false;
773
        }
774
        // This is an iFrame so return an error.
775
        // Display stack trace if WP_DEBUG is enabled.
776
        if (WP_DEBUG === true && current_user_can('edit_pages')) {
777
            $event_id = EE_Registry::instance()->REQ->get('event', 0);
778
            new ExceptionStackTraceDisplay(
779
                new InvalidArgumentException(
780
                    sprintf(
781
                        esc_html__(
782
                            'A valid Event ID is required to display the ticket selector.%3$sAn Event with an ID of "%1$s" could not be found.%3$sPlease verify that the embed code added to this post\'s content includes an "%2$s" argument and that its value corresponds to a valid Event ID.',
783
                            'event_espresso'
784
                        ),
785
                        $event_id,
786
                        'event',
787
                        '<br />'
788
                    )
789
                )
790
            );
791
            return '';
792
        }
793
        // If WP_DEBUG is not enabled, display a message stating the event could not be found.
794
        return EEH_HTML::p(
795
            esc_html__(
796
                'A valid Event could not be found. Please contact the event administrator for assistance.',
797
                'event_espresso'
798
            )
799
        );
800
    }
801
}
802