Completed
Branch dev (8d9313)
by
unknown
28:54 queued 19:27
created

EEM_Ticket::getTicketVisibilityValues()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Ticket Model
5
 *
6
 * @package            Event Espresso
7
 * @subpackage         includes/models/EEM_Ticket.model.php
8
 * @author             Darren Ethier
9
 */
10
class EEM_Ticket extends EEM_Soft_Delete_Base
11
{
12
13
    /**
14
     * the following constants define where tickets can be viewed throughout the UI
15
     *
16
     *  TICKET_VISIBILITY_NONE          - will not be displayed anywhere
17
     *  TICKET_VISIBILITY_PUBLIC        - displayed basically anywhere
18
     *  TICKET_VISIBILITY_MEMBERS_ONLY  - displayed to any logged in user
19
     *  TICKET_VISIBILITY_ADMINS_ONLY   - displayed to any logged in user that is an admin
20
     *  TICKET_VISIBILITY_ADMIN_UI_ONLY - only displayed in the admin, never publicly
21
     */
22
    public const TICKET_VISIBILITY_NONE_KEY            = 'NONE';
23
24
    public const TICKET_VISIBILITY_NONE_VALUE          = 0;
25
26
    public const TICKET_VISIBILITY_PUBLIC_KEY          = 'PUBLIC';
27
28
    public const TICKET_VISIBILITY_PUBLIC_VALUE        = 100;
29
30
    public const TICKET_VISIBILITY_MEMBERS_ONLY_KEY    = 'MEMBERS_ONLY';
31
32
    public const TICKET_VISIBILITY_MEMBERS_ONLY_VALUE  = 200;
33
34
    public const TICKET_VISIBILITY_ADMINS_ONLY_KEY     = 'ADMINS_ONLY';
35
36
    public const TICKET_VISIBILITY_ADMINS_ONLY_VALUE   = 300;
37
38
    public const TICKET_VISIBILITY_ADMIN_UI_ONLY_KEY   = 'ADMIN_UI_ONLY';
39
40
    public const TICKET_VISIBILITY_ADMIN_UI_ONLY_VALUE = 400;
41
42
43
    /**
44
     * defines where tickets can be viewed throughout the UI
45
     *
46
     * @var array
47
     */
48
    private $ticket_visibility;
49
50
    /**
51
     * private instance of the EEM_Ticket object
52
     *
53
     * @var EEM_Ticket $_instance
54
     */
55
    protected static $_instance;
56
57
58
    /**
59
     * private constructor to prevent direct creation
60
     *
61
     * @Constructor
62
     * @access private
63
     * @param string $timezone string representing the timezone we want to set for returned Date Time Strings
64
     *                         (and any incoming timezone data that gets saved).
65
     *                         Note this just sends the timezone info to the date time model field objects.
66
     *                         Default is NULL
67
     *                         (and will be assumed using the set timezone in the 'timezone_string' wp option)
68
     * @throws EE_Error
69
     */
70
    protected function __construct($timezone)
71
    {
72
        $this->singular_item = esc_html__('Ticket', 'event_espresso');
73
        $this->plural_item   = esc_html__('Tickets', 'event_espresso');
74
        $this->_tables       = [
75
            'Ticket' => new EE_Primary_Table('esp_ticket', 'TKT_ID'),
76
        ];
77
        $this->parseTicketVisibilityOptions();
78
        $this->_fields          = [
79
            'Ticket' => [
80
                'TKT_ID'                => new EE_Primary_Key_Int_Field(
81
                    'TKT_ID',
82
                    esc_html__('Ticket ID', 'event_espresso')
83
                ),
84
                'TTM_ID'                => new EE_Foreign_Key_Int_Field(
85
                    'TTM_ID',
86
                    esc_html__('Ticket Template ID', 'event_espresso'),
87
                    false,
88
                    0,
89
                    'Ticket_Template'
90
                ),
91
                'TKT_name'              => new EE_Plain_Text_Field(
92
                    'TKT_name',
93
                    esc_html__('Ticket Name', 'event_espresso'),
94
                    false,
95
                    ''
96
                ),
97
                'TKT_description'       => new EE_Post_Content_Field(
98
                    'TKT_description',
99
                    esc_html__('Description of Ticket', 'event_espresso'),
100
                    false,
101
                    ''
102
                ),
103
                'TKT_start_date'        => new EE_Datetime_Field(
104
                    'TKT_start_date',
105
                    esc_html__('Start time/date of Ticket', 'event_espresso'),
106
                    false,
107
                    EE_Datetime_Field::now,
108
                    $timezone
109
                ),
110
                'TKT_end_date'          => new EE_Datetime_Field(
111
                    'TKT_end_date',
112
                    esc_html__('End time/date of Ticket', 'event_espresso'),
113
                    false,
114
                    EE_Datetime_Field::now,
115
                    $timezone
116
                ),
117
                'TKT_min'               => new EE_Integer_Field(
118
                    'TKT_min',
119
                    esc_html__('Minimum quantity of this ticket that must be purchased', 'event_espresso'),
120
                    false,
121
                    0
122
                ),
123
                'TKT_max'               => new EE_Infinite_Integer_Field(
124
                    'TKT_max',
125
                    esc_html__(
126
                        'Maximum quantity of this ticket that can be purchased in one transaction',
127
                        'event_espresso'
128
                    ),
129
                    false,
130
                    EE_INF
131
                ),
132
                'TKT_price'             => new EE_Money_Field(
133
                    'TKT_price',
134
                    esc_html__('Final calculated price for ticket', 'event_espresso'),
135
                    false,
136
                    0
137
                ),
138
                'TKT_sold'              => new EE_Integer_Field(
139
                    'TKT_sold',
140
                    esc_html__('Number of this ticket sold', 'event_espresso'),
141
                    false,
142
                    0
143
                ),
144
                'TKT_qty'               => new EE_Infinite_Integer_Field(
145
                    'TKT_qty',
146
                    esc_html__('Quantity of this ticket that is available', 'event_espresso'),
147
                    false,
148
                    EE_INF
149
                ),
150
                'TKT_reserved'          => new EE_Integer_Field(
151
                    'TKT_reserved',
152
                    esc_html__(
153
                        'Quantity of this ticket that is reserved, but not yet fully purchased',
154
                        'event_espresso'
155
                    ),
156
                    false,
157
                    0
158
                ),
159
                'TKT_uses'              => new EE_Infinite_Integer_Field(
160
                    'TKT_uses',
161
                    esc_html__('Number of datetimes this ticket can be used at', 'event_espresso'),
162
                    false,
163
                    EE_INF
164
                ),
165
                'TKT_required'          => new EE_Boolean_Field(
166
                    'TKT_required',
167
                    esc_html__(
168
                        'Flag indicating whether this ticket must be purchased with a transaction',
169
                        'event_espresso'
170
                    ),
171
                    false,
172
                    false
173
                ),
174
                'TKT_taxable'           => new EE_Boolean_Field(
175
                    'TKT_taxable',
176
                    esc_html__(
177
                        'Flag indicating whether there is tax applied on this ticket',
178
                        'event_espresso'
179
                    ),
180
                    false,
181
                    false
182
                ),
183
                'TKT_is_default'        => new EE_Boolean_Field(
184
                    'TKT_is_default',
185
                    esc_html__('Flag indicating that this ticket is a default ticket', 'event_espresso'),
186
                    false,
187
                    false
188
                ),
189
                'TKT_order'             => new EE_Integer_Field(
190
                    'TKT_order',
191
                    esc_html__(
192
                        'The order in which the Ticket is displayed in the editor (used for autosaves when the form doesn\'t have the ticket ID yet)',
193
                        'event_espresso'
194
                    ),
195
                    false,
196
                    0
197
                ),
198
                'TKT_row'               => new EE_Integer_Field(
199
                    'TKT_row',
200
                    esc_html__('How tickets are displayed in the ui', 'event_espresso'),
201
                    false,
202
                    0
203
                ),
204
                'TKT_deleted'           => new EE_Trashed_Flag_Field(
205
                    'TKT_deleted',
206
                    esc_html__('Flag indicating if this has been archived or not', 'event_espresso'),
207
                    false,
208
                    false
209
                ),
210
                'TKT_wp_user'           => new EE_WP_User_Field(
211
                    'TKT_wp_user',
212
                    esc_html__('Ticket Creator ID', 'event_espresso'),
213
                    false
214
                ),
215
                'TKT_parent'            => new EE_Integer_Field(
216
                    'TKT_parent',
217
                    esc_html__(
218
                        'Indicates what TKT_ID is the parent of this TKT_ID (used in autosaves/revisions)',
219
                        'event_espresso'
220
                    ),
221
                    true,
222
                    0
223
                ),
224
                'TKT_reverse_calculate' => new EE_Boolean_Field(
225
                    'TKT_reverse_calculate',
226
                    esc_html__(
227
                        'Flag indicating whether ticket calculations should run in reverse and calculate the base ticket price from the provided ticket total.',
228
                        'event_espresso'
229
                    ),
230
                    false,
231
                    false
232
                ),
233
                'TKT_visibility'        => new EE_Enum_Integer_Field(
234
                    'TKT_visibility',
235
                    esc_html__('Defines where the ticket can be viewed throughout the UI.', 'event_espresso'),
236
                    false,
237
                    EEM_Ticket::TICKET_VISIBILITY_PUBLIC_VALUE,
238
                    $this->getTicketVisibilityEnumOptions()
239
                ),
240
            ],
241
        ];
242
        $this->_model_relations = [
243
            'Datetime'        => new EE_HABTM_Relation('Datetime_Ticket'),
244
            'Datetime_Ticket' => new EE_Has_Many_Relation(),
245
            'Price'           => new EE_HABTM_Relation('Ticket_Price'),
246
            'Ticket_Template' => new EE_Belongs_To_Relation(),
247
            'Registration'    => new EE_Has_Many_Relation(),
248
            'WP_User'         => new EE_Belongs_To_Relation(),
249
        ];
250
        // this model is generally available for reading
251
        $path_to_event                                            = 'Datetime.Event';
252
        $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Default_Public(
253
            'TKT_is_default',
254
            $path_to_event
255
        );
256
        // account for default tickets in the caps
257
        $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ]
258
            = new EE_Restriction_Generator_Default_Protected(
259
                'TKT_is_default',
260
                $path_to_event
261
            );
262
        $this->_cap_restriction_generators[ EEM_Base::caps_edit ]   = new EE_Restriction_Generator_Default_Protected(
263
            'TKT_is_default',
264
            $path_to_event
265
        );
266
        $this->_cap_restriction_generators[ EEM_Base::caps_delete ] = new EE_Restriction_Generator_Default_Protected(
267
            'TKT_is_default',
268
            $path_to_event
269
        );
270
        $this->model_chain_to_password                              = $path_to_event;
271
        parent::__construct($timezone);
272
    }
