Completed
Branch BUG-10381-asset-loading (189bf4)
by
unknown
13:54
created

TicketSelectorRowStandard::getHtml()   C

Complexity

Conditions 11
Paths 50

Size

Total Lines 91
Code Lines 58

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 58
nc 50
nop 0
dl 0
loc 91
rs 5.2653
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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