Completed
Branch barista (bd0c0c)
by
unknown
64:27 queued 54:05
created
core/db_models/EEM_Datetime.model.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -463,7 +463,7 @@  discard block
 block discarded – undo
463 463
      * @param int      $TKT_ID           ID of ticket to retrieve the datetimes for
464 464
      * @param boolean  $include_expired  whether to include expired datetimes or not
465 465
      * @param boolean  $include_deleted  whether to include trashed datetimes or not.
466
-     * @param int|null $limit            if null, no limit, if int then limit results by
466
+     * @param integer $limit            if null, no limit, if int then limit results by
467 467
      *                                   that number
468 468
      * @return EE_Datetime[]
469 469
      * @throws EE_Error
@@ -648,7 +648,7 @@  discard block
 block discarded – undo
648 648
     /**
649 649
      * This returns an array of counts of datetimes in the database for each Datetime status that can be queried.
650 650
      *
651
-     * @param array $stati_to_include  If included you can restrict the statuses we return counts for by including the
651
+     * @param string[] $stati_to_include  If included you can restrict the statuses we return counts for by including the
652 652
      *                                 stati you want counts for as values in the array.  An empty array returns counts
653 653
      *                                 for all valid stati.
654 654
      * @param array $query_params      If included can be used to refine the conditions for returning the count (i.e.
Please login to merge, or discard this patch.
Indentation   +830 added lines, -830 removed lines patch added patch discarded remove patch
@@ -13,834 +13,834 @@
 block discarded – undo
13 13
 class EEM_Datetime extends EEM_Soft_Delete_Base
14 14
 {
15 15
 
16
-    /**
17
-     * @var EEM_Datetime $_instance
18
-     */
19
-    protected static $_instance;
20
-
21
-
22
-    /**
23
-     * private constructor to prevent direct creation
24
-     *
25
-     * @param string $timezone A string representing the timezone we want to set for returned Date Time Strings
26
-     *                         (and any incoming timezone data that gets saved).
27
-     *                         Note this just sends the timezone info to the date time model field objects.
28
-     *                         Default is NULL
29
-     *                         (and will be assumed using the set timezone in the 'timezone_string' wp option)
30
-     * @throws EE_Error
31
-     * @throws InvalidArgumentException
32
-     * @throws InvalidArgumentException
33
-     */
34
-    protected function __construct($timezone)
35
-    {
36
-        $this->singular_item           = esc_html__('Datetime', 'event_espresso');
37
-        $this->plural_item             = esc_html__('Datetimes', 'event_espresso');
38
-        $this->_tables                 = [
39
-            'Datetime' => new EE_Primary_Table('esp_datetime', 'DTT_ID'),
40
-        ];
41
-        $this->_fields                 = [
42
-            'Datetime' => [
43
-                'DTT_ID'          => new EE_Primary_Key_Int_Field(
44
-                    'DTT_ID',
45
-                    esc_html__('Datetime ID', 'event_espresso')
46
-                ),
47
-                'EVT_ID'          => new EE_Foreign_Key_Int_Field(
48
-                    'EVT_ID',
49
-                    esc_html__('Event ID', 'event_espresso'),
50
-                    false,
51
-                    0,
52
-                    'Event'
53
-                ),
54
-                'DTT_name'        => new EE_Plain_Text_Field(
55
-                    'DTT_name',
56
-                    esc_html__('Datetime Name', 'event_espresso'),
57
-                    false,
58
-                    ''
59
-                ),
60
-                'DTT_description' => new EE_Post_Content_Field(
61
-                    'DTT_description',
62
-                    esc_html__('Description for Datetime', 'event_espresso'),
63
-                    false,
64
-                    ''
65
-                ),
66
-                'DTT_EVT_start'   => new EE_Datetime_Field(
67
-                    'DTT_EVT_start',
68
-                    esc_html__('Start time/date of Event', 'event_espresso'),
69
-                    false,
70
-                    EE_Datetime_Field::now,
71
-                    $timezone
72
-                ),
73
-                'DTT_EVT_end'     => new EE_Datetime_Field(
74
-                    'DTT_EVT_end',
75
-                    esc_html__('End time/date of Event', 'event_espresso'),
76
-                    false,
77
-                    EE_Datetime_Field::now,
78
-                    $timezone
79
-                ),
80
-                'DTT_reg_limit'   => new EE_Infinite_Integer_Field(
81
-                    'DTT_reg_limit',
82
-                    esc_html__('Registration Limit for this time', 'event_espresso'),
83
-                    true,
84
-                    EE_INF
85
-                ),
86
-                'DTT_sold'        => new EE_Integer_Field(
87
-                    'DTT_sold',
88
-                    esc_html__('How many sales for this Datetime that have occurred', 'event_espresso'),
89
-                    true,
90
-                    0
91
-                ),
92
-                'DTT_reserved'    => new EE_Integer_Field(
93
-                    'DTT_reserved',
94
-                    esc_html__('Quantity of tickets reserved, but not yet fully purchased', 'event_espresso'),
95
-                    false,
96
-                    0
97
-                ),
98
-                'DTT_is_primary'  => new EE_Boolean_Field(
99
-                    'DTT_is_primary',
100
-                    esc_html__('Flag indicating datetime is primary one for event', 'event_espresso'),
101
-                    false,
102
-                    false
103
-                ),
104
-                'DTT_order'       => new EE_Integer_Field(
105
-                    'DTT_order',
106
-                    esc_html__('The order in which the Datetime is displayed', 'event_espresso'),
107
-                    false,
108
-                    0
109
-                ),
110
-                'DTT_parent'      => new EE_Integer_Field(
111
-                    'DTT_parent',
112
-                    esc_html__('Indicates what DTT_ID is the parent of this DTT_ID', 'event_espresso'),
113
-                    true,
114
-                    0
115
-                ),
116
-                'DTT_deleted'     => new EE_Trashed_Flag_Field(
117
-                    'DTT_deleted',
118
-                    esc_html__('Flag indicating datetime is archived', 'event_espresso'),
119
-                    false,
120
-                    false
121
-                ),
122
-            ],
123
-        ];
124
-        $this->_model_relations        = [
125
-            'Ticket'          => new EE_HABTM_Relation('Datetime_Ticket'),
126
-            'Event'           => new EE_Belongs_To_Relation(),
127
-            'Checkin'         => new EE_Has_Many_Relation(),
128
-            'Datetime_Ticket' => new EE_Has_Many_Relation(),
129
-        ];
130
-        $path_to_event_model           = 'Event';
131
-        $this->model_chain_to_password = $path_to_event_model;
132
-        $this->_model_chain_to_wp_user = $path_to_event_model;
133
-        // this model is generally available for reading
134
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ]       =
135
-            new EE_Restriction_Generator_Event_Related_Public(
136
-                $path_to_event_model
137
-            );
138
-        $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] =
139
-            new EE_Restriction_Generator_Event_Related_Protected(
140
-                $path_to_event_model
141
-            );
142
-        $this->_cap_restriction_generators[ EEM_Base::caps_edit ]       =
143
-            new EE_Restriction_Generator_Event_Related_Protected(
144
-                $path_to_event_model
145
-            );
146
-        $this->_cap_restriction_generators[ EEM_Base::caps_delete ]     =
147
-            new EE_Restriction_Generator_Event_Related_Protected(
148
-                $path_to_event_model,
149
-                EEM_Base::caps_edit
150
-            );
151
-        parent::__construct($timezone);
152
-    }
153
-
154
-
155
-    /**
156
-     * create new blank datetime
157
-     *
158
-     * @access public
159
-     * @return EE_Datetime[] array on success, FALSE on fail
160
-     * @throws EE_Error
161
-     * @throws InvalidArgumentException
162
-     * @throws InvalidDataTypeException
163
-     * @throws ReflectionException
164
-     * @throws InvalidInterfaceException
165
-     */
166
-    public function create_new_blank_datetime()
167
-    {
168
-        // makes sure timezone is always set.
169
-        $timezone_string = $this->get_timezone();
170
-        /**
171
-         * Filters the initial start date for the new datetime.
172
-         * Any time included in this value will be overridden later so use additional filters to modify the time.
173
-         *
174
-         * @param int $start_date Unix timestamp representing now + 30 days in seconds.
175
-         * @return int Unix timestamp
176
-         */
177
-        $start_date = apply_filters(
178
-            'FHEE__EEM_Datetime__create_new_blank_datetime__start_date',
179
-            $this->current_time_for_query('DTT_EVT_start', true) + MONTH_IN_SECONDS
180
-        );
181
-        /**
182
-         * Filters the initial end date for the new datetime.
183
-         * Any time included in this value will be overridden later so use additional filters to modify the time.
184
-         *
185
-         * @param int $end_data Unix timestamp representing now + 30 days in seconds.
186
-         * @return int Unix timestamp
187
-         */
188
-        $end_date       = apply_filters(
189
-            'FHEE__EEM_Datetime__create_new_blank_datetime__end_date',
190
-            $this->current_time_for_query('DTT_EVT_end', true) + MONTH_IN_SECONDS
191
-        );
192
-        $blank_datetime = EE_Datetime::new_instance(
193
-            [
194
-                'DTT_EVT_start' => $start_date,
195
-                'DTT_EVT_end'   => $end_date,
196
-                'DTT_order'     => 1,
197
-                'DTT_reg_limit' => EE_INF,
198
-            ],
199
-            $timezone_string
200
-        );
201
-        /**
202
-         * Filters the initial start time and format for the new EE_Datetime instance.
203
-         *
204
-         * @param array $start_time An array having size 2.  First element is the time, second element is the time
205
-         *                          format.
206
-         * @return array
207
-         */
208
-        $start_time = apply_filters(
209
-            'FHEE__EEM_Datetime__create_new_blank_datetime__start_time',
210
-            ['8am', 'ga']
211
-        );
212
-        /**
213
-         * Filters the initial end time and format for the new EE_Datetime instance.
214
-         *
215
-         * @param array $end_time An array having size 2.  First element is the time, second element is the time
216
-         *                        format
217
-         * @return array
218
-         */
219
-        $end_time = apply_filters(
220
-            'FHEE__EEM_Datetime__create_new_blank_datetime__end_time',
221
-            ['5pm', 'ga']
222
-        );
223
-        $this->validateStartAndEndTimeForBlankDate($start_time, $end_time);
224
-        $blank_datetime->set_start_time(
225
-            $this->convert_datetime_for_query(
226
-                'DTT_EVT_start',
227
-                $start_time[0],
228
-                $start_time[1],
229
-                $timezone_string
230
-            )
231
-        );
232
-        $blank_datetime->set_end_time(
233
-            $this->convert_datetime_for_query(
234
-                'DTT_EVT_end',
235
-                $end_time[0],
236
-                $end_time[1],
237
-                $timezone_string
238
-            )
239
-        );
240
-        return [$blank_datetime];
241
-    }
242
-
243
-
244
-    /**
245
-     * Validates whether the start_time and end_time are in the expected format.
246
-     *
247
-     * @param array $start_time
248
-     * @param array $end_time
249
-     * @throws InvalidArgumentException
250
-     * @throws InvalidDataTypeException
251
-     */
252
-    private function validateStartAndEndTimeForBlankDate(array $start_time, array $end_time)
253
-    {
254
-        if (! is_array($start_time)) {
255
-            throw new InvalidDataTypeException('start_time', $start_time, 'array');
256
-        }
257
-        if (! is_array($end_time)) {
258
-            throw new InvalidDataTypeException('end_time', $end_time, 'array');
259
-        }
260
-        if (count($start_time) !== 2) {
261
-            throw new InvalidArgumentException(
262
-                sprintf(
263
-                    'The variable %1$s is expected to be an array with two elements.  The first item in the '
264
-                    . 'array should be a valid time string, the second item in the array should be a valid time format',
265
-                    '$start_time'
266
-                )
267
-            );
268
-        }
269
-        if (count($end_time) !== 2) {
270
-            throw new InvalidArgumentException(
271
-                sprintf(
272
-                    'The variable %1$s is expected to be an array with two elements.  The first item in the '
273
-                    . 'array should be a valid time string, the second item in the array should be a valid time format',
274
-                    '$end_time'
275
-                )
276
-            );
277
-        }
278
-    }
279
-
280
-
281
-    /**
282
-     * get event start date from db
283
-     *
284
-     * @access public
285
-     * @param int $EVT_ID
286
-     * @return EE_Datetime[] array on success, FALSE on fail
287
-     * @throws EE_Error
288
-     * @throws ReflectionException
289
-     */
290
-    public function get_all_event_dates($EVT_ID = 0)
291
-    {
292
-        if (! $EVT_ID) { // on add_new_event event_id gets set to 0
293
-            return $this->create_new_blank_datetime();
294
-        }
295
-        $results = $this->get_datetimes_for_event_ordered_by_DTT_order($EVT_ID);
296
-        if (empty($results)) {
297
-            return $this->create_new_blank_datetime();
298
-        }
299
-        return $results;
300
-    }
301
-
302
-
303
-    /**
304
-     * get all datetimes attached to an event ordered by the DTT_order field
305
-     *
306
-     * @public
307
-     * @param int     $EVT_ID     event id
308
-     * @param boolean $include_expired
309
-     * @param boolean $include_deleted
310
-     * @param int     $limit      If included then limit the count of results by
311
-     *                            the given number
312
-     * @return EE_Datetime[]
313
-     * @throws EE_Error
314
-     */
315
-    public function get_datetimes_for_event_ordered_by_DTT_order(
316
-        int $EVT_ID,
317
-        bool $include_expired = true,
318
-        bool $include_deleted = true,
319
-        $limit = 0
320
-    ) {
321
-        $prev_data_prep_value = $this->prepModelForQuery();
322
-        $where_params         = ['Event.EVT_ID' => absint($EVT_ID)];
323
-        $query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
324
-        $query_params         = $this->addDefaultWhereConditions($query_params);
325
-        $query_params         = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
326
-        return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
327
-    }
328
-
329
-
330
-    /**
331
-     * Gets the datetimes for the event (with the given limit), and orders them by "importance".
332
-     * By importance, we mean that the primary datetimes are most important (DEPRECATED FOR NOW),
333
-     * and then the earlier datetimes are the most important.
334
-     * Maybe we'll want this to take into account datetimes that haven't already passed, but we don't yet.
335
-     *
336
-     * @param int $EVT_ID
337
-     * @param int $limit
338
-     * @return EE_Datetime[]|EE_Base_Class[]
339
-     * @throws EE_Error
340
-     */
341
-    public function get_datetimes_for_event_ordered_by_importance(int $EVT_ID, $limit = 0)
342
-    {
343
-        $query_params[0] = ['Event.EVT_ID' => absint($EVT_ID)];
344
-        $query_params    = $this->addDefaultWhereConditions($query_params);
345
-        $query_params    = $this->addDefaultQueryParams($query_params, $limit);
346
-        return $this->get_all($query_params);
347
-    }
348
-
349
-
350
-    /**
351
-     * @param int     $EVT_ID
352
-     * @param boolean $include_expired
353
-     * @param boolean $include_deleted
354
-     * @return EE_Datetime
355
-     * @throws EE_Error
356
-     */
357
-    public function get_oldest_datetime_for_event(
358
-        int $EVT_ID,
359
-        bool $include_expired = false,
360
-        bool $include_deleted = false
361
-    ) {
362
-        $results = $this->get_datetimes_for_event_ordered_by_start_time(
363
-            $EVT_ID,
364
-            $include_expired,
365
-            $include_deleted,
366
-            1
367
-        );
368
-        if ($results) {
369
-            return array_shift($results);
370
-        }
371
-        return null;
372
-    }
373
-
374
-
375
-    /**
376
-     * Gets the 'primary' datetime for an event.
377
-     *
378
-     * @param int  $EVT_ID
379
-     * @param bool $try_to_exclude_expired
380
-     * @param bool $try_to_exclude_deleted
381
-     * @return EE_Datetime
382
-     * @throws EE_Error
383
-     */
384
-    public function get_primary_datetime_for_event(
385
-        int $EVT_ID,
386
-        bool $try_to_exclude_expired = true,
387
-        bool $try_to_exclude_deleted = true
388
-    ) {
389
-        if ($try_to_exclude_expired) {
390
-            $non_expired = $this->get_oldest_datetime_for_event($EVT_ID, false, false);
391
-            if ($non_expired) {
392
-                return $non_expired;
393
-            }
394
-        }
395
-        if ($try_to_exclude_deleted) {
396
-            $expired_even = $this->get_oldest_datetime_for_event($EVT_ID, true);
397
-            if ($expired_even) {
398
-                return $expired_even;
399
-            }
400
-        }
401
-        return $this->get_oldest_datetime_for_event($EVT_ID, true, true);
402
-    }
403
-
404
-
405
-    /**
406
-     * Gets ALL the datetimes for an event (including trashed ones, for now), ordered
407
-     * only by start date
408
-     *
409
-     * @param int     $EVT_ID
410
-     * @param boolean $include_expired
411
-     * @param boolean $include_deleted
412
-     * @param int     $limit
413
-     * @return EE_Datetime[]
414
-     * @throws EE_Error
415
-     */
416
-    public function get_datetimes_for_event_ordered_by_start_time(
417
-        int $EVT_ID,
418
-        bool $include_expired = true,
419
-        bool $include_deleted = true,
420
-        $limit = 0
421
-    ) {
422
-        $prev_data_prep_value = $this->prepModelForQuery();
423
-        $where_params         = ['Event.EVT_ID' => absint($EVT_ID)];
424
-        $query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
425
-        $query_params         = $this->addDefaultWhereConditions(
426
-            $query_params,
427
-            EEM_Base::default_where_conditions_this_only
428
-        );
429
-        $query_params         = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
430
-        return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
431
-    }
432
-
433
-
434
-    /**
435
-     * Gets ALL the datetimes for an ticket (including trashed ones, for now), ordered
436
-     * only by start date
437
-     *
438
-     * @param int     $TKT_ID
439
-     * @param boolean $include_expired
440
-     * @param boolean $include_deleted
441
-     * @param int     $limit
442
-     * @return EE_Datetime[]
443
-     * @throws EE_Error
444
-     */
445
-    public function get_datetimes_for_ticket_ordered_by_start_time(
446
-        int $TKT_ID,
447
-        bool $include_expired = true,
448
-        bool $include_deleted = true,
449
-        $limit = 0
450
-    ) {
451
-        $prev_data_prep_value = $this->prepModelForQuery();
452
-        $where_params         = ['Ticket.TKT_ID' => absint($TKT_ID)];
453
-        $query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
454
-        $query_params         = $this->addDefaultQueryParams($query_params, $limit);
455
-        return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
456
-    }
457
-
458
-
459
-    /**
460
-     * Gets all the datetimes for a ticket (including trashed ones, for now), ordered by the DTT_order for the
461
-     * datetimes.
462
-     *
463
-     * @param int      $TKT_ID           ID of ticket to retrieve the datetimes for
464
-     * @param boolean  $include_expired  whether to include expired datetimes or not
465
-     * @param boolean  $include_deleted  whether to include trashed datetimes or not.
466
-     * @param int|null $limit            if null, no limit, if int then limit results by
467
-     *                                   that number
468
-     * @return EE_Datetime[]
469
-     * @throws EE_Error
470
-     */
471
-    public function get_datetimes_for_ticket_ordered_by_DTT_order(
472
-        int $TKT_ID,
473
-        bool $include_expired = true,
474
-        bool $include_deleted = true,
475
-        $limit = 0
476
-    ) {
477
-        $prev_data_prep_value = $this->prepModelForQuery();
478
-        $where_params         = ['Ticket.TKT_ID' => absint($TKT_ID)];
479
-        $query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
480
-        $query_params         = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
481
-        return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
482
-    }
483
-
484
-
485
-    /**
486
-     * Gets the most important datetime for a particular event (ie, the primary event usually. But if for some WACK
487
-     * reason it doesn't exist, we consider the earliest event the most important)
488
-     *
489
-     * @param int $EVT_ID
490
-     * @return EE_Datetime
491
-     * @throws EE_Error
492
-     */
493
-    public function get_most_important_datetime_for_event(int $EVT_ID)
494
-    {
495
-        $results = $this->get_datetimes_for_event_ordered_by_importance($EVT_ID, 1);
496
-        if ($results) {
497
-            return array_shift($results);
498
-        }
499
-        return null;
500
-    }
501
-
502
-
503
-    /**
504
-     * This returns a wpdb->results        Array of all DTT month and years matching the incoming query params and
505
-     * grouped by month and year.
506
-     *
507
-     * @param array  $where_params       @see
508
-     *                                   https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
509
-     * @param string $evt_active_status  A string representing the evt active status to filter the months by.
510
-     *                                   Can be:
511
-     *                                   - '' = no filter
512
-     *                                   - upcoming = Published events with at least one upcoming datetime.
513
-     *                                   - expired = Events with all datetimes expired.
514
-     *                                   - active = Events that are published and have at least one datetime that
515
-     *                                   starts before now and ends after now.
516
-     *                                   - inactive = Events that are either not published.
517
-     * @return EE_Base_Class[]
518
-     * @throws EE_Error
519
-     * @throws InvalidArgumentException
520
-     * @throws InvalidArgumentException
521
-     */
522
-    public function get_dtt_months_and_years(array $where_params, $evt_active_status = '')
523
-    {
524
-        $current_time_for_DTT_EVT_start = $this->current_time_for_query('DTT_EVT_start');
525
-        $current_time_for_DTT_EVT_end   = $this->current_time_for_query('DTT_EVT_end');
526
-        switch ($evt_active_status) {
527
-            case 'upcoming':
528
-                $where_params['Event.status'] = 'publish';
529
-                // if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
530
-                if (isset($where_params['DTT_EVT_start'])) {
531
-                    $where_params['DTT_EVT_start*****'] = $where_params['DTT_EVT_start'];
532
-                }
533
-                $where_params['DTT_EVT_start'] = ['>', $current_time_for_DTT_EVT_start];
534
-                break;
535
-            case 'expired':
536
-                if (isset($where_params['Event.status'])) {
537
-                    unset($where_params['Event.status']);
538
-                }
539
-                // get events to exclude
540
-                $exclude_query[0] = array_merge(
541
-                    $where_params,
542
-                    ['DTT_EVT_end' => ['>', $current_time_for_DTT_EVT_end]]
543
-                );
544
-                // first get all events that have datetimes where its not expired.
545
-                $event_ids = $this->_get_all_wpdb_results(
546
-                    $exclude_query,
547
-                    OBJECT_K,
548
-                    'Datetime.EVT_ID'
549
-                );
550
-                $event_ids = array_keys($event_ids);
551
-                if (isset($where_params['DTT_EVT_end'])) {
552
-                    $where_params['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
553
-                }
554
-                $where_params['DTT_EVT_end']  = ['<', $current_time_for_DTT_EVT_end];
555
-                $where_params['Event.EVT_ID'] = ['NOT IN', $event_ids];
556
-                break;
557
-            case 'active':
558
-                $where_params['Event.status'] = 'publish';
559
-                if (isset($where_params['DTT_EVT_start'])) {
560
-                    $where_params['Datetime.DTT_EVT_start******'] = $where_params['DTT_EVT_start'];
561
-                }
562
-                if (isset($where_params['Datetime.DTT_EVT_end'])) {
563
-                    $where_params['Datetime.DTT_EVT_end*****'] = $where_params['DTT_EVT_end'];
564
-                }
565
-                $where_params['DTT_EVT_start'] = ['<', $current_time_for_DTT_EVT_start];
566
-                $where_params['DTT_EVT_end']   = ['>', $current_time_for_DTT_EVT_end];
567
-                break;
568
-            case 'inactive':
569
-                if (isset($where_params['Event.status'])) {
570
-                    unset($where_params['Event.status']);
571
-                }
572
-                if (isset($where_params['OR'])) {
573
-                    $where_params['AND']['OR'] = $where_params['OR'];
574
-                }
575
-                if (isset($where_params['DTT_EVT_end'])) {
576
-                    $where_params['AND']['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
577
-                    unset($where_params['DTT_EVT_end']);
578
-                }
579
-                if (isset($where_params['DTT_EVT_start'])) {
580
-                    $where_params['AND']['DTT_EVT_start'] = $where_params['DTT_EVT_start'];
581
-                    unset($where_params['DTT_EVT_start']);
582
-                }
583
-                $where_params['AND']['Event.status'] = ['!=', 'publish'];
584
-                break;
585
-        }
586
-        $query_params[0]          = $where_params;
587
-        $query_params['group_by'] = ['dtt_year', 'dtt_month'];
588
-        $query_params             = $this->addOrderByQueryParams($query_params, 'DTT_EVT_start', 'DESC');
589
-
590
-        $query_interval    = EEH_DTT_Helper::get_sql_query_interval_for_offset(
591
-            $this->get_timezone(),
592
-            'DTT_EVT_start'
593
-        );
594
-        $columns_to_select = [
595
-            'dtt_year'      => ['YEAR(' . $query_interval . ')', '%s'],
596
-            'dtt_month'     => ['MONTHNAME(' . $query_interval . ')', '%s'],
597
-            'dtt_month_num' => ['MONTH(' . $query_interval . ')', '%s'],
598
-        ];
599
-        return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
600
-    }
601
-
602
-
603
-    /**
604
-     * Updates the DTT_sold attribute on each datetime (based on the registrations
605
-     * for the tickets for each datetime)
606
-     *
607
-     * @param EE_Base_Class[]|EE_Datetime[] $datetimes
608
-     * @throws EE_Error
609
-     * @throws ReflectionException
610
-     */
611
-    public function update_sold(array $datetimes)
612
-    {
613
-        EE_Error::doing_it_wrong(
614
-            __FUNCTION__,
615
-            esc_html__(
616
-                'Please use \EEM_Ticket::update_tickets_sold() instead which will in turn correctly update both the Ticket AND Datetime counts.',
617
-                'event_espresso'
618
-            ),
619
-            '4.9.32.rc.005'
620
-        );
621
-        foreach ($datetimes as $datetime) {
622
-            $datetime->update_sold();
623
-        }
624
-    }
625
-
626
-
627
-    /**
628
-     *    Gets the total number of tickets available at a particular datetime
629
-     *    (does NOT take into account the datetime's spaces available)
630
-     *
631
-     * @param int   $DTT_ID
632
-     * @param array $query_params
633
-     * @return int of tickets available. If sold out, return less than 1. If infinite, returns EE_INF,  IF there are NO
634
-     *             tickets attached to datetime then FALSE is returned.
635
-     * @throws EE_Error
636
-     * @throws ReflectionException
637
-     */
638
-    public function sum_tickets_currently_available_at_datetime(int $DTT_ID, array $query_params = [])
639
-    {
640
-        $datetime = $this->get_one_by_ID($DTT_ID);
641
-        if ($datetime instanceof EE_Datetime) {
642
-            return $datetime->tickets_remaining($query_params);
643
-        }
644
-        return 0;
645
-    }
646
-
647
-
648
-    /**
649
-     * This returns an array of counts of datetimes in the database for each Datetime status that can be queried.
650
-     *
651
-     * @param array $stati_to_include  If included you can restrict the statuses we return counts for by including the
652
-     *                                 stati you want counts for as values in the array.  An empty array returns counts
653
-     *                                 for all valid stati.
654
-     * @param array $query_params      If included can be used to refine the conditions for returning the count (i.e.
655
-     *                                 only for Datetimes connected to a specific event, or specific ticket.
656
-     * @return array  The value returned is an array indexed by Datetime Status and the values are the counts.  The
657
-     * @throws EE_Error
658
-     *                                 stati used as index keys are: EE_Datetime::active EE_Datetime::upcoming
659
-     *                                 EE_Datetime::expired
660
-     */
661
-    public function get_datetime_counts_by_status(array $stati_to_include = [], array $query_params = [])
662
-    {
663
-        // only accept where conditions for this query.
664
-        $_where            = isset($query_params[0]) ? $query_params[0] : [];
665
-        $status_query_args = [
666
-            EE_Datetime::active   => array_merge(
667
-                $_where,
668
-                ['DTT_EVT_start' => ['<', time()], 'DTT_EVT_end' => ['>', time()]]
669
-            ),
670
-            EE_Datetime::upcoming => array_merge(
671
-                $_where,
672
-                ['DTT_EVT_start' => ['>', time()]]
673
-            ),
674
-            EE_Datetime::expired  => array_merge(
675
-                $_where,
676
-                ['DTT_EVT_end' => ['<', time()]]
677
-            ),
678
-        ];
679
-        if (! empty($stati_to_include)) {
680
-            foreach (array_keys($status_query_args) as $status) {
681
-                if (! in_array($status, $stati_to_include, true)) {
682
-                    unset($status_query_args[ $status ]);
683
-                }
684
-            }
685
-        }
686
-        // loop through and query counts for each stati.
687
-        $status_query_results = [];
688
-        foreach ($status_query_args as $status => $status_where_conditions) {
689
-            $status_query_results[ $status ] = EEM_Datetime::count(
690
-                [$status_where_conditions],
691
-                'DTT_ID',
692
-                true
693
-            );
694
-        }
695
-        return $status_query_results;
696
-    }
697
-
698
-
699
-    /**
700
-     * Returns the specific count for a given Datetime status matching any given query_params.
701
-     *
702
-     * @param string $status Valid string representation for Datetime status requested. (Defaults to Active).
703
-     * @param array  $query_params
704
-     * @return int
705
-     * @throws EE_Error
706
-     */
707
-    public function get_datetime_count_for_status($status = EE_Datetime::active, array $query_params = [])
708
-    {
709
-        $count = $this->get_datetime_counts_by_status([$status], $query_params);
710
-        return ! empty($count[ $status ]) ? $count[ $status ] : 0;
711
-    }
712
-
713
-
714
-    /**
715
-     * @return bool|int
716
-     * @since   $VID:$
717
-     */
718
-    private function prepModelForQuery()
719
-    {
720
-        $prev_data_prep_value = $this->get_assumption_concerning_values_already_prepared_by_model_object();
721
-        $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
722
-        return $prev_data_prep_value;
723
-    }
724
-
725
-
726
-    /**
727
-     * @param array    $query_params
728
-     * @param bool|int $prev_data_prep_value
729
-     * @return EE_Base_Class[]|EE_Datetime[]
730
-     * @throws EE_Error
731
-     * @since   $VID:$
732
-     */
733
-    private function getDatetimesAndRestoreModel(array $query_params, $prev_data_prep_value)
734
-    {
735
-        $result = $this->get_all($query_params);
736
-        $this->assume_values_already_prepared_by_model_object($prev_data_prep_value);
737
-        return $result;
738
-    }
739
-
740
-
741
-    /**
742
-     * @param array  $query_params
743
-     * @param int    $limit
744
-     * @param string $order_by
745
-     * @param string $order
746
-     * @return array
747
-     * @since   $VID:$
748
-     */
749
-    private function addDefaultQueryParams(array $query_params, $limit = 0, $order_by = 'DTT_EVT_start', $order = 'ASC')
750
-    {
751
-        $query_params = $this->addOrderByQueryParams($query_params, $order_by, $order);
752
-        $query_params = $this->addLimitQueryParams($query_params, $limit);
753
-        return $query_params;
754
-    }
755
-
756
-
757
-    /**
758
-     * @param array  $query_params
759
-     * @param string $default_where_conditions
760
-     * @return array
761
-     * @since   $VID:$
762
-     */
763
-    private function addDefaultWhereConditions(
764
-        array $query_params,
765
-        $default_where_conditions = EEM_Base::default_where_conditions_none
766
-    ) {
767
-        $query_params['default_where_conditions'] = $default_where_conditions;
768
-        return $query_params;
769
-    }
770
-
771
-
772
-    /**
773
-     * @param array $where_params
774
-     * @param bool  $include_deleted
775
-     * @param bool  $include_expired
776
-     * @return array
777
-     * @since   $VID:$
778
-     */
779
-    private function addDefaultWhereParams(array $where_params, bool $include_deleted = true, bool $include_expired = true)
780
-    {
781
-        $where_params = $this->addExpiredWhereParams($where_params, $include_expired);
782
-        $where_params = $this->addDeletedWhereParams($where_params, $include_deleted);
783
-        return $where_params;
784
-    }
785
-
786
-
787
-    /**
788
-     * @param array $where_params
789
-     * @param bool  $include_deleted
790
-     * @return array
791
-     * @since   $VID:$
792
-     */
793
-    private function addDeletedWhereParams(array $where_params, bool $include_deleted = true)
794
-    {
795
-        $deleted                     = $include_deleted ? [true, false] : [false];
796
-        $where_params['DTT_deleted'] = ['IN', $deleted];
797
-        return $where_params;
798
-    }
799
-
800
-
801
-    /**
802
-     * @param array $where_params
803
-     * @param bool  $include_expired
804
-     * @return array
805
-     * @since   $VID:$
806
-     */
807
-    private function addExpiredWhereParams(array $where_params, bool $include_expired = true)
808
-    {
809
-        if (! $include_expired) {
810
-            $where_params['DTT_EVT_end'] = ['>=', current_time('mysql', true)];
811
-        }
812
-        return $where_params;
813
-    }
814
-
815
-
816
-    /**
817
-     * @param array $query_params
818
-     * @param int   $limit
819
-     * @return array
820
-     * @since   $VID:$
821
-     */
822
-    private function addLimitQueryParams(array $query_params, $limit = 0)
823
-    {
824
-        if ($limit) {
825
-            $query_params['limit'] = $limit;
826
-        }
827
-        return $query_params;
828
-    }
829
-
830
-
831
-    /**
832
-     * @param array  $query_params
833
-     * @param string $order_by
834
-     * @param string $order
835
-     * @return array
836
-     * @since   $VID:$
837
-     */
838
-    private function addOrderByQueryParams(array $query_params, $order_by = 'DTT_EVT_start', $order = 'ASC')
839
-    {
840
-        $order                    = $order === 'ASC' ? 'ASC' : 'DESC';
841
-        $valid_order_columns      = ['DTT_ID', 'DTT_EVT_start', 'DTT_EVT_end', 'DTT_order'];
842
-        $order_by                 = in_array($order_by, $valid_order_columns, true) ? $order_by : 'DTT_EVT_start';
843
-        $query_params['order_by'] = [$order_by => $order];
844
-        return $query_params;
845
-    }
16
+	/**
17
+	 * @var EEM_Datetime $_instance
18
+	 */
19
+	protected static $_instance;
20
+
21
+
22
+	/**
23
+	 * private constructor to prevent direct creation
24
+	 *
25
+	 * @param string $timezone A string representing the timezone we want to set for returned Date Time Strings
26
+	 *                         (and any incoming timezone data that gets saved).
27
+	 *                         Note this just sends the timezone info to the date time model field objects.
28
+	 *                         Default is NULL
29
+	 *                         (and will be assumed using the set timezone in the 'timezone_string' wp option)
30
+	 * @throws EE_Error
31
+	 * @throws InvalidArgumentException
32
+	 * @throws InvalidArgumentException
33
+	 */
34
+	protected function __construct($timezone)
35
+	{
36
+		$this->singular_item           = esc_html__('Datetime', 'event_espresso');
37
+		$this->plural_item             = esc_html__('Datetimes', 'event_espresso');
38
+		$this->_tables                 = [
39
+			'Datetime' => new EE_Primary_Table('esp_datetime', 'DTT_ID'),
40
+		];
41
+		$this->_fields                 = [
42
+			'Datetime' => [
43
+				'DTT_ID'          => new EE_Primary_Key_Int_Field(
44
+					'DTT_ID',
45
+					esc_html__('Datetime ID', 'event_espresso')
46
+				),
47
+				'EVT_ID'          => new EE_Foreign_Key_Int_Field(
48
+					'EVT_ID',
49
+					esc_html__('Event ID', 'event_espresso'),
50
+					false,
51
+					0,
52
+					'Event'
53
+				),
54
+				'DTT_name'        => new EE_Plain_Text_Field(
55
+					'DTT_name',
56
+					esc_html__('Datetime Name', 'event_espresso'),
57
+					false,
58
+					''
59
+				),
60
+				'DTT_description' => new EE_Post_Content_Field(
61
+					'DTT_description',
62
+					esc_html__('Description for Datetime', 'event_espresso'),
63
+					false,
64
+					''
65
+				),
66
+				'DTT_EVT_start'   => new EE_Datetime_Field(
67
+					'DTT_EVT_start',
68
+					esc_html__('Start time/date of Event', 'event_espresso'),
69
+					false,
70
+					EE_Datetime_Field::now,
71
+					$timezone
72
+				),
73
+				'DTT_EVT_end'     => new EE_Datetime_Field(
74
+					'DTT_EVT_end',
75
+					esc_html__('End time/date of Event', 'event_espresso'),
76
+					false,
77
+					EE_Datetime_Field::now,
78
+					$timezone
79
+				),
80
+				'DTT_reg_limit'   => new EE_Infinite_Integer_Field(
81
+					'DTT_reg_limit',
82
+					esc_html__('Registration Limit for this time', 'event_espresso'),
83
+					true,
84
+					EE_INF
85
+				),
86
+				'DTT_sold'        => new EE_Integer_Field(
87
+					'DTT_sold',
88
+					esc_html__('How many sales for this Datetime that have occurred', 'event_espresso'),
89
+					true,
90
+					0
91
+				),
92
+				'DTT_reserved'    => new EE_Integer_Field(
93
+					'DTT_reserved',
94
+					esc_html__('Quantity of tickets reserved, but not yet fully purchased', 'event_espresso'),
95
+					false,
96
+					0
97
+				),
98
+				'DTT_is_primary'  => new EE_Boolean_Field(
99
+					'DTT_is_primary',
100
+					esc_html__('Flag indicating datetime is primary one for event', 'event_espresso'),
101
+					false,
102
+					false
103
+				),
104
+				'DTT_order'       => new EE_Integer_Field(
105
+					'DTT_order',
106
+					esc_html__('The order in which the Datetime is displayed', 'event_espresso'),
107
+					false,
108
+					0
109
+				),
110
+				'DTT_parent'      => new EE_Integer_Field(
111
+					'DTT_parent',
112
+					esc_html__('Indicates what DTT_ID is the parent of this DTT_ID', 'event_espresso'),
113
+					true,
114
+					0
115
+				),
116
+				'DTT_deleted'     => new EE_Trashed_Flag_Field(
117
+					'DTT_deleted',
118
+					esc_html__('Flag indicating datetime is archived', 'event_espresso'),
119
+					false,
120
+					false
121
+				),
122
+			],
123
+		];
124
+		$this->_model_relations        = [
125
+			'Ticket'          => new EE_HABTM_Relation('Datetime_Ticket'),
126
+			'Event'           => new EE_Belongs_To_Relation(),
127
+			'Checkin'         => new EE_Has_Many_Relation(),
128
+			'Datetime_Ticket' => new EE_Has_Many_Relation(),
129
+		];
130
+		$path_to_event_model           = 'Event';
131
+		$this->model_chain_to_password = $path_to_event_model;
132
+		$this->_model_chain_to_wp_user = $path_to_event_model;
133
+		// this model is generally available for reading
134
+		$this->_cap_restriction_generators[ EEM_Base::caps_read ]       =
135
+			new EE_Restriction_Generator_Event_Related_Public(
136
+				$path_to_event_model
137
+			);
138
+		$this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] =
139
+			new EE_Restriction_Generator_Event_Related_Protected(
140
+				$path_to_event_model
141
+			);
142
+		$this->_cap_restriction_generators[ EEM_Base::caps_edit ]       =
143
+			new EE_Restriction_Generator_Event_Related_Protected(
144
+				$path_to_event_model
145
+			);
146
+		$this->_cap_restriction_generators[ EEM_Base::caps_delete ]     =
147
+			new EE_Restriction_Generator_Event_Related_Protected(
148
+				$path_to_event_model,
149
+				EEM_Base::caps_edit
150
+			);
151
+		parent::__construct($timezone);
152
+	}
153
+
154
+
155
+	/**
156
+	 * create new blank datetime
157
+	 *
158
+	 * @access public
159
+	 * @return EE_Datetime[] array on success, FALSE on fail
160
+	 * @throws EE_Error
161
+	 * @throws InvalidArgumentException
162
+	 * @throws InvalidDataTypeException
163
+	 * @throws ReflectionException
164
+	 * @throws InvalidInterfaceException
165
+	 */
166
+	public function create_new_blank_datetime()
167
+	{
168
+		// makes sure timezone is always set.
169
+		$timezone_string = $this->get_timezone();
170
+		/**
171
+		 * Filters the initial start date for the new datetime.
172
+		 * Any time included in this value will be overridden later so use additional filters to modify the time.
173
+		 *
174
+		 * @param int $start_date Unix timestamp representing now + 30 days in seconds.
175
+		 * @return int Unix timestamp
176
+		 */
177
+		$start_date = apply_filters(
178
+			'FHEE__EEM_Datetime__create_new_blank_datetime__start_date',
179
+			$this->current_time_for_query('DTT_EVT_start', true) + MONTH_IN_SECONDS
180
+		);
181
+		/**
182
+		 * Filters the initial end date for the new datetime.
183
+		 * Any time included in this value will be overridden later so use additional filters to modify the time.
184
+		 *
185
+		 * @param int $end_data Unix timestamp representing now + 30 days in seconds.
186
+		 * @return int Unix timestamp
187
+		 */
188
+		$end_date       = apply_filters(
189
+			'FHEE__EEM_Datetime__create_new_blank_datetime__end_date',
190
+			$this->current_time_for_query('DTT_EVT_end', true) + MONTH_IN_SECONDS
191
+		);
192
+		$blank_datetime = EE_Datetime::new_instance(
193
+			[
194
+				'DTT_EVT_start' => $start_date,
195
+				'DTT_EVT_end'   => $end_date,
196
+				'DTT_order'     => 1,
197
+				'DTT_reg_limit' => EE_INF,
198
+			],
199
+			$timezone_string
200
+		);
201
+		/**
202
+		 * Filters the initial start time and format for the new EE_Datetime instance.
203
+		 *
204
+		 * @param array $start_time An array having size 2.  First element is the time, second element is the time
205
+		 *                          format.
206
+		 * @return array
207
+		 */
208
+		$start_time = apply_filters(
209
+			'FHEE__EEM_Datetime__create_new_blank_datetime__start_time',
210
+			['8am', 'ga']
211
+		);
212
+		/**
213
+		 * Filters the initial end time and format for the new EE_Datetime instance.
214
+		 *
215
+		 * @param array $end_time An array having size 2.  First element is the time, second element is the time
216
+		 *                        format
217
+		 * @return array
218
+		 */
219
+		$end_time = apply_filters(
220
+			'FHEE__EEM_Datetime__create_new_blank_datetime__end_time',
221
+			['5pm', 'ga']
222
+		);
223
+		$this->validateStartAndEndTimeForBlankDate($start_time, $end_time);
224
+		$blank_datetime->set_start_time(
225
+			$this->convert_datetime_for_query(
226
+				'DTT_EVT_start',
227
+				$start_time[0],
228
+				$start_time[1],
229
+				$timezone_string
230
+			)
231
+		);
232
+		$blank_datetime->set_end_time(
233
+			$this->convert_datetime_for_query(
234
+				'DTT_EVT_end',
235
+				$end_time[0],
236
+				$end_time[1],
237
+				$timezone_string
238
+			)
239
+		);
240
+		return [$blank_datetime];
241
+	}
242
+
243
+
244
+	/**
245
+	 * Validates whether the start_time and end_time are in the expected format.
246
+	 *
247
+	 * @param array $start_time
248
+	 * @param array $end_time
249
+	 * @throws InvalidArgumentException
250
+	 * @throws InvalidDataTypeException
251
+	 */
252
+	private function validateStartAndEndTimeForBlankDate(array $start_time, array $end_time)
253
+	{
254
+		if (! is_array($start_time)) {
255
+			throw new InvalidDataTypeException('start_time', $start_time, 'array');
256
+		}
257
+		if (! is_array($end_time)) {
258
+			throw new InvalidDataTypeException('end_time', $end_time, 'array');
259
+		}
260
+		if (count($start_time) !== 2) {
261
+			throw new InvalidArgumentException(
262
+				sprintf(
263
+					'The variable %1$s is expected to be an array with two elements.  The first item in the '
264
+					. 'array should be a valid time string, the second item in the array should be a valid time format',
265
+					'$start_time'
266
+				)
267
+			);
268
+		}
269
+		if (count($end_time) !== 2) {
270
+			throw new InvalidArgumentException(
271
+				sprintf(
272
+					'The variable %1$s is expected to be an array with two elements.  The first item in the '
273
+					. 'array should be a valid time string, the second item in the array should be a valid time format',
274
+					'$end_time'
275
+				)
276
+			);
277
+		}
278
+	}
279
+
280
+
281
+	/**
282
+	 * get event start date from db
283
+	 *
284
+	 * @access public
285
+	 * @param int $EVT_ID
286
+	 * @return EE_Datetime[] array on success, FALSE on fail
287
+	 * @throws EE_Error
288
+	 * @throws ReflectionException
289
+	 */
290
+	public function get_all_event_dates($EVT_ID = 0)
291
+	{
292
+		if (! $EVT_ID) { // on add_new_event event_id gets set to 0
293
+			return $this->create_new_blank_datetime();
294
+		}
295
+		$results = $this->get_datetimes_for_event_ordered_by_DTT_order($EVT_ID);
296
+		if (empty($results)) {
297
+			return $this->create_new_blank_datetime();
298
+		}
299
+		return $results;
300
+	}
301
+
302
+
303
+	/**
304
+	 * get all datetimes attached to an event ordered by the DTT_order field
305
+	 *
306
+	 * @public
307
+	 * @param int     $EVT_ID     event id
308
+	 * @param boolean $include_expired
309
+	 * @param boolean $include_deleted
310
+	 * @param int     $limit      If included then limit the count of results by
311
+	 *                            the given number
312
+	 * @return EE_Datetime[]
313
+	 * @throws EE_Error
314
+	 */
315
+	public function get_datetimes_for_event_ordered_by_DTT_order(
316
+		int $EVT_ID,
317
+		bool $include_expired = true,
318
+		bool $include_deleted = true,
319
+		$limit = 0
320
+	) {
321
+		$prev_data_prep_value = $this->prepModelForQuery();
322
+		$where_params         = ['Event.EVT_ID' => absint($EVT_ID)];
323
+		$query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
324
+		$query_params         = $this->addDefaultWhereConditions($query_params);
325
+		$query_params         = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
326
+		return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
327
+	}
328
+
329
+
330
+	/**
331
+	 * Gets the datetimes for the event (with the given limit), and orders them by "importance".
332
+	 * By importance, we mean that the primary datetimes are most important (DEPRECATED FOR NOW),
333
+	 * and then the earlier datetimes are the most important.
334
+	 * Maybe we'll want this to take into account datetimes that haven't already passed, but we don't yet.
335
+	 *
336
+	 * @param int $EVT_ID
337
+	 * @param int $limit
338
+	 * @return EE_Datetime[]|EE_Base_Class[]
339
+	 * @throws EE_Error
340
+	 */
341
+	public function get_datetimes_for_event_ordered_by_importance(int $EVT_ID, $limit = 0)
342
+	{
343
+		$query_params[0] = ['Event.EVT_ID' => absint($EVT_ID)];
344
+		$query_params    = $this->addDefaultWhereConditions($query_params);
345
+		$query_params    = $this->addDefaultQueryParams($query_params, $limit);
346
+		return $this->get_all($query_params);
347
+	}
348
+
349
+
350
+	/**
351
+	 * @param int     $EVT_ID
352
+	 * @param boolean $include_expired
353
+	 * @param boolean $include_deleted
354
+	 * @return EE_Datetime
355
+	 * @throws EE_Error
356
+	 */
357
+	public function get_oldest_datetime_for_event(
358
+		int $EVT_ID,
359
+		bool $include_expired = false,
360
+		bool $include_deleted = false
361
+	) {
362
+		$results = $this->get_datetimes_for_event_ordered_by_start_time(
363
+			$EVT_ID,
364
+			$include_expired,
365
+			$include_deleted,
366
+			1
367
+		);
368
+		if ($results) {
369
+			return array_shift($results);
370
+		}
371
+		return null;
372
+	}
373
+
374
+
375
+	/**
376
+	 * Gets the 'primary' datetime for an event.
377
+	 *
378
+	 * @param int  $EVT_ID
379
+	 * @param bool $try_to_exclude_expired
380
+	 * @param bool $try_to_exclude_deleted
381
+	 * @return EE_Datetime
382
+	 * @throws EE_Error
383
+	 */
384
+	public function get_primary_datetime_for_event(
385
+		int $EVT_ID,
386
+		bool $try_to_exclude_expired = true,
387
+		bool $try_to_exclude_deleted = true
388
+	) {
389
+		if ($try_to_exclude_expired) {
390
+			$non_expired = $this->get_oldest_datetime_for_event($EVT_ID, false, false);
391
+			if ($non_expired) {
392
+				return $non_expired;
393
+			}
394
+		}
395
+		if ($try_to_exclude_deleted) {
396
+			$expired_even = $this->get_oldest_datetime_for_event($EVT_ID, true);
397
+			if ($expired_even) {
398
+				return $expired_even;
399
+			}
400
+		}
401
+		return $this->get_oldest_datetime_for_event($EVT_ID, true, true);
402
+	}
403
+
404
+
405
+	/**
406
+	 * Gets ALL the datetimes for an event (including trashed ones, for now), ordered
407
+	 * only by start date
408
+	 *
409
+	 * @param int     $EVT_ID
410
+	 * @param boolean $include_expired
411
+	 * @param boolean $include_deleted
412
+	 * @param int     $limit
413
+	 * @return EE_Datetime[]
414
+	 * @throws EE_Error
415
+	 */
416
+	public function get_datetimes_for_event_ordered_by_start_time(
417
+		int $EVT_ID,
418
+		bool $include_expired = true,
419
+		bool $include_deleted = true,
420
+		$limit = 0
421
+	) {
422
+		$prev_data_prep_value = $this->prepModelForQuery();
423
+		$where_params         = ['Event.EVT_ID' => absint($EVT_ID)];
424
+		$query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
425
+		$query_params         = $this->addDefaultWhereConditions(
426
+			$query_params,
427
+			EEM_Base::default_where_conditions_this_only
428
+		);
429
+		$query_params         = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
430
+		return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
431
+	}
432
+
433
+
434
+	/**
435
+	 * Gets ALL the datetimes for an ticket (including trashed ones, for now), ordered
436
+	 * only by start date
437
+	 *
438
+	 * @param int     $TKT_ID
439
+	 * @param boolean $include_expired
440
+	 * @param boolean $include_deleted
441
+	 * @param int     $limit
442
+	 * @return EE_Datetime[]
443
+	 * @throws EE_Error
444
+	 */
445
+	public function get_datetimes_for_ticket_ordered_by_start_time(
446
+		int $TKT_ID,
447
+		bool $include_expired = true,
448
+		bool $include_deleted = true,
449
+		$limit = 0
450
+	) {
451
+		$prev_data_prep_value = $this->prepModelForQuery();
452
+		$where_params         = ['Ticket.TKT_ID' => absint($TKT_ID)];
453
+		$query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
454
+		$query_params         = $this->addDefaultQueryParams($query_params, $limit);
455
+		return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
456
+	}
457
+
458
+
459
+	/**
460
+	 * Gets all the datetimes for a ticket (including trashed ones, for now), ordered by the DTT_order for the
461
+	 * datetimes.
462
+	 *
463
+	 * @param int      $TKT_ID           ID of ticket to retrieve the datetimes for
464
+	 * @param boolean  $include_expired  whether to include expired datetimes or not
465
+	 * @param boolean  $include_deleted  whether to include trashed datetimes or not.
466
+	 * @param int|null $limit            if null, no limit, if int then limit results by
467
+	 *                                   that number
468
+	 * @return EE_Datetime[]
469
+	 * @throws EE_Error
470
+	 */
471
+	public function get_datetimes_for_ticket_ordered_by_DTT_order(
472
+		int $TKT_ID,
473
+		bool $include_expired = true,
474
+		bool $include_deleted = true,
475
+		$limit = 0
476
+	) {
477
+		$prev_data_prep_value = $this->prepModelForQuery();
478
+		$where_params         = ['Ticket.TKT_ID' => absint($TKT_ID)];
479
+		$query_params[0]      = $this->addDefaultWhereParams($where_params, $include_deleted, $include_expired);
480
+		$query_params         = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
481
+		return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
482
+	}
483
+
484
+
485
+	/**
486
+	 * Gets the most important datetime for a particular event (ie, the primary event usually. But if for some WACK
487
+	 * reason it doesn't exist, we consider the earliest event the most important)
488
+	 *
489
+	 * @param int $EVT_ID
490
+	 * @return EE_Datetime
491
+	 * @throws EE_Error
492
+	 */
493
+	public function get_most_important_datetime_for_event(int $EVT_ID)
494
+	{
495
+		$results = $this->get_datetimes_for_event_ordered_by_importance($EVT_ID, 1);
496
+		if ($results) {
497
+			return array_shift($results);
498
+		}
499
+		return null;
500
+	}
501
+
502
+
503
+	/**
504
+	 * This returns a wpdb->results        Array of all DTT month and years matching the incoming query params and
505
+	 * grouped by month and year.
506
+	 *
507
+	 * @param array  $where_params       @see
508
+	 *                                   https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
509
+	 * @param string $evt_active_status  A string representing the evt active status to filter the months by.
510
+	 *                                   Can be:
511
+	 *                                   - '' = no filter
512
+	 *                                   - upcoming = Published events with at least one upcoming datetime.
513
+	 *                                   - expired = Events with all datetimes expired.
514
+	 *                                   - active = Events that are published and have at least one datetime that
515
+	 *                                   starts before now and ends after now.
516
+	 *                                   - inactive = Events that are either not published.
517
+	 * @return EE_Base_Class[]
518
+	 * @throws EE_Error
519
+	 * @throws InvalidArgumentException
520
+	 * @throws InvalidArgumentException
521
+	 */
522
+	public function get_dtt_months_and_years(array $where_params, $evt_active_status = '')
523
+	{
524
+		$current_time_for_DTT_EVT_start = $this->current_time_for_query('DTT_EVT_start');
525
+		$current_time_for_DTT_EVT_end   = $this->current_time_for_query('DTT_EVT_end');
526
+		switch ($evt_active_status) {
527
+			case 'upcoming':
528
+				$where_params['Event.status'] = 'publish';
529
+				// if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
530
+				if (isset($where_params['DTT_EVT_start'])) {
531
+					$where_params['DTT_EVT_start*****'] = $where_params['DTT_EVT_start'];
532
+				}
533
+				$where_params['DTT_EVT_start'] = ['>', $current_time_for_DTT_EVT_start];
534
+				break;
535
+			case 'expired':
536
+				if (isset($where_params['Event.status'])) {
537
+					unset($where_params['Event.status']);
538
+				}
539
+				// get events to exclude
540
+				$exclude_query[0] = array_merge(
541
+					$where_params,
542
+					['DTT_EVT_end' => ['>', $current_time_for_DTT_EVT_end]]
543
+				);
544
+				// first get all events that have datetimes where its not expired.
545
+				$event_ids = $this->_get_all_wpdb_results(
546
+					$exclude_query,
547
+					OBJECT_K,
548
+					'Datetime.EVT_ID'
549
+				);
550
+				$event_ids = array_keys($event_ids);
551
+				if (isset($where_params['DTT_EVT_end'])) {
552
+					$where_params['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
553
+				}
554
+				$where_params['DTT_EVT_end']  = ['<', $current_time_for_DTT_EVT_end];
555
+				$where_params['Event.EVT_ID'] = ['NOT IN', $event_ids];
556
+				break;
557
+			case 'active':
558
+				$where_params['Event.status'] = 'publish';
559
+				if (isset($where_params['DTT_EVT_start'])) {
560
+					$where_params['Datetime.DTT_EVT_start******'] = $where_params['DTT_EVT_start'];
561
+				}
562
+				if (isset($where_params['Datetime.DTT_EVT_end'])) {
563
+					$where_params['Datetime.DTT_EVT_end*****'] = $where_params['DTT_EVT_end'];
564
+				}
565
+				$where_params['DTT_EVT_start'] = ['<', $current_time_for_DTT_EVT_start];
566
+				$where_params['DTT_EVT_end']   = ['>', $current_time_for_DTT_EVT_end];
567
+				break;
568
+			case 'inactive':
569
+				if (isset($where_params['Event.status'])) {
570
+					unset($where_params['Event.status']);
571
+				}
572
+				if (isset($where_params['OR'])) {
573
+					$where_params['AND']['OR'] = $where_params['OR'];
574
+				}
575
+				if (isset($where_params['DTT_EVT_end'])) {
576
+					$where_params['AND']['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
577
+					unset($where_params['DTT_EVT_end']);
578
+				}
579
+				if (isset($where_params['DTT_EVT_start'])) {
580
+					$where_params['AND']['DTT_EVT_start'] = $where_params['DTT_EVT_start'];
581
+					unset($where_params['DTT_EVT_start']);
582
+				}
583
+				$where_params['AND']['Event.status'] = ['!=', 'publish'];
584
+				break;
585
+		}
586
+		$query_params[0]          = $where_params;
587
+		$query_params['group_by'] = ['dtt_year', 'dtt_month'];
588
+		$query_params             = $this->addOrderByQueryParams($query_params, 'DTT_EVT_start', 'DESC');
589
+
590
+		$query_interval    = EEH_DTT_Helper::get_sql_query_interval_for_offset(
591
+			$this->get_timezone(),
592
+			'DTT_EVT_start'
593
+		);
594
+		$columns_to_select = [
595
+			'dtt_year'      => ['YEAR(' . $query_interval . ')', '%s'],
596
+			'dtt_month'     => ['MONTHNAME(' . $query_interval . ')', '%s'],
597
+			'dtt_month_num' => ['MONTH(' . $query_interval . ')', '%s'],
598
+		];
599
+		return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
600
+	}
601
+
602
+
603
+	/**
604
+	 * Updates the DTT_sold attribute on each datetime (based on the registrations
605
+	 * for the tickets for each datetime)
606
+	 *
607
+	 * @param EE_Base_Class[]|EE_Datetime[] $datetimes
608
+	 * @throws EE_Error
609
+	 * @throws ReflectionException
610
+	 */
611
+	public function update_sold(array $datetimes)
612
+	{
613
+		EE_Error::doing_it_wrong(
614
+			__FUNCTION__,
615
+			esc_html__(
616
+				'Please use \EEM_Ticket::update_tickets_sold() instead which will in turn correctly update both the Ticket AND Datetime counts.',
617
+				'event_espresso'
618
+			),
619
+			'4.9.32.rc.005'
620
+		);
621
+		foreach ($datetimes as $datetime) {
622
+			$datetime->update_sold();
623
+		}
624
+	}
625
+
626
+
627
+	/**
628
+	 *    Gets the total number of tickets available at a particular datetime
629
+	 *    (does NOT take into account the datetime's spaces available)
630
+	 *
631
+	 * @param int   $DTT_ID
632
+	 * @param array $query_params
633
+	 * @return int of tickets available. If sold out, return less than 1. If infinite, returns EE_INF,  IF there are NO
634
+	 *             tickets attached to datetime then FALSE is returned.
635
+	 * @throws EE_Error
636
+	 * @throws ReflectionException
637
+	 */
638
+	public function sum_tickets_currently_available_at_datetime(int $DTT_ID, array $query_params = [])
639
+	{
640
+		$datetime = $this->get_one_by_ID($DTT_ID);
641
+		if ($datetime instanceof EE_Datetime) {
642
+			return $datetime->tickets_remaining($query_params);
643
+		}
644
+		return 0;
645
+	}
646
+
647
+
648
+	/**
649
+	 * This returns an array of counts of datetimes in the database for each Datetime status that can be queried.
650
+	 *
651
+	 * @param array $stati_to_include  If included you can restrict the statuses we return counts for by including the
652
+	 *                                 stati you want counts for as values in the array.  An empty array returns counts
653
+	 *                                 for all valid stati.
654
+	 * @param array $query_params      If included can be used to refine the conditions for returning the count (i.e.
655
+	 *                                 only for Datetimes connected to a specific event, or specific ticket.
656
+	 * @return array  The value returned is an array indexed by Datetime Status and the values are the counts.  The
657
+	 * @throws EE_Error
658
+	 *                                 stati used as index keys are: EE_Datetime::active EE_Datetime::upcoming
659
+	 *                                 EE_Datetime::expired
660
+	 */
661
+	public function get_datetime_counts_by_status(array $stati_to_include = [], array $query_params = [])
662
+	{
663
+		// only accept where conditions for this query.
664
+		$_where            = isset($query_params[0]) ? $query_params[0] : [];
665
+		$status_query_args = [
666
+			EE_Datetime::active   => array_merge(
667
+				$_where,
668
+				['DTT_EVT_start' => ['<', time()], 'DTT_EVT_end' => ['>', time()]]
669
+			),
670
+			EE_Datetime::upcoming => array_merge(
671
+				$_where,
672
+				['DTT_EVT_start' => ['>', time()]]
673
+			),
674
+			EE_Datetime::expired  => array_merge(
675
+				$_where,
676
+				['DTT_EVT_end' => ['<', time()]]
677
+			),
678
+		];
679
+		if (! empty($stati_to_include)) {
680
+			foreach (array_keys($status_query_args) as $status) {
681
+				if (! in_array($status, $stati_to_include, true)) {
682
+					unset($status_query_args[ $status ]);
683
+				}
684
+			}
685
+		}
686
+		// loop through and query counts for each stati.
687
+		$status_query_results = [];
688
+		foreach ($status_query_args as $status => $status_where_conditions) {
689
+			$status_query_results[ $status ] = EEM_Datetime::count(
690
+				[$status_where_conditions],
691
+				'DTT_ID',
692
+				true
693
+			);
694
+		}
695
+		return $status_query_results;
696
+	}
697
+
698
+
699
+	/**
700
+	 * Returns the specific count for a given Datetime status matching any given query_params.
701
+	 *
702
+	 * @param string $status Valid string representation for Datetime status requested. (Defaults to Active).
703
+	 * @param array  $query_params
704
+	 * @return int
705
+	 * @throws EE_Error
706
+	 */
707
+	public function get_datetime_count_for_status($status = EE_Datetime::active, array $query_params = [])
708
+	{
709
+		$count = $this->get_datetime_counts_by_status([$status], $query_params);
710
+		return ! empty($count[ $status ]) ? $count[ $status ] : 0;
711
+	}
712
+
713
+
714
+	/**
715
+	 * @return bool|int
716
+	 * @since   $VID:$
717
+	 */
718
+	private function prepModelForQuery()
719
+	{
720
+		$prev_data_prep_value = $this->get_assumption_concerning_values_already_prepared_by_model_object();
721
+		$this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
722
+		return $prev_data_prep_value;
723
+	}
724
+
725
+
726
+	/**
727
+	 * @param array    $query_params
728
+	 * @param bool|int $prev_data_prep_value
729
+	 * @return EE_Base_Class[]|EE_Datetime[]
730
+	 * @throws EE_Error
731
+	 * @since   $VID:$
732
+	 */
733
+	private function getDatetimesAndRestoreModel(array $query_params, $prev_data_prep_value)
734
+	{
735
+		$result = $this->get_all($query_params);
736
+		$this->assume_values_already_prepared_by_model_object($prev_data_prep_value);
737
+		return $result;
738
+	}
739
+
740
+
741
+	/**
742
+	 * @param array  $query_params
743
+	 * @param int    $limit
744
+	 * @param string $order_by
745
+	 * @param string $order
746
+	 * @return array
747
+	 * @since   $VID:$
748
+	 */
749
+	private function addDefaultQueryParams(array $query_params, $limit = 0, $order_by = 'DTT_EVT_start', $order = 'ASC')
750
+	{
751
+		$query_params = $this->addOrderByQueryParams($query_params, $order_by, $order);
752
+		$query_params = $this->addLimitQueryParams($query_params, $limit);
753
+		return $query_params;
754
+	}
755
+
756
+
757
+	/**
758
+	 * @param array  $query_params
759
+	 * @param string $default_where_conditions
760
+	 * @return array
761
+	 * @since   $VID:$
762
+	 */
763
+	private function addDefaultWhereConditions(
764
+		array $query_params,
765
+		$default_where_conditions = EEM_Base::default_where_conditions_none
766
+	) {
767
+		$query_params['default_where_conditions'] = $default_where_conditions;
768
+		return $query_params;
769
+	}
770
+
771
+
772
+	/**
773
+	 * @param array $where_params
774
+	 * @param bool  $include_deleted
775
+	 * @param bool  $include_expired
776
+	 * @return array
777
+	 * @since   $VID:$
778
+	 */
779
+	private function addDefaultWhereParams(array $where_params, bool $include_deleted = true, bool $include_expired = true)
780
+	{
781
+		$where_params = $this->addExpiredWhereParams($where_params, $include_expired);
782
+		$where_params = $this->addDeletedWhereParams($where_params, $include_deleted);
783
+		return $where_params;
784
+	}
785
+
786
+
787
+	/**
788
+	 * @param array $where_params
789
+	 * @param bool  $include_deleted
790
+	 * @return array
791
+	 * @since   $VID:$
792
+	 */
793
+	private function addDeletedWhereParams(array $where_params, bool $include_deleted = true)
794
+	{
795
+		$deleted                     = $include_deleted ? [true, false] : [false];
796
+		$where_params['DTT_deleted'] = ['IN', $deleted];
797
+		return $where_params;
798
+	}
799
+
800
+
801
+	/**
802
+	 * @param array $where_params
803
+	 * @param bool  $include_expired
804
+	 * @return array
805
+	 * @since   $VID:$
806
+	 */
807
+	private function addExpiredWhereParams(array $where_params, bool $include_expired = true)
808
+	{
809
+		if (! $include_expired) {
810
+			$where_params['DTT_EVT_end'] = ['>=', current_time('mysql', true)];
811
+		}
812
+		return $where_params;
813
+	}
814
+
815
+
816
+	/**
817
+	 * @param array $query_params
818
+	 * @param int   $limit
819
+	 * @return array
820
+	 * @since   $VID:$
821
+	 */
822
+	private function addLimitQueryParams(array $query_params, $limit = 0)
823
+	{
824
+		if ($limit) {
825
+			$query_params['limit'] = $limit;
826
+		}
827
+		return $query_params;
828
+	}
829
+
830
+
831
+	/**
832
+	 * @param array  $query_params
833
+	 * @param string $order_by
834
+	 * @param string $order
835
+	 * @return array
836
+	 * @since   $VID:$
837
+	 */
838
+	private function addOrderByQueryParams(array $query_params, $order_by = 'DTT_EVT_start', $order = 'ASC')
839
+	{
840
+		$order                    = $order === 'ASC' ? 'ASC' : 'DESC';
841
+		$valid_order_columns      = ['DTT_ID', 'DTT_EVT_start', 'DTT_EVT_end', 'DTT_order'];
842
+		$order_by                 = in_array($order_by, $valid_order_columns, true) ? $order_by : 'DTT_EVT_start';
843
+		$query_params['order_by'] = [$order_by => $order];
844
+		return $query_params;
845
+	}
846 846
 }
Please login to merge, or discard this patch.
Spacing   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -121,7 +121,7 @@  discard block
 block discarded – undo
121 121
                 ),
122 122
             ],