273
274
275
    /**
276
     * This returns all tickets that are defaults from the db
277
     *
278
     * @return EE_Ticket[]
279
     * @throws EE_Error
280
     * @throws ReflectionException
281
     */
282
    public function get_all_default_tickets(): array
283
    {
284
        /** @type EE_Ticket[] $tickets */
285
        $tickets = $this->get_all(
286
            [
287
                [
288
                    'TKT_is_default' => 1,
289
                    'TKT_visibility' => ['>', EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE],
290
                ],
291
                'order_by' => ['TKT_ID' => 'ASC'],
292
            ]
293
        );
294
        // we need to set the start date and end date to today's date and the start of the default dtt
295
        return $this->_set_default_dates($tickets);
296
    }
297
298
299
    /**
300
     * sets up relevant start and end date for EE_Ticket (s)
301
     *
302
     * @param EE_Ticket[] $tickets
303
     * @return EE_Ticket[]
304
     * @throws EE_Error
305
     * @throws ReflectionException
306
     */
307
    private function _set_default_dates(array $tickets): array
308
    {
309
        foreach ($tickets as $ticket) {
310
            $ticket->set(
311
                'TKT_start_date',
312
                (int) $this->current_time_for_query('TKT_start_date', true)
313
            );
314
            $ticket->set(
315
                'TKT_end_date',
316
                (int) $this->current_time_for_query('TKT_end_date', true) + MONTH_IN_SECONDS
317
            );
318
            $ticket->set_end_time(
319
                $this->convert_datetime_for_query(
320
                    'TKT_end_date',
321
                    '11:59 pm',
322
                    'g:i a',
323
                    $this->_timezone
324
                )
325
            );
326
        }
327
        return $tickets;
328
    }
