Completed
Branch BUG-10375-migrations-not-repor... (1e9646)
by
unknown
62:53 queued 49:42
created

TicketSelectorRowStandard::getTicketPriceDetails()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 14
nc 4
nop 0
dl 0
loc 19
rs 9.2
c 0
b 0
f 0
1
<?php
2
namespace EventEspresso\modules\ticket_selector;
3
4
defined('EVENT_ESPRESSO_VERSION') || exit;
5
6
7
8
/**
9
 * Class TicketSelectorRowStandard
10
 * class for loading template and resolving template args for a single ticket row within a standard ticket selector
11
 *
12
 * @package       Event Espresso
13
 * @author        Brent Christensen
14
 * @since         $VID:$
15
 */
16
class TicketSelectorRowStandard extends TicketSelectorRow
17
{
18
19
    /**
20
     * @var TicketDetails $ticket_details
21
     */
22
    protected $ticket_details;
23
24
    /**
25
     * @var \EE_Ticket_Selector_Config $template_settings
26
     */
27
    protected $template_settings;
28
29
    /**
30
     * @var \EE_Tax_Config $tax_settings
31
     */
32
    protected $tax_settings;
33
34
    /**
35
     * @var boolean $required_ticket_sold_out
36
     */
37
    protected $required_ticket_sold_out;
38
39
    /**
40
     * @var boolean $prices_displayed_including_taxes
41
     */
42
    protected $prices_displayed_including_taxes;
43
44
    /**
45
     * @var string $event_status
46
     */
47
    protected $event_status;
48
49
    /**
50
     * @var int $row
51
     */
52
    protected $row;
53
54
    /**
55
     * @var int $cols
56
     */
57
    protected $cols;
58
59
    /**
60
     * @var boolean $hidden_input_qty
61
     */
62
    protected $hidden_input_qty;
63
64
    /**
65
     * @var string $ticket_datetime_classes
66
     */
67
    protected $ticket_datetime_classes;
68
69
70
71
    /**
72
     * TicketDetails constructor.
73
     *
74
     * @param \EE_Ticket $ticket
75
     * @param TicketDetails              $ticket_details
76
     * @param \EE_Ticket_Selector_Config $template_settings
77
     * @param \EE_Tax_Config             $tax_settings
78
     * @param int                        $max_atndz
79
     * @param int                        $row
80
     * @param int                        $cols
81
     * @param boolean                    $required_ticket_sold_out
82
     * @param string                     $event_status
83
     * @param string                     $date_format
84
     * @param string                     $ticket_datetime_classes
85
     */
86
    public function __construct(
87
        \EE_Ticket $ticket,
88
        TicketDetails $ticket_details,
89
        \EE_Ticket_Selector_Config $template_settings,
90
        \EE_Tax_Config $tax_settings,
91
        $max_atndz,
92
        $row,
93
        $cols,
94
        $required_ticket_sold_out,
95
        $event_status,
96
        $date_format,
97
        $ticket_datetime_classes
98
    ) {
99
        $this->ticket = $ticket;
100
        $this->ticket_details = $ticket_details;
101
        $this->template_settings = $template_settings;
102
        $this->tax_settings = $tax_settings;
103
        $this->max_atndz = $max_atndz;
104
        $this->row = $row;
105
        $this->cols = $cols;
106
        $this->required_ticket_sold_out = $required_ticket_sold_out;
107
        $this->event_status = $event_status;
108
        $this->date_format = $date_format;
109
        $this->ticket_datetime_classes = $ticket_datetime_classes;
110
        parent::__construct($ticket, $max_atndz, $date_format);
111
    }
112
113
114
115
    /**
116
     * other ticket rows will need to know if a required ticket is sold out,
117
     * so that they are not offered for sale
118
     *
119
     * @return boolean
120
     */
121
    public function getRequiredTicketSoldOut()
122
    {
123
        return $this->required_ticket_sold_out;
124
    }
125
126
127
128
    /**
129
     * @return int
130
     */
131
    public function getCols()
132
    {
133
        return $this->cols;
134
    }
135
136
137
138
    /**
139
     * getHtml
140
     *
141
     * @return string
142
     * @throws \EE_Error
143
     */
144
    public function getHtml()
145
    {
146
        $min = 0;
147
        $max = $this->ticket->max();
148
        $remaining = $this->ticket->remaining();
149
        if ($this->ticket->is_on_sale() && $this->ticket->is_remaining()) {
150
            list($min, $max) = $this->setTicketMinAndMax($remaining);
151
        } else {
152
            // set flag if ticket is required (flag is set to start date so that future tickets are not blocked)
153
            $this->required_ticket_sold_out = $this->ticket->required() && ! $remaining
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->ticket->required(...equired_ticket_sold_out can also be of type string or object<EE_Error>. However, the property $required_ticket_sold_out is declared as type boolean. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
154
                ? $this->ticket->start_date()
155
                : $this->required_ticket_sold_out;
156
        }
157
        list($ticket_price, $ticket_bundle) = $this->getTicketPriceDetails();
158
        list($tkt_status, $ticket_status, $status_class) = $this->getTicketStatusClasses($remaining);
159
        /**
160
         * Allow plugins to hook in and abort the generation and display of this row to do
161
         * something else if they want.
162
         * For an addon to abort things, all they have to do is register a filter with this hook, and
163
         * return a value that is NOT false.  Whatever is returned gets echoed instead of the
164
         * current row.
165
         *
166
         * @var string|bool
167
         */
168
        $ticket_selector_row_html = apply_filters(
169
            'FHEE__ticket_selector_chart_template__do_ticket_entire_row',
170
            false,
171
            $this->ticket,
172
            $max,
173
            $min,
174
            $this->required_ticket_sold_out,
175
            $ticket_price,
176
            $ticket_bundle,
177
            $ticket_status,
178
            $status_class
179
        );
180
        if ($ticket_selector_row_html !== false) {
181
            return $ticket_selector_row_html;
182
        }
183
        $ticket_selector_row_html = \EEH_HTML::tr(
184
            '', '',
185
            "tckt-slctr-tbl-tr {$status_class}{$this->ticket_datetime_classes} " . espresso_get_object_css_class($this->ticket)
186
        );
187
        /**
188
         * Allow plugins to hook in and abort the generation and display of the contents of this
189
         * row to do something else if they want.
190
         * For an addon to abort things, all they have to do is register a filter with this hook, and
191
         * return a value that is NOT false.  Whatever is returned gets echoed instead of the
192
         * current row.
193
         *
194
         * @var string|bool
195
         */
196
        $new_row_cells_content = apply_filters(
197
            'FHEE__ticket_selector_chart_template__do_ticket_inside_row',
198
            false,
199
            $this->ticket,
200
            $max,
201
            $min,
202
            $this->required_ticket_sold_out,
203
            $ticket_price,
204
            $ticket_bundle,
205
            $ticket_status,
206
            $status_class
207
        );
208
        if ($new_row_cells_content !== false) {
209
            return $ticket_selector_row_html
210
                   . $new_row_cells_content
211
                   . $this->ticketQtyAndIdHiddenInputs()
212
                   . \EEH_HTML::trx();
213
        }
214
        $this->hidden_input_qty = $this->max_atndz > 1 ? true : false;
215
216
        $ticket_selector_row_html .= $this->ticketNameTableCell();
217
        $ticket_selector_row_html .= $this->ticketPriceTableCell($ticket_price, $ticket_bundle);
218
        $ticket_selector_row_html .= \EEH_HTML::td('', '', 'tckt-slctr-tbl-td-qty cntr');
219
        $this->setTicketStatusDisplay($tkt_status, $ticket_status, $remaining);
220
        if (empty($this->ticket_status_display)) {
221
            if ($this->max_atndz === 1) {
222
                // only ONE attendee is allowed to register at a time
223
                $ticket_selector_row_html .= $this->onlyOneAttendeeCanRegister();
224
            } else if ($max > 0) {
225
                $ticket_selector_row_html .= $this->ticketQuantitySelector($min, $max);
226
            }
227
        }
228
        $ticket_selector_row_html .= $this->ticket_status_display;
229
        $ticket_selector_row_html .= $this->ticketQtyAndIdHiddenInputs();
230
        $ticket_selector_row_html .= $this->ticket_details->display($ticket_price, $remaining, $this->cols);
231
        $ticket_selector_row_html .= \EEH_HTML::tdx();
232
        $ticket_selector_row_html .= \EEH_HTML::trx();
233
234
235
        $this->row++;
236
        return $ticket_selector_row_html;
237
    }
238
239
240
241
    /**
242
     * setTicketMinAndMax
243
     *
244
     * @param int $remaining
245
     * @return array
246
     */
247
    protected function setTicketMinAndMax($remaining)
248
    {
249
        // offer the number of $tickets_remaining or $this->max_atndz, whichever is smaller
250
        $max = min($remaining, $this->max_atndz);
251
        // but... we also want to restrict the number of tickets by the ticket max setting,
252
        // however, the max still can't be higher than what was just set above
253
        $max = $this->ticket->max() > 0 ? min($this->ticket->max(), $max) : $max;
254
        // and we also want to restrict the minimum number of tickets by the ticket min setting
255
        $min = $this->ticket->min() > 0 ? $this->ticket->min() : 0;
256
        // and if the ticket is required, then make sure that min qty is at least 1
257
        $min = $this->ticket->required() ? max($min, 1) : $min;
258
        return array($min, $max);
259
    }
260
261
262
    /**
263
     * getTicketPriceDetails
264
     *
265
     * @return array
266
     */
267
    protected function getTicketPriceDetails()
268
    {
269
        $ticket_price = $this->tax_settings->prices_displayed_including_taxes
270
            ? $this->ticket->get_ticket_total_with_taxes()
271
            : $this->ticket->get_ticket_subtotal();
272
        $ticket_bundle = false;
273
        $ticket_min = $this->ticket->min();
274
        // for ticket bundles, set min and max qty the same
275
        if ($ticket_min !== 0 && $ticket_min === $this->ticket->max()) {
276
            $ticket_price *= $ticket_min;
277
            $ticket_bundle = true;
278
        }
279
        $ticket_price = apply_filters(
280
            'FHEE__ticket_selector_chart_template__ticket_price',
281
            $ticket_price,
282
            $this->ticket
283
        );
284
        return array($ticket_price, $ticket_bundle);
285
    }
286
287
288
289
    /**
290
     * getTicketStatusClasses
291
     *
292
     * @param int $remaining
293
     * @return array
294
     * @throws \EE_Error
295
     */
296
    protected function getTicketStatusClasses($remaining = 0)
297
    {
298
        // if a previous required ticket with the same sale start date is sold out,
299
        // then mark this ticket as sold out as well.
300
        // tickets that go on sale at a later date than the required ticket  will NOT be affected
301
        $tkt_status = $this->required_ticket_sold_out !== false
302
                      && $this->required_ticket_sold_out === $this->ticket->start_date()
303
            ? \EE_Ticket::sold_out
304
            : $this->ticket->ticket_status();
305
        $tkt_status = $this->event_status === \EE_Datetime::sold_out
306
            ? \EE_Ticket::sold_out
307
            : $tkt_status;
308
        // check ticket status
309
        switch ($tkt_status) {
310
            // sold_out
311
            case \EE_Ticket::sold_out :
312
                $ticket_status = 'ticket-sales-sold-out';
313
                $status_class = 'ticket-sales-sold-out lt-grey-text';
314
                break;
315
            // expired
316
            case \EE_Ticket::expired :
317
                $ticket_status = 'ticket-sales-expired';
318
                $status_class = 'ticket-sales-expired lt-grey-text';
319
                break;
320
            // archived
321
            case \EE_Ticket::archived :
322
                $ticket_status = 'archived-ticket';
323
                $status_class = 'archived-ticket hidden';
324
                break;
325
            // pending
326
            case \EE_Ticket::pending :
327
                $ticket_status = 'ticket-pending';
328
                $status_class = 'ticket-pending';
329
                break;
330
            // onsale
331
            case \EE_Ticket::onsale :
332
            default :
333
                $ticket_status = 'ticket-on-sale';
334
                $status_class = 'ticket-on-sale';
335
                break;
336
        }
337
        $ticket_status = \EEH_HTML::span($this->ticket->ticket_status(true, ($remaining > 0)), '', $ticket_status);
338
        return array($tkt_status, $ticket_status, $status_class);
339
    }
340
341
342
343
    /**
344
     * ticketNameTableCell
345
     *
346
     * @return string
347
     * @throws \EE_Error
348
     */
349
    protected function ticketNameTableCell()
350
    {
351
        $html = \EEH_HTML::td('', '', 'tckt-slctr-tbl-td-name');
352
        $html .= \EEH_HTML::strong($this->ticket->get_pretty('TKT_name'));
353
        $html .= $this->ticket_details->getShowHideLinks();
354
        if ($this->ticket->required()) {
355
            $html .= \EEH_HTML::p(
356
                    apply_filters(
357
                            'FHEE__ticket_selector_chart_template__ticket_required_message',
358
                            esc_html__('This ticket is required and must be purchased.', 'event_espresso')
359
                    ),
360
                    '', 'ticket-required-pg'
361
            );
362
        }
363
        $html .= \EEH_HTML::tdx();
364
        return $html;
365
    }
366
367
368
369
    /**
370
     * ticketPriceTableCell
371
     *
372
     * @param float $ticket_price
373
     * @param bool  $ticket_bundle
374
     * @return string
375
     * @throws \EE_Error
376
     */
377
    protected function ticketPriceTableCell($ticket_price, $ticket_bundle)
378
    {
379
        $html = '';
380
        if (apply_filters('FHEE__ticket_selector_chart_template__display_ticket_price_details', true)) {
381
            $html .= \EEH_HTML::td('', '', 'tckt-slctr-tbl-td-price jst-rght');
382
            $html .= \EEH_Template::format_currency($ticket_price);
383
            $html .= $this->ticket->taxable()
384
                ? \EEH_HTML::span( '*', '', 'taxable-tickets-asterisk grey-text' )
385
                : '';
386
            $html .= '&nbsp;';
387
            $html .= \EEH_HTML::span(
388
                $ticket_bundle
389
                    ? apply_filters(
390
                        'FHEE__ticket_selector_chart_template__per_ticket_bundle_text',
391
                        __(' / bundle', 'event_espresso')
392
                    )
393
                    : apply_filters(
394
                        'FHEE__ticket_selector_chart_template__per_ticket_text',
395
                        __('', 'event_espresso')
396
                    ),
397
                '', 'smaller-text no-bold'
398
            );
399
            $html .= '&nbsp;';
400
            $html .= \EEH_HTML::tdx();
401
            $this->cols++;
402
        }
403
        return $html;
404
    }
405
406
407
408
    /**
409
     * onlyOneAttendeeCanRegister
410
     *
411
     * @return string
412
     */
413
    protected function onlyOneAttendeeCanRegister()
414
    {
415
        // display submit button since we have tickets available
416
        add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true');
417
        $this->hidden_input_qty = false;
418
        $html = '<input type="radio" name="tkt-slctr-qty-' . $this->EVT_ID . '"';
419
        $html .= ' id="ticket-selector-tbl-qty-slct-' . $this->EVT_ID . '-' . $this->row . '"';
420
        $html .= ' class="ticket-selector-tbl-qty-slct" value="' . $this->row . '-1"';
421
        $html .= $this->row === 1 ? ' checked="checked"' : '';
422
        $html .= ' title=""/>';
423
        return $html;
424
    }
425
426
427
428
    /**
429
     * ticketQuantitySelector
430
     *
431
     * @param int $min
432
     * @param int $max
433
     * @return string
434
     */
435
    protected function ticketQuantitySelector($min = 0, $max = 0)
436
    {
437
        // display submit button since we have tickets available
438
        add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true');
439
        $this->hidden_input_qty = false;
440
        $html = '<select name="tkt-slctr-qty-' . $this->EVT_ID . '[]"';
441
        $html .= ' id="ticket-selector-tbl-qty-slct-' . $this->EVT_ID . '-' . $this->row . '"';
442
        $html .= ' class="ticket-selector-tbl-qty-slct">';
443
        // this ensures that non-required tickets with non-zero MIN QTYs don't HAVE to be purchased
444
        if ($min !== 0 && ! $this->ticket->required()) {
445
            $html .= '<option value="0">&nbsp;0&nbsp;</option>';
446
        }
447
        // offer ticket quantities from the min to the max
448
        for ($i = $min; $i <= $max; $i++) {
449
            $html .= '<option value="' . $i . '">&nbsp;' . $i . '&nbsp;</option>';
450
        }
451
        $html .= '</select>';
452
        return $html;
453
    }
454
455
456
457
    /**
458
     * getHiddenInputs
459
     *
460
     * @return string
461
     * @throws \EE_Error
462
     */
463
    protected function ticketQtyAndIdHiddenInputs()
464
    {
465
        $html = '';
466
        // depending on group reg we need to change the format for qty
467
        if ($this->hidden_input_qty) {
468
            $html .= '<input type="hidden" name="tkt-slctr-qty-' . $this->EVT_ID . '[]" value="0"/>';
469
        }
470
        $html .= '<input type="hidden" name="tkt-slctr-ticket-id-' . $this->EVT_ID . '[]"';
471
        $html .= ' value="' . $this->ticket->ID() . '"/>';
472
        return $html;
473
    }
474
475
}
476
// End of file TicketSelectorRowStandard.php
477
// Location: EventEspresso\modules\ticket_selector/TicketSelectorRowStandard.php