123 123
         ];
124
-        $this->_model_relations        = [
124
+        $this->_model_relations = [
125 125
             'Ticket'          => new EE_HABTM_Relation('Datetime_Ticket'),
126 126
             'Event'           => new EE_Belongs_To_Relation(),
127 127
             'Checkin'         => new EE_Has_Many_Relation(),
@@ -131,19 +131,19 @@  discard block
 block discarded – undo
131 131
         $this->model_chain_to_password = $path_to_event_model;
132 132
         $this->_model_chain_to_wp_user = $path_to_event_model;
133 133
         // this model is generally available for reading
134
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ]       =
134
+        $this->_cap_restriction_generators[EEM_Base::caps_read] =
135 135
             new EE_Restriction_Generator_Event_Related_Public(
136 136
                 $path_to_event_model
137 137
             );
138
-        $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] =
138
+        $this->_cap_restriction_generators[EEM_Base::caps_read_admin] =
139 139
             new EE_Restriction_Generator_Event_Related_Protected(
140 140
                 $path_to_event_model
141 141
             );
142
-        $this->_cap_restriction_generators[ EEM_Base::caps_edit ]       =
142
+        $this->_cap_restriction_generators[EEM_Base::caps_edit] =
143 143
             new EE_Restriction_Generator_Event_Related_Protected(
144 144
                 $path_to_event_model
145 145
             );