329
330
331
    /**
332
     * Gets the total number of tickets available at a particular datetime (does
333
     * NOT take int account the datetime's spaces available)
334
     *
335
     * @param int   $DTT_ID
336
     * @param array $query_params
337
     * @return int
338
     * @throws EE_Error
339
     * @throws ReflectionException
340
     */
341
    public function sum_tickets_currently_available_at_datetime(int $DTT_ID, array $query_params = []): int
342
    {
343
        $query_params += [['TKT_visibility' => ['>', EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE]]];
344
        return EEM_Datetime::instance()->sum_tickets_currently_available_at_datetime($DTT_ID, $query_params);
345
    }
346
347
348
    /**
349
     * Updates the TKT_sold quantity on all the tickets matching $query_params
350
     *
351
     * @param EE_Ticket[] $tickets
352
     * @return void
353
     * @throws EE_Error
354
     * @throws ReflectionException
355
     */
356
    public function update_tickets_sold(array $tickets)
357
    {
358
        foreach ($tickets as $ticket) {
359
            $ticket->update_tickets_sold();
360
        }
361
    }
362
363
364
    /**
365
     * returns an array of EE_Ticket objects with a non-zero value for TKT_reserved
366
     *
367
     * @return EE_Base_Class[]|EE_Ticket[]
368
     * @throws EE_Error
369
     */