146
-        $this->_cap_restriction_generators[ EEM_Base::caps_delete ]     =
146
+        $this->_cap_restriction_generators[EEM_Base::caps_delete] =
147 147
             new EE_Restriction_Generator_Event_Related_Protected(
148 148
                 $path_to_event_model,
149 149
                 EEM_Base::caps_edit
@@ -185,7 +185,7 @@  discard block
 block discarded – undo
185 185
          * @param int $end_data Unix timestamp representing now + 30 days in seconds.
186 186
          * @return int Unix timestamp
187 187
          */
188
-        $end_date       = apply_filters(
188
+        $end_date = apply_filters(
189 189
             'FHEE__EEM_Datetime__create_new_blank_datetime__end_date',
190 190
             $this->current_time_for_query('DTT_EVT_end', true) + MONTH_IN_SECONDS
191 191
         );
@@ -251,10 +251,10 @@  discard block
 block discarded – undo
251 251
      */
252 252
     private function validateStartAndEndTimeForBlankDate(array $start_time, array $end_time)
253 253
     {
254
-        if (! is_array($start_time)) {
254
+        if ( ! is_array($start_time)) {
255 255
             throw new InvalidDataTypeException('start_time', $start_time, 'array');
256 256
         }
257
-        if (! is_array($end_time)) {
257
+        if ( ! is_array($end_time)) {
258 258
             throw new InvalidDataTypeException('end_time', $end_time, 'array');
259 259
         }
260 260
         if (count($start_time) !== 2) {
@@ -289,7 +289,7 @@  discard block
 block discarded – undo
289 289
      */
290 290
     public function get_all_event_dates($EVT_ID = 0)
291 291
     {
292
-        if (! $EVT_ID) { // on add_new_event event_id gets set to 0
292
+        if ( ! $EVT_ID) { // on add_new_event event_id gets set to 0
293 293
             return $this->create_new_blank_datetime();
294 294
         }
295 295
         $results = $this->get_datetimes_for_event_ordered_by_DTT_order($EVT_ID);
@@ -426,7 +426,7 @@  discard block
 block discarded – undo
426 426
             $query_params,
427 427
             EEM_Base::default_where_conditions_this_only
428 428
         );
429
-        $query_params         = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
429
+        $query_params = $this->addDefaultQueryParams($query_params, $limit, 'DTT_order');
430 430
         return $this->getDatetimesAndRestoreModel($query_params, $prev_data_prep_value);
431 431
     }
432 432
 
@@ -587,14 +587,14 @@  discard block
 block discarded – undo
587 587
         $query_params['group_by'] = ['dtt_year', 'dtt_month'];
588 588
         $query_params             = $this->addOrderByQueryParams($query_params, 'DTT_EVT_start', 'DESC');
589 589
 
590
-        $query_interval    = EEH_DTT_Helper::get_sql_query_interval_for_offset(
590
+        $query_interval = EEH_DTT_Helper::get_sql_query_interval_for_offset(
591 591
             $this->get_timezone(),
592 592
             'DTT_EVT_start'
593 593
         );
594 594
         $columns_to_select = [
595
-            'dtt_year'      => ['YEAR(' . $query_interval . ')', '%s'],
596
-            'dtt_month'     => ['MONTHNAME(' . $query_interval . ')', '%s'],
597
-            'dtt_month_num' => ['MONTH(' . $query_interval . ')', '%s'],
595
+            'dtt_year'      => ['YEAR('.$query_interval.')', '%s'],
596
+            'dtt_month'     => ['MONTHNAME('.$query_interval.')', '%s'],
597
+            'dtt_month_num' => ['MONTH('.$query_interval.')', '%s'],
598 598
         ];
599 599
         return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
600 600
     }
@@ -676,17 +676,17 @@  discard block
 block discarded – undo
676 676
                 ['DTT_EVT_end' => ['<', time()]]
677 677
             ),
678 678
         ];
679
-        if (! empty($stati_to_include)) {
679
+        if ( ! empty($stati_to_include)) {
680 680
             foreach (array_keys($status_query_args) as $status) {
681
-                if (! in_array($status, $stati_to_include, true)) {
682
-                    unset($status_query_args[ $status ]);
681
+                if ( ! in_array($status, $stati_to_include, true)) {
682
+                    unset($status_query_args[$status]);
683 683
                 }
684 684
             }
685 685
         }
686 686
         // loop through and query counts for each stati.
687 687
         $status_query_results = [];
688 688
         foreach ($status_query_args as $status => $status_where_conditions) {
689
-            $status_query_results[ $status ] = EEM_Datetime::count(
689
+            $status_query_results[$status] = EEM_Datetime::count(
690 690
                 [$status_where_conditions],
691 691
                 'DTT_ID',
692 692
                 true
@@ -707,7 +707,7 @@  discard block
 block discarded – undo
707 707
     public function get_datetime_count_for_status($status = EE_Datetime::active, array $query_params = [])
708 708
     {
709 709
         $count = $this->get_datetime_counts_by_status([$status], $query_params);
710
-        return ! empty($count[ $status ]) ? $count[ $status ] : 0;
710
+        return ! empty($count[$status]) ? $count[$status] : 0;
711 711
     }
712 712
 
713 713
 
@@ -806,7 +806,7 @@  discard block
 block discarded – undo
806 806
      */
807 807
     private function addExpiredWhereParams(array $where_params, bool $include_expired = true)
808 808
     {
809
-        if (! $include_expired) {
809
+        if ( ! $include_expired) {
810 810
             $where_params['DTT_EVT_end'] = ['>=', current_time('mysql', true)];
811 811
         }
812 812
         return $where_params;
Please login to merge, or discard this patch.
core/helpers/EEH_File.helper.php 2 patches
Indentation   +901 added lines, -901 removed lines patch added patch discarded remove patch
@@ -25,905 +25,905 @@
 block discarded – undo
25 25
 class EEH_File extends EEH_Base implements EEHI_File
26 26
 {
27 27
 
28
-    /**
29
-     * @var string $_credentials_form
30
-     */
31
-    private static $_credentials_form;
32
-
33
-    /**
34
-     * @var WP_Filesystem_Base $_wp_filesystem
35
-     */
36
-    protected static $_wp_filesystem;
37
-
38
-
39
-    /**
40
-     * @param string|null $filepath the filepath we want to work in. If its in the
41
-     *                              wp uploads directory, we'll want to just use the filesystem directly.
42
-     *                              If not provided, we have to assume its not in the uploads directory
43
-     * @return WP_Filesystem_Base
44
-     */
45
-    private static function _get_wp_filesystem($filepath = null)
46
-    {
47
-        if (apply_filters(
48
-            'FHEE__EEH_File___get_wp_filesystem__allow_using_filesystem_direct',
49
-            $filepath && EEH_File::is_in_uploads_folder($filepath),
50
-            $filepath
51
-        )) {
52
-            return EEH_File::loadAlternateWpFileSystem();
53
-        }
54
-        return EEH_File::loadWpFileSystem();
55
-    }
56
-
57
-
58
-    /**
59
-     * @return WP_Filesystem_Base
60
-     */
61
-    private static function loadAlternateWpFileSystem()
62
-    {
63
-        if (! EEH_File::$_wp_filesystem instanceof WP_Filesystem_Base) {
64
-            require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
65
-            $method             = 'direct';
66
-            $wp_filesystem_file =
67
-                apply_filters(
68
-                    'filesystem_method_file',
69
-                    ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php',
70
-                    $method
71
-                );
72
-            // added the following validation logic
73
-            // because we allow the filesystem filepath to be filtered,
74
-            // and are loading whatever file the path pointed to,
75
-            // but we were not validating things in any way :scream_emoji:
76
-            $valid_wp_filesystem_types = [
77
-                'direct'     => 'WP_Filesystem_Direct',
78
-                'ftpext'     => 'WP_Filesystem_FTPext',
79
-                'ftpsockets' => 'WP_Filesystem_ftpsockets',
80
-                'ssh2'       => 'WP_Filesystem_SSH2',
81
-            ];
82
-            $valid                     = false;
83
-            $wp_filesystem_class       = '';
84
-            foreach ($valid_wp_filesystem_types as $method => $filesystem_class) {
85
-                // if file path matches for one of valid types, then toggle $valid to true
86
-                if (strpos($wp_filesystem_file, $method) > 0) {
87
-                    $valid               = true;
88
-                    $wp_filesystem_class = $filesystem_class;
89
-                }
90
-            }
91
-            if (! $valid || ! file_exists($wp_filesystem_file)) {
92
-                EE_Error::add_error(
93
-                    sprintf(
94
-                        __(
95
-                            'The supplied WP Filesystem filepath "%1$s" is either missing or invalid.',
96
-                            'event_espresso'
97
-                        ),
98
-                        $wp_filesystem_file
99
-                    ),
100
-                    __FILE__,
101
-                    __FUNCTION__,
102
-                    __LINE__
103
-                );
104
-            }
105
-            // check constants defined, just like in the wp-admin/includes/file.php WP_Filesystem()
106
-            if (! defined('FS_CHMOD_DIR')) {
107
-                define('FS_CHMOD_DIR', (fileperms(ABSPATH) & 0775 | 0755));
108
-            }
109
-            if (! defined('FS_CHMOD_FILE')) {
110
-                define('FS_CHMOD_FILE', (fileperms(ABSPATH . 'index.php') & 0775 | 0644));
111
-            }
112
-            require_once($wp_filesystem_file);
113
-            EEH_File::$_wp_filesystem = new $wp_filesystem_class([]);
114
-        }
115
-        return EEH_File::$_wp_filesystem;
116
-    }
117
-
118
-
119
-    /**
120
-     * @return WP_Filesystem_Base
121
-     */
122
-    private static function loadWpFileSystem()
123
-    {
124
-        global $wp_filesystem;
125
-        // no filesystem setup ???
126
-        if (! $wp_filesystem instanceof WP_Filesystem_Base) {
127
-            // if some eager beaver's just trying to get in there too early...
128
-            // let them do it, because we are one of those eager beavers! :P
129
-            /**
130
-             * more explanations are probably merited. http://codex.wordpress.org/Filesystem_API#Initializing_WP_Filesystem_Base
131
-             * says WP_Filesystem should be used after 'wp_loaded', but currently EE's activation process
132
-             * is setup to mostly happen on 'init', and refactoring to have it happen on
133
-             * 'wp_loaded' is too much work on a BETA milestone.
134
-             * So this fix is expected to work if the WP files are owned by the server user,
135
-             * but probably not if the user needs to enter their FTP credentials to modify files
136
-             * and there may be troubles if the WP files are owned by a different user
137
-             * than the server user. But both of these issues should exist in 4.4 and earlier too
138
-             */
139
-            if (false && ! did_action('wp_loaded')) {
140
-                $msg =
141
-                    __(
142
-                        'An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.',
143
-                        'event_espresso'
144
-                    );
145
-                if (WP_DEBUG) {
146
-                    $msg .= '<br />' . __(
147
-                        'The WP Filesystem can not be accessed until after the "wp_loaded" hook has run, so it\'s best not to attempt access until the "admin_init" hookpoint.',
148
-                        'event_espresso'
149
-                    );
150
-                }
151
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
152
-            }
153
-            // should be loaded if we are past the wp_loaded hook...
154
-            if (! function_exists('WP_Filesystem') || ! function_exists('submit_button')) {
155
-                require_once(ABSPATH . 'wp-admin/includes/file.php');
156
-                require_once(ABSPATH . 'wp-admin/includes/template.php');
157
-            }
158
-            // turn on output buffering so that we can capture the credentials form
159
-            ob_start();
160
-            $credentials = request_filesystem_credentials(false);
161
-            // store credentials form for the time being
162
-            EEH_File::$_credentials_form = ob_get_clean();
163
-            // if credentials do NOT exist
164
-            if ($credentials === false) {
165
-                add_action('admin_notices', ['EEH_File', 'display_request_filesystem_credentials_form'], 999);
166
-                EE_Error::add_error(
167
-                    __(
168
-                        'An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.',
169
-                        'event_espresso'
170
-                    ),
171
-                    __FILE__,
172
-                    __FUNCTION__,
173
-                    __LINE__
174
-                );
175
-            }
176
-            // basically check for direct or previously configured access
177
-            if (! WP_Filesystem($credentials)
178
-                && is_wp_error($wp_filesystem->errors)
179
-                && $wp_filesystem->errors->get_error_code()
180
-            ) {
181
-                add_action('admin_notices', ['EEH_File', 'display_request_filesystem_credentials_form'], 999);
182
-                EE_Error::add_error(
183
-                    sprintf(
184
-                        __('WP Filesystem Error: $1%s', 'event_espresso'),
185
-                        $wp_filesystem->errors->get_error_message()
186
-                    ),
187
-                    __FILE__,
188
-                    __FUNCTION__,
189
-                    __LINE__
190
-                );
191
-            }
192
-        }
193
-        return $wp_filesystem;
194
-    }
195
-
196
-
197
-    /**
198
-     * display_request_filesystem_credentials_form
199
-     */
200
-    public static function display_request_filesystem_credentials_form()
201
-    {
202
-        if (! empty(EEH_File::$_credentials_form)) {
203
-            echo '<div class="updated espresso-notices-attention"><p>' . EEH_File::$_credentials_form . '</p></div>';
204
-        }
205
-    }
206
-
207
-
208
-    /**
209
-     *    verify_filepath_and_permissions
210
-     *    checks that a file is readable and has sufficient file permissions set to access
211
-     *
212
-     * @access public
213
-     * @param string $full_file_path - full server path to the folder or file
214
-     * @param string $file_name      - name of file if checking a file
215
-     * @param string $file_ext       - file extension (ie: "php") if checking a file
216
-     * @param string $type_of_file   - general type of file (ie: "module"), this is only used to improve error messages
217
-     * @return bool
218
-     */
219
-    public static function verify_filepath_and_permissions(
220
-        $full_file_path = '',
221
-        $file_name = '',
222
-        $file_ext = '',
223
-        $type_of_file = ''
224
-    ) {
225
-        // load WP_Filesystem and set file permissions
226
-        $wp_filesystem  = EEH_File::_get_wp_filesystem($full_file_path);
227
-        $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
228
-        if (! $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
229
-            $file_name = ! empty($type_of_file) ? $file_name . ' ' . $type_of_file : $file_name;
230
-            $file_name .= ! empty($file_ext) ? ' file' : ' folder';
231
-            $msg       = sprintf(
232
-                __(
233
-                    'The requested %1$s could not be found or is not readable, possibly due to an incorrect filepath, or incorrect file permissions.%2$s',
234
-                    'event_espresso'
235
-                ),
236
-                $file_name,
237
-                '<br />'
238
-            );
239
-            if (EEH_File::exists($full_file_path)) {
240
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, $type_of_file);
241
-            } else {
242
-                // no file permissions means the file was not found
243
-                $msg .= sprintf(
244
-                    __('Please ensure the following path is correct: "%s".', 'event_espresso'),
245
-                    $full_file_path
246
-                );
247
-            }
248
-            if (defined('WP_DEBUG') && WP_DEBUG) {
249
-                EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
250
-            }
251
-            return false;
252
-        }
253
-        return true;
254
-    }
255
-
256
-
257
-    /**
258
-     * _permissions_error_for_unreadable_filepath - attempts to determine why permissions are set incorrectly for a
259
-     * file or folder
260
-     *
261
-     * @access private
262
-     * @param string $full_file_path - full server path to the folder or file
263
-     * @param string $type_of_file   - general type of file (ie: "module"), this is only used to improve error messages
264
-     * @return string
265
-     */
266
-    private static function _permissions_error_for_unreadable_filepath($full_file_path = '', $type_of_file = '')
267
-    {
268
-        // load WP_Filesystem and set file permissions
269
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
270
-        // check file permissions
271
-        $perms = $wp_filesystem->getchmod(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
272
-        if ($perms) {
273
-            // file permissions exist, but way be set incorrectly
274
-            $type_of_file = ! empty($type_of_file) ? $type_of_file . ' ' : '';
275
-            $type_of_file .= ! empty($type_of_file) ? 'file' : 'folder';
276
-            return ' ' . sprintf(
277
-                __(
278
-                    'File permissions for the requested %1$s are currently set at "%2$s". The recommended permissions are 644 for files and 755 for folders.',
279
-                    'event_espresso'
280
-                ),
281
-                $type_of_file,
282
-                $perms
283
-            );
284
-        } else {
285
-            // file exists but file permissions could not be read ?!?!
286
-            return ' ' . sprintf(
287
-                __(
288
-                    'Please ensure that the server and/or PHP configuration allows the current process to access the following file: "%s".',
289
-                    'event_espresso'
290
-                ),
291
-                $full_file_path
292
-            );
293
-        }
294
-    }
295
-
296
-
297
-    /**
298
-     * ensure_folder_exists_and_is_writable
299
-     * ensures that a folder exists and is writable, will attempt to create folder if it does not exist
300
-     * Also ensures all the parent folders exist, and if not tries to create them.
301
-     * Also, if this function creates the folder, adds a .htaccess file and index.html file
302
-     *
303
-     * @param string $folder
304
-     * @return bool false if folder isn't writable; true if it exists and is writeable,
305
-     */
306
-    public static function ensure_folder_exists_and_is_writable($folder = '')
307
-    {
308
-        if (empty($folder)) {
309
-            return false;
310
-        }
311
-        // remove ending /
312
-        $folder        = EEH_File::standardise_directory_separators(rtrim($folder, '/\\'));
313
-        $parent_folder = EEH_File::get_parent_folder($folder);
314
-        // add / to folder
315
-        $folder        = EEH_File::end_with_directory_separator($folder);
316
-        $wp_filesystem = EEH_File::_get_wp_filesystem($folder);
317
-        $remote_dir    = EEH_File::convert_local_filepath_to_remote_filepath($folder);
318
-        if (! $wp_filesystem->is_dir($remote_dir)) {
319
-            // ok so it doesn't exist. Does its parent? Can we write to it?
320
-            if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
321
-                return false;
322
-            }
323
-            if (! EEH_File::verify_is_writable($parent_folder, 'folder')) {
324
-                return false;
325
-            }
326
-            if (! $wp_filesystem->mkdir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
327
-                if (defined('WP_DEBUG') && WP_DEBUG) {
328
-                    $msg = sprintf(__('"%s" could not be created.', 'event_espresso'), $folder);
329
-                    $msg .= EEH_File::_permissions_error_for_unreadable_filepath($folder);
330
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
331
-                }
332
-                return false;
333
-            }
334
-            EEH_File::add_index_file($folder);
335
-        } elseif (! EEH_File::verify_is_writable($folder, 'folder')) {
336
-            return false;
337
-        }
338
-        return true;
339
-    }
340
-
341
-
342
-    /**
343
-     * verify_is_writable - checks if a file or folder is writable
344
-     *
345
-     * @param string $full_path      - full server path to file or folder
346
-     * @param string $file_or_folder - whether checking a file or folder
347
-     * @return bool
348
-     */
349
-    public static function verify_is_writable($full_path = '', $file_or_folder = 'folder')
350
-    {
351
-        // load WP_Filesystem and set file permissions
352
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_path);
353
-        $full_path     = EEH_File::standardise_directory_separators($full_path);
354
-        $remote_path   = EEH_File::convert_local_filepath_to_remote_filepath($full_path);
355
-        $remote_path   = rtrim($remote_path, '/\\');
356
-        if (! $wp_filesystem->is_writable($remote_path)) {
357
-            if (defined('WP_DEBUG') && WP_DEBUG) {
358
-                $msg = sprintf(__('The "%1$s" %2$s is not writable.', 'event_espresso'), $full_path, $file_or_folder);
359
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_path);
360
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
361
-            }
362
-            return false;
363
-        }
364
-        return true;
365
-    }
366
-
367
-
368
-    /**
369
-     * ensure_file_exists_and_is_writable
370
-     * ensures that a file exists and is writable, will attempt to create file if it does not exist.
371
-     * Also ensures all the parent folders exist, and if not tries to create them.
372
-     *
373
-     * @param string $full_file_path
374
-     * @return bool
375
-     */
376
-    public static function ensure_file_exists_and_is_writable($full_file_path = '')
377
-    {
378
-        // load WP_Filesystem and set file permissions
379
-        $wp_filesystem  = EEH_File::_get_wp_filesystem($full_file_path);
380
-        $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
381
-        $parent_folder  = EEH_File::get_parent_folder($full_file_path);
382
-        if (! EEH_File::exists($full_file_path)) {
383
-            if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
384
-                return false;
385
-            }
386
-            if (! $wp_filesystem->touch(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
387
-                if (defined('WP_DEBUG') && WP_DEBUG) {
388
-                    $msg = sprintf(__('The "%s" file could not be created.', 'event_espresso'), $full_file_path);
389
-                    $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
390
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
391
-                }
392
-                return false;
393
-            }
394
-        }
395
-        if (! EEH_File::verify_is_writable($full_file_path, 'file')) {
396
-            return false;
397
-        }
398
-        return true;
399
-    }
400
-
401
-
402
-    /**
403
-     * Gets the parent folder. If provided with file, gets the folder that contains it.
404
-     * If provided a folder, gets its parent folder.
405
-     *
406
-     * @param string $file_or_folder_path
407
-     * @return string parent folder, ENDING with a directory separator
408
-     */
409
-    public static function get_parent_folder($file_or_folder_path)
410
-    {
411
-        // find the last /, ignoring a / on the very end
412
-        // eg if given "/var/something/somewhere/", we want to get "somewhere"'s
413
-        // parent folder, "/var/something/"
414
-        $ds = strlen($file_or_folder_path) > 1
415
-            ? strrpos($file_or_folder_path, '/', -2)
416
-            : strlen($file_or_folder_path);
417
-        return substr($file_or_folder_path, 0, $ds + 1);
418
-    }
419
-
420
-
421
-    /**
422
-     * get_file_contents
423
-     *
424
-     * @param string $full_file_path
425
-     * @return string
426
-     */
427
-    public static function get_file_contents($full_file_path = '')
428
-    {
429
-        $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
430
-        if (EEH_File::verify_filepath_and_permissions(
431
-            $full_file_path,
432
-            EEH_File::get_filename_from_filepath($full_file_path),
433
-            EEH_File::get_file_extension($full_file_path)
434
-        )) {
435
-            // load WP_Filesystem and set file permissions
436
-            $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
437
-            return $wp_filesystem->get_contents(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
438
-        }
439
-        return '';
440
-    }
441
-
442
-
443
-    /**
444
-     * write_file
445
-     *
446
-     * @param string $full_file_path
447
-     * @param string $file_contents - the content to be written to the file
448
-     * @param string $file_type
449
-     * @return bool
450
-     */
451
-    public static function write_to_file($full_file_path = '', $file_contents = '', $file_type = '')
452
-    {
453
-        $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
454
-        $file_type      = ! empty($file_type) ? rtrim($file_type, ' ') . ' ' : '';
455
-        $folder         = EEH_File::remove_filename_from_filepath($full_file_path);
456
-        if (! EEH_File::verify_is_writable($folder, 'folder')) {
457
-            if (defined('WP_DEBUG') && WP_DEBUG) {
458
-                $msg =
459
-                    sprintf(
460
-                        __('The %1$sfile located at "%2$s" is not writable.', 'event_espresso'),
461
-                        $file_type,
462
-                        $full_file_path
463
-                    );
464
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
465
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
466
-            }
467
-            return false;
468
-        }
469
-        // load WP_Filesystem and set file permissions
470
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
471
-        // write the file
472
-        if (! $wp_filesystem->put_contents(
473
-            EEH_File::convert_local_filepath_to_remote_filepath($full_file_path),
474
-            $file_contents
475
-        )) {
476
-            if (defined('WP_DEBUG') && WP_DEBUG) {
477
-                $msg =
478
-                    sprintf(
479
-                        __('The %1$sfile located at "%2$s" could not be written to.', 'event_espresso'),
480
-                        $file_type,
481
-                        $full_file_path
482
-                    );
483
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, 'f');
484
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
485
-            }
486
-            return false;
487
-        }
488
-        return true;
489
-    }
490
-
491
-
492
-    /**
493
-     * Wrapper for WP_Filesystem_Base::delete
494
-     *
495
-     * @param string         $filepath
496
-     * @param boolean        $recursive
497
-     * @param boolean|string $type 'd' for directory, 'f' for file
498
-     * @return boolean
499
-     */
500
-    public static function delete($filepath, $recursive = false, $type = false)
501
-    {
502
-        $wp_filesystem = EEH_File::_get_wp_filesystem();
503
-        return $wp_filesystem->delete($filepath, $recursive, $type);
504
-    }
505
-
506
-
507
-    /**
508
-     * exists
509
-     * checks if a file exists using the WP filesystem
510
-     *
511
-     * @param string $full_file_path
512
-     * @return bool
513
-     */
514
-    public static function exists($full_file_path = '')
515
-    {
516
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
517
-        return $wp_filesystem->exists(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
518
-    }
519
-
520
-
521
-    /**
522
-     * is_readable
523
-     * checks if a file is_readable using the WP filesystem
524
-     *
525
-     * @param string $full_file_path
526
-     * @return bool
527
-     */
528
-    public static function is_readable($full_file_path = '')
529
-    {
530
-        $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
531
-        return $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
532
-    }
533
-
534
-
535
-    /**
536
-     * remove_filename_from_filepath
537
-     * given a full path to a file including the filename itself, this removes  the filename and returns the path, up
538
-     * to, but NOT including the filename OR slash
539
-     *
540
-     * @param string $full_file_path
541
-     * @return string
542
-     */
543
-    public static function remove_filename_from_filepath($full_file_path = '')
544
-    {
545
-        return pathinfo($full_file_path, PATHINFO_DIRNAME);
546
-    }
547
-
548
-
549
-    /**
550
-     * get_filename_from_filepath. Arguably the same as basename()
551
-     *
552
-     * @param string $full_file_path
553
-     * @return string
554
-     */
555
-    public static function get_filename_from_filepath($full_file_path = '')
556
-    {
557
-        return pathinfo($full_file_path, PATHINFO_BASENAME);
558
-    }
559
-
560
-
561
-    /**
562
-     * get_file_extension
563
-     *
564
-     * @param string $full_file_path
565
-     * @return string
566
-     */
567
-    public static function get_file_extension($full_file_path = '')
568
-    {
569
-        return pathinfo($full_file_path, PATHINFO_EXTENSION);
570
-    }
571
-
572
-
573
-    /**
574
-     * add_htaccess_deny_from_all so the web server cannot access this folder
575
-     *
576
-     * @param string $folder
577
-     * @return bool
578
-     */
579
-    public static function add_htaccess_deny_from_all($folder = '')
580
-    {
581
-        $folder = EEH_File::standardise_and_end_with_directory_separator($folder);
582
-        if (! EEH_File::exists($folder . '.htaccess')) {
583
-            if (! EEH_File::write_to_file($folder . '.htaccess', 'deny from all', '.htaccess')) {
584
-                return false;
585
-            }
586
-        }
587
-
588
-        return true;
589
-    }
590
-
591
-
592
-    /**
593
-     * Adds an index file to this folder, so folks can't list all the file's contents
594
-     *
595
-     * @param string $folder
596
-     * @return boolean
597
-     */
598
-    public static function add_index_file($folder)
599
-    {
600
-        $folder = EEH_File::standardise_and_end_with_directory_separator($folder);
601
-        if (! EEH_File::exists($folder . 'index.php')) {
602
-            if (! EEH_File::write_to_file(
603
-                $folder . 'index.php',
604
-                'You are not permitted to read from this folder',
605
-                '.php'
606
-            )) {
607
-                return false;
608
-            }
609
-        }
610
-        return true;
611
-    }
612
-
613
-
614
-    /**
615
-     * Given that the file in $file_path has the normal name, (ie, CLASSNAME.whatever.php),
616
-     * extract that classname.
617
-     *
618
-     * @param string $file_path
619
-     * @return string
620
-     */
621
-    public static function get_classname_from_filepath_with_standard_filename($file_path)
622
-    {
623
-        // extract file from path
624
-        $filename = basename($file_path);
625
-        // now remove the first period and everything after
626
-        $pos_of_first_period = strpos($filename, '.');
627
-        return substr($filename, 0, $pos_of_first_period);
628
-    }
629
-
630
-
631
-    /**
632
-     * standardise_directory_separators
633
-     *  convert all directory separators in a file path.
634
-     *
635
-     * @param string $file_path
636
-     * @param bool   $rtrim will remove trailing backslash
637
-     * @return string
638
-     */
639
-    public static function standardise_directory_separators($file_path, $rtrim = false)
640
-    {
641
-        $file_path = $rtrim ? rtrim($file_path, '/\\') : $file_path;
642
-        return str_replace(['\\', '/'], '/', $file_path);
643
-    }
644
-
645
-
646
-    /**
647
-     * end_with_directory_separator
648
-     *  ensures that file path ends with '/'
649
-     *
650
-     * @param string $file_path
651
-     * @return string
652
-     */
653
-    public static function end_with_directory_separator($file_path)
654
-    {
655
-        return rtrim($file_path, '/\\') . '/';
656
-    }
657
-
658
-
659
-    /**
660
-     * shorthand for both EEH_FIle::end_with_directory_separator AND EEH_File::standardise_directory_separators
661
-     *
662
-     * @param $file_path
663
-     * @return string
664
-     */
665
-    public static function standardise_and_end_with_directory_separator($file_path)
666
-    {
667
-        return self::end_with_directory_separator(self::standardise_directory_separators($file_path));
668
-    }
669
-
670
-
671
-    /**
672
-     * takes the folder name (with or without trailing slash) and finds the files it in,
673
-     * and what the class's name inside of each should be.
674
-     *
675
-     * @param array   $folder_paths
676
-     * @param boolean $index_numerically if TRUE, the returned array will be indexed numerically;
677
-     *                                   if FALSE (Default), returned array will be indexed by the filenames minus
678
-     *                                   extensions. Set it TRUE if you know there are files in the directory with the
679
-     *                                   same name but different extensions
680
-     * @return array if $index_numerically == TRUE keys are numeric ,
681
-     *                                   if $index_numerically == FALSE (Default) keys are what the class names SHOULD
682
-     *                                   be; and values are their file paths
683
-     */
684
-    public static function get_contents_of_folders($folder_paths = [], $index_numerically = false)
685
-    {
686
-        $class_to_folder_path = [];
687
-        foreach ($folder_paths as $folder_path) {
688
-            $folder_path = self::standardise_and_end_with_directory_separator($folder_path);
689
-            // load WP_Filesystem and set file permissions
690
-            $files_in_folder = glob($folder_path . '*.php');
691
-            $class_to_folder_path = [];
692
-            if ($files_in_folder) {
693
-                foreach ($files_in_folder as $file_path) {
694
-                    // only add files, not folders
695
-                    if (! is_dir($file_path)) {
696
-                        if ($index_numerically) {
697
-                            $class_to_folder_path[] = $file_path;
698
-                        } else {
699
-                            $classname =
700
-                                self::get_classname_from_filepath_with_standard_filename($file_path);
701
-                            $class_to_folder_path[ $classname ] = $file_path;
702
-                        }
703
-                    }
704
-                }
705
-            }
706
-        }
707
-        return $class_to_folder_path;
708
-    }
709
-
710
-
711
-    /**
712
-     * Copies a file. Mostly a wrapper of WP_Filesystem::copy
713
-     *
714
-     * @param string  $source_file
715
-     * @param string  $destination_file
716
-     * @param boolean $overwrite
717
-     * @return boolean success
718
-     */
719
-    public static function copy($source_file, $destination_file, $overwrite = false)
720
-    {
721
-        $source_file      = EEH_File::validateFileForCopyOrMove($source_file);
722
-        $destination_file = EEH_File::validateFolderForCopyOrMove($destination_file);
723
-        if (! $source_file || ! $destination_file) {
724
-            return false;
725
-        }
726
-        // load WP_Filesystem and set file permissions
727
-        $wp_filesystem = EEH_File::_get_wp_filesystem($destination_file);
728
-        // write the file
729
-        $copied = $wp_filesystem->copy(
730
-            EEH_File::convert_local_filepath_to_remote_filepath($source_file),
731
-            EEH_File::convert_local_filepath_to_remote_filepath($destination_file),
732
-            $overwrite
733
-        );
734
-        if (! $copied) {
735
-            if (defined('WP_DEBUG') && WP_DEBUG) {
736
-                $msg = sprintf(
737
-                    __(
738
-                        'Attempted writing to file %1$s, but could not, probably because of permissions issues',
739
-                        'event_espresso'
740
-                    ),
741
-                    $source_file
742
-                );
743
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($source_file, 'f');
744
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
745
-            }
746
-            return false;
747
-        }
748
-        return true;
749
-    }
750
-
751
-
752
-    /**
753
-     * Reports whether or not the filepath is in the EE uploads folder or not
754
-     *
755
-     * @param string $filepath
756
-     * @return boolean
757
-     */
758
-    public static function is_in_uploads_folder($filepath)
759
-    {
760
-        $uploads = wp_upload_dir();
761
-        return strpos($filepath, $uploads['basedir']) === 0;
762
-    }
763
-
764
-
765
-    /**
766
-     * Given a "local" filepath (what you probably thought was the only filepath),
767
-     * converts it into a "remote" filepath (the filepath the currently-in-use
768
-     * $wp_filesystem needs to use access the folder or file).
769
-     * See http://wordpress.stackexchange.com/questions/124900/using-wp-filesystem-in-plugins
770
-     *
771
-     * @param string $local_filepath the filepath to the folder/file locally
772
-     * @return string the remote filepath (eg the filepath the filesystem method, eg
773
-     *                               ftp or ssh, will use to access the folder
774
-     */
775
-    public static function convert_local_filepath_to_remote_filepath($local_filepath)
776
-    {
777
-        $wp_filesystem = EEH_File::_get_wp_filesystem($local_filepath);
778
-        return str_replace(WP_CONTENT_DIR . '/', $wp_filesystem->wp_content_dir(), $local_filepath);
779
-    }
780
-
781
-
782
-    /**
783
-     * wrapper for WP_Filesystem::chmod()
784
-     *
785
-     * @param string    $file      Path to the file.
786
-     * @param int|false $mode      Optional. The permissions as octal number, usually 0644 for files,
787
-     *                             0755 for directories. Default false.
788
-     * @param bool      $recursive Optional. If set to true, changes file permissions recursively.
789
-     *                             Default false.
790
-     * @return bool True on success, false on failure.
791
-     */
792
-    public static function chmod($file, $mode = false, $recursive = false)
793
-    {
794
-        $wp_filesystem = EEH_File::_get_wp_filesystem($file);
795
-        return $wp_filesystem->chmod($file, $mode, $recursive);
796
-    }
797
-
798
-
799
-    /**
800
-     * wrapper for WP_Filesystem::getchmod()
801
-     *
802
-     * @param string $file Path to the file.
803
-     * @return string Mode of the file (the last 3 digits).
804
-     */
805
-    public static function permissions($file)
806
-    {
807
-        $wp_filesystem = EEH_File::_get_wp_filesystem($file);
808
-        return $wp_filesystem->getchmod($file);
809
-    }
810
-
811
-
812
-    /**
813
-     * wrapper for WP_Filesystem::owner()
814
-     *
815
-     * @param string $file Path to the file.
816
-     * @return string|false Username of the owner on success, false on failure.
817
-     */
818
-    public static function owner($file)
819
-    {
820
-        $wp_filesystem = EEH_File::_get_wp_filesystem($file);
821
-        return $wp_filesystem->owner($file);
822
-    }
823
-
824
-
825
-    /**
826
-     * wrapper for WP_Filesystem::group()
827
-     *
828
-     * @param string $file Path to the file.
829
-     * @return string|false The group on success, false on failure.
830
-     */
831
-    public static function group($file)
832
-    {
833
-        $wp_filesystem = EEH_File::_get_wp_filesystem($file);
834
-        return $wp_filesystem->group($file);
835
-    }
836
-
837
-
838
-    /**
839
-     * wrapper for WP_Filesystem::move()
840
-     *
841
-     * @param string $source      Path to the source file.
842
-     * @param string $destination Path to the destination file.
843
-     * @param bool   $overwrite   Optional. Whether to overwrite the destination file if it exists.
844
-     *                            Default false.
845
-     * @return bool True on success, false on failure.
846
-     */
847
-    public static function move($source, $destination, $overwrite = false)
848
-    {
849
-        // throw new RuntimeException("source: {$source} && destination: {$destination}");
850
-        $source      = EEH_File::validateFileForCopyOrMove($source);
851
-        $destination = EEH_File::validateFolderForCopyOrMove($destination);
852
-        if (! $source || ! $destination) {
853
-            return false;
854
-        }
855
-        $wp_filesystem = EEH_File::_get_wp_filesystem($source);
856
-        if ($wp_filesystem->move($source, $destination, $overwrite)) {
857
-            return true;
858
-        }
859
-        if (defined('WP_DEBUG') && WP_DEBUG) {
860
-            $file        = EEH_File::convert_local_filepath_to_remote_filepath($source);
861
-            $owner       = EEH_File::owner($file);
862
-            $group       = EEH_File::group($file);
863
-            $permissions = EEH_File::permissions($file);
864
-            EE_Error::add_error(
865
-                sprintf(
866
-                    esc_html__(
867
-                        'Unable to move the file "%1$s" to new location (possible permissions errors). The existing "owner:group permissions" for the file are: "%2$s"',
868
-                        'event_espresso'
869
-                    ),
870
-                    $destination,
871
-                    "{$owner}:{$group} $permissions"
872
-                ),
873
-                __FILE__,
874
-                __FUNCTION__,
875
-                __LINE__
876
-            );
877
-        }
878
-        return false;
879
-    }
880
-
881
-
882
-    /**
883
-     * @param string $source_file
884
-     * @return string
885
-     */
886
-    private static function validateFileForCopyOrMove($source_file)
887
-    {
888
-        $full_source_path = EEH_File::standardise_directory_separators($source_file);
889
-        if (! EEH_File::exists($full_source_path)) {
890
-            if (defined('WP_DEBUG') && WP_DEBUG) {
891
-                $msg =
892
-                    sprintf(
893
-                        __('The file located at "%2$s" is not readable or doesn\'t exist.', 'event_espresso'),
894
-                        '',
895
-                        $full_source_path
896
-                    );
897
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_source_path);
898
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
899
-            }
900
-            return '';
901
-        }
902
-        return $full_source_path;
903
-    }
904
-
905
-
906
-    /**
907
-     * @param string $destination_file
908
-     * @return string
909
-     */
910
-    private static function validateFolderForCopyOrMove($destination_file)
911
-    {
912
-        $full_dest_path = EEH_File::standardise_directory_separators($destination_file);
913
-        $folder         = EEH_File::remove_filename_from_filepath($full_dest_path);
914
-        EEH_File::ensure_folder_exists_and_is_writable($folder);
915
-        if (! EEH_File::verify_is_writable($folder, 'folder')) {
916
-            if (defined('WP_DEBUG') && WP_DEBUG) {
917
-                $msg = sprintf(
918
-                    __('The file located at "%2$s" is not writable.', 'event_espresso'),
919
-                    '',
920
-                    $full_dest_path
921
-                );
922
-                $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_dest_path);
923
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
924
-            }
925
-            return '';
926
-        }
927
-        return $full_dest_path;
928
-    }
28
+	/**
29
+	 * @var string $_credentials_form
30
+	 */
31
+	private static $_credentials_form;
32
+
33
+	/**
34
+	 * @var WP_Filesystem_Base $_wp_filesystem
35
+	 */
36
+	protected static $_wp_filesystem;
37
+
38
+
39
+	/**
40
+	 * @param string|null $filepath the filepath we want to work in. If its in the
41
+	 *                              wp uploads directory, we'll want to just use the filesystem directly.
42
+	 *                              If not provided, we have to assume its not in the uploads directory
43
+	 * @return WP_Filesystem_Base
44
+	 */
45
+	private static function _get_wp_filesystem($filepath = null)
46
+	{
47
+		if (apply_filters(
48
+			'FHEE__EEH_File___get_wp_filesystem__allow_using_filesystem_direct',
49
+			$filepath && EEH_File::is_in_uploads_folder($filepath),
50
+			$filepath
51
+		)) {
52
+			return EEH_File::loadAlternateWpFileSystem();
53
+		}
54
+		return EEH_File::loadWpFileSystem();
55
+	}
56
+
57
+
58
+	/**
59
+	 * @return WP_Filesystem_Base
60
+	 */
61
+	private static function loadAlternateWpFileSystem()
62
+	{
63
+		if (! EEH_File::$_wp_filesystem instanceof WP_Filesystem_Base) {
64
+			require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
65
+			$method             = 'direct';
66
+			$wp_filesystem_file =
67
+				apply_filters(
68
+					'filesystem_method_file',
69
+					ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php',
70
+					$method
71
+				);
72
+			// added the following validation logic
73
+			// because we allow the filesystem filepath to be filtered,
74
+			// and are loading whatever file the path pointed to,
75
+			// but we were not validating things in any way :scream_emoji:
76
+			$valid_wp_filesystem_types = [
77
+				'direct'     => 'WP_Filesystem_Direct',
78
+				'ftpext'     => 'WP_Filesystem_FTPext',
79
+				'ftpsockets' => 'WP_Filesystem_ftpsockets',
80
+				'ssh2'       => 'WP_Filesystem_SSH2',
81
+			];
82
+			$valid                     = false;
83
+			$wp_filesystem_class       = '';
84
+			foreach ($valid_wp_filesystem_types as $method => $filesystem_class) {
85
+				// if file path matches for one of valid types, then toggle $valid to true
86
+				if (strpos($wp_filesystem_file, $method) > 0) {
87
+					$valid               = true;
88
+					$wp_filesystem_class = $filesystem_class;
89
+				}
90
+			}
91
+			if (! $valid || ! file_exists($wp_filesystem_file)) {
92
+				EE_Error::add_error(
93
+					sprintf(
94
+						__(
95
+							'The supplied WP Filesystem filepath "%1$s" is either missing or invalid.',
96
+							'event_espresso'
97
+						),
98
+						$wp_filesystem_file
99
+					),
100
+					__FILE__,
101
+					__FUNCTION__,
102
+					__LINE__
103
+				);
104
+			}
105
+			// check constants defined, just like in the wp-admin/includes/file.php WP_Filesystem()
106
+			if (! defined('FS_CHMOD_DIR')) {
107
+				define('FS_CHMOD_DIR', (fileperms(ABSPATH) & 0775 | 0755));
108
+			}
109
+			if (! defined('FS_CHMOD_FILE')) {
110
+				define('FS_CHMOD_FILE', (fileperms(ABSPATH . 'index.php') & 0775 | 0644));
111
+			}
112
+			require_once($wp_filesystem_file);
113
+			EEH_File::$_wp_filesystem = new $wp_filesystem_class([]);
114
+		}
115
+		return EEH_File::$_wp_filesystem;
116
+	}
117
+
118
+
119
+	/**
120
+	 * @return WP_Filesystem_Base
121
+	 */
122
+	private static function loadWpFileSystem()
123
+	{
124
+		global $wp_filesystem;
125
+		// no filesystem setup ???
126
+		if (! $wp_filesystem instanceof WP_Filesystem_Base) {
127
+			// if some eager beaver's just trying to get in there too early...
128
+			// let them do it, because we are one of those eager beavers! :P
129
+			/**
130
+			 * more explanations are probably merited. http://codex.wordpress.org/Filesystem_API#Initializing_WP_Filesystem_Base
131
+			 * says WP_Filesystem should be used after 'wp_loaded', but currently EE's activation process
132
+			 * is setup to mostly happen on 'init', and refactoring to have it happen on
133
+			 * 'wp_loaded' is too much work on a BETA milestone.
134
+			 * So this fix is expected to work if the WP files are owned by the server user,
135
+			 * but probably not if the user needs to enter their FTP credentials to modify files
136
+			 * and there may be troubles if the WP files are owned by a different user
137
+			 * than the server user. But both of these issues should exist in 4.4 and earlier too
138
+			 */
139
+			if (false && ! did_action('wp_loaded')) {
140
+				$msg =
141
+					__(
142
+						'An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.',
143
+						'event_espresso'
144
+					);
145
+				if (WP_DEBUG) {
146
+					$msg .= '<br />' . __(
147
+						'The WP Filesystem can not be accessed until after the "wp_loaded" hook has run, so it\'s best not to attempt access until the "admin_init" hookpoint.',
148
+						'event_espresso'
149
+					);
150
+				}
151
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
152
+			}
153
+			// should be loaded if we are past the wp_loaded hook...
154
+			if (! function_exists('WP_Filesystem') || ! function_exists('submit_button')) {
155
+				require_once(ABSPATH . 'wp-admin/includes/file.php');
156
+				require_once(ABSPATH . 'wp-admin/includes/template.php');
157
+			}
158
+			// turn on output buffering so that we can capture the credentials form
159
+			ob_start();
160
+			$credentials = request_filesystem_credentials(false);
161
+			// store credentials form for the time being
162
+			EEH_File::$_credentials_form = ob_get_clean();
163
+			// if credentials do NOT exist
164
+			if ($credentials === false) {
165
+				add_action('admin_notices', ['EEH_File', 'display_request_filesystem_credentials_form'], 999);
166
+				EE_Error::add_error(
167
+					__(
168
+						'An attempt to access and/or write to a file on the server could not be completed due to a lack of sufficient credentials.',
169
+						'event_espresso'
170
+					),
171
+					__FILE__,
172
+					__FUNCTION__,
173
+					__LINE__
174
+				);
175
+			}
176
+			// basically check for direct or previously configured access
177
+			if (! WP_Filesystem($credentials)
178
+				&& is_wp_error($wp_filesystem->errors)
179
+				&& $wp_filesystem->errors->get_error_code()
180
+			) {
181
+				add_action('admin_notices', ['EEH_File', 'display_request_filesystem_credentials_form'], 999);
182
+				EE_Error::add_error(
183
+					sprintf(
184
+						__('WP Filesystem Error: $1%s', 'event_espresso'),
185
+						$wp_filesystem->errors->get_error_message()
186
+					),
187
+					__FILE__,
188
+					__FUNCTION__,
189
+					__LINE__
190
+				);
191
+			}
192
+		}
193
+		return $wp_filesystem;
194
+	}
195
+
196
+
197
+	/**
198
+	 * display_request_filesystem_credentials_form
199
+	 */
200
+	public static function display_request_filesystem_credentials_form()
201
+	{
202
+		if (! empty(EEH_File::$_credentials_form)) {
203
+			echo '<div class="updated espresso-notices-attention"><p>' . EEH_File::$_credentials_form . '</p></div>';
204
+		}
205
+	}
206
+
207
+
208
+	/**
209
+	 *    verify_filepath_and_permissions
210
+	 *    checks that a file is readable and has sufficient file permissions set to access
211
+	 *
212
+	 * @access public
213
+	 * @param string $full_file_path - full server path to the folder or file
214
+	 * @param string $file_name      - name of file if checking a file
215
+	 * @param string $file_ext       - file extension (ie: "php") if checking a file
216
+	 * @param string $type_of_file   - general type of file (ie: "module"), this is only used to improve error messages
217
+	 * @return bool
218
+	 */
219
+	public static function verify_filepath_and_permissions(
220
+		$full_file_path = '',
221
+		$file_name = '',
222
+		$file_ext = '',
223
+		$type_of_file = ''
224
+	) {
225
+		// load WP_Filesystem and set file permissions
226
+		$wp_filesystem  = EEH_File::_get_wp_filesystem($full_file_path);
227
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
228
+		if (! $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
229
+			$file_name = ! empty($type_of_file) ? $file_name . ' ' . $type_of_file : $file_name;
230
+			$file_name .= ! empty($file_ext) ? ' file' : ' folder';
231
+			$msg       = sprintf(
232
+				__(
233
+					'The requested %1$s could not be found or is not readable, possibly due to an incorrect filepath, or incorrect file permissions.%2$s',
234
+					'event_espresso'
235
+				),
236
+				$file_name,
237
+				'<br />'
238
+			);
239
+			if (EEH_File::exists($full_file_path)) {
240
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, $type_of_file);
241
+			} else {
242
+				// no file permissions means the file was not found
243
+				$msg .= sprintf(
244
+					__('Please ensure the following path is correct: "%s".', 'event_espresso'),
245
+					$full_file_path
246
+				);
247
+			}
248
+			if (defined('WP_DEBUG') && WP_DEBUG) {
249
+				EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
250
+			}
251
+			return false;
252
+		}
253
+		return true;
254
+	}
255
+
256
+
257
+	/**
258
+	 * _permissions_error_for_unreadable_filepath - attempts to determine why permissions are set incorrectly for a
259
+	 * file or folder
260
+	 *
261
+	 * @access private
262
+	 * @param string $full_file_path - full server path to the folder or file
263
+	 * @param string $type_of_file   - general type of file (ie: "module"), this is only used to improve error messages
264
+	 * @return string
265
+	 */
266
+	private static function _permissions_error_for_unreadable_filepath($full_file_path = '', $type_of_file = '')
267
+	{
268
+		// load WP_Filesystem and set file permissions
269
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
270
+		// check file permissions
271
+		$perms = $wp_filesystem->getchmod(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
272
+		if ($perms) {
273
+			// file permissions exist, but way be set incorrectly
274
+			$type_of_file = ! empty($type_of_file) ? $type_of_file . ' ' : '';
275
+			$type_of_file .= ! empty($type_of_file) ? 'file' : 'folder';
276
+			return ' ' . sprintf(
277
+				__(
278
+					'File permissions for the requested %1$s are currently set at "%2$s". The recommended permissions are 644 for files and 755 for folders.',
279
+					'event_espresso'
280
+				),
281
+				$type_of_file,
282
+				$perms
283
+			);
284
+		} else {
285
+			// file exists but file permissions could not be read ?!?!
286
+			return ' ' . sprintf(
287
+				__(
288
+					'Please ensure that the server and/or PHP configuration allows the current process to access the following file: "%s".',
289
+					'event_espresso'
290
+				),
291
+				$full_file_path
292
+			);
293
+		}
294
+	}
295
+
296
+
297
+	/**
298
+	 * ensure_folder_exists_and_is_writable
299
+	 * ensures that a folder exists and is writable, will attempt to create folder if it does not exist
300
+	 * Also ensures all the parent folders exist, and if not tries to create them.
301
+	 * Also, if this function creates the folder, adds a .htaccess file and index.html file
302
+	 *
303
+	 * @param string $folder
304
+	 * @return bool false if folder isn't writable; true if it exists and is writeable,
305
+	 */
306
+	public static function ensure_folder_exists_and_is_writable($folder = '')
307
+	{
308
+		if (empty($folder)) {
309
+			return false;
310
+		}
311
+		// remove ending /
312
+		$folder        = EEH_File::standardise_directory_separators(rtrim($folder, '/\\'));
313
+		$parent_folder = EEH_File::get_parent_folder($folder);
314
+		// add / to folder
315
+		$folder        = EEH_File::end_with_directory_separator($folder);
316
+		$wp_filesystem = EEH_File::_get_wp_filesystem($folder);
317
+		$remote_dir    = EEH_File::convert_local_filepath_to_remote_filepath($folder);
318
+		if (! $wp_filesystem->is_dir($remote_dir)) {
319
+			// ok so it doesn't exist. Does its parent? Can we write to it?
320
+			if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
321
+				return false;
322
+			}
323
+			if (! EEH_File::verify_is_writable($parent_folder, 'folder')) {
324
+				return false;
325
+			}
326
+			if (! $wp_filesystem->mkdir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
327
+				if (defined('WP_DEBUG') && WP_DEBUG) {
328
+					$msg = sprintf(__('"%s" could not be created.', 'event_espresso'), $folder);
329
+					$msg .= EEH_File::_permissions_error_for_unreadable_filepath($folder);
330
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
331
+				}
332
+				return false;
333
+			}
334
+			EEH_File::add_index_file($folder);
335
+		} elseif (! EEH_File::verify_is_writable($folder, 'folder')) {
336
+			return false;
337
+		}
338
+		return true;
339
+	}
340
+
341
+
342
+	/**
343
+	 * verify_is_writable - checks if a file or folder is writable
344
+	 *
345
+	 * @param string $full_path      - full server path to file or folder
346
+	 * @param string $file_or_folder - whether checking a file or folder
347
+	 * @return bool
348
+	 */
349
+	public static function verify_is_writable($full_path = '', $file_or_folder = 'folder')
350
+	{
351
+		// load WP_Filesystem and set file permissions
352
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_path);
353
+		$full_path     = EEH_File::standardise_directory_separators($full_path);
354
+		$remote_path   = EEH_File::convert_local_filepath_to_remote_filepath($full_path);
355
+		$remote_path   = rtrim($remote_path, '/\\');
356
+		if (! $wp_filesystem->is_writable($remote_path)) {
357
+			if (defined('WP_DEBUG') && WP_DEBUG) {
358
+				$msg = sprintf(__('The "%1$s" %2$s is not writable.', 'event_espresso'), $full_path, $file_or_folder);
359
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_path);
360
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
361
+			}
362
+			return false;
363
+		}
364
+		return true;
365
+	}
366
+
367
+
368
+	/**
369
+	 * ensure_file_exists_and_is_writable
370
+	 * ensures that a file exists and is writable, will attempt to create file if it does not exist.
371
+	 * Also ensures all the parent folders exist, and if not tries to create them.
372
+	 *
373
+	 * @param string $full_file_path
374
+	 * @return bool
375
+	 */
376
+	public static function ensure_file_exists_and_is_writable($full_file_path = '')
377
+	{
378
+		// load WP_Filesystem and set file permissions
379
+		$wp_filesystem  = EEH_File::_get_wp_filesystem($full_file_path);
380
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
381
+		$parent_folder  = EEH_File::get_parent_folder($full_file_path);
382
+		if (! EEH_File::exists($full_file_path)) {
383
+			if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
384
+				return false;
385
+			}
386
+			if (! $wp_filesystem->touch(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
387
+				if (defined('WP_DEBUG') && WP_DEBUG) {
388
+					$msg = sprintf(__('The "%s" file could not be created.', 'event_espresso'), $full_file_path);
389
+					$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
390
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
391
+				}
392
+				return false;
393
+			}
394
+		}
395
+		if (! EEH_File::verify_is_writable($full_file_path, 'file')) {
396
+			return false;
397
+		}
398
+		return true;
399
+	}
400
+
401
+
402
+	/**
403
+	 * Gets the parent folder. If provided with file, gets the folder that contains it.
404
+	 * If provided a folder, gets its parent folder.
405
+	 *
406
+	 * @param string $file_or_folder_path
407
+	 * @return string parent folder, ENDING with a directory separator
408
+	 */
409
+	public static function get_parent_folder($file_or_folder_path)
410
+	{
411
+		// find the last /, ignoring a / on the very end
412
+		// eg if given "/var/something/somewhere/", we want to get "somewhere"'s
413
+		// parent folder, "/var/something/"
414
+		$ds = strlen($file_or_folder_path) > 1
415
+			? strrpos($file_or_folder_path, '/', -2)
416
+			: strlen($file_or_folder_path);
417
+		return substr($file_or_folder_path, 0, $ds + 1);
418
+	}
419
+
420
+
421
+	/**
422
+	 * get_file_contents
423
+	 *
424
+	 * @param string $full_file_path
425
+	 * @return string
426
+	 */
427
+	public static function get_file_contents($full_file_path = '')
428
+	{
429
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
430
+		if (EEH_File::verify_filepath_and_permissions(
431
+			$full_file_path,
432
+			EEH_File::get_filename_from_filepath($full_file_path),
433
+			EEH_File::get_file_extension($full_file_path)
434
+		)) {
435
+			// load WP_Filesystem and set file permissions
436
+			$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
437
+			return $wp_filesystem->get_contents(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
438
+		}
439
+		return '';
440
+	}
441
+
442
+
443
+	/**
444
+	 * write_file
445
+	 *
446
+	 * @param string $full_file_path
447
+	 * @param string $file_contents - the content to be written to the file
448
+	 * @param string $file_type
449
+	 * @return bool
450
+	 */
451
+	public static function write_to_file($full_file_path = '', $file_contents = '', $file_type = '')
452
+	{
453
+		$full_file_path = EEH_File::standardise_directory_separators($full_file_path);
454
+		$file_type      = ! empty($file_type) ? rtrim($file_type, ' ') . ' ' : '';
455
+		$folder         = EEH_File::remove_filename_from_filepath($full_file_path);
456
+		if (! EEH_File::verify_is_writable($folder, 'folder')) {
457
+			if (defined('WP_DEBUG') && WP_DEBUG) {
458
+				$msg =
459
+					sprintf(
460
+						__('The %1$sfile located at "%2$s" is not writable.', 'event_espresso'),
461
+						$file_type,
462
+						$full_file_path
463
+					);
464
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
465
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
466
+			}
467
+			return false;
468
+		}
469
+		// load WP_Filesystem and set file permissions
470
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
471
+		// write the file
472
+		if (! $wp_filesystem->put_contents(
473
+			EEH_File::convert_local_filepath_to_remote_filepath($full_file_path),
474
+			$file_contents
475
+		)) {
476
+			if (defined('WP_DEBUG') && WP_DEBUG) {
477
+				$msg =
478
+					sprintf(
479
+						__('The %1$sfile located at "%2$s" could not be written to.', 'event_espresso'),
480
+						$file_type,
481
+						$full_file_path
482
+					);
483
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path, 'f');
484
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
485
+			}
486
+			return false;
487
+		}
488
+		return true;
489
+	}
490
+
491
+
492
+	/**
493
+	 * Wrapper for WP_Filesystem_Base::delete
494
+	 *
495
+	 * @param string         $filepath
496
+	 * @param boolean        $recursive
497
+	 * @param boolean|string $type 'd' for directory, 'f' for file
498
+	 * @return boolean
499
+	 */
500
+	public static function delete($filepath, $recursive = false, $type = false)
501
+	{
502
+		$wp_filesystem = EEH_File::_get_wp_filesystem();
503
+		return $wp_filesystem->delete($filepath, $recursive, $type);
504
+	}
505
+
506
+
507
+	/**
508
+	 * exists
509
+	 * checks if a file exists using the WP filesystem
510
+	 *
511
+	 * @param string $full_file_path
512
+	 * @return bool
513
+	 */
514
+	public static function exists($full_file_path = '')
515
+	{
516
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
517
+		return $wp_filesystem->exists(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
518
+	}
519
+
520
+
521
+	/**
522
+	 * is_readable
523
+	 * checks if a file is_readable using the WP filesystem
524
+	 *
525
+	 * @param string $full_file_path
526
+	 * @return bool
527
+	 */
528
+	public static function is_readable($full_file_path = '')
529
+	{
530
+		$wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
531
+		return $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
532
+	}
533
+
534
+
535
+	/**
536
+	 * remove_filename_from_filepath
537
+	 * given a full path to a file including the filename itself, this removes  the filename and returns the path, up
538
+	 * to, but NOT including the filename OR slash
539
+	 *
540
+	 * @param string $full_file_path
541
+	 * @return string
542
+	 */
543
+	public static function remove_filename_from_filepath($full_file_path = '')
544
+	{
545
+		return pathinfo($full_file_path, PATHINFO_DIRNAME);
546
+	}
547
+
548
+
549
+	/**
550
+	 * get_filename_from_filepath. Arguably the same as basename()
551
+	 *
552
+	 * @param string $full_file_path
553
+	 * @return string
554
+	 */
555
+	public static function get_filename_from_filepath($full_file_path = '')
556
+	{
557
+		return pathinfo($full_file_path, PATHINFO_BASENAME);
558
+	}
559
+
560
+
561
+	/**
562
+	 * get_file_extension
563
+	 *
564
+	 * @param string $full_file_path
565
+	 * @return string
566
+	 */
567
+	public static function get_file_extension($full_file_path = '')
568
+	{
569
+		return pathinfo($full_file_path, PATHINFO_EXTENSION);
570
+	}
571
+
572
+
573
+	/**
574
+	 * add_htaccess_deny_from_all so the web server cannot access this folder
575
+	 *
576
+	 * @param string $folder
577
+	 * @return bool
578
+	 */
579
+	public static function add_htaccess_deny_from_all($folder = '')
580
+	{
581
+		$folder = EEH_File::standardise_and_end_with_directory_separator($folder);
582
+		if (! EEH_File::exists($folder . '.htaccess')) {
583
+			if (! EEH_File::write_to_file($folder . '.htaccess', 'deny from all', '.htaccess')) {
584
+				return false;
585
+			}
586
+		}
587
+
588
+		return true;
589
+	}
590
+
591
+
592
+	/**
593
+	 * Adds an index file to this folder, so folks can't list all the file's contents
594
+	 *
595
+	 * @param string $folder
596
+	 * @return boolean
597
+	 */
598
+	public static function add_index_file($folder)
599
+	{
600
+		$folder = EEH_File::standardise_and_end_with_directory_separator($folder);
601
+		if (! EEH_File::exists($folder . 'index.php')) {
602
+			if (! EEH_File::write_to_file(
603
+				$folder . 'index.php',
604
+				'You are not permitted to read from this folder',
605
+				'.php'
606
+			)) {
607
+				return false;
608
+			}
609
+		}
610
+		return true;
611
+	}
612
+
613
+
614
+	/**
615
+	 * Given that the file in $file_path has the normal name, (ie, CLASSNAME.whatever.php),
616
+	 * extract that classname.
617
+	 *
618
+	 * @param string $file_path
619
+	 * @return string
620
+	 */
621
+	public static function get_classname_from_filepath_with_standard_filename($file_path)
622
+	{
623
+		// extract file from path
624
+		$filename = basename($file_path);
625
+		// now remove the first period and everything after
626
+		$pos_of_first_period = strpos($filename, '.');
627
+		return substr($filename, 0, $pos_of_first_period);
628
+	}
629
+
630
+
631
+	/**
632
+	 * standardise_directory_separators
633
+	 *  convert all directory separators in a file path.
634
+	 *
635
+	 * @param string $file_path
636
+	 * @param bool   $rtrim will remove trailing backslash
637
+	 * @return string
638
+	 */
639
+	public static function standardise_directory_separators($file_path, $rtrim = false)
640
+	{
641
+		$file_path = $rtrim ? rtrim($file_path, '/\\') : $file_path;
642
+		return str_replace(['\\', '/'], '/', $file_path);
643
+	}
644
+
645
+
646
+	/**
647
+	 * end_with_directory_separator
648
+	 *  ensures that file path ends with '/'
649
+	 *
650
+	 * @param string $file_path
651
+	 * @return string
652
+	 */
653
+	public static function end_with_directory_separator($file_path)
654
+	{
655
+		return rtrim($file_path, '/\\') . '/';
656
+	}
657
+
658
+
659
+	/**
660
+	 * shorthand for both EEH_FIle::end_with_directory_separator AND EEH_File::standardise_directory_separators
661
+	 *
662
+	 * @param $file_path
663
+	 * @return string
664
+	 */
665
+	public static function standardise_and_end_with_directory_separator($file_path)
666
+	{
667
+		return self::end_with_directory_separator(self::standardise_directory_separators($file_path));
668
+	}
669
+
670
+
671
+	/**
672
+	 * takes the folder name (with or without trailing slash) and finds the files it in,
673
+	 * and what the class's name inside of each should be.
674
+	 *
675
+	 * @param array   $folder_paths
676
+	 * @param boolean $index_numerically if TRUE, the returned array will be indexed numerically;
677
+	 *                                   if FALSE (Default), returned array will be indexed by the filenames minus
678
+	 *                                   extensions. Set it TRUE if you know there are files in the directory with the
679
+	 *                                   same name but different extensions
680
+	 * @return array if $index_numerically == TRUE keys are numeric ,
681
+	 *                                   if $index_numerically == FALSE (Default) keys are what the class names SHOULD
682
+	 *                                   be; and values are their file paths
683
+	 */
684
+	public static function get_contents_of_folders($folder_paths = [], $index_numerically = false)
685
+	{
686
+		$class_to_folder_path = [];
687
+		foreach ($folder_paths as $folder_path) {
688
+			$folder_path = self::standardise_and_end_with_directory_separator($folder_path);
689
+			// load WP_Filesystem and set file permissions
690
+			$files_in_folder = glob($folder_path . '*.php');
691
+			$class_to_folder_path = [];
692
+			if ($files_in_folder) {
693
+				foreach ($files_in_folder as $file_path) {
694
+					// only add files, not folders
695
+					if (! is_dir($file_path)) {
696
+						if ($index_numerically) {
697
+							$class_to_folder_path[] = $file_path;
698
+						} else {
699
+							$classname =
700
+								self::get_classname_from_filepath_with_standard_filename($file_path);
701
+							$class_to_folder_path[ $classname ] = $file_path;
702
+						}
703
+					}
704
+				}
705
+			}
706
+		}
707
+		return $class_to_folder_path;
708
+	}
709
+
710
+
711
+	/**
712
+	 * Copies a file. Mostly a wrapper of WP_Filesystem::copy
713
+	 *
714
+	 * @param string  $source_file
715
+	 * @param string  $destination_file
716
+	 * @param boolean $overwrite
717
+	 * @return boolean success
718
+	 */
719
+	public static function copy($source_file, $destination_file, $overwrite = false)
720
+	{
721
+		$source_file      = EEH_File::validateFileForCopyOrMove($source_file);
722
+		$destination_file = EEH_File::validateFolderForCopyOrMove($destination_file);
723
+		if (! $source_file || ! $destination_file) {
724
+			return false;
725
+		}
726
+		// load WP_Filesystem and set file permissions
727
+		$wp_filesystem = EEH_File::_get_wp_filesystem($destination_file);
728
+		// write the file
729
+		$copied = $wp_filesystem->copy(
730
+			EEH_File::convert_local_filepath_to_remote_filepath($source_file),
731
+			EEH_File::convert_local_filepath_to_remote_filepath($destination_file),
732
+			$overwrite
733
+		);
734
+		if (! $copied) {
735
+			if (defined('WP_DEBUG') && WP_DEBUG) {
736
+				$msg = sprintf(
737
+					__(
738
+						'Attempted writing to file %1$s, but could not, probably because of permissions issues',
739
+						'event_espresso'
740
+					),
741
+					$source_file
742
+				);
743
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($source_file, 'f');
744
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
745
+			}
746
+			return false;
747
+		}
748
+		return true;
749
+	}
750
+
751
+
752
+	/**
753
+	 * Reports whether or not the filepath is in the EE uploads folder or not
754
+	 *
755
+	 * @param string $filepath
756
+	 * @return boolean
757
+	 */
758
+	public static function is_in_uploads_folder($filepath)
759
+	{
760
+		$uploads = wp_upload_dir();
761
+		return strpos($filepath, $uploads['basedir']) === 0;
762
+	}
763
+
764
+
765
+	/**
766
+	 * Given a "local" filepath (what you probably thought was the only filepath),
767
+	 * converts it into a "remote" filepath (the filepath the currently-in-use
768
+	 * $wp_filesystem needs to use access the folder or file).
769
+	 * See http://wordpress.stackexchange.com/questions/124900/using-wp-filesystem-in-plugins
770
+	 *
771
+	 * @param string $local_filepath the filepath to the folder/file locally
772
+	 * @return string the remote filepath (eg the filepath the filesystem method, eg
773
+	 *                               ftp or ssh, will use to access the folder
774
+	 */
775
+	public static function convert_local_filepath_to_remote_filepath($local_filepath)
776
+	{
777
+		$wp_filesystem = EEH_File::_get_wp_filesystem($local_filepath);
778
+		return str_replace(WP_CONTENT_DIR . '/', $wp_filesystem->wp_content_dir(), $local_filepath);
779
+	}
780
+
781
+
782
+	/**
783
+	 * wrapper for WP_Filesystem::chmod()
784
+	 *
785
+	 * @param string    $file      Path to the file.
786
+	 * @param int|false $mode      Optional. The permissions as octal number, usually 0644 for files,
787
+	 *                             0755 for directories. Default false.
788
+	 * @param bool      $recursive Optional. If set to true, changes file permissions recursively.
789
+	 *                             Default false.
790
+	 * @return bool True on success, false on failure.
791
+	 */
792
+	public static function chmod($file, $mode = false, $recursive = false)
793
+	{
794
+		$wp_filesystem = EEH_File::_get_wp_filesystem($file);
795
+		return $wp_filesystem->chmod($file, $mode, $recursive);
796
+	}
797
+
798
+
799
+	/**
800
+	 * wrapper for WP_Filesystem::getchmod()
801
+	 *
802
+	 * @param string $file Path to the file.
803
+	 * @return string Mode of the file (the last 3 digits).
804
+	 */
805
+	public static function permissions($file)
806
+	{
807
+		$wp_filesystem = EEH_File::_get_wp_filesystem($file);
808
+		return $wp_filesystem->getchmod($file);
809
+	}
810
+
811
+
812
+	/**
813
+	 * wrapper for WP_Filesystem::owner()
814
+	 *
815
+	 * @param string $file Path to the file.
816
+	 * @return string|false Username of the owner on success, false on failure.
817
+	 */
818
+	public static function owner($file)
819
+	{
820
+		$wp_filesystem = EEH_File::_get_wp_filesystem($file);
821
+		return $wp_filesystem->owner($file);
822
+	}
823
+
824
+
825
+	/**
826
+	 * wrapper for WP_Filesystem::group()
827
+	 *
828
+	 * @param string $file Path to the file.
829
+	 * @return string|false The group on success, false on failure.
830
+	 */
831
+	public static function group($file)
832
+	{
833
+		$wp_filesystem = EEH_File::_get_wp_filesystem($file);
834
+		return $wp_filesystem->group($file);
835
+	}
836
+
837
+
838
+	/**
839
+	 * wrapper for WP_Filesystem::move()
840
+	 *
841
+	 * @param string $source      Path to the source file.
842
+	 * @param string $destination Path to the destination file.
843
+	 * @param bool   $overwrite   Optional. Whether to overwrite the destination file if it exists.
844
+	 *                            Default false.
845
+	 * @return bool True on success, false on failure.
846
+	 */
847
+	public static function move($source, $destination, $overwrite = false)
848
+	{
849
+		// throw new RuntimeException("source: {$source} && destination: {$destination}");
850
+		$source      = EEH_File::validateFileForCopyOrMove($source);
851
+		$destination = EEH_File::validateFolderForCopyOrMove($destination);
852
+		if (! $source || ! $destination) {
853
+			return false;
854
+		}
855
+		$wp_filesystem = EEH_File::_get_wp_filesystem($source);
856
+		if ($wp_filesystem->move($source, $destination, $overwrite)) {
857
+			return true;
858
+		}
859
+		if (defined('WP_DEBUG') && WP_DEBUG) {
860
+			$file        = EEH_File::convert_local_filepath_to_remote_filepath($source);
861
+			$owner       = EEH_File::owner($file);
862
+			$group       = EEH_File::group($file);
863
+			$permissions = EEH_File::permissions($file);
864
+			EE_Error::add_error(
865
+				sprintf(
866
+					esc_html__(
867
+						'Unable to move the file "%1$s" to new location (possible permissions errors). The existing "owner:group permissions" for the file are: "%2$s"',
868
+						'event_espresso'
869
+					),
870
+					$destination,
871
+					"{$owner}:{$group} $permissions"
872
+				),
873
+				__FILE__,
874
+				__FUNCTION__,
875
+				__LINE__
876
+			);
877
+		}
878
+		return false;
879
+	}
880
+
881
+
882
+	/**
883
+	 * @param string $source_file
884
+	 * @return string
885
+	 */
886
+	private static function validateFileForCopyOrMove($source_file)
887
+	{
888
+		$full_source_path = EEH_File::standardise_directory_separators($source_file);
889
+		if (! EEH_File::exists($full_source_path)) {
890
+			if (defined('WP_DEBUG') && WP_DEBUG) {
891
+				$msg =
892
+					sprintf(
893
+						__('The file located at "%2$s" is not readable or doesn\'t exist.', 'event_espresso'),
894
+						'',
895
+						$full_source_path
896
+					);
897
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_source_path);
898
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
899
+			}
900
+			return '';
901
+		}
902
+		return $full_source_path;
903
+	}
904
+
905
+
906
+	/**
907
+	 * @param string $destination_file
908
+	 * @return string
909
+	 */
910
+	private static function validateFolderForCopyOrMove($destination_file)
911
+	{
912
+		$full_dest_path = EEH_File::standardise_directory_separators($destination_file);
913
+		$folder         = EEH_File::remove_filename_from_filepath($full_dest_path);
914
+		EEH_File::ensure_folder_exists_and_is_writable($folder);
915
+		if (! EEH_File::verify_is_writable($folder, 'folder')) {
916
+			if (defined('WP_DEBUG') && WP_DEBUG) {
917
+				$msg = sprintf(
918
+					__('The file located at "%2$s" is not writable.', 'event_espresso'),
919
+					'',
920
+					$full_dest_path
921
+				);
922
+				$msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_dest_path);
923
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
924
+			}
925
+			return '';
926
+		}
927
+		return $full_dest_path;
928
+	}
929 929
 }
Please login to merge, or discard this patch.
Spacing   +49 added lines, -49 removed lines patch added patch discarded remove patch
@@ -60,13 +60,13 @@  discard block
 block discarded – undo
60 60
      */
61 61
     private static function loadAlternateWpFileSystem()
62 62
     {
63
-        if (! EEH_File::$_wp_filesystem instanceof WP_Filesystem_Base) {
64
-            require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
63
+        if ( ! EEH_File::$_wp_filesystem instanceof WP_Filesystem_Base) {
64
+            require_once(ABSPATH.'wp-admin/includes/class-wp-filesystem-base.php');
65 65
             $method             = 'direct';
66 66
             $wp_filesystem_file =
67 67
                 apply_filters(
68 68
                     'filesystem_method_file',
69
-                    ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php',
69
+                    ABSPATH.'wp-admin/includes/class-wp-filesystem-'.$method.'.php',
70 70
                     $method
71 71
                 );
72 72
             // added the following validation logic
@@ -88,7 +88,7 @@  discard block
 block discarded – undo
88 88
                     $wp_filesystem_class = $filesystem_class;
89 89
                 }
90 90
             }
91
-            if (! $valid || ! file_exists($wp_filesystem_file)) {
91
+            if ( ! $valid || ! file_exists($wp_filesystem_file)) {
92 92
                 EE_Error::add_error(
93 93
                     sprintf(
94 94
                         __(
@@ -103,11 +103,11 @@  discard block
 block discarded – undo
103 103
                 );
104 104
             }
105 105
             // check constants defined, just like in the wp-admin/includes/file.php WP_Filesystem()
106
-            if (! defined('FS_CHMOD_DIR')) {
106
+            if ( ! defined('FS_CHMOD_DIR')) {
107 107
                 define('FS_CHMOD_DIR', (fileperms(ABSPATH) & 0775 | 0755));
108 108
             }
109
-            if (! defined('FS_CHMOD_FILE')) {
110
-                define('FS_CHMOD_FILE', (fileperms(ABSPATH . 'index.php') & 0775 | 0644));
109
+            if ( ! defined('FS_CHMOD_FILE')) {
110
+                define('FS_CHMOD_FILE', (fileperms(ABSPATH.'index.php') & 0775 | 0644));
111 111
             }
112 112
             require_once($wp_filesystem_file);
113 113
             EEH_File::$_wp_filesystem = new $wp_filesystem_class([]);
@@ -123,7 +123,7 @@  discard block
 block discarded – undo
123 123
     {
124 124
         global $wp_filesystem;
125 125
         // no filesystem setup ???
126
-        if (! $wp_filesystem instanceof WP_Filesystem_Base) {
126
+        if ( ! $wp_filesystem instanceof WP_Filesystem_Base) {
127 127
             // if some eager beaver's just trying to get in there too early...
128 128
             // let them do it, because we are one of those eager beavers! :P
129 129
             /**
@@ -143,7 +143,7 @@  discard block
 block discarded – undo
143 143
                         'event_espresso'
144 144
                     );
145 145
                 if (WP_DEBUG) {
146
-                    $msg .= '<br />' . __(
146
+                    $msg .= '<br />'.__(
147 147
                         'The WP Filesystem can not be accessed until after the "wp_loaded" hook has run, so it\'s best not to attempt access until the "admin_init" hookpoint.',
148 148
                         'event_espresso'
149 149
                     );
@@ -151,9 +151,9 @@  discard block
 block discarded – undo
151 151
                 EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
152 152
             }
153 153
             // should be loaded if we are past the wp_loaded hook...
154
-            if (! function_exists('WP_Filesystem') || ! function_exists('submit_button')) {
155
-                require_once(ABSPATH . 'wp-admin/includes/file.php');
156
-                require_once(ABSPATH . 'wp-admin/includes/template.php');
154
+            if ( ! function_exists('WP_Filesystem') || ! function_exists('submit_button')) {
155
+                require_once(ABSPATH.'wp-admin/includes/file.php');
156
+                require_once(ABSPATH.'wp-admin/includes/template.php');
157 157
             }
158 158
             // turn on output buffering so that we can capture the credentials form
159 159
             ob_start();
@@ -174,7 +174,7 @@  discard block
 block discarded – undo
174 174
                 );
175 175
             }
176 176
             // basically check for direct or previously configured access
177
-            if (! WP_Filesystem($credentials)
177
+            if ( ! WP_Filesystem($credentials)
178 178
                 && is_wp_error($wp_filesystem->errors)
179 179
                 && $wp_filesystem->errors->get_error_code()
180 180
             ) {
@@ -199,8 +199,8 @@  discard block
 block discarded – undo
199 199
      */
200 200
     public static function display_request_filesystem_credentials_form()
201 201
     {
202
-        if (! empty(EEH_File::$_credentials_form)) {
203
-            echo '<div class="updated espresso-notices-attention"><p>' . EEH_File::$_credentials_form . '</p></div>';
202
+        if ( ! empty(EEH_File::$_credentials_form)) {
203
+            echo '<div class="updated espresso-notices-attention"><p>'.EEH_File::$_credentials_form.'</p></div>';
204 204
         }
205 205
     }
206 206
 
@@ -225,8 +225,8 @@  discard block
 block discarded – undo
225 225
         // load WP_Filesystem and set file permissions
226 226
         $wp_filesystem  = EEH_File::_get_wp_filesystem($full_file_path);
227 227
         $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
228
-        if (! $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
229
-            $file_name = ! empty($type_of_file) ? $file_name . ' ' . $type_of_file : $file_name;
228
+        if ( ! $wp_filesystem->is_readable(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
229
+            $file_name = ! empty($type_of_file) ? $file_name.' '.$type_of_file : $file_name;
230 230
             $file_name .= ! empty($file_ext) ? ' file' : ' folder';
231 231
             $msg       = sprintf(
232 232
                 __(
@@ -246,7 +246,7 @@  discard block
 block discarded – undo
246 246
                 );
247 247
             }
248 248
             if (defined('WP_DEBUG') && WP_DEBUG) {
249
-                EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
249
+                EE_Error::add_error($msg.'||'.$msg, __FILE__, __FUNCTION__, __LINE__);
250 250
             }
251 251
             return false;
252 252
         }
@@ -271,9 +271,9 @@  discard block
 block discarded – undo
271 271
         $perms = $wp_filesystem->getchmod(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path));
272 272
         if ($perms) {
273 273
             // file permissions exist, but way be set incorrectly
274
-            $type_of_file = ! empty($type_of_file) ? $type_of_file . ' ' : '';
274
+            $type_of_file = ! empty($type_of_file) ? $type_of_file.' ' : '';
275 275
             $type_of_file .= ! empty($type_of_file) ? 'file' : 'folder';
276
-            return ' ' . sprintf(
276
+            return ' '.sprintf(
277 277
                 __(
278 278
                     'File permissions for the requested %1$s are currently set at "%2$s". The recommended permissions are 644 for files and 755 for folders.',
279 279
                     'event_espresso'
@@ -283,7 +283,7 @@  discard block
 block discarded – undo
283 283
             );
284 284
         } else {
285 285
             // file exists but file permissions could not be read ?!?!
286
-            return ' ' . sprintf(
286
+            return ' '.sprintf(
287 287
                 __(
288 288
                     'Please ensure that the server and/or PHP configuration allows the current process to access the following file: "%s".',
289 289
                     'event_espresso'
@@ -315,15 +315,15 @@  discard block
 block discarded – undo
315 315
         $folder        = EEH_File::end_with_directory_separator($folder);
316 316
         $wp_filesystem = EEH_File::_get_wp_filesystem($folder);
317 317
         $remote_dir    = EEH_File::convert_local_filepath_to_remote_filepath($folder);
318
-        if (! $wp_filesystem->is_dir($remote_dir)) {
318
+        if ( ! $wp_filesystem->is_dir($remote_dir)) {
319 319
             // ok so it doesn't exist. Does its parent? Can we write to it?
320
-            if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
320
+            if ( ! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
321 321
                 return false;
322 322
             }
323
-            if (! EEH_File::verify_is_writable($parent_folder, 'folder')) {
323
+            if ( ! EEH_File::verify_is_writable($parent_folder, 'folder')) {
324 324
                 return false;
325 325
             }
326
-            if (! $wp_filesystem->mkdir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
326
+            if ( ! $wp_filesystem->mkdir(EEH_File::convert_local_filepath_to_remote_filepath($folder))) {
327 327
                 if (defined('WP_DEBUG') && WP_DEBUG) {
328 328
                     $msg = sprintf(__('"%s" could not be created.', 'event_espresso'), $folder);
329 329
                     $msg .= EEH_File::_permissions_error_for_unreadable_filepath($folder);
@@ -332,7 +332,7 @@  discard block
 block discarded – undo
332 332
                 return false;
333 333
             }
334 334
             EEH_File::add_index_file($folder);
335
-        } elseif (! EEH_File::verify_is_writable($folder, 'folder')) {
335
+        } elseif ( ! EEH_File::verify_is_writable($folder, 'folder')) {
336 336
             return false;
337 337
         }
338 338
         return true;
@@ -353,7 +353,7 @@  discard block
 block discarded – undo
353 353
         $full_path     = EEH_File::standardise_directory_separators($full_path);
354 354
         $remote_path   = EEH_File::convert_local_filepath_to_remote_filepath($full_path);
355 355
         $remote_path   = rtrim($remote_path, '/\\');
356
-        if (! $wp_filesystem->is_writable($remote_path)) {
356
+        if ( ! $wp_filesystem->is_writable($remote_path)) {
357 357
             if (defined('WP_DEBUG') && WP_DEBUG) {
358 358
                 $msg = sprintf(__('The "%1$s" %2$s is not writable.', 'event_espresso'), $full_path, $file_or_folder);
359 359
                 $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_path);
@@ -379,11 +379,11 @@  discard block
 block discarded – undo
379 379
         $wp_filesystem  = EEH_File::_get_wp_filesystem($full_file_path);
380 380
         $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
381 381
         $parent_folder  = EEH_File::get_parent_folder($full_file_path);
382
-        if (! EEH_File::exists($full_file_path)) {
383
-            if (! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
382
+        if ( ! EEH_File::exists($full_file_path)) {
383
+            if ( ! EEH_File::ensure_folder_exists_and_is_writable($parent_folder)) {
384 384
                 return false;
385 385
             }
386
-            if (! $wp_filesystem->touch(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
386
+            if ( ! $wp_filesystem->touch(EEH_File::convert_local_filepath_to_remote_filepath($full_file_path))) {
387 387
                 if (defined('WP_DEBUG') && WP_DEBUG) {
388 388
                     $msg = sprintf(__('The "%s" file could not be created.', 'event_espresso'), $full_file_path);
389 389
                     $msg .= EEH_File::_permissions_error_for_unreadable_filepath($full_file_path);
@@ -392,7 +392,7 @@  discard block
 block discarded – undo
392 392
                 return false;
393 393
             }
394 394
         }
395
-        if (! EEH_File::verify_is_writable($full_file_path, 'file')) {
395
+        if ( ! EEH_File::verify_is_writable($full_file_path, 'file')) {
396 396
             return false;
397 397
         }
398 398
         return true;
@@ -451,9 +451,9 @@  discard block
 block discarded – undo
451 451
     public static function write_to_file($full_file_path = '', $file_contents = '', $file_type = '')
452 452
     {
453 453
         $full_file_path = EEH_File::standardise_directory_separators($full_file_path);
454
-        $file_type      = ! empty($file_type) ? rtrim($file_type, ' ') . ' ' : '';
454
+        $file_type      = ! empty($file_type) ? rtrim($file_type, ' ').' ' : '';
455 455
         $folder         = EEH_File::remove_filename_from_filepath($full_file_path);
456
-        if (! EEH_File::verify_is_writable($folder, 'folder')) {
456
+        if ( ! EEH_File::verify_is_writable($folder, 'folder')) {
457 457
             if (defined('WP_DEBUG') && WP_DEBUG) {
458 458
                 $msg =
459 459
                     sprintf(
@@ -469,7 +469,7 @@  discard block
 block discarded – undo
469 469
         // load WP_Filesystem and set file permissions
470 470
         $wp_filesystem = EEH_File::_get_wp_filesystem($full_file_path);
471 471
         // write the file
472
-        if (! $wp_filesystem->put_contents(
472
+        if ( ! $wp_filesystem->put_contents(
473 473
             EEH_File::convert_local_filepath_to_remote_filepath($full_file_path),
474 474
             $file_contents
475 475
         )) {
@@ -579,8 +579,8 @@  discard block
 block discarded – undo
579 579
     public static function add_htaccess_deny_from_all($folder = '')
580 580
     {
581 581
         $folder = EEH_File::standardise_and_end_with_directory_separator($folder);
582
-        if (! EEH_File::exists($folder . '.htaccess')) {
583
-            if (! EEH_File::write_to_file($folder . '.htaccess', 'deny from all', '.htaccess')) {
582
+        if ( ! EEH_File::exists($folder.'.htaccess')) {
583
+            if ( ! EEH_File::write_to_file($folder.'.htaccess', 'deny from all', '.htaccess')) {
584 584
                 return false;
585 585
             }
586 586
         }
@@ -598,9 +598,9 @@  discard block
 block discarded – undo
598 598
     public static function add_index_file($folder)
599 599
     {
600 600
         $folder = EEH_File::standardise_and_end_with_directory_separator($folder);
601
-        if (! EEH_File::exists($folder . 'index.php')) {
602
-            if (! EEH_File::write_to_file(
603
-                $folder . 'index.php',
601
+        if ( ! EEH_File::exists($folder.'index.php')) {
602
+            if ( ! EEH_File::write_to_file(
603
+                $folder.'index.php',
604 604
                 'You are not permitted to read from this folder',
605 605
                 '.php'
606 606
             )) {
@@ -652,7 +652,7 @@  discard block
 block discarded – undo
652 652
      */
653 653
     public static function end_with_directory_separator($file_path)
654 654
     {
655
-        return rtrim($file_path, '/\\') . '/';
655
+        return rtrim($file_path, '/\\').'/';
656 656
     }
657 657
 
658 658
 
@@ -687,18 +687,18 @@  discard block
 block discarded – undo
687 687
         foreach ($folder_paths as $folder_path) {
688 688
             $folder_path = self::standardise_and_end_with_directory_separator($folder_path);
689 689
             // load WP_Filesystem and set file permissions
690
-            $files_in_folder = glob($folder_path . '*.php');
690
+            $files_in_folder = glob($folder_path.'*.php');
691 691
             $class_to_folder_path = [];
692 692
             if ($files_in_folder) {
693 693
                 foreach ($files_in_folder as $file_path) {
694 694
                     // only add files, not folders
695
-                    if (! is_dir($file_path)) {
695
+                    if ( ! is_dir($file_path)) {
696 696
                         if ($index_numerically) {
697 697
                             $class_to_folder_path[] = $file_path;
698 698
                         } else {
699 699
                             $classname =
700 700
                                 self::get_classname_from_filepath_with_standard_filename($file_path);
701
-                            $class_to_folder_path[ $classname ] = $file_path;
701
+                            $class_to_folder_path[$classname] = $file_path;
702 702
                         }
703 703
                     }
704 704
                 }
@@ -720,7 +720,7 @@  discard block
 block discarded – undo
720 720
     {
721 721
         $source_file      = EEH_File::validateFileForCopyOrMove($source_file);
722 722
         $destination_file = EEH_File::validateFolderForCopyOrMove($destination_file);
723
-        if (! $source_file || ! $destination_file) {
723
+        if ( ! $source_file || ! $destination_file) {
724 724
             return false;
725 725
         }
726 726
         // load WP_Filesystem and set file permissions
@@ -731,7 +731,7 @@  discard block
 block discarded – undo
731 731
             EEH_File::convert_local_filepath_to_remote_filepath($destination_file),
732 732
             $overwrite
733 733
         );
734
-        if (! $copied) {
734
+        if ( ! $copied) {
735 735
             if (defined('WP_DEBUG') && WP_DEBUG) {
736 736
                 $msg = sprintf(
737 737
                     __(
@@ -775,7 +775,7 @@  discard block
 block discarded – undo
775 775
     public static function convert_local_filepath_to_remote_filepath($local_filepath)
776 776
     {
777 777
         $wp_filesystem = EEH_File::_get_wp_filesystem($local_filepath);
778
-        return str_replace(WP_CONTENT_DIR . '/', $wp_filesystem->wp_content_dir(), $local_filepath);
778
+        return str_replace(WP_CONTENT_DIR.'/', $wp_filesystem->wp_content_dir(), $local_filepath);
779 779
     }
780 780
 
781 781
 
@@ -849,7 +849,7 @@  discard block
 block discarded – undo
849 849
         // throw new RuntimeException("source: {$source} && destination: {$destination}");
850 850
         $source      = EEH_File::validateFileForCopyOrMove($source);
851 851
         $destination = EEH_File::validateFolderForCopyOrMove($destination);
852
-        if (! $source || ! $destination) {
852
+        if ( ! $source || ! $destination) {
853 853
             return false;
854 854
         }
855 855
         $wp_filesystem = EEH_File::_get_wp_filesystem($source);
@@ -886,7 +886,7 @@  discard block
 block discarded – undo
886 886
     private static function validateFileForCopyOrMove($source_file)
887 887
     {
888 888
         $full_source_path = EEH_File::standardise_directory_separators($source_file);
889
-        if (! EEH_File::exists($full_source_path)) {
889
+        if ( ! EEH_File::exists($full_source_path)) {
890 890
             if (defined('WP_DEBUG') && WP_DEBUG) {
891 891
                 $msg =
892 892
                     sprintf(
@@ -912,7 +912,7 @@  discard block
 block discarded – undo
912 912
         $full_dest_path = EEH_File::standardise_directory_separators($destination_file);
913 913
         $folder         = EEH_File::remove_filename_from_filepath($full_dest_path);
914 914
         EEH_File::ensure_folder_exists_and_is_writable($folder);
915
-        if (! EEH_File::verify_is_writable($folder, 'folder')) {
915
+        if ( ! EEH_File::verify_is_writable($folder, 'folder')) {
916 916
             if (defined('WP_DEBUG') && WP_DEBUG) {
917 917
                 $msg = sprintf(
918 918
                     __('The file located at "%2$s" is not writable.', 'event_espresso'),
Please login to merge, or discard this patch.
languages/event_espresso-translations-js.php 1 patch
Spacing   +409 added lines, -409 removed lines patch added patch discarded remove patch
@@ -2,240 +2,240 @@  discard block
 block discarded – undo
2 2
 /* THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY. */
3 3
 $generated_i18n_strings = array(
4 4
 	// Reference: packages/components/src/Pagination/constants.ts:6
5
-	__( '2', 'event_espresso' ),
5
+	__('2', 'event_espresso'),
6 6
 
7 7
 	// Reference: packages/components/src/Pagination/constants.ts:7
8
-	__( '6', 'event_espresso' ),
8
+	__('6', 'event_espresso'),
9 9
 
10 10
 	// Reference: packages/components/src/Pagination/constants.ts:8
11
-	__( '12', 'event_espresso' ),
11
+	__('12', 'event_espresso'),
12 12
 
13 13
 	// Reference: packages/components/src/Pagination/constants.ts:9
14
-	__( '24', 'event_espresso' ),
14
+	__('24', 'event_espresso'),
15 15
 
16 16
 	// Reference: packages/components/src/Pagination/constants.ts:10
17
-	__( '48', 'event_espresso' ),
17
+	__('48', 'event_espresso'),
18 18
 
19 19
 	// Reference: domains/blocks/src/components/AvatarImage.tsx:27
20
-	__( 'contact avatar', 'event_espresso' ),
20
+	__('contact avatar', 'event_espresso'),
21 21
 
22 22
 	// Reference: domains/blocks/src/components/OrderByControl.tsx:13
23
-	__( 'Order by', 'event_espresso' ),
23
+	__('Order by', 'event_espresso'),
24 24
 
25 25
 	// Reference: domains/blocks/src/components/RegStatusControl.tsx:18
26 26
 	// Reference: domains/blocks/src/event-attendees/controls/SelectStatus.tsx:12
27
-	__( 'Select Registration Status', 'event_espresso' ),
27
+	__('Select Registration Status', 'event_espresso'),
28 28
 
29 29
 	// Reference: domains/blocks/src/components/SortOrderControl.tsx:15
30
-	__( 'Ascending', 'event_espresso' ),
30
+	__('Ascending', 'event_espresso'),
31 31
 
32 32
 	// Reference: domains/blocks/src/components/SortOrderControl.tsx:19
33
-	__( 'Descending', 'event_espresso' ),
33
+	__('Descending', 'event_espresso'),
34 34
 
35 35
 	// Reference: domains/blocks/src/components/SortOrderControl.tsx:25
36
-	__( 'Sort order:', 'event_espresso' ),
36
+	__('Sort order:', 'event_espresso'),
37 37
 
38 38
 	// Reference: domains/blocks/src/event-attendees/AttendeesDisplay.tsx:40
39
-	__( 'There was some error fetching attendees list', 'event_espresso' ),
39
+	__('There was some error fetching attendees list', 'event_espresso'),
40 40
 
41 41
 	// Reference: domains/blocks/src/event-attendees/AttendeesDisplay.tsx:46
42
-	__( 'To get started, select what event you want to show attendees from in the block settings.', 'event_espresso' ),
42
+	__('To get started, select what event you want to show attendees from in the block settings.', 'event_espresso'),
43 43
 
44 44
 	// Reference: domains/blocks/src/event-attendees/AttendeesDisplay.tsx:52
45
-	__( 'There are no attendees for selected options.', 'event_espresso' ),
45
+	__('There are no attendees for selected options.', 'event_espresso'),
46 46
 
47 47
 	// Reference: domains/blocks/src/event-attendees/controls/ArchiveSettings.tsx:11
48
-	__( 'Display on Archives', 'event_espresso' ),
48
+	__('Display on Archives', 'event_espresso'),
49 49
 
50 50
 	// Reference: domains/blocks/src/event-attendees/controls/ArchiveSettings.tsx:16
51
-	__( 'Attendees are shown whenever this post is listed in an archive view.', 'event_espresso' ),
51
+	__('Attendees are shown whenever this post is listed in an archive view.', 'event_espresso'),
52 52
 
53 53
 	// Reference: domains/blocks/src/event-attendees/controls/ArchiveSettings.tsx:17
54
-	__( 'Attendees are hidden whenever this post is listed in an archive view.', 'event_espresso' ),
54
+	__('Attendees are hidden whenever this post is listed in an archive view.', 'event_espresso'),
55 55
 
56 56
 	// Reference: domains/blocks/src/event-attendees/controls/AttendeeLimit.tsx:28
57
-	__( 'Number of Attendees to Display:', 'event_espresso' ),
57
+	__('Number of Attendees to Display:', 'event_espresso'),
58 58
 
59 59
 	// Reference: domains/blocks/src/event-attendees/controls/AttendeeLimit.tsx:33
60 60
 	/* translators: %d attendees count */
61
-	_n_noop( 'Used to adjust the number of attendees displayed (There is %d total attendee for the current filter settings).', 'Used to adjust the number of attendees displayed (There are %d total attendees for the current filter settings).', 'event_espresso' ),
61
+	_n_noop('Used to adjust the number of attendees displayed (There is %d total attendee for the current filter settings).', 'Used to adjust the number of attendees displayed (There are %d total attendees for the current filter settings).', 'event_espresso'),
62 62
 
63 63
 	// Reference: domains/blocks/src/event-attendees/controls/GravatarSettings.tsx:26
64
-	__( 'Display Gravatar', 'event_espresso' ),
64
+	__('Display Gravatar', 'event_espresso'),
65 65
 
66 66
 	// Reference: domains/blocks/src/event-attendees/controls/GravatarSettings.tsx:31
67
-	__( 'Gravatar images are shown for each attendee.', 'event_espresso' ),
67
+	__('Gravatar images are shown for each attendee.', 'event_espresso'),
68 68
 
69 69
 	// Reference: domains/blocks/src/event-attendees/controls/GravatarSettings.tsx:32
70
-	__( 'No gravatar images are shown for each attendee.', 'event_espresso' ),
70
+	__('No gravatar images are shown for each attendee.', 'event_espresso'),
71 71
 
72 72
 	// Reference: domains/blocks/src/event-attendees/controls/GravatarSettings.tsx:37
73
-	__( 'Size of Gravatar', 'event_espresso' ),
73
+	__('Size of Gravatar', 'event_espresso'),
74 74
 
75 75
 	// Reference: domains/blocks/src/event-attendees/controls/SelectDatetime.tsx:21
76
-	__( 'Select Datetime', 'event_espresso' ),
76
+	__('Select Datetime', 'event_espresso'),
77 77
 
78 78
 	// Reference: domains/blocks/src/event-attendees/controls/SelectEvent.tsx:21
79
-	__( 'Select Event', 'event_espresso' ),
79
+	__('Select Event', 'event_espresso'),
80 80
 
81 81
 	// Reference: domains/blocks/src/event-attendees/controls/SelectOrderBy.tsx:10
82
-	__( 'Attendee id', 'event_espresso' ),
82
+	__('Attendee id', 'event_espresso'),
83 83
 
84 84
 	// Reference: domains/blocks/src/event-attendees/controls/SelectOrderBy.tsx:14
85
-	__( 'Last name only', 'event_espresso' ),
85
+	__('Last name only', 'event_espresso'),
86 86
 
87 87
 	// Reference: domains/blocks/src/event-attendees/controls/SelectOrderBy.tsx:18
88
-	__( 'First name only', 'event_espresso' ),
88
+	__('First name only', 'event_espresso'),
89 89
 
90 90
 	// Reference: domains/blocks/src/event-attendees/controls/SelectOrderBy.tsx:22
91
-	__( 'First, then Last name', 'event_espresso' ),
91
+	__('First, then Last name', 'event_espresso'),
92 92
 
93 93
 	// Reference: domains/blocks/src/event-attendees/controls/SelectOrderBy.tsx:26
94
-	__( 'Last, then First name', 'event_espresso' ),
94
+	__('Last, then First name', 'event_espresso'),
95 95
 
96 96
 	// Reference: domains/blocks/src/event-attendees/controls/SelectOrderBy.tsx:40
97
-	__( 'Order Attendees by:', 'event_espresso' ),
97
+	__('Order Attendees by:', 'event_espresso'),
98 98
 
99 99
 	// Reference: domains/blocks/src/event-attendees/controls/SelectTicket.tsx:21
100
-	__( 'Select Ticket', 'event_espresso' ),
100
+	__('Select Ticket', 'event_espresso'),
101 101
 
102 102
 	// Reference: domains/blocks/src/event-attendees/controls/index.tsx:22
103
-	__( 'Filter By Settings', 'event_espresso' ),
103
+	__('Filter By Settings', 'event_espresso'),
104 104
 
105 105
 	// Reference: domains/blocks/src/event-attendees/controls/index.tsx:37
106
-	__( 'Gravatar Setttings', 'event_espresso' ),
106
+	__('Gravatar Setttings', 'event_espresso'),
107 107
 
108 108
 	// Reference: domains/blocks/src/event-attendees/controls/index.tsx:40
109
-	__( 'Archive Settings', 'event_espresso' ),
109
+	__('Archive Settings', 'event_espresso'),
110 110
 
111 111
 	// Reference: domains/blocks/src/event-attendees/index.tsx:10
112
-	__( 'Event Attendees', 'event_espresso' ),
112
+	__('Event Attendees', 'event_espresso'),
113 113
 
114 114
 	// Reference: domains/blocks/src/event-attendees/index.tsx:11
115
-	__( 'Displays a list of people that have registered for the specified event', 'event_espresso' ),
115
+	__('Displays a list of people that have registered for the specified event', 'event_espresso'),
116 116
 
117 117
 	// Reference: domains/blocks/src/event-attendees/index.tsx:14
118
-	__( 'event', 'event_espresso' ),
118
+	__('event', 'event_espresso'),
119 119
 
120 120
 	// Reference: domains/blocks/src/event-attendees/index.tsx:14
121
-	__( 'attendees', 'event_espresso' ),
121
+	__('attendees', 'event_espresso'),
122 122
 
123 123
 	// Reference: domains/blocks/src/event-attendees/index.tsx:14
124
-	__( 'list', 'event_espresso' ),
124
+	__('list', 'event_espresso'),
125 125
 
126 126
 	// Reference: domains/blocks/src/services/utils.ts:11
127
-	__( 'Loading…', 'event_espresso' ),
127
+	__('Loading…', 'event_espresso'),
128 128
 
129 129
 	// Reference: domains/blocks/src/services/utils.ts:19
130 130
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:32
131
-	__( 'Error', 'event_espresso' ),
131
+	__('Error', 'event_espresso'),
132 132
 
133 133
 	// Reference: domains/blocks/src/services/utils.ts:26
134
-	__( 'Select…', 'event_espresso' ),
134
+	__('Select…', 'event_espresso'),
135 135
 
136 136
 	// Reference: domains/eventEditor/src/ui/EventRegistrationOptions/ActiveStatus.tsx:34
137
-	__( 'Active Status', 'event_espresso' ),
137
+	__('Active Status', 'event_espresso'),
138 138
 
139 139
 	// Reference: domains/eventEditor/src/ui/EventRegistrationOptions/AltRegPage.tsx:37
140
-	__( 'Alternative Registration Page', 'event_espresso' ),
140
+	__('Alternative Registration Page', 'event_espresso'),
141 141
 
142 142
 	// Reference: domains/eventEditor/src/ui/EventRegistrationOptions/DefaultRegistrationStatus.tsx:17
143
-	__( 'Default Registration Status', 'event_espresso' ),
143
+	__('Default Registration Status', 'event_espresso'),
144 144
 
145 145
 	// Reference: domains/eventEditor/src/ui/EventRegistrationOptions/Donations.tsx:19
146
-	__( 'Disable Donations', 'event_espresso' ),
146
+	__('Disable Donations', 'event_espresso'),
147 147
 
148 148
 	// Reference: domains/eventEditor/src/ui/EventRegistrationOptions/Donations.tsx:19
149
-	__( 'Enable Donations', 'event_espresso' ),
149
+	__('Enable Donations', 'event_espresso'),
150 150
 
151 151
 	// Reference: domains/eventEditor/src/ui/EventRegistrationOptions/EventManager.tsx:37
152
-	__( 'Event Manager', 'event_espresso' ),
152
+	__('Event Manager', 'event_espresso'),
153 153
 
154 154
 	// Reference: domains/eventEditor/src/ui/EventRegistrationOptions/EventPhoneNumber.tsx:26
155
-	__( 'Event Phone Number', 'event_espresso' ),
155
+	__('Event Phone Number', 'event_espresso'),
156 156
 
157 157
 	// Reference: domains/eventEditor/src/ui/EventRegistrationOptions/MaxRegistrations.tsx:35
158
-	__( 'Maximum Number of Registrations Allowed per Transaction', 'event_espresso' ),
158
+	__('Maximum Number of Registrations Allowed per Transaction', 'event_espresso'),
159 159
 
160 160
 	// Reference: domains/eventEditor/src/ui/EventRegistrationOptions/TicketSelector.tsx:20
161
-	__( 'hide ticket selector', 'event_espresso' ),
161
+	__('hide ticket selector', 'event_espresso'),
162 162
 
163 163
 	// Reference: domains/eventEditor/src/ui/EventRegistrationOptions/TicketSelector.tsx:20
164
-	__( 'show ticket selector', 'event_espresso' ),
164
+	__('show ticket selector', 'event_espresso'),
165 165
 
166 166
 	// Reference: domains/eventEditor/src/ui/EventRegistrationOptions/TicketSelector.tsx:24
167
-	__( 'Display Ticket Selector', 'event_espresso' ),
167
+	__('Display Ticket Selector', 'event_espresso'),
168 168
 
169 169
 	// Reference: domains/eventEditor/src/ui/EventRegistrationOptions/index.tsx:22
170
-	__( 'Registration Options', 'event_espresso' ),
170
+	__('Registration Options', 'event_espresso'),
171 171
 
172 172
 	// Reference: domains/eventEditor/src/ui/datetimes/DateRegistrationsLink.tsx:17
173
-	__( 'view ALL registrations for this date.', 'event_espresso' ),
173
+	__('view ALL registrations for this date.', 'event_espresso'),
174 174
 
175 175
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/formValidation.ts:15
176 176
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/formValidation.ts:15
177
-	__( 'Name is required', 'event_espresso' ),
177
+	__('Name is required', 'event_espresso'),
178 178
 
179 179
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/formValidation.ts:16
180 180
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/formValidation.ts:12
181 181
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/formValidation.ts:16
182 182
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/formValidation.ts:12
183
-	__( 'Name must be at least three characters', 'event_espresso' ),
183
+	__('Name must be at least three characters', 'event_espresso'),
184 184
 
185 185
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/Container.tsx:22
186 186
 	/* translators: %s datetime id */
187
-	__( 'Edit datetime %s', 'event_espresso' ),
187
+	__('Edit datetime %s', 'event_espresso'),
188 188
 
189 189
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/Container.tsx:25
190
-	__( 'New Datetime', 'event_espresso' ),
190
+	__('New Datetime', 'event_espresso'),
191 191
 
192 192
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/ContentBody.tsx:40
193
-	__( 'Save and assign tickets', 'event_espresso' ),
193
+	__('Save and assign tickets', 'event_espresso'),
194 194
 
195 195
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:11
196
-	__( 'primary information about the date', 'event_espresso' ),
196
+	__('primary information about the date', 'event_espresso'),
197 197
 
198 198
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:11
199
-	__( 'Date Details', 'event_espresso' ),
199
+	__('Date Details', 'event_espresso'),
200 200
 
201 201
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:12
202 202
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:17
203
-	__( 'relations between tickets and dates', 'event_espresso' ),
203
+	__('relations between tickets and dates', 'event_espresso'),
204 204
 
205 205
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:12
206
-	__( 'Assign Tickets', 'event_espresso' ),
206
+	__('Assign Tickets', 'event_espresso'),
207 207
 
208 208
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:102
209 209
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:63
210 210
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:115
211
-	__( 'End Date', 'event_espresso' ),
211
+	__('End Date', 'event_espresso'),
212 212
 
213 213
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:111
214 214
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:108
215 215
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:124
216 216
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:108
217
-	__( 'Details', 'event_espresso' ),
217
+	__('Details', 'event_espresso'),
218 218
 
219 219
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:115
220 220
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:112
221 221
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:75
222
-	__( 'Capacity', 'event_espresso' ),
222
+	__('Capacity', 'event_espresso'),
223 223
 
224 224
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:120
225
-	__( 'The maximum number of registrants that can attend the event at this particular date.', 'event_espresso' ),
225
+	__('The maximum number of registrants that can attend the event at this particular date.', 'event_espresso'),
226 226
 
227 227
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:124
228
-	__( 'Set to 0 to close registration or leave blank for no limit.', 'event_espresso' ),
228
+	__('Set to 0 to close registration or leave blank for no limit.', 'event_espresso'),
229 229
 
230 230
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:129
231 231
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:203
232
-	__( 'Trash', 'event_espresso' ),
232
+	__('Trash', 'event_espresso'),
233 233
 
234 234
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:73
235 235
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:45
236 236
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:86
237 237
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:45
238
-	__( 'Basics', 'event_espresso' ),
238
+	__('Basics', 'event_espresso'),
239 239
 
240 240
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:77
241 241
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:49
@@ -243,217 +243,217 @@  discard block
 block discarded – undo
243 243
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:90
244 244
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:49
245 245
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:42
246
-	__( 'Name', 'event_espresso' ),
246
+	__('Name', 'event_espresso'),
247 247
 
248 248
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:84
249 249
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:55
250 250
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:97
251 251
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:55
252 252
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:41
253
-	__( 'Description', 'event_espresso' ),
253
+	__('Description', 'event_espresso'),
254 254
 
255 255
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:92
256 256
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:63
257 257
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:63
258
-	__( 'Dates', 'event_espresso' ),
258
+	__('Dates', 'event_espresso'),
259 259
 
260 260
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:96
261 261
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:52
262 262
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:109
263
-	__( 'Start Date', 'event_espresso' ),
263
+	__('Start Date', 'event_espresso'),
264 264
 
265 265
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/DatesList.tsx:34
266 266
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/TableView.tsx:42
267
-	__( 'Event Dates', 'event_espresso' ),
267
+	__('Event Dates', 'event_espresso'),
268 268
 
269 269
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/DatesList.tsx:37
270
-	__( 'loading event dates…', 'event_espresso' ),
270
+	__('loading event dates…', 'event_espresso'),
271 271
 
272 272
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/DatesListButtons.tsx:22
273
-	__( 'Ticket Assignments', 'event_espresso' ),
273
+	__('Ticket Assignments', 'event_espresso'),
274 274
 
275 275
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:27
276
-	__( 'Number of related tickets', 'event_espresso' ),
276
+	__('Number of related tickets', 'event_espresso'),
277 277
 
278 278
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:28
279
-	__( 'There are no tickets assigned to this datetime. Please click the ticket icon to update the assignments.', 'event_espresso' ),
279
+	__('There are no tickets assigned to this datetime. Please click the ticket icon to update the assignments.', 'event_espresso'),
280 280
 
281 281
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:42
282
-	__( 'assign tickets', 'event_espresso' ),
282
+	__('assign tickets', 'event_espresso'),
283 283
 
284 284
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:19
285
-	__( 'Permanently delete Datetime?', 'event_espresso' ),
285
+	__('Permanently delete Datetime?', 'event_espresso'),
286 286
 
287 287
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:19
288
-	__( 'Move Datetime to Trash?', 'event_espresso' ),
288
+	__('Move Datetime to Trash?', 'event_espresso'),
289 289
 
290 290
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:21
291
-	__( 'Are you sure you want to permanently delete this datetime? This action is permanent and can not be undone.', 'event_espresso' ),
291
+	__('Are you sure you want to permanently delete this datetime? This action is permanent and can not be undone.', 'event_espresso'),
292 292
 
293 293
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:24
294
-	__( 'Are you sure you want to move this datetime to the trash? You can "untrash" this datetime later if you need to.', 'event_espresso' ),
294
+	__('Are you sure you want to move this datetime to the trash? You can "untrash" this datetime later if you need to.', 'event_espresso'),
295 295
 
296 296
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:34
297
-	__( 'event date main menu', 'event_espresso' ),
297
+	__('event date main menu', 'event_espresso'),
298 298
 
299 299
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:38
300 300
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:37
301
-	__( 'delete permanently', 'event_espresso' ),
301
+	__('delete permanently', 'event_espresso'),
302 302
 
303 303
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:38
304
-	__( 'trash datetime', 'event_espresso' ),
304
+	__('trash datetime', 'event_espresso'),
305 305
 
306 306
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:49
307
-	__( 'edit datetime', 'event_espresso' ),
307
+	__('edit datetime', 'event_espresso'),
308 308
 
309 309
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:50
310
-	__( 'copy datetime', 'event_espresso' ),
310
+	__('copy datetime', 'event_espresso'),
311 311
 
312 312
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:30
313
-	__( 'edit datetime details', 'event_espresso' ),
313
+	__('edit datetime details', 'event_espresso'),
314 314
 
315 315
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:34
316
-	__( 'delete datetimes', 'event_espresso' ),
316
+	__('delete datetimes', 'event_espresso'),
317 317
 
318 318
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:34
319
-	__( 'trash datetimes', 'event_espresso' ),
319
+	__('trash datetimes', 'event_espresso'),
320 320
 
321 321
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:13
322
-	__( 'Are you sure you want to permanently delete these datetimes? This action can NOT be undone!', 'event_espresso' ),
322
+	__('Are you sure you want to permanently delete these datetimes? This action can NOT be undone!', 'event_espresso'),
323 323
 
324 324
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:14
325
-	__( 'Are you sure you want to trash these datetimes?', 'event_espresso' ),
325
+	__('Are you sure you want to trash these datetimes?', 'event_espresso'),
326 326
 
327 327
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:15
328
-	__( 'Delete datetimes permanently', 'event_espresso' ),
328
+	__('Delete datetimes permanently', 'event_espresso'),
329 329
 
330 330
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:15
331
-	__( 'Trash datetimes', 'event_espresso' ),
331
+	__('Trash datetimes', 'event_espresso'),
332 332
 
333 333
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/EditDetails.tsx:22
334
-	__( 'Bulk edit date details', 'event_espresso' ),
334
+	__('Bulk edit date details', 'event_espresso'),
335 335
 
336 336
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/EditDetails.tsx:23
337
-	__( 'any changes will be applied to ALL of the selected dates.', 'event_espresso' ),
337
+	__('any changes will be applied to ALL of the selected dates.', 'event_espresso'),
338 338
 
339 339
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:67
340 340
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:67
341
-	__( 'Shift dates', 'event_espresso' ),
341
+	__('Shift dates', 'event_espresso'),
342 342
 
343 343
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:92
344 344
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:92
345
-	__( 'earlier', 'event_espresso' ),
345
+	__('earlier', 'event_espresso'),
346 346
 
347 347
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:96
348 348
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:96
349
-	__( 'later', 'event_espresso' ),
349
+	__('later', 'event_espresso'),
350 350
 
351 351
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/DateCapacity.tsx:35
352
-	__( 'edit capacity (registration limit)…', 'event_espresso' ),
352
+	__('edit capacity (registration limit)…', 'event_espresso'),
353 353
 
354 354
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:37
355
-	__( 'Edit Event Date', 'event_espresso' ),
355
+	__('Edit Event Date', 'event_espresso'),
356 356
 
357 357
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:40
358
-	__( 'edit start and end dates', 'event_espresso' ),
358
+	__('edit start and end dates', 'event_espresso'),
359 359
 
360 360
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:14
361 361
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:14
362
-	__( 'sold', 'event_espresso' ),
362
+	__('sold', 'event_espresso'),
363 363
 
364 364
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:27
365
-	__( 'capacity', 'event_espresso' ),
365
+	__('capacity', 'event_espresso'),
366 366
 
367 367
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:33
368 368
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:32
369
-	__( 'reg list', 'event_espresso' ),
369
+	__('reg list', 'event_espresso'),
370 370
 
371 371
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:42
372 372
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:40
373
-	__( 'Edit description', 'event_espresso' ),
373
+	__('Edit description', 'event_espresso'),
374 374
 
375 375
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:43
376 376
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:41
377
-	__( 'edit description…', 'event_espresso' ),
377
+	__('edit description…', 'event_espresso'),
378 378
 
379 379
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/config.ts:13
380
-	__( 'Active', 'event_espresso' ),
380
+	__('Active', 'event_espresso'),
381 381
 
382 382
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/config.ts:14
383 383
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/config.ts:13
384
-	__( 'Trashed', 'event_espresso' ),
384
+	__('Trashed', 'event_espresso'),
385 385
 
386 386
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/config.ts:15
387 387
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/config.ts:14
388
-	__( 'Expired', 'event_espresso' ),
388
+	__('Expired', 'event_espresso'),
389 389
 
390 390
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/config.ts:16
391 391
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/config.ts:16
392
-	__( 'Sold Out', 'event_espresso' ),
392
+	__('Sold Out', 'event_espresso'),
393 393
 
394 394
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/config.ts:17
395
-	__( 'Upcoming', 'event_espresso' ),
395
+	__('Upcoming', 'event_espresso'),
396 396
 
397 397
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/editable/EditableName.tsx:17
398 398
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/editable/EditableName.tsx:27
399
-	__( 'edit title…', 'event_espresso' ),
399
+	__('edit title…', 'event_espresso'),
400 400
 
401 401
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/ActiveDatesFilters.tsx:25
402 402
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/ActiveTicketsFilters.tsx:25
403
-	__( 'ON', 'event_espresso' ),
403
+	__('ON', 'event_espresso'),
404 404
 
405 405
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:10
406
-	__( 'end dates only', 'event_espresso' ),
406
+	__('end dates only', 'event_espresso'),
407 407
 
408 408
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:11
409
-	__( 'start and end dates', 'event_espresso' ),
409
+	__('start and end dates', 'event_espresso'),
410 410
 
411 411
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:16
412
-	__( 'dates above 90% capacity', 'event_espresso' ),
412
+	__('dates above 90% capacity', 'event_espresso'),
413 413
 
414 414
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:17
415
-	__( 'dates above 75% capacity', 'event_espresso' ),
415
+	__('dates above 75% capacity', 'event_espresso'),
416 416
 
417 417
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:18
418
-	__( 'dates above 50% capacity', 'event_espresso' ),
418
+	__('dates above 50% capacity', 'event_espresso'),
419 419
 
420 420
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:19
421
-	__( 'dates below 50% capacity', 'event_espresso' ),
421
+	__('dates below 50% capacity', 'event_espresso'),
422 422
 
423 423
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:23
424
-	__( 'all dates', 'event_espresso' ),
424
+	__('all dates', 'event_espresso'),
425 425
 
426 426
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:24
427
-	__( 'all active and upcoming', 'event_espresso' ),
427
+	__('all active and upcoming', 'event_espresso'),
428 428
 
429 429
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:25
430
-	__( 'active dates only', 'event_espresso' ),
430
+	__('active dates only', 'event_espresso'),
431 431
 
432 432
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:26
433
-	__( 'upcoming dates only', 'event_espresso' ),
433
+	__('upcoming dates only', 'event_espresso'),
434 434
 
435 435
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:27
436
-	__( 'next active or upcoming only', 'event_espresso' ),
436
+	__('next active or upcoming only', 'event_espresso'),
437 437
 
438 438
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:28
439
-	__( 'sold out dates only', 'event_espresso' ),
439
+	__('sold out dates only', 'event_espresso'),
440 440
 
441 441
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:29
442
-	__( 'recently expired dates', 'event_espresso' ),
442
+	__('recently expired dates', 'event_espresso'),
443 443
 
444 444
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:30
445
-	__( 'all expired dates', 'event_espresso' ),
445
+	__('all expired dates', 'event_espresso'),
446 446
 
447 447
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:31
448
-	__( 'trashed dates only', 'event_espresso' ),
448
+	__('trashed dates only', 'event_espresso'),
449 449
 
450 450
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:35
451 451
 	// Reference: packages/dates/src/DateRangePicker/DateRangePickerLegend.tsx:10
452 452
 	// Reference: packages/dates/src/DateRangePicker/index.tsx:42
453
-	__( 'start date', 'event_espresso' ),
453
+	__('start date', 'event_espresso'),
454 454
 
455 455
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:36
456
-	__( 'name', 'event_espresso' ),
456
+	__('name', 'event_espresso'),
457 457
 
458 458
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:37
459 459
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:38
@@ -461,103 +461,103 @@  discard block
 block discarded – undo
461 461
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/table/HeaderCell.tsx:20
462 462
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:36
463 463
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:23
464
-	__( 'ID', 'event_espresso' ),
464
+	__('ID', 'event_espresso'),
465 465
 
466 466
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:38
467 467
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:47
468
-	__( 'custom order', 'event_espresso' ),
468
+	__('custom order', 'event_espresso'),
469 469
 
470 470
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:42
471 471
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:52
472
-	__( 'display', 'event_espresso' ),
472
+	__('display', 'event_espresso'),
473 473
 
474 474
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:43
475
-	__( 'recurrence', 'event_espresso' ),
475
+	__('recurrence', 'event_espresso'),
476 476
 
477 477
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:44
478 478
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:54
479
-	__( 'sales', 'event_espresso' ),
479
+	__('sales', 'event_espresso'),
480 480
 
481 481
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:45
482 482
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:56
483
-	__( 'sort by', 'event_espresso' ),
483
+	__('sort by', 'event_espresso'),
484 484
 
485 485
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:46
486 486
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:55
487 487
 	// Reference: packages/components/src/EntityList/filterBar/EntityListFilterBar.tsx:73
488
-	__( 'search', 'event_espresso' ),
488
+	__('search', 'event_espresso'),
489 489
 
490 490
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:47
491 491
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:57
492
-	__( 'status', 'event_espresso' ),
492
+	__('status', 'event_espresso'),
493 493
 
494 494
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:9
495
-	__( 'start dates only', 'event_espresso' ),
495
+	__('start dates only', 'event_espresso'),
496 496
 
497 497
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:20
498 498
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/newDateOptions/NewDateModal.tsx:15
499 499
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/newDateOptions/OptionsModalButton.tsx:11
500
-	__( 'Add New Date', 'event_espresso' ),
500
+	__('Add New Date', 'event_espresso'),
501 501
 
502 502
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:20
503
-	__( 'Add Single Date', 'event_espresso' ),
503
+	__('Add Single Date', 'event_espresso'),
504 504
 
505 505
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:34
506
-	__( 'Add a single date that only occurs once', 'event_espresso' ),
506
+	__('Add a single date that only occurs once', 'event_espresso'),
507 507
 
508 508
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:36
509
-	__( 'Single Date', 'event_espresso' ),
509
+	__('Single Date', 'event_espresso'),
510 510
 
511 511
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:105
512 512
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:103
513 513
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:53
514
-	__( 'Actions', 'event_espresso' ),
514
+	__('Actions', 'event_espresso'),
515 515
 
516 516
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:53
517
-	__( 'Start', 'event_espresso' ),
517
+	__('Start', 'event_espresso'),
518 518
 
519 519
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:64
520
-	__( 'End', 'event_espresso' ),
520
+	__('End', 'event_espresso'),
521 521
 
522 522
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:76
523
-	__( 'Cap', 'event_espresso' ),
523
+	__('Cap', 'event_espresso'),
524 524
 
525 525
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:84
526 526
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:85
527
-	__( 'Sold', 'event_espresso' ),
527
+	__('Sold', 'event_espresso'),
528 528
 
529 529
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:93
530
-	__( 'Reg list', 'event_espresso' ),
530
+	__('Reg list', 'event_espresso'),
531 531
 
532 532
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:94
533 533
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:95
534
-	__( 'Regs', 'event_espresso' ),
534
+	__('Regs', 'event_espresso'),
535 535
 
536 536
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:18
537
-	__( 'Tickets must always have at least one date assigned to them but one or more of the tickets below does not have any. Please correct the assignments for the highlighted cells.', 'event_espresso' ),
537
+	__('Tickets must always have at least one date assigned to them but one or more of the tickets below does not have any. Please correct the assignments for the highlighted cells.', 'event_espresso'),
538 538
 
539 539
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:22
540
-	__( 'Event Dates must always have at least one Ticket assigned to them but one or more of the Event Dates below does not have any. Please correct the assignments for the highlighted cells.', 'event_espresso' ),
540
+	__('Event Dates must always have at least one Ticket assigned to them but one or more of the Event Dates below does not have any. Please correct the assignments for the highlighted cells.', 'event_espresso'),
541 541
 
542 542
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:25
543
-	__( 'There seem to be some dates/tickets which have no tickets/dates assigned. Do you want to fix them now?', 'event_espresso' ),
543
+	__('There seem to be some dates/tickets which have no tickets/dates assigned. Do you want to fix them now?', 'event_espresso'),
544 544
 
545 545
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:28
546 546
 	// Reference: packages/components/src/Modal/ModalWithAlert.tsx:23
547
-	__( 'Alert!', 'event_espresso' ),
547
+	__('Alert!', 'event_espresso'),
548 548
 
549 549
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:41
550 550
 	/* translators: 1 entity id, 2 entity name */
551
-	__( 'Ticket Assignment Manager for Datetime: %1$s - %2$s', 'event_espresso' ),
551
+	__('Ticket Assignment Manager for Datetime: %1$s - %2$s', 'event_espresso'),
552 552
 
553 553
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:48
554 554
 	/* translators: 1 entity id, 2 entity name */
555
-	__( 'Ticket Assignment Manager for Ticket: %1$s - %2$s', 'event_espresso' ),
555
+	__('Ticket Assignment Manager for Ticket: %1$s - %2$s', 'event_espresso'),
556 556
 
557 557
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/TicketAssignmentsManagerModal/buttons/useCancelButtonProps.tsx:18
558 558
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:16
559 559
 	// Reference: packages/components/src/Modal/useCancelButtonProps.tsx:10
560
-	__( 'Cancel', 'event_espresso' ),
560
+	__('Cancel', 'event_espresso'),
561 561
 
562 562
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/TicketAssignmentsManagerModal/buttons/useSubmitButtonProps.tsx:25
563 563
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:17
@@ -566,770 +566,770 @@  discard block
 block discarded – undo
566 566
 	// Reference: packages/components/src/bulkEdit/details/Submit.tsx:38
567 567
 	// Reference: packages/form/src/Submit.tsx:26
568 568
 	// Reference: packages/tpc/src/buttons/useSubmitButtonProps.tsx:25
569
-	__( 'Submit', 'event_espresso' ),
569
+	__('Submit', 'event_espresso'),
570 570
 
571 571
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/TicketAssignmentsManagerModal/index.tsx:30
572 572
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/table/Table.tsx:14
573
-	__( 'Ticket Assignment Manager', 'event_espresso' ),
573
+	__('Ticket Assignment Manager', 'event_espresso'),
574 574
 
575 575
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/table/BodyCell.tsx:24
576
-	__( 'assign ticket', 'event_espresso' ),
576
+	__('assign ticket', 'event_espresso'),
577 577
 
578 578
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/DatesByMonthControl.tsx:19
579
-	__( 'All Dates', 'event_espresso' ),
579
+	__('All Dates', 'event_espresso'),
580 580
 
581 581
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/DatesByMonthControl.tsx:26
582
-	__( 'dates by month', 'event_espresso' ),
582
+	__('dates by month', 'event_espresso'),
583 583
 
584 584
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowExpiredTicketsControl.tsx:14
585
-	__( 'show expired tickets', 'event_espresso' ),
585
+	__('show expired tickets', 'event_espresso'),
586 586
 
587 587
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowTrashedDatesControl.tsx:10
588
-	__( 'show trashed dates', 'event_espresso' ),
588
+	__('show trashed dates', 'event_espresso'),
589 589
 
590 590
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowTrashedTicketsControl.tsx:14
591
-	__( 'show trashed tickets', 'event_espresso' ),
591
+	__('show trashed tickets', 'event_espresso'),
592 592
 
593 593
 	// Reference: domains/eventEditor/src/ui/tickets/TicketRegistrationsLink.tsx:17
594
-	__( 'total registrations.', 'event_espresso' ),
594
+	__('total registrations.', 'event_espresso'),
595 595
 
596 596
 	// Reference: domains/eventEditor/src/ui/tickets/TicketRegistrationsLink.tsx:18
597
-	__( 'view ALL registrations for this ticket.', 'event_espresso' ),
597
+	__('view ALL registrations for this ticket.', 'event_espresso'),
598 598
 
599 599
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/Container.tsx:21
600 600
 	/* translators: %s ticket id */
601
-	__( 'Edit ticket %s', 'event_espresso' ),
601
+	__('Edit ticket %s', 'event_espresso'),
602 602
 
603 603
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/Container.tsx:24
604
-	__( 'New Ticket Details', 'event_espresso' ),
604
+	__('New Ticket Details', 'event_espresso'),
605 605
 
606 606
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/ContentBody.tsx:47
607
-	__( 'Set ticket prices', 'event_espresso' ),
607
+	__('Set ticket prices', 'event_espresso'),
608 608
 
609 609
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/ContentBody.tsx:54
610
-	__( 'Skip prices - assign dates', 'event_espresso' ),
610
+	__('Skip prices - assign dates', 'event_espresso'),
611 611
 
612 612
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/ContentBody.tsx:70
613
-	__( 'Save and assign dates', 'event_espresso' ),
613
+	__('Save and assign dates', 'event_espresso'),
614 614
 
615 615
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/ContentBody.tsx:83
616
-	__( 'Ticket details', 'event_espresso' ),
616
+	__('Ticket details', 'event_espresso'),
617 617
 
618 618
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:11
619
-	__( 'primary information about the ticket', 'event_espresso' ),
619
+	__('primary information about the ticket', 'event_espresso'),
620 620
 
621 621
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:11
622
-	__( 'Ticket Details', 'event_espresso' ),
622
+	__('Ticket Details', 'event_espresso'),
623 623
 
624 624
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:13
625
-	__( 'apply ticket price modifiers and taxes', 'event_espresso' ),
625
+	__('apply ticket price modifiers and taxes', 'event_espresso'),
626 626
 
627 627
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:15
628
-	__( 'Price Calculator', 'event_espresso' ),
628
+	__('Price Calculator', 'event_espresso'),
629 629
 
630 630
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:17
631
-	__( 'Assign Dates', 'event_espresso' ),
631
+	__('Assign Dates', 'event_espresso'),
632 632
 
633 633
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:105
634
-	__( 'Ticket Sales', 'event_espresso' ),
634
+	__('Ticket Sales', 'event_espresso'),
635 635
 
636 636
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:128
637 637
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:112
638
-	__( 'Quantity For Sale', 'event_espresso' ),
638
+	__('Quantity For Sale', 'event_espresso'),
639 639
 
640 640
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:134
641
-	__( 'The maximum number of this ticket available for sale.', 'event_espresso' ),
641
+	__('The maximum number of this ticket available for sale.', 'event_espresso'),
642 642
 
643 643
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:136
644
-	__( 'Set to 0 to stop sales, or leave blank for no limit.', 'event_espresso' ),
644
+	__('Set to 0 to stop sales, or leave blank for no limit.', 'event_espresso'),
645 645
 
646 646
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:141
647 647
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:121
648
-	__( 'Number of Uses', 'event_espresso' ),
648
+	__('Number of Uses', 'event_espresso'),
649 649
 
650 650
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:147
651
-	__( 'Controls the total number of times this ticket can be used, regardless of the number of dates it is assigned to.', 'event_espresso' ),
651
+	__('Controls the total number of times this ticket can be used, regardless of the number of dates it is assigned to.', 'event_espresso'),
652 652
 
653 653
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:151
654
-	__( 'Example: A ticket might have access to 4 different dates, but setting this field to 2 would mean that the ticket could only be used twice. Leave blank for no limit.', 'event_espresso' ),
654
+	__('Example: A ticket might have access to 4 different dates, but setting this field to 2 would mean that the ticket could only be used twice. Leave blank for no limit.', 'event_espresso'),
655 655
 
656 656
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:158
657 657
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:129
658
-	__( 'Minimum Quantity', 'event_espresso' ),
658
+	__('Minimum Quantity', 'event_espresso'),
659 659
 
660 660
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:163
661
-	__( 'The minimum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso' ),
661
+	__('The minimum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso'),
662 662
 
663 663
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:167
664
-	__( 'Leave blank for no minimum.', 'event_espresso' ),
664
+	__('Leave blank for no minimum.', 'event_espresso'),
665 665
 
666 666
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:172
667 667
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:137
668
-	__( 'Maximum Quantity', 'event_espresso' ),
668
+	__('Maximum Quantity', 'event_espresso'),
669 669
 
670 670
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:178
671
-	__( 'The maximum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso' ),
671
+	__('The maximum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso'),
672 672
 
673 673
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:182
674
-	__( 'Leave blank for no maximum.', 'event_espresso' ),
674
+	__('Leave blank for no maximum.', 'event_espresso'),
675 675
 
676 676
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:187
677 677
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:146
678
-	__( 'Required Ticket', 'event_espresso' ),
678
+	__('Required Ticket', 'event_espresso'),
679 679
 
680 680
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:189
681
-	__( 'If enabled, the ticket must be selected and will appear first in frontend ticket lists.', 'event_espresso' ),
681
+	__('If enabled, the ticket must be selected and will appear first in frontend ticket lists.', 'event_espresso'),
682 682
 
683 683
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:196
684
-	__( 'Default Ticket', 'event_espresso' ),
684
+	__('Default Ticket', 'event_espresso'),
685 685
 
686 686
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:198
687
-	__( 'If enabled, the ticket will appear on all new events.', 'event_espresso' ),
687
+	__('If enabled, the ticket will appear on all new events.', 'event_espresso'),
688 688
 
689 689
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/TicketsList.tsx:35
690
-	__( 'Available Tickets', 'event_espresso' ),
690
+	__('Available Tickets', 'event_espresso'),
691 691
 
692 692
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/TicketsList.tsx:38
693
-	__( 'loading tickets…', 'event_espresso' ),
693
+	__('loading tickets…', 'event_espresso'),
694 694
 
695 695
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:27
696
-	__( 'Number of related dates', 'event_espresso' ),
696
+	__('Number of related dates', 'event_espresso'),
697 697
 
698 698
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:28
699
-	__( 'There are no event dates assigned to this ticket. Please click the calendar icon to update the assignments.', 'event_espresso' ),
699
+	__('There are no event dates assigned to this ticket. Please click the calendar icon to update the assignments.', 'event_espresso'),
700 700
 
701 701
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:44
702
-	__( 'assign dates', 'event_espresso' ),
702
+	__('assign dates', 'event_espresso'),
703 703
 
704 704
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:19
705
-	__( 'Permanently delete Ticket?', 'event_espresso' ),
705
+	__('Permanently delete Ticket?', 'event_espresso'),
706 706
 
707 707
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:19
708
-	__( 'Move Ticket to Trash?', 'event_espresso' ),
708
+	__('Move Ticket to Trash?', 'event_espresso'),
709 709
 
710 710
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:21
711
-	__( 'Are you sure you want to permanently delete this ticket? This action is permanent and can not be undone.', 'event_espresso' ),
711
+	__('Are you sure you want to permanently delete this ticket? This action is permanent and can not be undone.', 'event_espresso'),
712 712
 
713 713
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:22
714
-	__( 'Are you sure you want to move this ticket to the trash? You can "untrash" this ticket later if you need to.', 'event_espresso' ),
714
+	__('Are you sure you want to move this ticket to the trash? You can "untrash" this ticket later if you need to.', 'event_espresso'),
715 715
 
716 716
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:33
717
-	__( 'ticket main menu', 'event_espresso' ),
717
+	__('ticket main menu', 'event_espresso'),
718 718
 
719 719
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:37
720
-	__( 'trash ticket', 'event_espresso' ),
720
+	__('trash ticket', 'event_espresso'),
721 721
 
722 722
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:48
723
-	__( 'edit ticket', 'event_espresso' ),
723
+	__('edit ticket', 'event_espresso'),
724 724
 
725 725
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:49
726
-	__( 'copy ticket', 'event_espresso' ),
726
+	__('copy ticket', 'event_espresso'),
727 727
 
728 728
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:39
729 729
 	// Reference: packages/components/src/bulkEdit/BulkActions.tsx:44
730
-	__( 'bulk actions', 'event_espresso' ),
730
+	__('bulk actions', 'event_espresso'),
731 731
 
732 732
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:43
733
-	__( 'edit ticket details', 'event_espresso' ),
733
+	__('edit ticket details', 'event_espresso'),
734 734
 
735 735
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:47
736
-	__( 'delete tickets', 'event_espresso' ),
736
+	__('delete tickets', 'event_espresso'),
737 737
 
738 738
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:47
739
-	__( 'trash tickets', 'event_espresso' ),
739
+	__('trash tickets', 'event_espresso'),
740 740
 
741 741
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:51
742
-	__( 'edit ticket prices', 'event_espresso' ),
742
+	__('edit ticket prices', 'event_espresso'),
743 743
 
744 744
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:13
745
-	__( 'Are you sure you want to permanently delete these tickets? This action can NOT be undone!', 'event_espresso' ),
745
+	__('Are you sure you want to permanently delete these tickets? This action can NOT be undone!', 'event_espresso'),
746 746
 
747 747
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:14
748
-	__( 'Are you sure you want to trash these tickets?', 'event_espresso' ),
748
+	__('Are you sure you want to trash these tickets?', 'event_espresso'),
749 749
 
750 750
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:15
751
-	__( 'Delete tickets permanently', 'event_espresso' ),
751
+	__('Delete tickets permanently', 'event_espresso'),
752 752
 
753 753
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:15
754
-	__( 'Trash tickets', 'event_espresso' ),
754
+	__('Trash tickets', 'event_espresso'),
755 755
 
756 756
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/EditDetails.tsx:22
757
-	__( 'Bulk edit ticket details', 'event_espresso' ),
757
+	__('Bulk edit ticket details', 'event_espresso'),
758 758
 
759 759
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/EditDetails.tsx:23
760
-	__( 'any changes will be applied to ALL of the selected tickets.', 'event_espresso' ),
760
+	__('any changes will be applied to ALL of the selected tickets.', 'event_espresso'),
761 761
 
762 762
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/EditPrices.tsx:18
763
-	__( 'Bulk edit ticket prices', 'event_espresso' ),
763
+	__('Bulk edit ticket prices', 'event_espresso'),
764 764
 
765 765
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:19
766
-	__( 'Edit all prices together', 'event_espresso' ),
766
+	__('Edit all prices together', 'event_espresso'),
767 767
 
768 768
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:20
769
-	__( 'Edit all the selected ticket prices dynamically', 'event_espresso' ),
769
+	__('Edit all the selected ticket prices dynamically', 'event_espresso'),
770 770
 
771 771
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:24
772
-	__( 'Edit prices individually', 'event_espresso' ),
772
+	__('Edit prices individually', 'event_espresso'),
773 773
 
774 774
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:25
775
-	__( 'Edit prices for each ticket individually', 'event_espresso' ),
775
+	__('Edit prices for each ticket individually', 'event_espresso'),
776 776
 
777 777
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:15
778 778
 	// Reference: packages/components/src/bulkEdit/details/Submit.tsx:45
779 779
 	// Reference: packages/form/src/ResetButton.tsx:17
780 780
 	// Reference: packages/tpc/src/buttons/useResetButtonProps.tsx:12
781
-	__( 'Reset', 'event_espresso' ),
781
+	__('Reset', 'event_espresso'),
782 782
 
783 783
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/editSeparately/TPCInstance.tsx:25
784 784
 	/* translators: %s ticket name */
785
-	__( 'Edit prices for Ticket: %s', 'event_espresso' ),
785
+	__('Edit prices for Ticket: %s', 'event_espresso'),
786 786
 
787 787
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:36
788
-	__( 'Edit Ticket Sale Dates', 'event_espresso' ),
788
+	__('Edit Ticket Sale Dates', 'event_espresso'),
789 789
 
790 790
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:38
791
-	__( 'edit ticket sales start and end dates', 'event_espresso' ),
791
+	__('edit ticket sales start and end dates', 'event_espresso'),
792 792
 
793 793
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:27
794
-	__( 'quantity', 'event_espresso' ),
794
+	__('quantity', 'event_espresso'),
795 795
 
796 796
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/TicketQuantity.tsx:26
797
-	__( 'edit quantity of tickets available…', 'event_espresso' ),
797
+	__('edit quantity of tickets available…', 'event_espresso'),
798 798
 
799 799
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/config.ts:15
800 800
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:51
801
-	__( 'On Sale', 'event_espresso' ),
801
+	__('On Sale', 'event_espresso'),
802 802
 
803 803
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/config.ts:17
804
-	__( 'Pending', 'event_espresso' ),
804
+	__('Pending', 'event_espresso'),
805 805
 
806 806
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/editable/EditablePrice.tsx:32
807
-	__( 'edit ticket total…', 'event_espresso' ),
807
+	__('edit ticket total…', 'event_espresso'),
808 808
 
809 809
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/editable/EditablePrice.tsx:42
810
-	__( 'set price…', 'event_espresso' ),
810
+	__('set price…', 'event_espresso'),
811 811
 
812 812
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/IsChainedButton.tsx:24
813
-	__( 'tickets list is linked to dates list and is showing tickets for above dates only', 'event_espresso' ),
813
+	__('tickets list is linked to dates list and is showing tickets for above dates only', 'event_espresso'),
814 814
 
815 815
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/IsChainedButton.tsx:25
816
-	__( 'tickets list is unlinked and is showing tickets for all event dates', 'event_espresso' ),
816
+	__('tickets list is unlinked and is showing tickets for all event dates', 'event_espresso'),
817 817
 
818 818
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:10
819
-	__( 'ticket sales start and end dates', 'event_espresso' ),
819
+	__('ticket sales start and end dates', 'event_espresso'),
820 820
 
821 821
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:15
822
-	__( 'tickets with 90% or more sold', 'event_espresso' ),
822
+	__('tickets with 90% or more sold', 'event_espresso'),
823 823
 
824 824
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:16
825
-	__( 'tickets with 75% or more sold', 'event_espresso' ),
825
+	__('tickets with 75% or more sold', 'event_espresso'),
826 826
 
827 827
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:17
828
-	__( 'tickets with 50% or more sold', 'event_espresso' ),
828
+	__('tickets with 50% or more sold', 'event_espresso'),
829 829
 
830 830
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:19
831
-	__( 'tickets with less than 50% sold', 'event_espresso' ),
831
+	__('tickets with less than 50% sold', 'event_espresso'),
832 832
 
833 833
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:28
834
-	__( 'all tickets for all dates', 'event_espresso' ),
834
+	__('all tickets for all dates', 'event_espresso'),
835 835
 
836 836
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:29
837
-	__( 'all on sale and sale pending', 'event_espresso' ),
837
+	__('all on sale and sale pending', 'event_espresso'),
838 838
 
839 839
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:30
840
-	__( 'on sale tickets only', 'event_espresso' ),
840
+	__('on sale tickets only', 'event_espresso'),
841 841
 
842 842
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:31
843
-	__( 'sale pending tickets only', 'event_espresso' ),
843
+	__('sale pending tickets only', 'event_espresso'),
844 844
 
845 845
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:32
846
-	__( 'next on sale or sale pending only', 'event_espresso' ),
846
+	__('next on sale or sale pending only', 'event_espresso'),
847 847
 
848 848
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:33
849
-	__( 'sold out tickets only', 'event_espresso' ),
849
+	__('sold out tickets only', 'event_espresso'),
850 850
 
851 851
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:34
852
-	__( 'expired tickets only', 'event_espresso' ),
852
+	__('expired tickets only', 'event_espresso'),
853 853
 
854 854
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:35
855
-	__( 'trashed tickets only', 'event_espresso' ),
855
+	__('trashed tickets only', 'event_espresso'),
856 856
 
857 857
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:40
858
-	__( 'all tickets for above dates', 'event_espresso' ),
858
+	__('all tickets for above dates', 'event_espresso'),
859 859
 
860 860
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:44
861
-	__( 'ticket sale date', 'event_espresso' ),
861
+	__('ticket sale date', 'event_espresso'),
862 862
 
863 863
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:45
864
-	__( 'ticket name', 'event_espresso' ),
864
+	__('ticket name', 'event_espresso'),
865 865
 
866 866
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:46
867
-	__( 'ticket ID', 'event_espresso' ),
867
+	__('ticket ID', 'event_espresso'),
868 868
 
869 869
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:53
870
-	__( 'link', 'event_espresso' ),
870
+	__('link', 'event_espresso'),
871 871
 
872 872
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:8
873
-	__( 'ticket sales start date only', 'event_espresso' ),
873
+	__('ticket sales start date only', 'event_espresso'),
874 874
 
875 875
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:9
876
-	__( 'ticket sales end date only', 'event_espresso' ),
876
+	__('ticket sales end date only', 'event_espresso'),
877 877
 
878 878
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:19
879
-	__( 'Add New Ticket', 'event_espresso' ),
879
+	__('Add New Ticket', 'event_espresso'),
880 880
 
881 881
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:31
882
-	__( 'Single Ticket', 'event_espresso' ),
882
+	__('Single Ticket', 'event_espresso'),
883 883
 
884 884
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:33
885
-	__( 'Add a single ticket and assign the dates to it', 'event_espresso' ),
885
+	__('Add a single ticket and assign the dates to it', 'event_espresso'),
886 886
 
887 887
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/TableView.tsx:40
888
-	__( 'Tickets', 'event_espresso' ),
888
+	__('Tickets', 'event_espresso'),
889 889
 
890 890
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:50
891
-	__( 'Goes on Sale', 'event_espresso' ),
891
+	__('Goes on Sale', 'event_espresso'),
892 892
 
893 893
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:61
894
-	__( 'Sale Ends', 'event_espresso' ),
894
+	__('Sale Ends', 'event_espresso'),
895 895
 
896 896
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:62
897
-	__( 'Ends', 'event_espresso' ),
897
+	__('Ends', 'event_espresso'),
898 898
 
899 899
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:71
900
-	__( 'Price', 'event_espresso' ),
900
+	__('Price', 'event_espresso'),
901 901
 
902 902
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:78
903
-	__( 'Quantity', 'event_espresso' ),
903
+	__('Quantity', 'event_espresso'),
904 904
 
905 905
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:94
906
-	__( 'Registrations', 'event_espresso' ),
906
+	__('Registrations', 'event_espresso'),
907 907
 
908 908
 	// Reference: domains/wpPluginsPage/src/exitSurvey/Popup.tsx:28
909
-	__( 'Do you have a moment to share why you are deactivating Event Espresso?', 'event_espresso' ),
909
+	__('Do you have a moment to share why you are deactivating Event Espresso?', 'event_espresso'),
910 910
 
911 911
 	// Reference: domains/wpPluginsPage/src/exitSurvey/Popup.tsx:39
912
-	__( 'Skip', 'event_espresso' ),
912
+	__('Skip', 'event_espresso'),
913 913
 
914 914
 	// Reference: domains/wpPluginsPage/src/exitSurvey/Popup.tsx:41
915
-	__( 'Sure I\'ll help', 'event_espresso' ),
915
+	__('Sure I\'ll help', 'event_espresso'),
916 916
 
917 917
 	// Reference: packages/adapters/src/Pagination/Pagination.tsx:24
918
-	__( 'pagination', 'event_espresso' ),
918
+	__('pagination', 'event_espresso'),
919 919
 
920 920
 	// Reference: packages/components/src/ActiveFilters/ActiveFilters.tsx:9
921
-	__( 'active filters:', 'event_espresso' ),
921
+	__('active filters:', 'event_espresso'),
922 922
 
923 923
 	// Reference: packages/components/src/ActiveFilters/FilterTag.tsx:11
924 924
 	/* translators: %s filter name */
925
-	__( 'remove filter - %s', 'event_espresso' ),
925
+	__('remove filter - %s', 'event_espresso'),
926 926
 
927 927
 	// Reference: packages/components/src/CalendarDateRange/CalendarDateRange.tsx:39
928
-	__( 'to', 'event_espresso' ),
928
+	__('to', 'event_espresso'),
929 929
 
930 930
 	// Reference: packages/components/src/CalendarDateSwitcher/CalendarDateSwitcher.tsx:33
931
-	__( 'starts', 'event_espresso' ),
931
+	__('starts', 'event_espresso'),
932 932
 
933 933
 	// Reference: packages/components/src/CalendarDateSwitcher/CalendarDateSwitcher.tsx:45
934
-	__( 'ends', 'event_espresso' ),
934
+	__('ends', 'event_espresso'),
935 935
 
936 936
 	// Reference: packages/components/src/CalendarPageDate/CalendarPageDate.tsx:57
937
-	__( 'TO', 'event_espresso' ),
937
+	__('TO', 'event_espresso'),
938 938
 
939 939
 	// Reference: packages/components/src/Confirm/ConfirmClose.tsx:8
940 940
 	// Reference: packages/components/src/Modal/ModalWithAlert.tsx:24
941
-	__( 'Are you sure you want to close this?', 'event_espresso' ),
941
+	__('Are you sure you want to close this?', 'event_espresso'),
942 942
 
943 943
 	// Reference: packages/components/src/Confirm/ConfirmDelete.tsx:8
944
-	__( 'Are you sure you want to delete this?', 'event_espresso' ),
944
+	__('Are you sure you want to delete this?', 'event_espresso'),
945 945
 
946 946
 	// Reference: packages/components/src/Confirm/useConfirmWithButton.tsx:11
947
-	__( 'Please confirm this action.', 'event_espresso' ),
947
+	__('Please confirm this action.', 'event_espresso'),
948 948
 
949 949
 	// Reference: packages/components/src/Confirm/useConfirmationDialog.tsx:32
950
-	__( 'No', 'event_espresso' ),
950
+	__('No', 'event_espresso'),
951 951
 
952 952
 	// Reference: packages/components/src/Confirm/useConfirmationDialog.tsx:33
953
-	__( 'Yes', 'event_espresso' ),
953
+	__('Yes', 'event_espresso'),
954 954
 
955 955
 	// Reference: packages/components/src/DateTimeRangePicker/index.tsx:74
956 956
 	// Reference: packages/components/src/Popover/PopoverForm/PopoverForm.tsx:42
957
-	__( 'save', 'event_espresso' ),
957
+	__('save', 'event_espresso'),
958 958
 
959 959
 	// Reference: packages/components/src/DebugInfo/DebugInfo.tsx:38
960
-	__( 'Hide Debug Info', 'event_espresso' ),
960
+	__('Hide Debug Info', 'event_espresso'),
961 961
 
962 962
 	// Reference: packages/components/src/DebugInfo/DebugInfo.tsx:38
963
-	__( 'Show Debug Info', 'event_espresso' ),
963
+	__('Show Debug Info', 'event_espresso'),
964 964
 
965 965
 	// Reference: packages/components/src/EditDateRangeButton/index.tsx:41
966
-	__( 'Edit Start and End Dates and Times', 'event_espresso' ),
966
+	__('Edit Start and End Dates and Times', 'event_espresso'),
967 967
 
968 968
 	// Reference: packages/components/src/EntityActionsMenu/entityMenuItems/Copy.tsx:9
969
-	__( 'copy', 'event_espresso' ),
969
+	__('copy', 'event_espresso'),
970 970
 
971 971
 	// Reference: packages/components/src/EntityActionsMenu/entityMenuItems/Edit.tsx:9
972
-	__( 'edit', 'event_espresso' ),
972
+	__('edit', 'event_espresso'),
973 973
 
974 974
 	// Reference: packages/components/src/EntityActionsMenu/entityMenuItems/Trash.tsx:9
975
-	__( 'trash', 'event_espresso' ),
975
+	__('trash', 'event_espresso'),
976 976
 
977 977
 	// Reference: packages/components/src/EntityDetailsPanel/EntityDetailsPanelSold.tsx:36
978
-	__( 'view approved registrations for this date.', 'event_espresso' ),
978
+	__('view approved registrations for this date.', 'event_espresso'),
979 979
 
980 980
 	// Reference: packages/components/src/EntityDetailsPanel/EntityDetailsPanelSold.tsx:37
981
-	__( 'view approved registrations for this ticket.', 'event_espresso' ),
981
+	__('view approved registrations for this ticket.', 'event_espresso'),
982 982
 
983 983
 	// Reference: packages/components/src/EntityList/EntityList.tsx:36
984
-	__( 'no results found', 'event_espresso' ),
984
+	__('no results found', 'event_espresso'),
985 985
 
986 986
 	// Reference: packages/components/src/EntityList/EntityList.tsx:37
987
-	__( 'try changing filter settings', 'event_espresso' ),
987
+	__('try changing filter settings', 'event_espresso'),
988 988
 
989 989
 	// Reference: packages/components/src/EntityList/filterBar/buttons/CardViewFilterButton.tsx:22
990
-	__( 'card view', 'event_espresso' ),
990
+	__('card view', 'event_espresso'),
991 991
 
992 992
 	// Reference: packages/components/src/EntityList/filterBar/buttons/TableViewFilterButton.tsx:22
993
-	__( 'table view', 'event_espresso' ),
993
+	__('table view', 'event_espresso'),
994 994
 
995 995
 	// Reference: packages/components/src/EntityList/filterBar/buttons/ToggleFiltersButton.tsx:11
996
-	__( 'hide filters', 'event_espresso' ),
996
+	__('hide filters', 'event_espresso'),
997 997
 
998 998
 	// Reference: packages/components/src/EntityList/filterBar/buttons/ToggleFiltersButton.tsx:11
999
-	__( 'show filters', 'event_espresso' ),
999
+	__('show filters', 'event_espresso'),
1000 1000
 
1001 1001
 	// Reference: packages/components/src/EntityList/filterBar/buttons/ToggleSortingButton.tsx:28
1002
-	__( 'disable sorting', 'event_espresso' ),
1002
+	__('disable sorting', 'event_espresso'),
1003 1003
 
1004 1004
 	// Reference: packages/components/src/EntityList/filterBar/buttons/ToggleSortingButton.tsx:28
1005
-	__( 'enable sorting', 'event_espresso' ),
1005
+	__('enable sorting', 'event_espresso'),
1006 1006
 
1007 1007
 	// Reference: packages/components/src/Legend/ToggleLegendButton.tsx:27
1008
-	__( 'hide legend', 'event_espresso' ),
1008
+	__('hide legend', 'event_espresso'),
1009 1009
 
1010 1010
 	// Reference: packages/components/src/Legend/ToggleLegendButton.tsx:27
1011
-	__( 'show legend', 'event_espresso' ),
1011
+	__('show legend', 'event_espresso'),
1012 1012
 
1013 1013
 	// Reference: packages/components/src/LoadingNotice/LoadingNotice.tsx:12
1014
-	__( 'loading…', 'event_espresso' ),
1014
+	__('loading…', 'event_espresso'),
1015 1015
 
1016 1016
 	// Reference: packages/components/src/Modal/Modal.tsx:59
1017
-	__( 'close modal', 'event_espresso' ),
1017
+	__('close modal', 'event_espresso'),
1018 1018
 
1019 1019
 	// Reference: packages/components/src/Pagination/ItemRender.tsx:10
1020
-	__( 'next', 'event_espresso' ),
1020
+	__('next', 'event_espresso'),
1021 1021
 
1022 1022
 	// Reference: packages/components/src/Pagination/ItemRender.tsx:11
1023
-	__( 'jump to previous', 'event_espresso' ),
1023
+	__('jump to previous', 'event_espresso'),
1024 1024
 
1025 1025
 	// Reference: packages/components/src/Pagination/ItemRender.tsx:12
1026
-	__( 'jump to next', 'event_espresso' ),
1026
+	__('jump to next', 'event_espresso'),
1027 1027
 
1028 1028
 	// Reference: packages/components/src/Pagination/ItemRender.tsx:13
1029
-	__( 'page', 'event_espresso' ),
1029
+	__('page', 'event_espresso'),
1030 1030
 
1031 1031
 	// Reference: packages/components/src/Pagination/ItemRender.tsx:9
1032
-	__( 'previous', 'event_espresso' ),
1032
+	__('previous', 'event_espresso'),
1033 1033
 
1034 1034
 	// Reference: packages/components/src/Pagination/PerPage.tsx:37
1035
-	__( 'items per page', 'event_espresso' ),
1035
+	__('items per page', 'event_espresso'),
1036 1036
 
1037 1037
 	// Reference: packages/components/src/Pagination/constants.ts:10
1038 1038
 	/* translators: %s is per page value */
1039
-	__( '%s / page', 'event_espresso' ),
1039
+	__('%s / page', 'event_espresso'),
1040 1040
 
1041 1041
 	// Reference: packages/components/src/Pagination/constants.ts:13
1042
-	__( 'Next Page', 'event_espresso' ),
1042
+	__('Next Page', 'event_espresso'),
1043 1043
 
1044 1044
 	// Reference: packages/components/src/Pagination/constants.ts:14
1045
-	__( 'Previous Page', 'event_espresso' ),
1045
+	__('Previous Page', 'event_espresso'),
1046 1046
 
1047 1047
 	// Reference: packages/components/src/PercentSign/index.tsx:11
1048
-	__( '%', 'event_espresso' ),
1048
+	__('%', 'event_espresso'),
1049 1049
 
1050 1050
 	// Reference: packages/components/src/Stepper/buttons/Next.tsx:12
1051
-	__( 'Next', 'event_espresso' ),
1051
+	__('Next', 'event_espresso'),
1052 1052
 
1053 1053
 	// Reference: packages/components/src/Stepper/buttons/Previous.tsx:12
1054
-	__( 'Previous', 'event_espresso' ),
1054
+	__('Previous', 'event_espresso'),
1055 1055
 
1056 1056
 	// Reference: packages/components/src/Steps/Steps.tsx:30
1057
-	__( 'Steps', 'event_espresso' ),
1057
+	__('Steps', 'event_espresso'),
1058 1058
 
1059 1059
 	// Reference: packages/components/src/TabbableText/index.tsx:19
1060
-	__( 'Click to edit…', 'event_espresso' ),
1060
+	__('Click to edit…', 'event_espresso'),
1061 1061
 
1062 1062
 	// Reference: packages/components/src/TimezoneTimeInfo/Content.tsx:16
1063
-	__( 'Your Local Time Zone', 'event_espresso' ),
1063
+	__('Your Local Time Zone', 'event_espresso'),
1064 1064
 
1065 1065
 	// Reference: packages/components/src/TimezoneTimeInfo/Content.tsx:21
1066
-	__( 'The Website\'s Time Zone', 'event_espresso' ),
1066
+	__('The Website\'s Time Zone', 'event_espresso'),
1067 1067
 
1068 1068
 	// Reference: packages/components/src/TimezoneTimeInfo/Content.tsx:26
1069
-	__( 'UTC (Greenwich Mean Time)', 'event_espresso' ),
1069
+	__('UTC (Greenwich Mean Time)', 'event_espresso'),
1070 1070
 
1071 1071
 	// Reference: packages/components/src/TimezoneTimeInfo/TimezoneTimeInfo.tsx:22
1072
-	__( 'This Date Converted To:', 'event_espresso' ),
1072
+	__('This Date Converted To:', 'event_espresso'),
1073 1073
 
1074 1074
 	// Reference: packages/components/src/TimezoneTimeInfo/TimezoneTimeInfo.tsx:23
1075
-	__( 'click for timezone information', 'event_espresso' ),
1075
+	__('click for timezone information', 'event_espresso'),
1076 1076
 
1077 1077
 	// Reference: packages/components/src/bulkEdit/ActionCheckbox.tsx:38
1078 1078
 	/* translators: %d entity id */
1079
-	__( 'select entity with id %d', 'event_espresso' ),
1079
+	__('select entity with id %d', 'event_espresso'),
1080 1080
 
1081 1081
 	// Reference: packages/components/src/bulkEdit/ActionCheckbox.tsx:41
1082
-	__( 'select all entities', 'event_espresso' ),
1082
+	__('select all entities', 'event_espresso'),
1083 1083
 
1084 1084
 	// Reference: packages/components/src/bulkEdit/BulkActions.tsx:52
1085
-	__( 'select all', 'event_espresso' ),
1085
+	__('select all', 'event_espresso'),
1086 1086
 
1087 1087
 	// Reference: packages/components/src/bulkEdit/BulkActions.tsx:54
1088
-	__( 'apply', 'event_espresso' ),
1088
+	__('apply', 'event_espresso'),
1089 1089
 
1090 1090
 	// Reference: packages/components/src/bulkEdit/details/BulkEditDetailsProps.tsx:20
1091
-	__( 'Note: ', 'event_espresso' ),
1091
+	__('Note: ', 'event_espresso'),
1092 1092
 
1093 1093
 	// Reference: packages/components/src/bulkEdit/details/BulkEditDetailsProps.tsx:20
1094
-	__( 'any changes will be applied to ALL of the selected entities.', 'event_espresso' ),
1094
+	__('any changes will be applied to ALL of the selected entities.', 'event_espresso'),
1095 1095
 
1096 1096
 	// Reference: packages/components/src/bulkEdit/details/BulkEditDetailsProps.tsx:26
1097
-	__( 'Bulk edit details', 'event_espresso' ),
1097
+	__('Bulk edit details', 'event_espresso'),
1098 1098
 
1099 1099
 	// Reference: packages/components/src/bulkEdit/details/Submit.tsx:28
1100
-	__( 'Are you sure you want to bulk update the details?', 'event_espresso' ),
1100
+	__('Are you sure you want to bulk update the details?', 'event_espresso'),
1101 1101
 
1102 1102
 	// Reference: packages/components/src/bulkEdit/details/Submit.tsx:29
1103
-	__( 'Bulk update details', 'event_espresso' ),
1103
+	__('Bulk update details', 'event_espresso'),
1104 1104
 
1105 1105
 	// Reference: packages/dates/src/DateRangePicker/DateRangePickerLegend.tsx:14
1106
-	__( 'day in range', 'event_espresso' ),
1106
+	__('day in range', 'event_espresso'),
1107 1107
 
1108 1108
 	// Reference: packages/dates/src/DateRangePicker/DateRangePickerLegend.tsx:18
1109 1109
 	// Reference: packages/dates/src/DateRangePicker/index.tsx:60
1110
-	__( 'end date', 'event_espresso' ),
1110
+	__('end date', 'event_espresso'),
1111 1111
 
1112 1112
 	// Reference: packages/dates/src/DateTimePicker.tsx:13
1113 1113
 	// Reference: packages/dates/src/TimePicker.tsx:14
1114
-	__( 'time', 'event_espresso' ),
1114
+	__('time', 'event_espresso'),
1115 1115
 
1116 1116
 	// Reference: packages/dates/src/constants.ts:5
1117
-	__( 'End Date & Time must be set later than the Start Date & Time', 'event_espresso' ),
1117
+	__('End Date & Time must be set later than the Start Date & Time', 'event_espresso'),
1118 1118
 
1119 1119
 	// Reference: packages/dates/src/constants.ts:7
1120
-	__( 'Start Date & Time must be set before the End Date & Time', 'event_espresso' ),
1120
+	__('Start Date & Time must be set before the End Date & Time', 'event_espresso'),
1121 1121
 
1122 1122
 	// Reference: packages/dates/src/utils/misc.ts:14
1123
-	__( 'month(s)', 'event_espresso' ),
1123
+	__('month(s)', 'event_espresso'),
1124 1124
 
1125 1125
 	// Reference: packages/dates/src/utils/misc.ts:15
1126
-	__( 'week(s)', 'event_espresso' ),
1126
+	__('week(s)', 'event_espresso'),
1127 1127
 
1128 1128
 	// Reference: packages/dates/src/utils/misc.ts:16
1129
-	__( 'day(s)', 'event_espresso' ),
1129
+	__('day(s)', 'event_espresso'),
1130 1130
 
1131 1131
 	// Reference: packages/dates/src/utils/misc.ts:17
1132
-	__( 'hour(s)', 'event_espresso' ),
1132
+	__('hour(s)', 'event_espresso'),
1133 1133
 
1134 1134
 	// Reference: packages/dates/src/utils/misc.ts:18
1135
-	__( 'minute(s)', 'event_espresso' ),
1135
+	__('minute(s)', 'event_espresso'),
1136 1136
 
1137 1137
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:104
1138
-	__( 'price types initialized', 'event_espresso' ),
1138
+	__('price types initialized', 'event_espresso'),
1139 1139
 
1140 1140
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:114
1141
-	__( 'datetimes initialized', 'event_espresso' ),
1141
+	__('datetimes initialized', 'event_espresso'),
1142 1142
 
1143 1143
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:124
1144
-	__( 'tickets initialized', 'event_espresso' ),
1144
+	__('tickets initialized', 'event_espresso'),
1145 1145
 
1146 1146
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:134
1147
-	__( 'prices initialized', 'event_espresso' ),
1147
+	__('prices initialized', 'event_espresso'),
1148 1148
 
1149 1149
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:22
1150
-	__( 'End date has been set one hour after start date', 'event_espresso' ),
1150
+	__('End date has been set one hour after start date', 'event_espresso'),
1151 1151
 
1152 1152
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:35
1153
-	__( 'Start date has been set one hour before end date', 'event_espresso' ),
1153
+	__('Start date has been set one hour before end date', 'event_espresso'),
1154 1154
 
1155 1155
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:47
1156
-	__( 'Required', 'event_espresso' ),
1156
+	__('Required', 'event_espresso'),
1157 1157
 
1158 1158
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:52
1159
-	__( 'Start Date is required', 'event_espresso' ),
1159
+	__('Start Date is required', 'event_espresso'),
1160 1160
 
1161 1161
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:56
1162
-	__( 'End Date is required', 'event_espresso' ),
1162
+	__('End Date is required', 'event_espresso'),
1163 1163
 
1164 1164
 	// Reference: packages/form/src/renderers/RepeatableRenderer.tsx:35
1165 1165
 	/* translators: %d the entry number */
1166
-	__( 'Entry %d', 'event_espresso' ),
1166
+	__('Entry %d', 'event_espresso'),
1167 1167
 
1168 1168
 	// Reference: packages/form/src/renderers/RepeatableRenderer.tsx:51
1169
-	__( 'Add', 'event_espresso' ),
1169
+	__('Add', 'event_espresso'),
1170 1170
 
1171 1171
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:11
1172 1172
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:17
1173
-	__( 'sold out', 'event_espresso' ),
1173
+	__('sold out', 'event_espresso'),
1174 1174
 
1175 1175
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:14
1176 1176
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:14
1177
-	__( 'expired', 'event_espresso' ),
1177
+	__('expired', 'event_espresso'),
1178 1178
 
1179 1179
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:17
1180
-	__( 'upcoming', 'event_espresso' ),
1180
+	__('upcoming', 'event_espresso'),
1181 1181
 
1182 1182
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:20
1183
-	__( 'active', 'event_espresso' ),
1183
+	__('active', 'event_espresso'),
1184 1184
 
1185 1185
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:23
1186 1186
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:11
1187
-	__( 'trashed', 'event_espresso' ),
1187
+	__('trashed', 'event_espresso'),
1188 1188
 
1189 1189
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:26
1190
-	__( 'cancelled', 'event_espresso' ),
1190
+	__('cancelled', 'event_espresso'),
1191 1191
 
1192 1192
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:29
1193
-	__( 'postponed', 'event_espresso' ),
1193
+	__('postponed', 'event_espresso'),
1194 1194
 
1195 1195
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:33
1196
-	__( 'inactive', 'event_espresso' ),
1196
+	__('inactive', 'event_espresso'),
1197 1197
 
1198 1198
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:20
1199
-	__( 'pending', 'event_espresso' ),
1199
+	__('pending', 'event_espresso'),
1200 1200
 
1201 1201
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:23
1202
-	__( 'on sale', 'event_espresso' ),
1202
+	__('on sale', 'event_espresso'),
1203 1203
 
1204 1204
 	// Reference: packages/predicates/src/registration/statusOptions.ts:10
1205
-	__( 'Cancelled', 'event_espresso' ),
1205
+	__('Cancelled', 'event_espresso'),
1206 1206
 
1207 1207
 	// Reference: packages/predicates/src/registration/statusOptions.ts:14
1208
-	__( 'Declined', 'event_espresso' ),
1208
+	__('Declined', 'event_espresso'),
1209 1209
 
1210 1210
 	// Reference: packages/predicates/src/registration/statusOptions.ts:18
1211
-	__( 'Incomplete', 'event_espresso' ),
1211
+	__('Incomplete', 'event_espresso'),
1212 1212
 
1213 1213
 	// Reference: packages/predicates/src/registration/statusOptions.ts:22
1214
-	__( 'Not Approved', 'event_espresso' ),
1214
+	__('Not Approved', 'event_espresso'),
1215 1215
 
1216 1216
 	// Reference: packages/predicates/src/registration/statusOptions.ts:26
1217
-	__( 'Pending Payment', 'event_espresso' ),
1217
+	__('Pending Payment', 'event_espresso'),
1218 1218
 
1219 1219
 	// Reference: packages/predicates/src/registration/statusOptions.ts:30
1220
-	__( 'Wait List', 'event_espresso' ),
1220
+	__('Wait List', 'event_espresso'),
1221 1221
 
1222 1222
 	// Reference: packages/predicates/src/registration/statusOptions.ts:6
1223
-	__( 'Approved', 'event_espresso' ),
1223
+	__('Approved', 'event_espresso'),
1224 1224
 
1225 1225
 	// Reference: packages/tpc/src/buttons/AddPriceModifierButton.tsx:15
1226
-	__( 'add new price modifier after this row', 'event_espresso' ),
1226
+	__('add new price modifier after this row', 'event_espresso'),
1227 1227
 
1228 1228
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:13
1229
-	__( 'Delete all prices', 'event_espresso' ),
1229
+	__('Delete all prices', 'event_espresso'),
1230 1230
 
1231 1231
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:26
1232
-	__( 'Are you sure you want to delete all of this ticket\'s prices and make it free? This action is permanent and can not be undone.', 'event_espresso' ),
1232
+	__('Are you sure you want to delete all of this ticket\'s prices and make it free? This action is permanent and can not be undone.', 'event_espresso'),
1233 1233
 
1234 1234
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:30
1235
-	__( 'Delete all prices?', 'event_espresso' ),
1235
+	__('Delete all prices?', 'event_espresso'),
1236 1236
 
1237 1237
 	// Reference: packages/tpc/src/buttons/DeletePriceModifierButton.tsx:12
1238
-	__( 'delete price modifier', 'event_espresso' ),
1238
+	__('delete price modifier', 'event_espresso'),
1239 1239
 
1240 1240
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:15
1241
-	__( 'Ticket base price is being reverse calculated from bottom to top starting with the ticket total. Entering a new ticket total will reverse calculate the ticket base price after applying all price modifiers in reverse. Click to turn off reverse calculations', 'event_espresso' ),
1241
+	__('Ticket base price is being reverse calculated from bottom to top starting with the ticket total. Entering a new ticket total will reverse calculate the ticket base price after applying all price modifiers in reverse. Click to turn off reverse calculations', 'event_espresso'),
1242 1242
 
1243 1243
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:18
1244
-	__( 'Ticket total is being calculated normally from top to bottom starting from the base price. Entering a new ticket base price will recalculate the ticket total after applying all price modifiers. Click to turn on reverse calculations', 'event_espresso' ),
1244
+	__('Ticket total is being calculated normally from top to bottom starting from the base price. Entering a new ticket base price will recalculate the ticket total after applying all price modifiers. Click to turn on reverse calculations', 'event_espresso'),
1245 1245
 
1246 1246
 	// Reference: packages/tpc/src/buttons/TicketPriceCalculatorButton.tsx:29
1247
-	__( 'ticket price calculator', 'event_espresso' ),
1247
+	__('ticket price calculator', 'event_espresso'),
1248 1248
 
1249 1249
 	// Reference: packages/tpc/src/buttons/taxes/AddDefaultTaxesButton.tsx:10
1250
-	__( 'Add default taxes', 'event_espresso' ),
1250
+	__('Add default taxes', 'event_espresso'),
1251 1251
 
1252 1252
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:11
1253
-	__( 'Are you sure you want to remove all of this ticket\'s taxes?', 'event_espresso' ),
1253
+	__('Are you sure you want to remove all of this ticket\'s taxes?', 'event_espresso'),
1254 1254
 
1255 1255
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:15
1256
-	__( 'Remove all taxes?', 'event_espresso' ),
1256
+	__('Remove all taxes?', 'event_espresso'),
1257 1257
 
1258 1258
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:8
1259
-	__( 'Remove taxes', 'event_espresso' ),
1259
+	__('Remove taxes', 'event_espresso'),
1260 1260
 
1261 1261
 	// Reference: packages/tpc/src/components/DefaultPricesInfo.tsx:28
1262
-	__( 'Modify default prices.', 'event_espresso' ),
1262
+	__('Modify default prices.', 'event_espresso'),
1263 1263
 
1264 1264
 	// Reference: packages/tpc/src/components/DefaultTaxesInfo.tsx:28
1265
-	__( 'New default taxes are available. Click the - Add default taxes - button to add them now.', 'event_espresso' ),
1265
+	__('New default taxes are available. Click the - Add default taxes - button to add them now.', 'event_espresso'),
1266 1266
 
1267 1267
 	// Reference: packages/tpc/src/components/NoPricesBanner/AddDefaultPricesButton.tsx:10
1268
-	__( 'Add default prices', 'event_espresso' ),
1268
+	__('Add default prices', 'event_espresso'),
1269 1269
 
1270 1270
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:14
1271
-	__( 'This Ticket is Currently Free', 'event_espresso' ),
1271
+	__('This Ticket is Currently Free', 'event_espresso'),
1272 1272
 
1273 1273
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:22
1274 1274
 	/* translators: %s default prices */
1275
-	__( 'Click the button below to load your %s into the calculator.', 'event_espresso' ),
1275
+	__('Click the button below to load your %s into the calculator.', 'event_espresso'),
1276 1276
 
1277 1277
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:23
1278
-	__( 'default prices', 'event_espresso' ),
1278
+	__('default prices', 'event_espresso'),
1279 1279
 
1280 1280
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:30
1281
-	__( 'Additional ticket price modifiers can be added or removed.', 'event_espresso' ),
1281
+	__('Additional ticket price modifiers can be added or removed.', 'event_espresso'),
1282 1282
 
1283 1283
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:33
1284
-	__( 'Click the save button below to assign which dates this ticket will be available for purchase on.', 'event_espresso' ),
1284
+	__('Click the save button below to assign which dates this ticket will be available for purchase on.', 'event_espresso'),
1285 1285
 
1286 1286
 	// Reference: packages/tpc/src/components/TicketPriceCalculatorModal.tsx:31
1287 1287
 	/* translators: %s ticket name */
1288
-	__( 'Price Calculator for Ticket: %s', 'event_espresso' ),
1288
+	__('Price Calculator for Ticket: %s', 'event_espresso'),
1289 1289
 
1290 1290
 	// Reference: packages/tpc/src/components/table/Table.tsx:43
1291
-	__( 'Ticket Price Calculator', 'event_espresso' ),
1291
+	__('Ticket Price Calculator', 'event_espresso'),
1292 1292
 
1293 1293
 	// Reference: packages/tpc/src/components/table/useFooterRowGenerator.tsx:41
1294
-	__( 'Total', 'event_espresso' ),
1294
+	__('Total', 'event_espresso'),
1295 1295
 
1296 1296
 	// Reference: packages/tpc/src/components/table/useFooterRowGenerator.tsx:50
1297
-	__( 'ticket total', 'event_espresso' ),
1297
+	__('ticket total', 'event_espresso'),
1298 1298
 
1299 1299
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:29
1300
-	__( 'Price Type', 'event_espresso' ),
1300
+	__('Price Type', 'event_espresso'),
1301 1301
 
1302 1302
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:35
1303
-	__( 'Label', 'event_espresso' ),
1303
+	__('Label', 'event_espresso'),
1304 1304
 
1305 1305
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:47
1306
-	__( 'Amount', 'event_espresso' ),
1306
+	__('Amount', 'event_espresso'),
1307 1307
 
1308 1308
 	// Reference: packages/tpc/src/inputs/PriceAmountInput.tsx:31
1309
-	__( 'amount', 'event_espresso' ),
1309
+	__('amount', 'event_espresso'),
1310 1310
 
1311 1311
 	// Reference: packages/tpc/src/inputs/PriceAmountInput.tsx:42
1312
-	__( 'amount…', 'event_espresso' ),
1312
+	__('amount…', 'event_espresso'),
1313 1313
 
1314 1314
 	// Reference: packages/tpc/src/inputs/PriceDescriptionInput.tsx:10
1315
-	__( 'price description', 'event_espresso' ),
1315
+	__('price description', 'event_espresso'),
1316 1316
 
1317 1317
 	// Reference: packages/tpc/src/inputs/PriceDescriptionInput.tsx:15
1318
-	__( 'description…', 'event_espresso' ),
1318
+	__('description…', 'event_espresso'),
1319 1319
 
1320 1320
 	// Reference: packages/tpc/src/inputs/PriceIdInput.tsx:9
1321
-	__( 'price id', 'event_espresso' ),
1321
+	__('price id', 'event_espresso'),
1322 1322
 
1323 1323
 	// Reference: packages/tpc/src/inputs/PriceNameInput.tsx:10
1324
-	__( 'price name', 'event_espresso' ),
1324
+	__('price name', 'event_espresso'),
1325 1325
 
1326 1326
 	// Reference: packages/tpc/src/inputs/PriceNameInput.tsx:15
1327
-	__( 'label…', 'event_espresso' ),
1327
+	__('label…', 'event_espresso'),
1328 1328
 
1329 1329
 	// Reference: packages/tpc/src/inputs/PriceTypeInput.tsx:16
1330
-	__( 'price type', 'event_espresso' ),
1330
+	__('price type', 'event_espresso'),
1331 1331
 
1332 1332
 	// Reference: packages/tpc/src/utils/constants.ts:13
1333
-	__( 'Ticket price modifications are blocked for Tickets that have already been sold to registrants, because doing so would negatively affect internal accounting for the event. If you still need to modify ticket prices, then create a copy of those tickets, edit the prices for the new tickets, and then archive the old tickets.', 'event_espresso' )
1333
+	__('Ticket price modifications are blocked for Tickets that have already been sold to registrants, because doing so would negatively affect internal accounting for the event. If you still need to modify ticket prices, then create a copy of those tickets, edit the prices for the new tickets, and then archive the old tickets.', 'event_espresso')
1334 1334
 );
1335 1335
 /* THIS IS THE END OF THE GENERATED FILE */
Please login to merge, or discard this patch.