370
    public function get_tickets_with_reservations()
371
    {
372
        return $this->get_all(
373
            [
374
                [
375
                    'TKT_reserved'   => ['>', 0],
376
                    'TKT_visibility' => ['>', EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE],
377
                ],
378
            ]
379
        );
380
    }
381
382
383
    /**
384
     * returns an array of EE_Ticket objects matching the supplied list of IDs
385
     *
386
     * @param array $ticket_IDs
387
     * @return EE_Base_Class[]|EE_Ticket[]
388
     * @throws EE_Error
389
     */
390
    public function get_tickets_with_IDs(array $ticket_IDs)
391
    {
392
        return $this->get_all(
393
            [
394
                [
395
                    'TKT_ID' => ['IN', $ticket_IDs],
396
                ],
397
            ]
398
        );
399
    }
400
401
402
    /**
403
     * @return void
404
     */
405
    private function parseTicketVisibilityOptions()
406
    {
407
        $this->ticket_visibility = (array) apply_filters(
408
            'FHEE__EEM_Ticket__construct__ticket_visibility',
409
            [
410
                EEM_Ticket::TICKET_VISIBILITY_PUBLIC_KEY        => [
411
                    'label' => esc_html__('Public', 'event_espresso'),
412
                    'value' => EEM_Ticket::TICKET_VISIBILITY_PUBLIC_VALUE,
413
                ],
414
                EEM_Ticket::TICKET_VISIBILITY_MEMBERS_ONLY_KEY  => [
415
                    'label' => esc_html__('Members only', 'event_espresso'),
416
                    'value' => EEM_Ticket::TICKET_VISIBILITY_MEMBERS_ONLY_VALUE,
417
                ],
418
                EEM_Ticket::TICKET_VISIBILITY_ADMINS_ONLY_KEY   => [
419
                    'label' => esc_html__('Admins only', 'event_espresso'),
420
                    'value' => EEM_Ticket::TICKET_VISIBILITY_ADMINS_ONLY_VALUE,
421
                ],
422
                EEM_Ticket::TICKET_VISIBILITY_ADMIN_UI_ONLY_KEY => [
423
                    'label' => esc_html__('Admin UI only', 'event_espresso'),
424
                    'value' => EEM_Ticket::TICKET_VISIBILITY_ADMIN_UI_ONLY_VALUE,
425
                ],
426
                EEM_Ticket::TICKET_VISIBILITY_NONE_KEY          => [
427
                    'label' => esc_html__('None', 'event_espresso'),
428
                    'value' => EEM_Ticket::TICKET_VISIBILITY_NONE_VALUE,
429
                ],
430
            ]
431
        );
432
    }
433
434
435
    /**
436
     * @return array
437
     */
438
    public function getTicketVisibilityEnumOptions(): array
439
    {
440
        $ticket_visibility = [];
441
        foreach ($this->ticket_visibility as $visibility) {
442
            if (isset($visibility['value'], $visibility['label'])) {
443
                $ticket_visibility[ $visibility['value'] ] = $visibility['label'];
444
            }
445
        }
446
        return $ticket_visibility;
447
    }
448
449
450
    /**
451
     * @return array
452
     */
453
    public function getTicketVisibilityValues(): array
454
    {
455
        // copy ticket_visibility array
456
        $ticket_visibility_options = $this->ticket_visibility;
457
        foreach ($ticket_visibility_options as $ticket_visibility_option) {
458
            // remove labels because we only want the values
459
            unset($ticket_visibility_option['label']);
460
        }
461
        return $ticket_visibility_options;
462
    }
463
464
465
    /**
466
     * @return array
467
     */
468
    public function getTicketVisibilityLabels(): array
469
    {
470
        $ticket_visibility_options = [];
471
        foreach ($this->ticket_visibility as $key => $ticket_visibility_option) {
472
            if (isset($ticket_visibility_option['label'])) {
473
                // change because we only want the labels tied to the keys
474
                $ticket_visibility_options[] = [
475
                    'value' => $key,
476
                    'label' => $ticket_visibility_option['label']
477
                ];
478
            }
479
        }
480
        return $ticket_visibility_options;
481
    }
482
483
484
    /**
485
     * @return array
486
     */
487
    public function ticketVisibilityOptions(): array
488
    {
489
        return $this->ticket_visibility;
490
    }
491
}
492