Completed
Branch barista (839c56)
by
unknown
34:41 queued 25:41
created
core/db_models/EEM_Event.model.php 1 patch
Indentation   +915 added lines, -915 removed lines patch added patch discarded remove patch
@@ -15,919 +15,919 @@
 block discarded – undo
15 15
 class EEM_Event extends EEM_CPT_Base
16 16
 {
17 17
 
18
-    /**
19
-     * constant used by status(), indicating that no more tickets can be purchased for any of the datetimes for the
20
-     * event
21
-     */
22
-    const sold_out = 'sold_out';
23
-
24
-    /**
25
-     * constant used by status(), indicating that upcoming event dates have been postponed (may be pushed to a later
26
-     * date)
27
-     */
28
-    const postponed = 'postponed';
29
-
30
-    /**
31
-     * constant used by status(), indicating that the event will no longer occur
32
-     */
33
-    const cancelled = 'cancelled';
34
-
35
-
36
-    /**
37
-     * @var string
38
-     */
39
-    protected static $_default_reg_status;
40
-
41
-
42
-    /**
43
-     * This is the default for the additional limit field.
44
-     * @var int
45
-     */
46
-    protected static $_default_additional_limit = 10;
47
-
48
-
49
-    /**
50
-     * private instance of the Event object
51
-     *
52
-     * @var EEM_Event
53
-     */
54
-    protected static $_instance;
55
-
56
-
57
-
58
-
59
-    /**
60
-     * Adds a relationship to Term_Taxonomy for each CPT_Base
61
-     *
62
-     * @param string $timezone
63
-     * @throws \EE_Error
64
-     */
65
-    protected function __construct($timezone = null)
66
-    {
67
-        EE_Registry::instance()->load_model('Registration');
68
-        $this->singular_item = esc_html__('Event', 'event_espresso');
69
-        $this->plural_item = esc_html__('Events', 'event_espresso');
70
-        // to remove Cancelled events from the frontend, copy the following filter to your functions.php file
71
-        // add_filter( 'AFEE__EEM_Event__construct___custom_stati__cancelled__Public', '__return_false' );
72
-        // to remove Postponed events from the frontend, copy the following filter to your functions.php file
73
-        // add_filter( 'AFEE__EEM_Event__construct___custom_stati__postponed__Public', '__return_false' );
74
-        // to remove Sold Out events from the frontend, copy the following filter to your functions.php file
75
-        //  add_filter( 'AFEE__EEM_Event__construct___custom_stati__sold_out__Public', '__return_false' );
76
-        $this->_custom_stati = apply_filters(
77
-            'AFEE__EEM_Event__construct___custom_stati',
78
-            array(
79
-                EEM_Event::cancelled => array(
80
-                    'label'  => esc_html__('Cancelled', 'event_espresso'),
81
-                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__cancelled__Public', true),
82
-                ),
83
-                EEM_Event::postponed => array(
84
-                    'label'  => esc_html__('Postponed', 'event_espresso'),
85
-                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__postponed__Public', true),
86
-                ),
87
-                EEM_Event::sold_out  => array(
88
-                    'label'  => esc_html__('Sold Out', 'event_espresso'),
89
-                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__sold_out__Public', true),
90
-                ),
91
-            )
92
-        );
93
-        self::$_default_reg_status = empty(self::$_default_reg_status) ? EEM_Registration::status_id_pending_payment
94
-            : self::$_default_reg_status;
95
-        $this->_tables = array(
96
-            'Event_CPT'  => new EE_Primary_Table('posts', 'ID'),
97
-            'Event_Meta' => new EE_Secondary_Table('esp_event_meta', 'EVTM_ID', 'EVT_ID'),
98
-        );
99
-        $this->_fields = array(
100
-            'Event_CPT'  => array(
101
-                'EVT_ID'         => new EE_Primary_Key_Int_Field(
102
-                    'ID',
103
-                    esc_html__('Post ID for Event', 'event_espresso')
104
-                ),
105
-                'EVT_name'       => new EE_Plain_Text_Field(
106
-                    'post_title',
107
-                    esc_html__('Event Name', 'event_espresso'),
108
-                    false,
109
-                    ''
110
-                ),
111
-                'EVT_desc'       => new EE_Post_Content_Field(
112
-                    'post_content',
113
-                    esc_html__('Event Description', 'event_espresso'),
114
-                    false,
115
-                    ''
116
-                ),
117
-                'EVT_slug'       => new EE_Slug_Field(
118
-                    'post_name',
119
-                    esc_html__('Event Slug', 'event_espresso'),
120
-                    false,
121
-                    ''
122
-                ),
123
-                'EVT_created'    => new EE_Datetime_Field(
124
-                    'post_date',
125
-                    esc_html__('Date/Time Event Created', 'event_espresso'),
126
-                    false,
127
-                    EE_Datetime_Field::now
128
-                ),
129
-                'EVT_short_desc' => new EE_Simple_HTML_Field(
130
-                    'post_excerpt',
131
-                    esc_html__('Event Short Description', 'event_espresso'),
132
-                    false,
133
-                    ''
134
-                ),
135
-                'EVT_modified'   => new EE_Datetime_Field(
136
-                    'post_modified',
137
-                    esc_html__('Date/Time Event Modified', 'event_espresso'),
138
-                    false,
139
-                    EE_Datetime_Field::now
140
-                ),
141
-                'EVT_wp_user'    => new EE_WP_User_Field(
142
-                    'post_author',
143
-                    esc_html__('Event Creator ID', 'event_espresso'),
144
-                    false
145
-                ),
146
-                'parent'         => new EE_Integer_Field(
147
-                    'post_parent',
148
-                    esc_html__('Event Parent ID', 'event_espresso'),
149
-                    false,
150
-                    0
151
-                ),
152
-                'EVT_order'      => new EE_Integer_Field(
153
-                    'menu_order',
154
-                    esc_html__('Event Menu Order', 'event_espresso'),
155
-                    false,
156
-                    1
157
-                ),
158
-                'post_type'      => new EE_WP_Post_Type_Field('espresso_events'),
159
-                // EE_Plain_Text_Field( 'post_type', esc_html__( 'Event Post Type', 'event_espresso' ), FALSE, 'espresso_events' ),
160
-                'status'         => new EE_WP_Post_Status_Field(
161
-                    'post_status',
162
-                    esc_html__('Event Status', 'event_espresso'),
163
-                    false,
164
-                    'draft',
165
-                    $this->_custom_stati
166
-                ),
167
-                'password' => new EE_Password_Field(
168
-                    'post_password',
169
-                    __('Password', 'event_espresso'),
170
-                    false,
171
-                    '',
172
-                    array(
173
-                        'EVT_desc',
174
-                        'EVT_short_desc',
175
-                        'EVT_display_desc',
176
-                        'EVT_display_ticket_selector',
177
-                        'EVT_visible_on',
178
-                        'EVT_additional_limit',
179
-                        'EVT_default_registration_status',
180
-                        'EVT_member_only',
181
-                        'EVT_phone',
182
-                        'EVT_allow_overflow',
183
-                        'EVT_timezone_string',
184
-                        'EVT_external_URL',
185
-                        'EVT_donations'
186
-                    )
187
-                )
188
-            ),
189
-            'Event_Meta' => array(
190
-                'EVTM_ID'                         => new EE_DB_Only_Float_Field(
191
-                    'EVTM_ID',
192
-                    esc_html__('Event Meta Row ID', 'event_espresso'),
193
-                    false
194
-                ),
195
-                'EVT_ID_fk'                       => new EE_DB_Only_Int_Field(
196
-                    'EVT_ID',
197
-                    esc_html__('Foreign key to Event ID from Event Meta table', 'event_espresso'),
198
-                    false
199
-                ),
200
-                'EVT_display_desc'                => new EE_Boolean_Field(
201
-                    'EVT_display_desc',
202
-                    esc_html__('Display Description Flag', 'event_espresso'),
203
-                    false,
204
-                    true
205
-                ),
206
-                'EVT_display_ticket_selector'     => new EE_Boolean_Field(
207
-                    'EVT_display_ticket_selector',
208
-                    esc_html__('Display Ticket Selector Flag', 'event_espresso'),
209
-                    false,
210
-                    true
211
-                ),
212
-                'EVT_visible_on'                  => new EE_Datetime_Field(
213
-                    'EVT_visible_on',
214
-                    esc_html__('Event Visible Date', 'event_espresso'),
215
-                    true,
216
-                    EE_Datetime_Field::now
217
-                ),
218
-                'EVT_additional_limit'            => new EE_Integer_Field(
219
-                    'EVT_additional_limit',
220
-                    esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
221
-                    true,
222
-                    self::$_default_additional_limit
223
-                ),
224
-                'EVT_default_registration_status' => new EE_Enum_Text_Field(
225
-                    'EVT_default_registration_status',
226
-                    esc_html__('Default Registration Status on this Event', 'event_espresso'),
227
-                    false,
228
-                    EEM_Event::$_default_reg_status,
229
-                    EEM_Registration::reg_status_array()
230
-                ),
231
-                'EVT_member_only'                 => new EE_Boolean_Field(
232
-                    'EVT_member_only',
233
-                    esc_html__('Member-Only Event Flag', 'event_espresso'),
234
-                    false,
235
-                    false
236
-                ),
237
-                'EVT_phone'                       => new EE_Plain_Text_Field(
238
-                    'EVT_phone',
239
-                    esc_html__('Event Phone Number', 'event_espresso'),
240
-                    false,
241
-                    ''
242
-                ),
243
-                'EVT_allow_overflow'              => new EE_Boolean_Field(
244
-                    'EVT_allow_overflow',
245
-                    esc_html__('Allow Overflow on Event', 'event_espresso'),
246
-                    false,
247
-                    false
248
-                ),
249
-                'EVT_timezone_string'             => new EE_Plain_Text_Field(
250
-                    'EVT_timezone_string',
251
-                    esc_html__('Timezone (name) for Event times', 'event_espresso'),
252
-                    false,
253
-                    ''
254
-                ),
255
-                'EVT_external_URL'                => new EE_Plain_Text_Field(
256
-                    'EVT_external_URL',
257
-                    esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso'),
258
-                    true
259
-                ),
260
-                'EVT_donations'                   => new EE_Boolean_Field(
261
-                    'EVT_donations',
262
-                    esc_html__('Accept Donations?', 'event_espresso'),
263
-                    false,
264
-                    false
265
-                ),
266
-            ),
267
-        );
268
-        $this->_model_relations = array(
269
-            'Registration'           => new EE_Has_Many_Relation(),
270
-            'Datetime'               => new EE_Has_Many_Relation(),
271
-            'Question_Group'         => new EE_HABTM_Relation('Event_Question_Group'),
272
-            'Event_Question_Group'   => new EE_Has_Many_Relation(),
273
-            'Venue'                  => new EE_HABTM_Relation('Event_Venue'),
274
-            'Term_Relationship'      => new EE_Has_Many_Relation(),
275
-            'Term_Taxonomy'          => new EE_HABTM_Relation('Term_Relationship'),
276
-            'Message_Template_Group' => new EE_HABTM_Relation('Event_Message_Template'),
277
-            'Attendee'               => new EE_HABTM_Relation('Registration'),
278
-            'WP_User'                => new EE_Belongs_To_Relation(),
279
-        );
280
-        // this model is generally available for reading
281
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public();
282
-        $this->model_chain_to_password = '';
283
-        parent::__construct($timezone);
284
-    }
285
-
286
-
287
-
288
-    /**
289
-     * @param string $default_reg_status
290
-     */
291
-    public static function set_default_reg_status($default_reg_status)
292
-    {
293
-        self::$_default_reg_status = $default_reg_status;
294
-        // if EEM_Event has already been instantiated,
295
-        // then we need to reset the `EVT_default_reg_status` field to use the new default.
296
-        if (self::$_instance instanceof EEM_Event) {
297
-            $default_reg_status = new EE_Enum_Text_Field(
298
-                'EVT_default_registration_status',
299
-                esc_html__('Default Registration Status on this Event', 'event_espresso'),
300
-                false,
301
-                $default_reg_status,
302
-                EEM_Registration::reg_status_array()
303
-            );
304
-            $default_reg_status->_construct_finalize(
305
-                'Event_Meta',
306
-                'EVT_default_registration_status',
307
-                'EEM_Event'
308
-            );
309
-            self::$_instance->_fields['Event_Meta']['EVT_default_registration_status'] = $default_reg_status;
310
-        }
311
-    }
312
-
313
-
314
-    /**
315
-     * Used to override the default for the additional limit field.
316
-     * @param $additional_limit
317
-     */
318
-    public static function set_default_additional_limit($additional_limit)
319
-    {
320
-        self::$_default_additional_limit = (int) $additional_limit;
321
-        if (self::$_instance instanceof EEM_Event) {
322
-            self::$_instance->_fields['Event_Meta']['EVT_additional_limit'] = new EE_Integer_Field(
323
-                'EVT_additional_limit',
324
-                __('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
325
-                true,
326
-                self::$_default_additional_limit
327
-            );
328
-            self::$_instance->_fields['Event_Meta']['EVT_additional_limit']->_construct_finalize(
329
-                'Event_Meta',
330
-                'EVT_additional_limit',
331
-                'EEM_Event'
332
-            );
333
-        }
334
-    }
335
-
336
-
337
-    /**
338
-     * Return what is currently set as the default additional limit for the event.
339
-     * @return int
340
-     */
341
-    public static function get_default_additional_limit()
342
-    {
343
-        return apply_filters('FHEE__EEM_Event__get_default_additional_limit', self::$_default_additional_limit);
344
-    }
345
-
346
-
347
-    /**
348
-     * get_question_groups
349
-     *
350
-     * @return array
351
-     * @throws \EE_Error
352
-     */
353
-    public function get_all_question_groups()
354
-    {
355
-        return EE_Registry::instance()->load_model('Question_Group')->get_all(
356
-            array(
357
-                array('QSG_deleted' => false),
358
-                'order_by' => array('QSG_order' => 'ASC'),
359
-            )
360
-        );
361
-    }
362
-
363
-
364
-
365
-    /**
366
-     * get_question_groups
367
-     *
368
-     * @param int $EVT_ID
369
-     * @return array|bool
370
-     * @throws \EE_Error
371
-     */
372
-    public function get_all_event_question_groups($EVT_ID = 0)
373
-    {
374
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
375
-            EE_Error::add_error(
376
-                esc_html__(
377
-                    'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
378
-                    'event_espresso'
379
-                ),
380
-                __FILE__,
381
-                __FUNCTION__,
382
-                __LINE__
383
-            );
384
-            return false;
385
-        }
386
-        return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(
387
-            array(
388
-                array('EVT_ID' => $EVT_ID),
389
-            )
390
-        );
391
-    }
392
-
393
-
394
-    /**
395
-     * get_question_groups
396
-     *
397
-     * @param int $EVT_ID
398
-     * @param boolean $for_primary_attendee
399
-     * @return array|bool
400
-     * @throws EE_Error
401
-     * @throws InvalidArgumentException
402
-     * @throws ReflectionException
403
-     * @throws InvalidDataTypeException
404
-     * @throws InvalidInterfaceException
405
-     */
406
-    public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true)
407
-    {
408
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
409
-            EE_Error::add_error(
410
-                esc_html__(
411
-                    // @codingStandardsIgnoreStart
412
-                    'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
413
-                    // @codingStandardsIgnoreEnd
414
-                    'event_espresso'
415
-                ),
416
-                __FILE__,
417
-                __FUNCTION__,
418
-                __LINE__
419
-            );
420
-            return false;
421
-        }
422
-        $query_params = [
423
-            [
424
-                'EVT_ID' => $EVT_ID,
425
-                EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary_attendee) => true
426
-            ]
427
-        ];
428
-        if ($for_primary_attendee) {
429
-            $query_params[0]['EQG_primary'] = true;
430
-        } else {
431
-            $query_params[0]['EQG_additional'] = true;
432
-        }
433
-        return EE_Registry::instance()->load_model('Event_Question_Group')->get_all($query_params);
434
-    }
435
-
436
-
437
-    /**
438
-     * get_question_groups
439
-     *
440
-     * @param int $EVT_ID
441
-     * @param EE_Registration $registration
442
-     * @return array|bool
443
-     * @throws EE_Error
444
-     * @throws InvalidArgumentException
445
-     * @throws InvalidDataTypeException
446
-     * @throws InvalidInterfaceException
447
-     * @throws ReflectionException
448
-     */
449
-    public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration)
450
-    {
451
-        if (! isset($EVT_ID) || ! absint($EVT_ID)) {
452
-            EE_Error::add_error(
453
-                esc_html__(
454
-                    'An error occurred. No Question Groups could be retrieved because an Event ID was not received.',
455
-                    'event_espresso'
456
-                ),
457
-                __FILE__,
458
-                __FUNCTION__,
459
-                __LINE__
460
-            );
461
-            return false;
462
-        }
463
-        return EE_Registry::instance()->load_model('Question_Group')->get_all(
464
-            [
465
-                [
466
-                    'Event_Question_Group.EVT_ID'      => $EVT_ID,
467
-                    'Event_Question_Group.'
468
-                        . EEM_Event_Question_Group::instance()->fieldNameForContext(
469
-                            $registration->is_primary_registrant()
470
-                        ) => true
471
-                ],
472
-                'order_by' => ['QSG_order' => 'ASC'],
473
-            ]
474
-        );
475
-    }
476
-
477
-
478
-
479
-    /**
480
-     * get_question_target_db_column
481
-     *
482
-     * @param string $QSG_IDs csv list of $QSG IDs
483
-     * @return array|bool
484
-     * @throws \EE_Error
485
-     */
486
-    public function get_questions_in_groups($QSG_IDs = '')
487
-    {
488
-        if (empty($QSG_IDs)) {
489
-            EE_Error::add_error(
490
-                esc_html__('An error occurred. No Question Group IDs were received.', 'event_espresso'),
491
-                __FILE__,
492
-                __FUNCTION__,
493
-                __LINE__
494
-            );
495
-            return false;
496
-        }
497
-        return EE_Registry::instance()->load_model('Question')->get_all(
498
-            array(
499
-                array(
500
-                    'Question_Group.QSG_ID' => array('IN', $QSG_IDs),
501
-                    'QST_deleted'           => false,
502
-                    'QST_admin_only'        => is_admin(),
503
-                ),
504
-                'order_by' => 'QST_order',
505
-            )
506
-        );
507
-    }
508
-
509
-
510
-
511
-    /**
512
-     * get_options_for_question
513
-     *
514
-     * @param string $QST_IDs csv list of $QST IDs
515
-     * @return array|bool
516
-     * @throws \EE_Error
517
-     */
518
-    public function get_options_for_question($QST_IDs)
519
-    {
520
-        if (empty($QST_IDs)) {
521
-            EE_Error::add_error(
522
-                esc_html__('An error occurred. No Question IDs were received.', 'event_espresso'),
523
-                __FILE__,
524
-                __FUNCTION__,
525
-                __LINE__
526
-            );
527
-            return false;
528
-        }
529
-        return EE_Registry::instance()->load_model('Question_Option')->get_all(
530
-            array(
531
-                array(
532
-                    'Question.QST_ID' => array('IN', $QST_IDs),
533
-                    'QSO_deleted'     => false,
534
-                ),
535
-                'order_by' => 'QSO_ID',
536
-            )
537
-        );
538
-    }
539
-
540
-
541
-
542
-
543
-
544
-
545
-
546
-    /**
547
-     * Gets all events that are published
548
-     * and have event start time earlier than now and an event end time later than now
549
-     *
550
-     * @param  array $query_params An array of query params to further filter on
551
-     *                             (note that status and DTT_EVT_start and DTT_EVT_end will be overridden)
552
-     * @param bool   $count        whether to return the count or not (default FALSE)
553
-     * @return EE_Event[]|int
554
-     * @throws \EE_Error
555
-     */
556
-    public function get_active_events($query_params, $count = false)
557
-    {
558
-        if (array_key_exists(0, $query_params)) {
559
-            $where_params = $query_params[0];
560
-            unset($query_params[0]);
561
-        } else {
562
-            $where_params = array();
563
-        }
564
-        // if we have count make sure we don't include group by
565
-        if ($count && isset($query_params['group_by'])) {
566
-            unset($query_params['group_by']);
567
-        }
568
-        // let's add specific query_params for active_events
569
-        // keep in mind this will override any sent status in the query AND any date queries.
570
-        $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
571
-        // if already have where params for DTT_EVT_start or DTT_EVT_end then append these conditions
572
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
573
-            $where_params['Datetime.DTT_EVT_start******'] = array(
574
-                '<',
575
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
576
-            );
577
-        } else {
578
-            $where_params['Datetime.DTT_EVT_start'] = array(
579
-                '<',
580
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
581
-            );
582
-        }
583
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
584
-            $where_params['Datetime.DTT_EVT_end*****'] = array(
585
-                '>',
586
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
587
-            );
588
-        } else {
589
-            $where_params['Datetime.DTT_EVT_end'] = array(
590
-                '>',
591
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
592
-            );
593
-        }
594
-        $query_params[0] = $where_params;
595
-        // don't use $query_params with count()
596
-        // because we don't want to include additional query clauses like "GROUP BY"
597
-        return $count
598
-            ? $this->count(array($where_params), 'EVT_ID', true)
599
-            : $this->get_all($query_params);
600
-    }
601
-
602
-
603
-
604
-    /**
605
-     * get all events that are published and have an event start time later than now
606
-     *
607
-     * @param  array $query_params An array of query params to further filter on
608
-     *                             (Note that status and DTT_EVT_start will be overridden)
609
-     * @param bool   $count        whether to return the count or not (default FALSE)
610
-     * @return EE_Event[]|int
611
-     * @throws \EE_Error
612
-     */
613
-    public function get_upcoming_events($query_params, $count = false)
614
-    {
615
-        if (array_key_exists(0, $query_params)) {
616
-            $where_params = $query_params[0];
617
-            unset($query_params[0]);
618
-        } else {
619
-            $where_params = array();
620
-        }
621
-        // if we have count make sure we don't include group by
622
-        if ($count && isset($query_params['group_by'])) {
623
-            unset($query_params['group_by']);
624
-        }
625
-        // let's add specific query_params for active_events
626
-        // keep in mind this will override any sent status in the query AND any date queries.
627
-        // we need to pull events with a status of publish and sold_out
628
-        $event_status = array('publish', EEM_Event::sold_out);
629
-        // check if the user can read private events and if so add the 'private status to the were params'
630
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_upcoming_events')) {
631
-            $event_status[] = 'private';
632
-        }
633
-        $where_params['status'] = array('IN', $event_status);
634
-        // if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
635
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
636
-            $where_params['Datetime.DTT_EVT_start*****'] = array(
637
-                '>',
638
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
639
-            );
640
-        } else {
641
-            $where_params['Datetime.DTT_EVT_start'] = array(
642
-                '>',
643
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
644
-            );
645
-        }
646
-        $query_params[0] = $where_params;
647
-        // don't use $query_params with count()
648
-        // because we don't want to include additional query clauses like "GROUP BY"
649
-        return $count
650
-            ? $this->count(array($where_params), 'EVT_ID', true)
651
-            : $this->get_all($query_params);
652
-    }
653
-
654
-
655
-
656
-    /**
657
-     * Gets all events that are published
658
-     * and have an event end time later than now
659
-     *
660
-     * @param  array $query_params An array of query params to further filter on
661
-     *                             (note that status and DTT_EVT_end will be overridden)
662
-     * @param bool   $count        whether to return the count or not (default FALSE)
663
-     * @return EE_Event[]|int
664
-     * @throws \EE_Error
665
-     */
666
-    public function get_active_and_upcoming_events($query_params, $count = false)
667
-    {
668
-        if (array_key_exists(0, $query_params)) {
669
-            $where_params = $query_params[0];
670
-            unset($query_params[0]);
671
-        } else {
672
-            $where_params = array();
673
-        }
674
-        // if we have count make sure we don't include group by
675
-        if ($count && isset($query_params['group_by'])) {
676
-            unset($query_params['group_by']);
677
-        }
678
-        // let's add specific query_params for active_events
679
-        // keep in mind this will override any sent status in the query AND any date queries.
680
-        $where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
681
-        // add where params for DTT_EVT_end
682
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
683
-            $where_params['Datetime.DTT_EVT_end*****'] = array(
684
-                '>',
685
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
686
-            );
687
-        } else {
688
-            $where_params['Datetime.DTT_EVT_end'] = array(
689
-                '>',
690
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
691
-            );
692
-        }
693
-        $query_params[0] = $where_params;
694
-        // don't use $query_params with count()
695
-        // because we don't want to include additional query clauses like "GROUP BY"
696
-        return $count
697
-            ? $this->count(array($where_params), 'EVT_ID', true)
698
-            : $this->get_all($query_params);
699
-    }
700
-
701
-
702
-
703
-    /**
704
-     * This only returns events that are expired.
705
-     * They may still be published but all their datetimes have expired.
706
-     *
707
-     * @param  array $query_params An array of query params to further filter on
708
-     *                             (note that status and DTT_EVT_end will be overridden)
709
-     * @param bool   $count        whether to return the count or not (default FALSE)
710
-     * @return EE_Event[]|int
711
-     * @throws \EE_Error
712
-     */
713
-    public function get_expired_events($query_params, $count = false)
714
-    {
715
-        $where_params = isset($query_params[0]) ? $query_params[0] : array();
716
-        // if we have count make sure we don't include group by
717
-        if ($count && isset($query_params['group_by'])) {
718
-            unset($query_params['group_by']);
719
-        }
720
-        // let's add specific query_params for active_events
721
-        // keep in mind this will override any sent status in the query AND any date queries.
722
-        if (isset($where_params['status'])) {
723
-            unset($where_params['status']);
724
-        }
725
-        $exclude_query = $query_params;
726
-        if (isset($exclude_query[0])) {
727
-            unset($exclude_query[0]);
728
-        }
729
-        $exclude_query[0] = array(
730
-            'Datetime.DTT_EVT_end' => array(
731
-                '>',
732
-                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
733
-            ),
734
-        );
735
-        // first get all events that have datetimes where its not expired.
736
-        $event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Event_CPT.ID');
737
-        $event_ids = array_keys($event_ids);
738
-        // if we have any additional query_params, let's add them to the 'AND' condition
739
-        $and_condition = array(
740
-            'Datetime.DTT_EVT_end' => array('<', EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')),
741
-            'EVT_ID'               => array('NOT IN', $event_ids),
742
-        );
743
-        if (isset($where_params['OR'])) {
744
-            $and_condition['OR'] = $where_params['OR'];
745
-            unset($where_params['OR']);
746
-        }
747
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
748
-            $and_condition['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
749
-            unset($where_params['Datetime.DTT_EVT_end']);
750
-        }
751
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
752
-            $and_condition['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
753
-            unset($where_params['Datetime.DTT_EVT_start']);
754
-        }
755
-        // merge remaining $where params with the and conditions.
756
-        $where_params['AND'] = array_merge($and_condition, $where_params);
757
-        $query_params[0] = $where_params;
758
-        // don't use $query_params with count()
759
-        // because we don't want to include additional query clauses like "GROUP BY"
760
-        return $count
761
-            ? $this->count(array($where_params), 'EVT_ID', true)
762
-            : $this->get_all($query_params);
763
-    }
764
-
765
-
766
-
767
-    /**
768
-     * This basically just returns the events that do not have the publish status.
769
-     *
770
-     * @param  array   $query_params An array of query params to further filter on
771
-     *                               (note that status will be overwritten)
772
-     * @param  boolean $count        whether to return the count or not (default FALSE)
773
-     * @return EE_Event[]|int
774
-     * @throws \EE_Error
775
-     */
776
-    public function get_inactive_events($query_params, $count = false)
777
-    {
778
-        $where_params = isset($query_params[0]) ? $query_params[0] : array();
779
-        // let's add in specific query_params for inactive events.
780
-        if (isset($where_params['status'])) {
781
-            unset($where_params['status']);
782
-        }
783
-        // if we have count make sure we don't include group by
784
-        if ($count && isset($query_params['group_by'])) {
785
-            unset($query_params['group_by']);
786
-        }
787
-        // if we have any additional query_params, let's add them to the 'AND' condition
788
-        $where_params['AND']['status'] = array('!=', 'publish');
789
-        if (isset($where_params['OR'])) {
790
-            $where_params['AND']['OR'] = $where_params['OR'];
791
-            unset($where_params['OR']);
792
-        }
793
-        if (isset($where_params['Datetime.DTT_EVT_end'])) {
794
-            $where_params['AND']['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
795
-            unset($where_params['Datetime.DTT_EVT_end']);
796
-        }
797
-        if (isset($where_params['Datetime.DTT_EVT_start'])) {
798
-            $where_params['AND']['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
799
-            unset($where_params['Datetime.DTT_EVT_start']);
800
-        }
801
-        $query_params[0] = $where_params;
802
-        // don't use $query_params with count()
803
-        // because we don't want to include additional query clauses like "GROUP BY"
804
-        return $count
805
-            ? $this->count(array($where_params), 'EVT_ID', true)
806
-            : $this->get_all($query_params);
807
-    }
808
-
809
-
810
-
811
-    /**
812
-     * This is just injecting into the parent add_relationship_to so we do special handling on price relationships
813
-     * because we don't want to override any existing global default prices but instead insert NEW prices that get
814
-     * attached to the event. See parent for param descriptions
815
-     *
816
-     * @param        $id_or_obj
817
-     * @param        $other_model_id_or_obj
818
-     * @param string $relationName
819
-     * @param array  $where_query
820
-     * @return EE_Base_Class
821
-     * @throws EE_Error
822
-     */
823
-    public function add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array())
824
-    {
825
-        if ($relationName === 'Price') {
826
-            // let's get the PRC object for the given ID to make sure that we aren't dealing with a default
827
-            $prc_chk = $this->get_related_model_obj($relationName)->ensure_is_obj($other_model_id_or_obj);
828
-            // if EVT_ID = 0, then this is a default
829
-            if ((int) $prc_chk->get('EVT_ID') === 0) {
830
-                // let's set the prc_id as 0 so we force an insert on the add_relation_to carried out by relation
831
-                $prc_chk->set('PRC_ID', 0);
832
-            }
833
-            // run parent
834
-            return parent::add_relationship_to($id_or_obj, $prc_chk, $relationName, $where_query);
835
-        }
836
-        // otherwise carry on as normal
837
-        return parent::add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query);
838
-    }
839
-
840
-
841
-
842
-    /******************** DEPRECATED METHODS ********************/
843
-
844
-
845
-
846
-    /**
847
-     * _get_question_target_db_column
848
-     *
849
-     * @deprecated as of 4.8.32.rc.001. Instead consider using
850
-     *             EE_Registration_Custom_Questions_Form located in
851
-     *             admin_pages/registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php
852
-     * @access     public
853
-     * @param    EE_Registration $registration (so existing answers for registration are included)
854
-     * @param    int             $EVT_ID       so all question groups are included for event (not just answers from
855
-     *                                         registration).
856
-     * @throws EE_Error
857
-     * @return    array
858
-     */
859
-    public function assemble_array_of_groups_questions_and_options(EE_Registration $registration, $EVT_ID = 0)
860
-    {
861
-        if (empty($EVT_ID)) {
862
-            throw new EE_Error(__(
863
-                'An error occurred. No EVT_ID is included.  Needed to know which question groups to retrieve.',
864
-                'event_espresso'
865
-            ));
866
-        }
867
-        $questions = array();
868
-        // get all question groups for event
869
-        $qgs = $this->get_question_groups_for_event($EVT_ID, $registration);
870
-        if (! empty($qgs)) {
871
-            foreach ($qgs as $qg) {
872
-                $qsts = $qg->questions();
873
-                $questions[ $qg->ID() ] = $qg->model_field_array();
874
-                $questions[ $qg->ID() ]['QSG_questions'] = array();
875
-                foreach ($qsts as $qst) {
876
-                    if ($qst->is_system_question()) {
877
-                        continue;
878
-                    }
879
-                    $answer = EEM_Answer::instance()->get_one(array(
880
-                        array(
881
-                            'QST_ID' => $qst->ID(),
882
-                            'REG_ID' => $registration->ID(),
883
-                        ),
884
-                    ));
885
-                    $answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object();
886
-                    $qst_name = $qstn_id = $qst->ID();
887
-                    $ans_id = $answer->ID();
888
-                    $qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']';
889
-                    $input_name = '';
890
-                    $input_id = sanitize_key($qst->display_text());
891
-                    $input_class = '';
892
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array();
893
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn'
894
-                                                                                           . $input_name
895
-                                                                                           . $qst_name;
896
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id;
897
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class;
898
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array();
899
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst;
900
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer;
901
-                    // leave responses as-is, don't convert stuff into html entities please!
902
-                    $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false;
903
-                    if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') {
904
-                        $QSOs = $qst->options(true, $answer->value());
905
-                        if (is_array($QSOs)) {
906
-                            foreach ($QSOs as $QSO_ID => $QSO) {
907
-                                $questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array();
908
-                            }
909
-                        }
910
-                    }
911
-                }
912
-            }
913
-        }
914
-        return $questions;
915
-    }
916
-
917
-
918
-    /**
919
-     * @param mixed $cols_n_values either an array of where each key is the name of a field, and the value is its value
920
-     *                             or an stdClass where each property is the name of a column,
921
-     * @return EE_Base_Class
922
-     * @throws \EE_Error
923
-     */
924
-    public function instantiate_class_from_array_or_object($cols_n_values)
925
-    {
926
-        $classInstance = parent::instantiate_class_from_array_or_object($cols_n_values);
927
-        if ($classInstance instanceof EE_Event) {
928
-            // events have their timezone defined in the DB, so use it immediately
929
-            $this->set_timezone($classInstance->get_timezone());
930
-        }
931
-        return $classInstance;
932
-    }
18
+	/**
19
+	 * constant used by status(), indicating that no more tickets can be purchased for any of the datetimes for the
20
+	 * event
21
+	 */
22
+	const sold_out = 'sold_out';
23
+
24
+	/**
25
+	 * constant used by status(), indicating that upcoming event dates have been postponed (may be pushed to a later
26
+	 * date)
27
+	 */
28
+	const postponed = 'postponed';
29
+
30
+	/**
31
+	 * constant used by status(), indicating that the event will no longer occur
32
+	 */
33
+	const cancelled = 'cancelled';
34
+
35
+
36
+	/**
37
+	 * @var string
38
+	 */
39
+	protected static $_default_reg_status;
40
+
41
+
42
+	/**
43
+	 * This is the default for the additional limit field.
44
+	 * @var int
45
+	 */
46
+	protected static $_default_additional_limit = 10;
47
+
48
+
49
+	/**
50
+	 * private instance of the Event object
51
+	 *
52
+	 * @var EEM_Event
53
+	 */
54
+	protected static $_instance;
55
+
56
+
57
+
58
+
59
+	/**
60
+	 * Adds a relationship to Term_Taxonomy for each CPT_Base
61
+	 *
62
+	 * @param string $timezone
63
+	 * @throws \EE_Error
64
+	 */
65
+	protected function __construct($timezone = null)
66
+	{
67
+		EE_Registry::instance()->load_model('Registration');
68
+		$this->singular_item = esc_html__('Event', 'event_espresso');
69
+		$this->plural_item = esc_html__('Events', 'event_espresso');
70
+		// to remove Cancelled events from the frontend, copy the following filter to your functions.php file
71
+		// add_filter( 'AFEE__EEM_Event__construct___custom_stati__cancelled__Public', '__return_false' );
72
+		// to remove Postponed events from the frontend, copy the following filter to your functions.php file
73
+		// add_filter( 'AFEE__EEM_Event__construct___custom_stati__postponed__Public', '__return_false' );
74
+		// to remove Sold Out events from the frontend, copy the following filter to your functions.php file
75
+		//  add_filter( 'AFEE__EEM_Event__construct___custom_stati__sold_out__Public', '__return_false' );
76
+		$this->_custom_stati = apply_filters(
77
+			'AFEE__EEM_Event__construct___custom_stati',
78
+			array(
79
+				EEM_Event::cancelled => array(
80
+					'label'  => esc_html__('Cancelled', 'event_espresso'),
81
+					'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__cancelled__Public', true),
82
+				),
83
+				EEM_Event::postponed => array(
84
+					'label'  => esc_html__('Postponed', 'event_espresso'),
85
+					'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__postponed__Public', true),
86
+				),
87
+				EEM_Event::sold_out  => array(
88
+					'label'  => esc_html__('Sold Out', 'event_espresso'),
89
+					'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__sold_out__Public', true),
90
+				),
91
+			)
92
+		);
93
+		self::$_default_reg_status = empty(self::$_default_reg_status) ? EEM_Registration::status_id_pending_payment
94
+			: self::$_default_reg_status;
95
+		$this->_tables = array(
96
+			'Event_CPT'  => new EE_Primary_Table('posts', 'ID'),
97
+			'Event_Meta' => new EE_Secondary_Table('esp_event_meta', 'EVTM_ID', 'EVT_ID'),
98
+		);
99
+		$this->_fields = array(
100
+			'Event_CPT'  => array(
101
+				'EVT_ID'         => new EE_Primary_Key_Int_Field(
102
+					'ID',
103
+					esc_html__('Post ID for Event', 'event_espresso')
104
+				),
105
+				'EVT_name'       => new EE_Plain_Text_Field(
106
+					'post_title',
107
+					esc_html__('Event Name', 'event_espresso'),
108
+					false,
109
+					''
110
+				),
111
+				'EVT_desc'       => new EE_Post_Content_Field(
112
+					'post_content',
113
+					esc_html__('Event Description', 'event_espresso'),
114
+					false,
115
+					''
116
+				),
117
+				'EVT_slug'       => new EE_Slug_Field(
118
+					'post_name',
119
+					esc_html__('Event Slug', 'event_espresso'),
120
+					false,
121
+					''
122
+				),
123
+				'EVT_created'    => new EE_Datetime_Field(
124
+					'post_date',
125
+					esc_html__('Date/Time Event Created', 'event_espresso'),
126
+					false,
127
+					EE_Datetime_Field::now
128
+				),
129
+				'EVT_short_desc' => new EE_Simple_HTML_Field(
130
+					'post_excerpt',
131
+					esc_html__('Event Short Description', 'event_espresso'),
132
+					false,
133
+					''
134
+				),
135
+				'EVT_modified'   => new EE_Datetime_Field(
136
+					'post_modified',
137
+					esc_html__('Date/Time Event Modified', 'event_espresso'),
138
+					false,
139
+					EE_Datetime_Field::now
140
+				),
141
+				'EVT_wp_user'    => new EE_WP_User_Field(
142
+					'post_author',
143
+					esc_html__('Event Creator ID', 'event_espresso'),
144
+					false
145
+				),
146
+				'parent'         => new EE_Integer_Field(
147
+					'post_parent',
148
+					esc_html__('Event Parent ID', 'event_espresso'),
149
+					false,
150
+					0
151
+				),
152
+				'EVT_order'      => new EE_Integer_Field(
153
+					'menu_order',
154
+					esc_html__('Event Menu Order', 'event_espresso'),
155
+					false,
156
+					1
157
+				),
158
+				'post_type'      => new EE_WP_Post_Type_Field('espresso_events'),
159
+				// EE_Plain_Text_Field( 'post_type', esc_html__( 'Event Post Type', 'event_espresso' ), FALSE, 'espresso_events' ),
160
+				'status'         => new EE_WP_Post_Status_Field(
161
+					'post_status',
162
+					esc_html__('Event Status', 'event_espresso'),
163
+					false,
164
+					'draft',
165
+					$this->_custom_stati
166
+				),
167
+				'password' => new EE_Password_Field(
168
+					'post_password',
169
+					__('Password', 'event_espresso'),
170
+					false,
171
+					'',
172
+					array(
173
+						'EVT_desc',
174
+						'EVT_short_desc',
175
+						'EVT_display_desc',
176
+						'EVT_display_ticket_selector',
177
+						'EVT_visible_on',
178
+						'EVT_additional_limit',
179
+						'EVT_default_registration_status',
180
+						'EVT_member_only',
181
+						'EVT_phone',
182
+						'EVT_allow_overflow',
183
+						'EVT_timezone_string',
184
+						'EVT_external_URL',
185
+						'EVT_donations'
186
+					)
187
+				)
188
+			),
189
+			'Event_Meta' => array(
190
+				'EVTM_ID'                         => new EE_DB_Only_Float_Field(
191
+					'EVTM_ID',
192
+					esc_html__('Event Meta Row ID', 'event_espresso'),
193
+					false
194
+				),
195
+				'EVT_ID_fk'                       => new EE_DB_Only_Int_Field(
196
+					'EVT_ID',
197
+					esc_html__('Foreign key to Event ID from Event Meta table', 'event_espresso'),
198
+					false
199
+				),
200
+				'EVT_display_desc'                => new EE_Boolean_Field(
201
+					'EVT_display_desc',
202
+					esc_html__('Display Description Flag', 'event_espresso'),
203
+					false,
204
+					true
205
+				),
206
+				'EVT_display_ticket_selector'     => new EE_Boolean_Field(
207
+					'EVT_display_ticket_selector',
208
+					esc_html__('Display Ticket Selector Flag', 'event_espresso'),
209
+					false,
210
+					true
211
+				),
212
+				'EVT_visible_on'                  => new EE_Datetime_Field(
213
+					'EVT_visible_on',
214
+					esc_html__('Event Visible Date', 'event_espresso'),
215
+					true,
216
+					EE_Datetime_Field::now
217
+				),
218
+				'EVT_additional_limit'            => new EE_Integer_Field(
219
+					'EVT_additional_limit',
220
+					esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
221
+					true,
222
+					self::$_default_additional_limit
223
+				),
224
+				'EVT_default_registration_status' => new EE_Enum_Text_Field(
225
+					'EVT_default_registration_status',
226
+					esc_html__('Default Registration Status on this Event', 'event_espresso'),
227
+					false,
228
+					EEM_Event::$_default_reg_status,
229
+					EEM_Registration::reg_status_array()
230
+				),
231
+				'EVT_member_only'                 => new EE_Boolean_Field(
232
+					'EVT_member_only',
233
+					esc_html__('Member-Only Event Flag', 'event_espresso'),
234
+					false,
235
+					false
236
+				),
237
+				'EVT_phone'                       => new EE_Plain_Text_Field(
238
+					'EVT_phone',
239
+					esc_html__('Event Phone Number', 'event_espresso'),
240
+					false,
241
+					''
242
+				),
243
+				'EVT_allow_overflow'              => new EE_Boolean_Field(
244
+					'EVT_allow_overflow',
245
+					esc_html__('Allow Overflow on Event', 'event_espresso'),
246
+					false,
247
+					false
248
+				),
249
+				'EVT_timezone_string'             => new EE_Plain_Text_Field(
250
+					'EVT_timezone_string',
251
+					esc_html__('Timezone (name) for Event times', 'event_espresso'),
252
+					false,
253
+					''
254
+				),
255
+				'EVT_external_URL'                => new EE_Plain_Text_Field(
256
+					'EVT_external_URL',
257
+					esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso'),
258
+					true
259
+				),
260
+				'EVT_donations'                   => new EE_Boolean_Field(
261
+					'EVT_donations',
262
+					esc_html__('Accept Donations?', 'event_espresso'),
263
+					false,
264
+					false
265
+				),
266
+			),
267
+		);
268
+		$this->_model_relations = array(
269
+			'Registration'           => new EE_Has_Many_Relation(),
270
+			'Datetime'               => new EE_Has_Many_Relation(),
271
+			'Question_Group'         => new EE_HABTM_Relation('Event_Question_Group'),
272
+			'Event_Question_Group'   => new EE_Has_Many_Relation(),
273
+			'Venue'                  => new EE_HABTM_Relation('Event_Venue'),
274
+			'Term_Relationship'      => new EE_Has_Many_Relation(),
275
+			'Term_Taxonomy'          => new EE_HABTM_Relation('Term_Relationship'),
276
+			'Message_Template_Group' => new EE_HABTM_Relation('Event_Message_Template'),
277
+			'Attendee'               => new EE_HABTM_Relation('Registration'),
278
+			'WP_User'                => new EE_Belongs_To_Relation(),
279
+		);
280
+		// this model is generally available for reading
281
+		$this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public();
282
+		$this->model_chain_to_password = '';
283
+		parent::__construct($timezone);
284
+	}
285
+
286
+
287
+
288
+	/**
289
+	 * @param string $default_reg_status
290
+	 */
291
+	public static function set_default_reg_status($default_reg_status)
292
+	{
293
+		self::$_default_reg_status = $default_reg_status;
294
+		// if EEM_Event has already been instantiated,
295
+		// then we need to reset the `EVT_default_reg_status` field to use the new default.
296
+		if (self::$_instance instanceof EEM_Event) {
297
+			$default_reg_status = new EE_Enum_Text_Field(
298
+				'EVT_default_registration_status',
299
+				esc_html__('Default Registration Status on this Event', 'event_espresso'),
300
+				false,
301
+				$default_reg_status,
302
+				EEM_Registration::reg_status_array()
303
+			);
304
+			$default_reg_status->_construct_finalize(
305
+				'Event_Meta',
306
+				'EVT_default_registration_status',
307
+				'EEM_Event'
308
+			);
309
+			self::$_instance->_fields['Event_Meta']['EVT_default_registration_status'] = $default_reg_status;
310
+		}
311
+	}
312
+
313
+
314
+	/**
315
+	 * Used to override the default for the additional limit field.
316
+	 * @param $additional_limit
317
+	 */
318
+	public static function set_default_additional_limit($additional_limit)
319
+	{
320
+		self::$_default_additional_limit = (int) $additional_limit;
321
+		if (self::$_instance instanceof EEM_Event) {
322
+			self::$_instance->_fields['Event_Meta']['EVT_additional_limit'] = new EE_Integer_Field(
323
+				'EVT_additional_limit',
324
+				__('Limit of Additional Registrations on Same Transaction', 'event_espresso'),
325
+				true,
326
+				self::$_default_additional_limit
327
+			);
328
+			self::$_instance->_fields['Event_Meta']['EVT_additional_limit']->_construct_finalize(
329
+				'Event_Meta',
330
+				'EVT_additional_limit',
331
+				'EEM_Event'
332
+			);
333
+		}
334
+	}
335
+
336
+
337
+	/**
338
+	 * Return what is currently set as the default additional limit for the event.
339
+	 * @return int
340
+	 */
341
+	public static function get_default_additional_limit()
342
+	{
343
+		return apply_filters('FHEE__EEM_Event__get_default_additional_limit', self::$_default_additional_limit);
344
+	}
345
+
346
+
347
+	/**
348
+	 * get_question_groups
349
+	 *
350
+	 * @return array
351
+	 * @throws \EE_Error
352
+	 */
353
+	public function get_all_question_groups()
354
+	{
355
+		return EE_Registry::instance()->load_model('Question_Group')->get_all(
356
+			array(
357
+				array('QSG_deleted' => false),
358
+				'order_by' => array('QSG_order' => 'ASC'),
359
+			)
360
+		);
361
+	}
362
+
363
+
364
+
365
+	/**
366
+	 * get_question_groups
367
+	 *
368
+	 * @param int $EVT_ID
369
+	 * @return array|bool
370
+	 * @throws \EE_Error
371
+	 */
372
+	public function get_all_event_question_groups($EVT_ID = 0)
373
+	{
374
+		if (! isset($EVT_ID) || ! absint($EVT_ID)) {
375
+			EE_Error::add_error(
376
+				esc_html__(
377
+					'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
378
+					'event_espresso'
379
+				),
380
+				__FILE__,
381
+				__FUNCTION__,
382
+				__LINE__
383
+			);
384
+			return false;
385
+		}
386
+		return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(
387
+			array(
388
+				array('EVT_ID' => $EVT_ID),
389
+			)
390
+		);
391
+	}
392
+
393
+
394
+	/**
395
+	 * get_question_groups
396
+	 *
397
+	 * @param int $EVT_ID
398
+	 * @param boolean $for_primary_attendee
399
+	 * @return array|bool
400
+	 * @throws EE_Error
401
+	 * @throws InvalidArgumentException
402
+	 * @throws ReflectionException
403
+	 * @throws InvalidDataTypeException
404
+	 * @throws InvalidInterfaceException
405
+	 */
406
+	public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true)
407
+	{
408
+		if (! isset($EVT_ID) || ! absint($EVT_ID)) {
409
+			EE_Error::add_error(
410
+				esc_html__(
411
+					// @codingStandardsIgnoreStart
412
+					'An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
413
+					// @codingStandardsIgnoreEnd
414
+					'event_espresso'
415
+				),
416
+				__FILE__,
417
+				__FUNCTION__,
418
+				__LINE__
419
+			);
420
+			return false;
421
+		}
422
+		$query_params = [
423
+			[
424
+				'EVT_ID' => $EVT_ID,
425
+				EEM_Event_Question_Group::instance()->fieldNameForContext($for_primary_attendee) => true
426
+			]
427
+		];
428
+		if ($for_primary_attendee) {
429
+			$query_params[0]['EQG_primary'] = true;
430
+		} else {
431
+			$query_params[0]['EQG_additional'] = true;
432
+		}
433
+		return EE_Registry::instance()->load_model('Event_Question_Group')->get_all($query_params);
434
+	}
435
+
436
+
437
+	/**
438
+	 * get_question_groups
439
+	 *
440
+	 * @param int $EVT_ID
441
+	 * @param EE_Registration $registration
442
+	 * @return array|bool
443
+	 * @throws EE_Error
444
+	 * @throws InvalidArgumentException
445
+	 * @throws InvalidDataTypeException
446
+	 * @throws InvalidInterfaceException
447
+	 * @throws ReflectionException
448
+	 */
449
+	public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration)
450
+	{
451
+		if (! isset($EVT_ID) || ! absint($EVT_ID)) {
452
+			EE_Error::add_error(
453
+				esc_html__(
454
+					'An error occurred. No Question Groups could be retrieved because an Event ID was not received.',
455
+					'event_espresso'
456
+				),
457
+				__FILE__,
458
+				__FUNCTION__,
459
+				__LINE__
460
+			);
461
+			return false;
462
+		}
463
+		return EE_Registry::instance()->load_model('Question_Group')->get_all(
464
+			[
465
+				[
466
+					'Event_Question_Group.EVT_ID'      => $EVT_ID,
467
+					'Event_Question_Group.'
468
+						. EEM_Event_Question_Group::instance()->fieldNameForContext(
469
+							$registration->is_primary_registrant()
470
+						) => true
471
+				],
472
+				'order_by' => ['QSG_order' => 'ASC'],
473
+			]
474
+		);
475
+	}
476
+
477
+
478
+
479
+	/**
480
+	 * get_question_target_db_column
481
+	 *
482
+	 * @param string $QSG_IDs csv list of $QSG IDs
483
+	 * @return array|bool
484
+	 * @throws \EE_Error
485
+	 */
486
+	public function get_questions_in_groups($QSG_IDs = '')
487
+	{
488
+		if (empty($QSG_IDs)) {
489
+			EE_Error::add_error(
490
+				esc_html__('An error occurred. No Question Group IDs were received.', 'event_espresso'),
491
+				__FILE__,
492
+				__FUNCTION__,
493
+				__LINE__
494
+			);
495
+			return false;
496
+		}
497
+		return EE_Registry::instance()->load_model('Question')->get_all(
498
+			array(
499
+				array(
500
+					'Question_Group.QSG_ID' => array('IN', $QSG_IDs),
501
+					'QST_deleted'           => false,
502
+					'QST_admin_only'        => is_admin(),
503
+				),
504
+				'order_by' => 'QST_order',
505
+			)
506
+		);
507
+	}
508
+
509
+
510
+
511
+	/**
512
+	 * get_options_for_question
513
+	 *
514
+	 * @param string $QST_IDs csv list of $QST IDs
515
+	 * @return array|bool
516
+	 * @throws \EE_Error
517
+	 */
518
+	public function get_options_for_question($QST_IDs)
519
+	{
520
+		if (empty($QST_IDs)) {
521
+			EE_Error::add_error(
522
+				esc_html__('An error occurred. No Question IDs were received.', 'event_espresso'),
523
+				__FILE__,
524
+				__FUNCTION__,
525
+				__LINE__
526
+			);
527
+			return false;
528
+		}
529
+		return EE_Registry::instance()->load_model('Question_Option')->get_all(
530
+			array(
531
+				array(
532
+					'Question.QST_ID' => array('IN', $QST_IDs),
533
+					'QSO_deleted'     => false,
534
+				),
535
+				'order_by' => 'QSO_ID',
536
+			)
537
+		);
538
+	}
539
+
540
+
541
+
542
+
543
+
544
+
545
+
546
+	/**
547
+	 * Gets all events that are published
548
+	 * and have event start time earlier than now and an event end time later than now
549
+	 *
550
+	 * @param  array $query_params An array of query params to further filter on
551
+	 *                             (note that status and DTT_EVT_start and DTT_EVT_end will be overridden)
552
+	 * @param bool   $count        whether to return the count or not (default FALSE)
553
+	 * @return EE_Event[]|int
554
+	 * @throws \EE_Error
555
+	 */
556
+	public function get_active_events($query_params, $count = false)
557
+	{
558
+		if (array_key_exists(0, $query_params)) {
559
+			$where_params = $query_params[0];
560
+			unset($query_params[0]);
561
+		} else {
562
+			$where_params = array();
563
+		}
564
+		// if we have count make sure we don't include group by
565
+		if ($count && isset($query_params['group_by'])) {
566
+			unset($query_params['group_by']);
567
+		}
568
+		// let's add specific query_params for active_events
569
+		// keep in mind this will override any sent status in the query AND any date queries.
570
+		$where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
571
+		// if already have where params for DTT_EVT_start or DTT_EVT_end then append these conditions
572
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
573
+			$where_params['Datetime.DTT_EVT_start******'] = array(
574
+				'<',
575
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
576
+			);
577
+		} else {
578
+			$where_params['Datetime.DTT_EVT_start'] = array(
579
+				'<',
580
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
581
+			);
582
+		}
583
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
584
+			$where_params['Datetime.DTT_EVT_end*****'] = array(
585
+				'>',
586
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
587
+			);
588
+		} else {
589
+			$where_params['Datetime.DTT_EVT_end'] = array(
590
+				'>',
591
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
592
+			);
593
+		}
594
+		$query_params[0] = $where_params;
595
+		// don't use $query_params with count()
596
+		// because we don't want to include additional query clauses like "GROUP BY"
597
+		return $count
598
+			? $this->count(array($where_params), 'EVT_ID', true)
599
+			: $this->get_all($query_params);
600
+	}
601
+
602
+
603
+
604
+	/**
605
+	 * get all events that are published and have an event start time later than now
606
+	 *
607
+	 * @param  array $query_params An array of query params to further filter on
608
+	 *                             (Note that status and DTT_EVT_start will be overridden)
609
+	 * @param bool   $count        whether to return the count or not (default FALSE)
610
+	 * @return EE_Event[]|int
611
+	 * @throws \EE_Error
612
+	 */
613
+	public function get_upcoming_events($query_params, $count = false)
614
+	{
615
+		if (array_key_exists(0, $query_params)) {
616
+			$where_params = $query_params[0];
617
+			unset($query_params[0]);
618
+		} else {
619
+			$where_params = array();
620
+		}
621
+		// if we have count make sure we don't include group by
622
+		if ($count && isset($query_params['group_by'])) {
623
+			unset($query_params['group_by']);
624
+		}
625
+		// let's add specific query_params for active_events
626
+		// keep in mind this will override any sent status in the query AND any date queries.
627
+		// we need to pull events with a status of publish and sold_out
628
+		$event_status = array('publish', EEM_Event::sold_out);
629
+		// check if the user can read private events and if so add the 'private status to the were params'
630
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_upcoming_events')) {
631
+			$event_status[] = 'private';
632
+		}
633
+		$where_params['status'] = array('IN', $event_status);
634
+		// if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
635
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
636
+			$where_params['Datetime.DTT_EVT_start*****'] = array(
637
+				'>',
638
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
639
+			);
640
+		} else {
641
+			$where_params['Datetime.DTT_EVT_start'] = array(
642
+				'>',
643
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start'),
644
+			);
645
+		}
646
+		$query_params[0] = $where_params;
647
+		// don't use $query_params with count()
648
+		// because we don't want to include additional query clauses like "GROUP BY"
649
+		return $count
650
+			? $this->count(array($where_params), 'EVT_ID', true)
651
+			: $this->get_all($query_params);
652
+	}
653
+
654
+
655
+
656
+	/**
657
+	 * Gets all events that are published
658
+	 * and have an event end time later than now
659
+	 *
660
+	 * @param  array $query_params An array of query params to further filter on
661
+	 *                             (note that status and DTT_EVT_end will be overridden)
662
+	 * @param bool   $count        whether to return the count or not (default FALSE)
663
+	 * @return EE_Event[]|int
664
+	 * @throws \EE_Error
665
+	 */
666
+	public function get_active_and_upcoming_events($query_params, $count = false)
667
+	{
668
+		if (array_key_exists(0, $query_params)) {
669
+			$where_params = $query_params[0];
670
+			unset($query_params[0]);
671
+		} else {
672
+			$where_params = array();
673
+		}
674
+		// if we have count make sure we don't include group by
675
+		if ($count && isset($query_params['group_by'])) {
676
+			unset($query_params['group_by']);
677
+		}
678
+		// let's add specific query_params for active_events
679
+		// keep in mind this will override any sent status in the query AND any date queries.
680
+		$where_params['status'] = array('IN', array('publish', EEM_Event::sold_out));
681
+		// add where params for DTT_EVT_end
682
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
683
+			$where_params['Datetime.DTT_EVT_end*****'] = array(
684
+				'>',
685
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
686
+			);
687
+		} else {
688
+			$where_params['Datetime.DTT_EVT_end'] = array(
689
+				'>',
690
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
691
+			);
692
+		}
693
+		$query_params[0] = $where_params;
694
+		// don't use $query_params with count()
695
+		// because we don't want to include additional query clauses like "GROUP BY"
696
+		return $count
697
+			? $this->count(array($where_params), 'EVT_ID', true)
698
+			: $this->get_all($query_params);
699
+	}
700
+
701
+
702
+
703
+	/**
704
+	 * This only returns events that are expired.
705
+	 * They may still be published but all their datetimes have expired.
706
+	 *
707
+	 * @param  array $query_params An array of query params to further filter on
708
+	 *                             (note that status and DTT_EVT_end will be overridden)
709
+	 * @param bool   $count        whether to return the count or not (default FALSE)
710
+	 * @return EE_Event[]|int
711
+	 * @throws \EE_Error
712
+	 */
713
+	public function get_expired_events($query_params, $count = false)
714
+	{
715
+		$where_params = isset($query_params[0]) ? $query_params[0] : array();
716
+		// if we have count make sure we don't include group by
717
+		if ($count && isset($query_params['group_by'])) {
718
+			unset($query_params['group_by']);
719
+		}
720
+		// let's add specific query_params for active_events
721
+		// keep in mind this will override any sent status in the query AND any date queries.
722
+		if (isset($where_params['status'])) {
723
+			unset($where_params['status']);
724
+		}
725
+		$exclude_query = $query_params;
726
+		if (isset($exclude_query[0])) {
727
+			unset($exclude_query[0]);
728
+		}
729
+		$exclude_query[0] = array(
730
+			'Datetime.DTT_EVT_end' => array(
731
+				'>',
732
+				EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end'),
733
+			),
734
+		);
735
+		// first get all events that have datetimes where its not expired.
736
+		$event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Event_CPT.ID');
737
+		$event_ids = array_keys($event_ids);
738
+		// if we have any additional query_params, let's add them to the 'AND' condition
739
+		$and_condition = array(
740
+			'Datetime.DTT_EVT_end' => array('<', EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')),
741
+			'EVT_ID'               => array('NOT IN', $event_ids),
742
+		);
743
+		if (isset($where_params['OR'])) {
744
+			$and_condition['OR'] = $where_params['OR'];
745
+			unset($where_params['OR']);
746
+		}
747
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
748
+			$and_condition['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
749
+			unset($where_params['Datetime.DTT_EVT_end']);
750
+		}
751
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
752
+			$and_condition['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
753
+			unset($where_params['Datetime.DTT_EVT_start']);
754
+		}
755
+		// merge remaining $where params with the and conditions.
756
+		$where_params['AND'] = array_merge($and_condition, $where_params);
757
+		$query_params[0] = $where_params;
758
+		// don't use $query_params with count()
759
+		// because we don't want to include additional query clauses like "GROUP BY"
760
+		return $count
761
+			? $this->count(array($where_params), 'EVT_ID', true)
762
+			: $this->get_all($query_params);
763
+	}
764
+
765
+
766
+
767
+	/**
768
+	 * This basically just returns the events that do not have the publish status.
769
+	 *
770
+	 * @param  array   $query_params An array of query params to further filter on
771
+	 *                               (note that status will be overwritten)
772
+	 * @param  boolean $count        whether to return the count or not (default FALSE)
773
+	 * @return EE_Event[]|int
774
+	 * @throws \EE_Error
775
+	 */
776
+	public function get_inactive_events($query_params, $count = false)
777
+	{
778
+		$where_params = isset($query_params[0]) ? $query_params[0] : array();
779
+		// let's add in specific query_params for inactive events.
780
+		if (isset($where_params['status'])) {
781
+			unset($where_params['status']);
782
+		}
783
+		// if we have count make sure we don't include group by
784
+		if ($count && isset($query_params['group_by'])) {
785
+			unset($query_params['group_by']);
786
+		}
787
+		// if we have any additional query_params, let's add them to the 'AND' condition
788
+		$where_params['AND']['status'] = array('!=', 'publish');
789
+		if (isset($where_params['OR'])) {
790
+			$where_params['AND']['OR'] = $where_params['OR'];
791
+			unset($where_params['OR']);
792
+		}
793
+		if (isset($where_params['Datetime.DTT_EVT_end'])) {
794
+			$where_params['AND']['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
795
+			unset($where_params['Datetime.DTT_EVT_end']);
796
+		}
797
+		if (isset($where_params['Datetime.DTT_EVT_start'])) {
798
+			$where_params['AND']['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
799
+			unset($where_params['Datetime.DTT_EVT_start']);
800
+		}
801
+		$query_params[0] = $where_params;
802
+		// don't use $query_params with count()
803
+		// because we don't want to include additional query clauses like "GROUP BY"
804
+		return $count
805
+			? $this->count(array($where_params), 'EVT_ID', true)
806
+			: $this->get_all($query_params);
807
+	}
808
+
809
+
810
+
811
+	/**
812
+	 * This is just injecting into the parent add_relationship_to so we do special handling on price relationships
813
+	 * because we don't want to override any existing global default prices but instead insert NEW prices that get
814
+	 * attached to the event. See parent for param descriptions
815
+	 *
816
+	 * @param        $id_or_obj
817
+	 * @param        $other_model_id_or_obj
818
+	 * @param string $relationName
819
+	 * @param array  $where_query
820
+	 * @return EE_Base_Class
821
+	 * @throws EE_Error
822
+	 */
823
+	public function add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array())
824
+	{
825
+		if ($relationName === 'Price') {
826
+			// let's get the PRC object for the given ID to make sure that we aren't dealing with a default
827
+			$prc_chk = $this->get_related_model_obj($relationName)->ensure_is_obj($other_model_id_or_obj);
828
+			// if EVT_ID = 0, then this is a default
829
+			if ((int) $prc_chk->get('EVT_ID') === 0) {
830
+				// let's set the prc_id as 0 so we force an insert on the add_relation_to carried out by relation
831
+				$prc_chk->set('PRC_ID', 0);
832
+			}
833
+			// run parent
834
+			return parent::add_relationship_to($id_or_obj, $prc_chk, $relationName, $where_query);
835
+		}
836
+		// otherwise carry on as normal
837
+		return parent::add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query);
838
+	}
839
+
840
+
841
+
842
+	/******************** DEPRECATED METHODS ********************/
843
+
844
+
845
+
846
+	/**
847
+	 * _get_question_target_db_column
848
+	 *
849
+	 * @deprecated as of 4.8.32.rc.001. Instead consider using
850
+	 *             EE_Registration_Custom_Questions_Form located in
851
+	 *             admin_pages/registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php
852
+	 * @access     public
853
+	 * @param    EE_Registration $registration (so existing answers for registration are included)
854
+	 * @param    int             $EVT_ID       so all question groups are included for event (not just answers from
855
+	 *                                         registration).
856
+	 * @throws EE_Error
857
+	 * @return    array
858
+	 */
859
+	public function assemble_array_of_groups_questions_and_options(EE_Registration $registration, $EVT_ID = 0)
860
+	{
861
+		if (empty($EVT_ID)) {
862
+			throw new EE_Error(__(
863
+				'An error occurred. No EVT_ID is included.  Needed to know which question groups to retrieve.',
864
+				'event_espresso'
865
+			));
866
+		}
867
+		$questions = array();
868
+		// get all question groups for event
869
+		$qgs = $this->get_question_groups_for_event($EVT_ID, $registration);
870
+		if (! empty($qgs)) {
871
+			foreach ($qgs as $qg) {
872
+				$qsts = $qg->questions();
873
+				$questions[ $qg->ID() ] = $qg->model_field_array();
874
+				$questions[ $qg->ID() ]['QSG_questions'] = array();
875
+				foreach ($qsts as $qst) {
876
+					if ($qst->is_system_question()) {
877
+						continue;
878
+					}
879
+					$answer = EEM_Answer::instance()->get_one(array(
880
+						array(
881
+							'QST_ID' => $qst->ID(),
882
+							'REG_ID' => $registration->ID(),
883
+						),
884
+					));
885
+					$answer = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object();
886
+					$qst_name = $qstn_id = $qst->ID();
887
+					$ans_id = $answer->ID();
888
+					$qst_name = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']';
889
+					$input_name = '';
890
+					$input_id = sanitize_key($qst->display_text());
891
+					$input_class = '';
892
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ] = $qst->model_field_array();
893
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_name'] = 'qstn'
894
+																						   . $input_name
895
+																						   . $qst_name;
896
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_id'] = $input_id . '-' . $qstn_id;
897
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_input_class'] = $input_class;
898
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'] = array();
899
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['qst_obj'] = $qst;
900
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['ans_obj'] = $answer;
901
+					// leave responses as-is, don't convert stuff into html entities please!
902
+					$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['htmlentities'] = false;
903
+					if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') {
904
+						$QSOs = $qst->options(true, $answer->value());
905
+						if (is_array($QSOs)) {
906
+							foreach ($QSOs as $QSO_ID => $QSO) {
907
+								$questions[ $qg->ID() ]['QSG_questions'][ $qst->ID() ]['QST_options'][ $QSO_ID ] = $QSO->model_field_array();
908
+							}
909
+						}
910
+					}
911
+				}
912
+			}
913
+		}
914
+		return $questions;
915
+	}
916
+
917
+
918
+	/**
919
+	 * @param mixed $cols_n_values either an array of where each key is the name of a field, and the value is its value
920
+	 *                             or an stdClass where each property is the name of a column,
921
+	 * @return EE_Base_Class
922
+	 * @throws \EE_Error
923
+	 */
924
+	public function instantiate_class_from_array_or_object($cols_n_values)
925
+	{
926
+		$classInstance = parent::instantiate_class_from_array_or_object($cols_n_values);
927
+		if ($classInstance instanceof EE_Event) {
928
+			// events have their timezone defined in the DB, so use it immediately
929
+			$this->set_timezone($classInstance->get_timezone());
930
+		}
931
+		return $classInstance;
932
+	}
933 933
 }
Please login to merge, or discard this patch.
core/EE_Load_Textdomain.core.php 2 patches
Indentation   +91 added lines, -91 removed lines patch added patch discarded remove patch
@@ -13,105 +13,105 @@
 block discarded – undo
13 13
 class EE_Load_Textdomain extends EE_Base
14 14
 {
15 15
 
16
-    /**
17
-     * holds the current lang in WP
18
-     *
19
-     * @var string
20
-     */
21
-    private static $locale;
16
+	/**
17
+	 * holds the current lang in WP
18
+	 *
19
+	 * @var string
20
+	 */
21
+	private static $locale;
22 22
 
23 23
 
24
-    /**
25
-     * this takes care of retrieving a matching textdomain for event espresso for the current WPLANG from EE GitHub
26
-     * repo (if necessary) and then loading it for translations. should only be called in wp plugins_loaded callback
27
-     *
28
-     * @return void
29
-     * @throws EE_Error
30
-     * @throws InvalidArgumentException
31
-     * @throws ReflectionException
32
-     * @throws InvalidDataTypeException
33
-     * @throws InvalidInterfaceException
34
-     */
35
-    public static function load_textdomain()
36
-    {
37
-        EE_Load_Textdomain::loadTranslationsForLocale();
38
-        // now load the textdomain
39
-        if (!empty(EE_Load_Textdomain::$locale)) {
40
-            $github_mo_path = EE_LANGUAGES_SAFE_DIR . 'event_espresso-' . EE_Load_Textdomain::$locale . '.mo';
41
-            if (is_readable($github_mo_path)) {
42
-                load_plugin_textdomain('event_espresso', false, EE_LANGUAGES_SAFE_LOC);
43
-                return;
44
-            }
45
-            $glotpress_mo_path = EE_LANGUAGES_SAFE_DIR . 'event-espresso-4-' . EE_Load_Textdomain::$locale . '.mo';
46
-            if (is_readable($glotpress_mo_path)) {
47
-                load_textdomain('event_espresso', $glotpress_mo_path);
48
-                return;
49
-            }
50
-        }
51
-        load_plugin_textdomain('event_espresso', false, dirname(EE_PLUGIN_BASENAME) . '/languages/');
52
-    }
24
+	/**
25
+	 * this takes care of retrieving a matching textdomain for event espresso for the current WPLANG from EE GitHub
26
+	 * repo (if necessary) and then loading it for translations. should only be called in wp plugins_loaded callback
27
+	 *
28
+	 * @return void
29
+	 * @throws EE_Error
30
+	 * @throws InvalidArgumentException
31
+	 * @throws ReflectionException
32
+	 * @throws InvalidDataTypeException
33
+	 * @throws InvalidInterfaceException
34
+	 */
35
+	public static function load_textdomain()
36
+	{
37
+		EE_Load_Textdomain::loadTranslationsForLocale();
38
+		// now load the textdomain
39
+		if (!empty(EE_Load_Textdomain::$locale)) {
40
+			$github_mo_path = EE_LANGUAGES_SAFE_DIR . 'event_espresso-' . EE_Load_Textdomain::$locale . '.mo';
41
+			if (is_readable($github_mo_path)) {
42
+				load_plugin_textdomain('event_espresso', false, EE_LANGUAGES_SAFE_LOC);
43
+				return;
44
+			}
45
+			$glotpress_mo_path = EE_LANGUAGES_SAFE_DIR . 'event-espresso-4-' . EE_Load_Textdomain::$locale . '.mo';
46
+			if (is_readable($glotpress_mo_path)) {
47
+				load_textdomain('event_espresso', $glotpress_mo_path);
48
+				return;
49
+			}
50
+		}
51
+		load_plugin_textdomain('event_espresso', false, dirname(EE_PLUGIN_BASENAME) . '/languages/');
52
+	}
53 53
 
54 54
 
55
-    /**
56
-     * The purpose of this method is to sideload all of the lang files for EE, this includes the POT file and also the PO/MO files for the given WPLANG locale (if necessary).
57
-     *
58
-     * @access private
59
-     * @static
60
-     * @return void
61
-     * @throws EE_Error
62
-     * @throws InvalidArgumentException
63
-     * @throws ReflectionException
64
-     * @throws InvalidDataTypeException
65
-     * @throws InvalidInterfaceException
66
-     */
67
-    private static function loadTranslationsForLocale()
68
-    {
69
-        EE_Load_Textdomain::$locale = get_locale();
70
-        // can't download a language file if a language isn't set <taps temple>
71
-        if (empty(EE_Load_Textdomain::$locale)) {
72
-            return;
73
-        }
74
-        $language_check_option_name = 'ee_lang_check_' . EE_Load_Textdomain::$locale . '_' . EVENT_ESPRESSO_VERSION;
75
-        // check if language files has already been sideloaded
76
-        if (get_option($language_check_option_name)) {
77
-            return;
78
-        }
55
+	/**
56
+	 * The purpose of this method is to sideload all of the lang files for EE, this includes the POT file and also the PO/MO files for the given WPLANG locale (if necessary).
57
+	 *
58
+	 * @access private
59
+	 * @static
60
+	 * @return void
61
+	 * @throws EE_Error
62
+	 * @throws InvalidArgumentException
63
+	 * @throws ReflectionException
64
+	 * @throws InvalidDataTypeException
65
+	 * @throws InvalidInterfaceException
66
+	 */
67
+	private static function loadTranslationsForLocale()
68
+	{
69
+		EE_Load_Textdomain::$locale = get_locale();
70
+		// can't download a language file if a language isn't set <taps temple>
71
+		if (empty(EE_Load_Textdomain::$locale)) {
72
+			return;
73
+		}
74
+		$language_check_option_name = 'ee_lang_check_' . EE_Load_Textdomain::$locale . '_' . EVENT_ESPRESSO_VERSION;
75
+		// check if language files has already been sideloaded
76
+		if (get_option($language_check_option_name)) {
77
+			return;
78
+		}
79 79
 
80
-        $repo_base_URL = 'https://github.com/eventespresso/languages-ee4/blob/master/event_espresso';
80
+		$repo_base_URL = 'https://github.com/eventespresso/languages-ee4/blob/master/event_espresso';
81 81
 
82
-        // load sideloader and sideload the .POT file as this should always be included.
83
-        $sideloader_args = array(
84
-            '_upload_to'     => EE_PLUGIN_DIR_PATH . 'languages/',
85
-            '_download_from'   => $repo_base_URL .'.pot?raw=true',
86
-            '_new_file_name' => 'event_espresso.pot',
87
-        );
88
-        /** @var EEH_Sideloader $sideloader */
89
-        $sideloader = EE_Registry::instance()->load_helper('Sideloader', $sideloader_args, false);
90
-        // sideload the .POT file only for main site of the network, or if not running Multisite.
91
-        if (is_main_site()) {
92
-            $sideloader->sideload();
93
-        }
82
+		// load sideloader and sideload the .POT file as this should always be included.
83
+		$sideloader_args = array(
84
+			'_upload_to'     => EE_PLUGIN_DIR_PATH . 'languages/',
85
+			'_download_from'   => $repo_base_URL .'.pot?raw=true',
86
+			'_new_file_name' => 'event_espresso.pot',
87
+		);
88
+		/** @var EEH_Sideloader $sideloader */
89
+		$sideloader = EE_Registry::instance()->load_helper('Sideloader', $sideloader_args, false);
90
+		// sideload the .POT file only for main site of the network, or if not running Multisite.
91
+		if (is_main_site()) {
92
+			$sideloader->sideload();
93
+		}
94 94
 
95
-        // if locale is "en_US" then lets just get out, since Event Espresso core is already "en_US"
96
-        if (EE_Load_Textdomain::$locale === 'en_US') {
97
-            // but set option first else we'll forever be downloading the pot file
98
-            update_option($language_check_option_name, 1);
99
-            return;
100
-        }
101
-        $repo_locale_URL = $repo_base_URL . '-' . EE_Load_Textdomain::$locale;
102
-        $file_name_base = 'event_espresso-' . EE_Load_Textdomain::$locale;
95
+		// if locale is "en_US" then lets just get out, since Event Espresso core is already "en_US"
96
+		if (EE_Load_Textdomain::$locale === 'en_US') {
97
+			// but set option first else we'll forever be downloading the pot file
98
+			update_option($language_check_option_name, 1);
99
+			return;
100
+		}
101
+		$repo_locale_URL = $repo_base_URL . '-' . EE_Load_Textdomain::$locale;
102
+		$file_name_base = 'event_espresso-' . EE_Load_Textdomain::$locale;
103 103
 
104
-        // made it here so let's get the language files from the github repo, first the .mo file
105
-        $sideloader->set_download_from("{$repo_locale_URL}.mo?raw=true");
106
-        $sideloader->set_new_file_name("{$file_name_base}.mo");
107
-        $sideloader->sideload();
104
+		// made it here so let's get the language files from the github repo, first the .mo file
105
+		$sideloader->set_download_from("{$repo_locale_URL}.mo?raw=true");
106
+		$sideloader->set_new_file_name("{$file_name_base}.mo");
107
+		$sideloader->sideload();
108 108
 
109
-        // now the .po file:
110
-        $sideloader->set_download_from("{$repo_locale_URL}.po?raw=true");
111
-        $sideloader->set_new_file_name("{$file_name_base}.po");
112
-        $sideloader->sideload();
109
+		// now the .po file:
110
+		$sideloader->set_download_from("{$repo_locale_URL}.po?raw=true");
111
+		$sideloader->set_new_file_name("{$file_name_base}.po");
112
+		$sideloader->sideload();
113 113
 
114
-        // set option so the above only runs when EE updates.
115
-        update_option($language_check_option_name, 1);
116
-    }
114
+		// set option so the above only runs when EE updates.
115
+		update_option($language_check_option_name, 1);
116
+	}
117 117
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -36,19 +36,19 @@  discard block
 block discarded – undo
36 36
     {
37 37
         EE_Load_Textdomain::loadTranslationsForLocale();
38 38
         // now load the textdomain
39
-        if (!empty(EE_Load_Textdomain::$locale)) {
40
-            $github_mo_path = EE_LANGUAGES_SAFE_DIR . 'event_espresso-' . EE_Load_Textdomain::$locale . '.mo';
39
+        if ( ! empty(EE_Load_Textdomain::$locale)) {
40
+            $github_mo_path = EE_LANGUAGES_SAFE_DIR.'event_espresso-'.EE_Load_Textdomain::$locale.'.mo';
41 41
             if (is_readable($github_mo_path)) {
42 42
                 load_plugin_textdomain('event_espresso', false, EE_LANGUAGES_SAFE_LOC);
43 43
                 return;
44 44
             }
45
-            $glotpress_mo_path = EE_LANGUAGES_SAFE_DIR . 'event-espresso-4-' . EE_Load_Textdomain::$locale . '.mo';
45
+            $glotpress_mo_path = EE_LANGUAGES_SAFE_DIR.'event-espresso-4-'.EE_Load_Textdomain::$locale.'.mo';
46 46
             if (is_readable($glotpress_mo_path)) {
47 47
                 load_textdomain('event_espresso', $glotpress_mo_path);
48 48
                 return;
49 49
             }
50 50
         }
51
-        load_plugin_textdomain('event_espresso', false, dirname(EE_PLUGIN_BASENAME) . '/languages/');
51
+        load_plugin_textdomain('event_espresso', false, dirname(EE_PLUGIN_BASENAME).'/languages/');
52 52
     }
53 53
 
54 54
 
@@ -71,7 +71,7 @@  discard block
 block discarded – undo
71 71
         if (empty(EE_Load_Textdomain::$locale)) {
72 72
             return;
73 73
         }
74
-        $language_check_option_name = 'ee_lang_check_' . EE_Load_Textdomain::$locale . '_' . EVENT_ESPRESSO_VERSION;
74
+        $language_check_option_name = 'ee_lang_check_'.EE_Load_Textdomain::$locale.'_'.EVENT_ESPRESSO_VERSION;
75 75
         // check if language files has already been sideloaded
76 76
         if (get_option($language_check_option_name)) {
77 77
             return;
@@ -81,8 +81,8 @@  discard block
 block discarded – undo
81 81
 
82 82
         // load sideloader and sideload the .POT file as this should always be included.
83 83
         $sideloader_args = array(
84
-            '_upload_to'     => EE_PLUGIN_DIR_PATH . 'languages/',
85
-            '_download_from'   => $repo_base_URL .'.pot?raw=true',
84
+            '_upload_to'     => EE_PLUGIN_DIR_PATH.'languages/',
85
+            '_download_from'   => $repo_base_URL.'.pot?raw=true',
86 86
             '_new_file_name' => 'event_espresso.pot',
87 87
         );
88 88
         /** @var EEH_Sideloader $sideloader */
@@ -98,8 +98,8 @@  discard block
 block discarded – undo
98 98
             update_option($language_check_option_name, 1);
99 99
             return;
100 100
         }
101
-        $repo_locale_URL = $repo_base_URL . '-' . EE_Load_Textdomain::$locale;
102
-        $file_name_base = 'event_espresso-' . EE_Load_Textdomain::$locale;
101
+        $repo_locale_URL = $repo_base_URL.'-'.EE_Load_Textdomain::$locale;
102
+        $file_name_base = 'event_espresso-'.EE_Load_Textdomain::$locale;
103 103
 
104 104
         // made it here so let's get the language files from the github repo, first the .mo file
105 105
         $sideloader->set_download_from("{$repo_locale_URL}.mo?raw=true");
Please login to merge, or discard this patch.
core/libraries/messages/EE_Messages_Scheduler.lib.php 2 patches
Indentation   +206 added lines, -206 removed lines patch added patch discarded remove patch
@@ -11,210 +11,210 @@
 block discarded – undo
11 11
 class EE_Messages_Scheduler extends EE_Base
12 12
 {
13 13
 
14
-    /**
15
-     * Number of seconds between batch sends/generates on the cron job.
16
-     * Defaults to 5 minutes in seconds.  If you want to change this interval, you can use the native WordPress
17
-     * `cron_schedules` filter and modify the existing custom `ee_message_cron` schedule interval added.
18
-     *
19
-     * @type int
20
-     */
21
-    const message_cron_schedule = 300;
22
-
23
-    /**
24
-     * Constructor
25
-     */
26
-    public function __construct()
27
-    {
28
-        // register tasks (and make sure only registered once).
29
-        if (! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
30
-            add_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'), 10);
31
-        }
32
-
33
-        // register callbacks for scheduled events (but make sure they are set only once).
34
-        if (! has_action(
35
-            'AHEE__EE_Messages_Scheduler__generation',
36
-            array('EE_Messages_Scheduler', 'batch_generation')
37
-        )) {
38
-            add_action('AHEE__EE_Messages_Scheduler__generation', array('EE_Messages_Scheduler', 'batch_generation'));
39
-            add_action('AHEE__EE_Messages_Scheduler__sending', array('EE_Messages_Scheduler', 'batch_sending'));
40
-            add_action('AHEE__EE_Messages_Scheduler__cleanup', array('EE_Messages_Scheduler', 'cleanup'));
41
-        }
42
-
43
-        // add custom schedules
44
-        add_filter('cron_schedules', array($this, 'custom_schedules'));
45
-    }
46
-
47
-
48
-    /**
49
-     * Add custom schedules for wp_cron
50
-     *
51
-     * @param $schedules
52
-     */
53
-    public function custom_schedules($schedules)
54
-    {
55
-        $schedules['ee_message_cron'] = array(
56
-            'interval' => self::message_cron_schedule,
57
-            'display'  => __(
58
-                'This is the cron time interval for EE Message schedules (defaults to once every 5 minutes)',
59
-                'event_espresso'
60
-            ),
61
-        );
62
-        return $schedules;
63
-    }
64
-
65
-
66
-    /**
67
-     * Callback for FHEE__EEH_Activation__get_cron_tasks that is used to retrieve scheduled Cron events to add and
68
-     * remove.
69
-     *
70
-     * @param array $tasks already existing scheduled tasks
71
-     * @return array
72
-     */
73
-    public function register_scheduled_tasks($tasks)
74
-    {
75
-        EE_Registry::instance()->load_helper('DTT_Helper');
76
-        $tasks['AHEE__EE_Messages_Scheduler__generation'] = 'ee_message_cron';
77
-        $tasks['AHEE__EE_Messages_Scheduler__sending']    = 'ee_message_cron';
78
-        $tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array( EEH_DTT_Helper::tomorrow(), 'daily');
79
-        return $tasks;
80
-    }
81
-
82
-
83
-    /**
84
-     * This initiates a non-blocking separate request to execute on a scheduled task.
85
-     * Note: The EED_Messages module has the handlers for these requests.
86
-     *
87
-     * @param string $task The task the request is being generated for.
88
-     */
89
-    public static function initiate_scheduled_non_blocking_request($task)
90
-    {
91
-        if (apply_filters(
92
-            'EE_Messages_Scheduler__initiate_scheduled_non_blocking_request__do_separate_request',
93
-            true
94
-        )) {
95
-            $request_url  = add_query_arg(
96
-                array_merge(
97
-                    array('ee' => 'msg_cron_trigger'),
98
-                    EE_Messages_Scheduler::get_request_params($task)
99
-                ),
100
-                site_url()
101
-            );
102
-            $request_args = array(
103
-                'timeout'     => 300,
104
-                'blocking'    => (defined('DOING_CRON') && DOING_CRON) || (defined('DOING_AJAX') && DOING_AJAX) ? true : false,
105
-                'sslverify'   => false,
106
-                'redirection' => 10,
107
-            );
108
-            $response     = wp_remote_get($request_url, $request_args);
109
-            if (is_wp_error($response)) {
110
-                trigger_error($response->get_error_message());
111
-            }
112
-        } else {
113
-            EE_Messages_Scheduler::initiate_immediate_request_on_cron($task);
114
-        }
115
-    }
116
-
117
-
118
-    /**
119
-     * This returns
120
-     * the request params used for a scheduled message task request.
121
-     *
122
-     * @param string $task The task the request is for.
123
-     * @return array
124
-     */
125
-    public static function get_request_params($task)
126
-    {
127
-        // transient is used for flood control on msg_cron_trigger requests
128
-        $transient_key = 'ee_trans_' . uniqid($task);
129
-        set_transient($transient_key, 1, 5 * MINUTE_IN_SECONDS);
130
-        return array(
131
-            'type' => $task,
132
-            'key'  => $transient_key,
133
-        );
134
-    }
135
-
136
-
137
-    /**
138
-     * This is used to execute an immediate call to the run_cron task performed by EED_Messages
139
-     *
140
-     * @param string $task The task the request is being generated for.
141
-     */
142
-    public static function initiate_immediate_request_on_cron($task)
143
-    {
144
-        $request_args = EE_Messages_Scheduler::get_request_params($task);
145
-        // set those request args in the request so it gets picked up
146
-        foreach ($request_args as $request_key => $request_value) {
147
-            EE_Registry::instance()->REQ->set($request_key, $request_value);
148
-        }
149
-        EED_Messages::instance()->run_cron();
150
-    }
151
-
152
-
153
-    /**
154
-     * Callback for scheduled AHEE__EE_Messages_Scheduler__generation wp cron event
155
-     */
156
-    public static function batch_generation()
157
-    {
158
-        /**
159
-         * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
160
-         */
161
-        if (! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
162
-            || ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
163
-        ) {
164
-            EE_Messages_Scheduler::initiate_immediate_request_on_cron('generate');
165
-        }
166
-    }
167
-
168
-
169
-    /**
170
-     * Callback for scheduled AHEE__EE_Messages_Scheduler__sending
171
-     */
172
-    public static function batch_sending()
173
-    {
174
-        /**
175
-         * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
176
-         */
177
-        if (! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
178
-            || ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
179
-        ) {
180
-            EE_Messages_Scheduler::initiate_immediate_request_on_cron('send');
181
-        }
182
-    }
183
-
184
-
185
-    /**
186
-     * This is the callback for the `AHEE__EE_Messages_Scheduler__cleanup` scheduled event action.
187
-     * This runs once a day and if cleanup is active (set via messages settings), it will (by default) delete permanently
188
-     * from the database messages that have a MSG_modified date older than 30 days.
189
-     */
190
-    public static function cleanup()
191
-    {
192
-        // First, confirm that the generation and sending EE_Messages_Scheduler crons are
193
-        // set and reschedule them if they are not.
194
-        $message_crons_to_check = array(
195
-            'AHEE__EE_Messages_Scheduler__generation' => 'ee_message_cron',
196
-            'AHEE__EE_Messages_Scheduler__sending'    => 'ee_message_cron',
197
-        );
198
-        foreach ($message_crons_to_check as $hook_name => $frequency) {
199
-            if (! wp_next_scheduled($hook_name)) {
200
-                wp_schedule_event(time(), $frequency, $hook_name);
201
-            }
202
-        }
203
-
204
-        // check if user has cleanup turned on or if we're in maintenance mode.  If in maintenance mode we'll wait
205
-        // until the next scheduled event.
206
-        if (! EE_Registry::instance()->CFG->messages->delete_threshold
207
-            || ! EE_Maintenance_Mode::instance()->models_can_query()
208
-        ) {
209
-            return;
210
-        }
211
-
212
-        /**
213
-         * This filter switch allows other code (such as the EE_Worker_Queue add-on) to replace this with its own handling
214
-         * of deleting messages.
215
-         */
216
-        if (apply_filters('FHEE__EE_Messages_Scheduler__cleanup__handle_cleanup_on_cron', true)) {
217
-            EEM_Message::instance()->delete_old_messages(EE_Registry::instance()->CFG->messages->delete_threshold);
218
-        }
219
-    }
14
+	/**
15
+	 * Number of seconds between batch sends/generates on the cron job.
16
+	 * Defaults to 5 minutes in seconds.  If you want to change this interval, you can use the native WordPress
17
+	 * `cron_schedules` filter and modify the existing custom `ee_message_cron` schedule interval added.
18
+	 *
19
+	 * @type int
20
+	 */
21
+	const message_cron_schedule = 300;
22
+
23
+	/**
24
+	 * Constructor
25
+	 */
26
+	public function __construct()
27
+	{
28
+		// register tasks (and make sure only registered once).
29
+		if (! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
30
+			add_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'), 10);
31
+		}
32
+
33
+		// register callbacks for scheduled events (but make sure they are set only once).
34
+		if (! has_action(
35
+			'AHEE__EE_Messages_Scheduler__generation',
36
+			array('EE_Messages_Scheduler', 'batch_generation')
37
+		)) {
38
+			add_action('AHEE__EE_Messages_Scheduler__generation', array('EE_Messages_Scheduler', 'batch_generation'));
39
+			add_action('AHEE__EE_Messages_Scheduler__sending', array('EE_Messages_Scheduler', 'batch_sending'));
40
+			add_action('AHEE__EE_Messages_Scheduler__cleanup', array('EE_Messages_Scheduler', 'cleanup'));
41
+		}
42
+
43
+		// add custom schedules
44
+		add_filter('cron_schedules', array($this, 'custom_schedules'));
45
+	}
46
+
47
+
48
+	/**
49
+	 * Add custom schedules for wp_cron
50
+	 *
51
+	 * @param $schedules
52
+	 */
53
+	public function custom_schedules($schedules)
54
+	{
55
+		$schedules['ee_message_cron'] = array(
56
+			'interval' => self::message_cron_schedule,
57
+			'display'  => __(
58
+				'This is the cron time interval for EE Message schedules (defaults to once every 5 minutes)',
59
+				'event_espresso'
60
+			),
61
+		);
62
+		return $schedules;
63
+	}
64
+
65
+
66
+	/**
67
+	 * Callback for FHEE__EEH_Activation__get_cron_tasks that is used to retrieve scheduled Cron events to add and
68
+	 * remove.
69
+	 *
70
+	 * @param array $tasks already existing scheduled tasks
71
+	 * @return array
72
+	 */
73
+	public function register_scheduled_tasks($tasks)
74
+	{
75
+		EE_Registry::instance()->load_helper('DTT_Helper');
76
+		$tasks['AHEE__EE_Messages_Scheduler__generation'] = 'ee_message_cron';
77
+		$tasks['AHEE__EE_Messages_Scheduler__sending']    = 'ee_message_cron';
78
+		$tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array( EEH_DTT_Helper::tomorrow(), 'daily');
79
+		return $tasks;
80
+	}
81
+
82
+
83
+	/**
84
+	 * This initiates a non-blocking separate request to execute on a scheduled task.
85
+	 * Note: The EED_Messages module has the handlers for these requests.
86
+	 *
87
+	 * @param string $task The task the request is being generated for.
88
+	 */
89
+	public static function initiate_scheduled_non_blocking_request($task)
90
+	{
91
+		if (apply_filters(
92
+			'EE_Messages_Scheduler__initiate_scheduled_non_blocking_request__do_separate_request',
93
+			true
94
+		)) {
95
+			$request_url  = add_query_arg(
96
+				array_merge(
97
+					array('ee' => 'msg_cron_trigger'),
98
+					EE_Messages_Scheduler::get_request_params($task)
99
+				),
100
+				site_url()
101
+			);
102
+			$request_args = array(
103
+				'timeout'     => 300,
104
+				'blocking'    => (defined('DOING_CRON') && DOING_CRON) || (defined('DOING_AJAX') && DOING_AJAX) ? true : false,
105
+				'sslverify'   => false,
106
+				'redirection' => 10,
107
+			);
108
+			$response     = wp_remote_get($request_url, $request_args);
109
+			if (is_wp_error($response)) {
110
+				trigger_error($response->get_error_message());
111
+			}
112
+		} else {
113
+			EE_Messages_Scheduler::initiate_immediate_request_on_cron($task);
114
+		}
115
+	}
116
+
117
+
118
+	/**
119
+	 * This returns
120
+	 * the request params used for a scheduled message task request.
121
+	 *
122
+	 * @param string $task The task the request is for.
123
+	 * @return array
124
+	 */
125
+	public static function get_request_params($task)
126
+	{
127
+		// transient is used for flood control on msg_cron_trigger requests
128
+		$transient_key = 'ee_trans_' . uniqid($task);
129
+		set_transient($transient_key, 1, 5 * MINUTE_IN_SECONDS);
130
+		return array(
131
+			'type' => $task,
132
+			'key'  => $transient_key,
133
+		);
134
+	}
135
+
136
+
137
+	/**
138
+	 * This is used to execute an immediate call to the run_cron task performed by EED_Messages
139
+	 *
140
+	 * @param string $task The task the request is being generated for.
141
+	 */
142
+	public static function initiate_immediate_request_on_cron($task)
143
+	{
144
+		$request_args = EE_Messages_Scheduler::get_request_params($task);
145
+		// set those request args in the request so it gets picked up
146
+		foreach ($request_args as $request_key => $request_value) {
147
+			EE_Registry::instance()->REQ->set($request_key, $request_value);
148
+		}
149
+		EED_Messages::instance()->run_cron();
150
+	}
151
+
152
+
153
+	/**
154
+	 * Callback for scheduled AHEE__EE_Messages_Scheduler__generation wp cron event
155
+	 */
156
+	public static function batch_generation()
157
+	{
158
+		/**
159
+		 * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
160
+		 */
161
+		if (! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
162
+			|| ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
163
+		) {
164
+			EE_Messages_Scheduler::initiate_immediate_request_on_cron('generate');
165
+		}
166
+	}
167
+
168
+
169
+	/**
170
+	 * Callback for scheduled AHEE__EE_Messages_Scheduler__sending
171
+	 */
172
+	public static function batch_sending()
173
+	{
174
+		/**
175
+		 * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
176
+		 */
177
+		if (! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
178
+			|| ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
179
+		) {
180
+			EE_Messages_Scheduler::initiate_immediate_request_on_cron('send');
181
+		}
182
+	}
183
+
184
+
185
+	/**
186
+	 * This is the callback for the `AHEE__EE_Messages_Scheduler__cleanup` scheduled event action.
187
+	 * This runs once a day and if cleanup is active (set via messages settings), it will (by default) delete permanently
188
+	 * from the database messages that have a MSG_modified date older than 30 days.
189
+	 */
190
+	public static function cleanup()
191
+	{
192
+		// First, confirm that the generation and sending EE_Messages_Scheduler crons are
193
+		// set and reschedule them if they are not.
194
+		$message_crons_to_check = array(
195
+			'AHEE__EE_Messages_Scheduler__generation' => 'ee_message_cron',
196
+			'AHEE__EE_Messages_Scheduler__sending'    => 'ee_message_cron',
197
+		);
198
+		foreach ($message_crons_to_check as $hook_name => $frequency) {
199
+			if (! wp_next_scheduled($hook_name)) {
200
+				wp_schedule_event(time(), $frequency, $hook_name);
201
+			}
202
+		}
203
+
204
+		// check if user has cleanup turned on or if we're in maintenance mode.  If in maintenance mode we'll wait
205
+		// until the next scheduled event.
206
+		if (! EE_Registry::instance()->CFG->messages->delete_threshold
207
+			|| ! EE_Maintenance_Mode::instance()->models_can_query()
208
+		) {
209
+			return;
210
+		}
211
+
212
+		/**
213
+		 * This filter switch allows other code (such as the EE_Worker_Queue add-on) to replace this with its own handling
214
+		 * of deleting messages.
215
+		 */
216
+		if (apply_filters('FHEE__EE_Messages_Scheduler__cleanup__handle_cleanup_on_cron', true)) {
217
+			EEM_Message::instance()->delete_old_messages(EE_Registry::instance()->CFG->messages->delete_threshold);
218
+		}
219
+	}
220 220
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -26,12 +26,12 @@  discard block
 block discarded – undo
26 26
     public function __construct()
27 27
     {
28 28
         // register tasks (and make sure only registered once).
29
-        if (! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
29
+        if ( ! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
30 30
             add_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'), 10);
31 31
         }
32 32
 
33 33
         // register callbacks for scheduled events (but make sure they are set only once).
34
-        if (! has_action(
34
+        if ( ! has_action(
35 35
             'AHEE__EE_Messages_Scheduler__generation',
36 36
             array('EE_Messages_Scheduler', 'batch_generation')
37 37
         )) {
@@ -75,7 +75,7 @@  discard block
 block discarded – undo
75 75
         EE_Registry::instance()->load_helper('DTT_Helper');
76 76
         $tasks['AHEE__EE_Messages_Scheduler__generation'] = 'ee_message_cron';
77 77
         $tasks['AHEE__EE_Messages_Scheduler__sending']    = 'ee_message_cron';
78
-        $tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array( EEH_DTT_Helper::tomorrow(), 'daily');
78
+        $tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array(EEH_DTT_Helper::tomorrow(), 'daily');
79 79
         return $tasks;
80 80
     }
81 81
 
@@ -92,7 +92,7 @@  discard block
 block discarded – undo
92 92
             'EE_Messages_Scheduler__initiate_scheduled_non_blocking_request__do_separate_request',
93 93
             true
94 94
         )) {
95
-            $request_url  = add_query_arg(
95
+            $request_url = add_query_arg(
96 96
                 array_merge(
97 97
                     array('ee' => 'msg_cron_trigger'),
98 98
                     EE_Messages_Scheduler::get_request_params($task)
@@ -105,7 +105,7 @@  discard block
 block discarded – undo
105 105
                 'sslverify'   => false,
106 106
                 'redirection' => 10,
107 107
             );
108
-            $response     = wp_remote_get($request_url, $request_args);
108
+            $response = wp_remote_get($request_url, $request_args);
109 109
             if (is_wp_error($response)) {
110 110
                 trigger_error($response->get_error_message());
111 111
             }
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
     public static function get_request_params($task)
126 126
     {
127 127
         // transient is used for flood control on msg_cron_trigger requests
128
-        $transient_key = 'ee_trans_' . uniqid($task);
128
+        $transient_key = 'ee_trans_'.uniqid($task);
129 129
         set_transient($transient_key, 1, 5 * MINUTE_IN_SECONDS);
130 130
         return array(
131 131
             'type' => $task,
@@ -158,7 +158,7 @@  discard block
 block discarded – undo
158 158
         /**
159 159
          * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
160 160
          */
161
-        if (! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
161
+        if ( ! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
162 162
             || ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
163 163
         ) {
164 164
             EE_Messages_Scheduler::initiate_immediate_request_on_cron('generate');
@@ -174,7 +174,7 @@  discard block
 block discarded – undo
174 174
         /**
175 175
          * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
176 176
          */
177
-        if (! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
177
+        if ( ! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
178 178
             || ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
179 179
         ) {
180 180
             EE_Messages_Scheduler::initiate_immediate_request_on_cron('send');
@@ -196,14 +196,14 @@  discard block
 block discarded – undo
196 196
             'AHEE__EE_Messages_Scheduler__sending'    => 'ee_message_cron',
197 197
         );
198 198
         foreach ($message_crons_to_check as $hook_name => $frequency) {
199
-            if (! wp_next_scheduled($hook_name)) {
199
+            if ( ! wp_next_scheduled($hook_name)) {
200 200
                 wp_schedule_event(time(), $frequency, $hook_name);
201 201
             }
202 202
         }
203 203
 
204 204
         // check if user has cleanup turned on or if we're in maintenance mode.  If in maintenance mode we'll wait
205 205
         // until the next scheduled event.
206
-        if (! EE_Registry::instance()->CFG->messages->delete_threshold
206
+        if ( ! EE_Registry::instance()->CFG->messages->delete_threshold
207 207
             || ! EE_Maintenance_Mode::instance()->models_can_query()
208 208
         ) {
209 209
             return;
Please login to merge, or discard this patch.
core/helpers/EEH_Event_Query.helper.php 2 patches
Indentation   +672 added lines, -672 removed lines patch added patch discarded remove patch
@@ -15,676 +15,676 @@
 block discarded – undo
15 15
 class EEH_Event_Query
16 16
 {
17 17
 
18
-    /**
19
-     * Start Date
20
-     *
21
-     * @var $_event_query_month
22
-     */
23
-    protected static $_event_query_month;
24
-
25
-    /**
26
-     * Category
27
-     *
28
-     * @var $_event_query_category
29
-     */
30
-    protected static $_event_query_category;
31
-
32
-    /**
33
-     * whether to display expired events in the event list
34
-     *
35
-     * @var bool $_show_expired
36
-     */
37
-    protected static $_event_query_show_expired = false;
38
-
39
-    /**
40
-     * list of params for controlling how the query results are ordered
41
-     *
42
-     * @var array $_event_query_orderby
43
-     */
44
-    protected static $_event_query_orderby = array();
45
-
46
-    /**
47
-     * direction list is sorted
48
-     *
49
-     * @var string $_event_query_sort
50
-     */
51
-    protected static $_event_query_sort;
52
-
53
-    /**
54
-     * list of params used to build the query's various clauses
55
-     *
56
-     * @var $_query_params
57
-     */
58
-    protected static $_query_params = array();
59
-
60
-
61
-
62
-    /**
63
-     * @return void
64
-     */
65
-    public static function add_query_filters()
66
-    {
67
-        // add query filters
68
-        add_action('pre_get_posts', array('EEH_Event_Query', 'filter_query_parts'), 10, 1);
69
-    }
70
-
71
-
72
-
73
-    /**
74
-     * @param WP_Query $WP_Query
75
-     * @return bool
76
-     */
77
-    public static function apply_query_filters(WP_Query $WP_Query)
78
-    {
79
-        return (
80
-                   isset($WP_Query->query['post_type'])
81
-                   && $WP_Query->query['post_type'] === 'espresso_events'
82
-               )
83
-               || apply_filters('FHEE__EEH_Event_Query__apply_query_filters', false);
84
-    }
85
-
86
-
87
-    /**
88
-     * @param WP_Query $WP_Query
89
-     */
90
-    public static function filter_query_parts(WP_Query $WP_Query)
91
-    {
92
-        // ONLY add our filters if this isn't the main wp_query,
93
-        // because if this is the main wp_query we already have
94
-        // our cpt strategies take care of adding things in.
95
-        if ($WP_Query instanceof WP_Query && ! $WP_Query->is_main_query()) {
96
-            // build event list query
97
-            add_filter('posts_fields', array('EEH_Event_Query', 'posts_fields'), 10, 2);
98
-            add_filter('posts_join', array('EEH_Event_Query', 'posts_join'), 10, 2);
99
-            add_filter('posts_where', array('EEH_Event_Query', 'posts_where'), 10, 2);
100
-            add_filter('posts_orderby', array('EEH_Event_Query', 'posts_orderby'), 10, 2);
101
-            add_filter('posts_clauses_request', array('EEH_Event_Query', 'posts_clauses'), 10, 2);
102
-        }
103
-    }
104
-
105
-
106
-
107
-    /**
108
-     * @param string $month
109
-     * @param string $category
110
-     * @param bool   $show_expired
111
-     * @param string $orderby
112
-     * @param string $sort
113
-     * @throws InvalidArgumentException
114
-     * @throws InvalidDataTypeException
115
-     * @throws InvalidInterfaceException
116
-     */
117
-    public static function set_query_params(
118
-        $month = '',
119
-        $category = '',
120
-        $show_expired = false,
121
-        $orderby = 'start_date',
122
-        $sort = 'ASC'
123
-    ) {
124
-        self::$_query_params                        = array();
125
-        EEH_Event_Query::$_event_query_month        = EEH_Event_Query::_display_month($month);
126
-        EEH_Event_Query::$_event_query_category     = EEH_Event_Query::_event_category_slug($category);
127
-        EEH_Event_Query::$_event_query_show_expired = EEH_Event_Query::_show_expired($show_expired);
128
-        EEH_Event_Query::$_event_query_orderby      = EEH_Event_Query::_orderby($orderby);
129
-        EEH_Event_Query::$_event_query_sort         = EEH_Event_Query::_sort($sort);
130
-    }
131
-
132
-
133
-
134
-    /**
135
-     * what month should the event list display events for?
136
-     *
137
-     * @param string $month
138
-     * @return string
139
-     * @throws InvalidArgumentException
140
-     * @throws InvalidDataTypeException
141
-     * @throws InvalidInterfaceException
142
-     */
143
-    private static function _display_month($month = '')
144
-    {
145
-        return sanitize_text_field(EE_Registry::instance()->REQ->get('event_query_month', $month));
146
-    }
147
-
148
-
149
-
150
-    /**
151
-     * @param string $category
152
-     * @return string
153
-     * @throws InvalidArgumentException
154
-     * @throws InvalidDataTypeException
155
-     * @throws InvalidInterfaceException
156
-     */
157
-    private static function _event_category_slug($category = '')
158
-    {
159
-        return sanitize_text_field(EE_Registry::instance()->REQ->get('event_query_category', $category));
160
-    }
161
-
162
-
163
-
164
-    /**
165
-     * @param bool $show_expired
166
-     * @return bool
167
-     * @throws InvalidArgumentException
168
-     * @throws InvalidDataTypeException
169
-     * @throws InvalidInterfaceException
170
-     */
171
-    private static function _show_expired($show_expired = false)
172
-    {
173
-        // override default expired option if set via filter
174
-        return filter_var(
175
-            EE_Registry::instance()->REQ->get('event_query_show_expired', $show_expired),
176
-            FILTER_VALIDATE_BOOLEAN
177
-        );
178
-    }
179
-
180
-
181
-
182
-    /**
183
-     * @param    string $orderby
184
-     * @return array
185
-     * @throws InvalidArgumentException
186
-     * @throws InvalidDataTypeException
187
-     * @throws InvalidInterfaceException
188
-     */
189
-    private static function _orderby($orderby = 'start_date')
190
-    {
191
-        $event_query_orderby = EE_Registry::instance()->REQ->get('event_query_orderby', $orderby);
192
-        $event_query_orderby = is_array($event_query_orderby)
193
-            ? $event_query_orderby
194
-            : explode(',', $event_query_orderby);
195
-        $event_query_orderby = array_map('trim', $event_query_orderby);
196
-        $event_query_orderby = array_map('sanitize_text_field', $event_query_orderby);
197
-        return $event_query_orderby;
198
-    }
199
-
200
-
201
-
202
-    /**
203
-     * @param string $sort
204
-     * @return string
205
-     * @throws InvalidArgumentException
206
-     * @throws InvalidDataTypeException
207
-     * @throws InvalidInterfaceException
208
-     */
209
-    private static function _sort($sort = 'ASC')
210
-    {
211
-        $sort = EE_Registry::instance()->REQ->get('event_query_sort', $sort);
212
-        return in_array($sort, array('ASC', 'asc', 'DESC', 'desc'), true)
213
-            ? strtoupper($sort)
214
-            : 'ASC';
215
-    }
216
-
217
-
218
-
219
-    /**
220
-     * Filters the clauses for the WP_Query object
221
-     *
222
-     * @param array    $clauses array of clauses
223
-     * @param WP_Query $wp_query
224
-     * @return array   array of clauses
225
-     */
226
-    public static function posts_clauses($clauses, WP_Query $wp_query)
227
-    {
228
-        if (EEH_Event_Query::apply_query_filters($wp_query)) {
229
-            global $wpdb;
230
-            $clauses['groupby'] = $wpdb->posts . '.ID ';
231
-        }
232
-        return $clauses;
233
-    }
234
-
235
-
236
-
237
-    /**
238
-     * @param string   $SQL
239
-     * @param WP_Query $wp_query
240
-     * @return string
241
-     * @throws EE_Error
242
-     * @throws InvalidArgumentException
243
-     * @throws InvalidDataTypeException
244
-     * @throws InvalidInterfaceException
245
-     */
246
-    public static function posts_fields($SQL, WP_Query $wp_query)
247
-    {
248
-        if (EEH_Event_Query::apply_query_filters($wp_query)) {
249
-            // adds something like ", wp_esp_datetime.* " to WP Query SELECT statement
250
-            $SQL .= EEH_Event_Query::posts_fields_sql_for_orderby(EEH_Event_Query::$_event_query_orderby);
251
-        }
252
-        return $SQL;
253
-    }
254
-
255
-
256
-
257
-    /**
258
-     * @param array $orderby_params
259
-     * @return string
260
-     * @throws EE_Error
261
-     * @throws InvalidArgumentException
262
-     * @throws InvalidDataTypeException
263
-     * @throws InvalidInterfaceException
264
-     */
265
-    public static function posts_fields_sql_for_orderby(array $orderby_params = array())
266
-    {
267
-        $SQL = ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date ';
268
-        foreach ($orderby_params as $orderby) {
269
-            switch ($orderby) {
270
-                case 'ticket_start':
271
-                    $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_start_date';
272
-                    break;
273
-                case 'ticket_end':
274
-                    $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_end_date';
275
-                    break;
276
-                case 'venue_title':
277
-                    $SQL .= ', Venue.post_title AS venue_title';
278
-                    break;
279
-                case 'city':
280
-                    $SQL .= ', ' . EEM_Venue::instance()->second_table() . '.VNU_city';
281
-                    break;
282
-                case 'state':
283
-                    $SQL .= ', ' . EEM_State::instance()->table() . '.STA_name';
284
-                    break;
285
-            }
286
-        }
287
-        return $SQL;
288
-    }
289
-
290
-
291
-
292
-    /**
293
-     * @param string   $SQL
294
-     * @param WP_Query $wp_query
295
-     * @return string
296
-     * @throws EE_Error
297
-     * @throws InvalidArgumentException
298
-     * @throws InvalidDataTypeException
299
-     * @throws InvalidInterfaceException
300
-     */
301
-    public static function posts_join($SQL = '', WP_Query $wp_query)
302
-    {
303
-        if (EEH_Event_Query::apply_query_filters($wp_query)) {
304
-            // Category
305
-            $SQL = EEH_Event_Query::posts_join_sql_for_show_expired($SQL, EEH_Event_Query::$_event_query_show_expired);
306
-            $SQL = EEH_Event_Query::posts_join_sql_for_terms($SQL, EEH_Event_Query::$_event_query_category);
307
-            $SQL = EEH_Event_Query::posts_join_for_orderby($SQL, EEH_Event_Query::$_event_query_orderby);
308
-        }
309
-        return $SQL;
310
-    }
311
-
312
-
313
-
314
-    /**
315
-     * @param string  $SQL
316
-     * @param boolean $show_expired if TRUE, then displayed past events
317
-     * @return string
318
-     * @throws EE_Error
319
-     * @throws InvalidArgumentException
320
-     * @throws InvalidDataTypeException
321
-     * @throws InvalidInterfaceException
322
-     */
323
-    public static function posts_join_sql_for_show_expired($SQL = '', $show_expired = false)
324
-    {
325
-        if (! $show_expired) {
326
-            $join = EEM_Event::instance()->table() . '.ID = ';
327
-            $join .= EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name();
328
-            // don't add if this is already in the SQL
329
-            if (strpos($SQL, $join) === false) {
330
-                $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' ) ';
331
-            }
332
-        }
333
-        return $SQL;
334
-    }
335
-
336
-
337
-
338
-    /**
339
-     * @param string $SQL
340
-     * @param string $join_terms    pass TRUE or term string, doesn't really matter since this value doesn't really get
341
-     *                              used for anything yet
342
-     * @return string
343
-     */
344
-    public static function posts_join_sql_for_terms($SQL = '', $join_terms = '')
345
-    {
346
-        if (! empty($join_terms)) {
347
-            global $wpdb;
348
-            $SQL .= " LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)";
349
-            $SQL .= " LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
350
-            $SQL .= " LEFT JOIN $wpdb->terms ON ($wpdb->terms.term_id = $wpdb->term_taxonomy.term_id) ";
351
-        }
352
-        return $SQL;
353
-    }
354
-
355
-
356
-
357
-    /**
358
-     * usage:  $SQL .= EEH_Event_Query::posts_join_for_orderby( $orderby_params );
359
-     *
360
-     * @param    string $SQL
361
-     * @param    array  $orderby_params
362
-     * @return string
363
-     * @throws EE_Error
364
-     * @throws InvalidArgumentException
365
-     * @throws InvalidDataTypeException
366
-     * @throws InvalidInterfaceException
367
-     */
368
-    public static function posts_join_for_orderby($SQL = '', array $orderby_params = array())
369
-    {
370
-        foreach ($orderby_params as $orderby) {
371
-            switch ($orderby) {
372
-                case 'ticket_start':
373
-                case 'ticket_end':
374
-                    $SQL .= EEH_Event_Query::_posts_join_for_datetime(
375
-                        $SQL,
376
-                        EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Datetime::instance()->primary_key_name()
377
-                    );
378
-                    $SQL .= ' LEFT JOIN ' . EEM_Ticket::instance()->table();
379
-                    $SQL .= ' ON (';
380
-                    $SQL .= EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name();
381
-                    $SQL .= ' = ';
382
-                    $SQL .= EEM_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name();
383
-                    $SQL .= ' )';
384
-                    break;
385
-                case 'venue_title':
386
-                case 'city':
387
-                    $SQL .= EEH_Event_Query::_posts_join_for_event_venue($SQL);
388
-                    break;
389
-                case 'state':
390
-                    $SQL .= EEH_Event_Query::_posts_join_for_event_venue($SQL);
391
-                    $SQL .= EEH_Event_Query::_posts_join_for_venue_state($SQL);
392
-                    break;
393
-                case 'start_date':
394
-                default:
395
-                    $SQL .= EEH_Event_Query::_posts_join_for_datetime($SQL, EEM_Event::instance()->table() . '.ID');
396
-                    break;
397
-            }
398
-        }
399
-        return $SQL;
400
-    }
401
-
402
-
403
-
404
-    /**
405
-     * @param string $SQL
406
-     * @param string $join
407
-     * @return string
408
-     * @throws EE_Error
409
-     * @throws InvalidArgumentException
410
-     * @throws InvalidDataTypeException
411
-     * @throws InvalidInterfaceException
412
-     */
413
-    protected static function _posts_join_for_datetime($SQL = '', $join = '')
414
-    {
415
-        if (! empty($join)) {
416
-            $join .= ' = ' . EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name();
417
-            if (strpos($SQL, $join) === false) {
418
-                return ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' )';
419
-            }
420
-        }
421
-        return '';
422
-    }
423
-
424
-
425
-
426
-    /**
427
-     * @param string $SQL
428
-     * @return string
429
-     * @throws EE_Error
430
-     * @throws InvalidArgumentException
431
-     * @throws InvalidDataTypeException
432
-     * @throws InvalidInterfaceException
433
-     */
434
-    protected static function _posts_join_for_event_venue($SQL = '')
435
-    {
436
-        // Event Venue table name
437
-        $event_venue_table = EEM_Event_Venue::instance()->table();
438
-        // generate conditions for:  Event <=> Event Venue  JOIN clause
439
-        $event_to_event_venue_join = EEM_Event::instance()->table() . '.ID = ';
440
-        $event_to_event_venue_join .= $event_venue_table . '.' . EEM_Event::instance()->primary_key_name();
441
-        // don't add joins if they have already been added
442
-        if (strpos($SQL, $event_to_event_venue_join) === false) {
443
-            // Venue table name
444
-            $venue_table = EEM_Venue::instance()->table();
445
-            // Venue table pk
446
-            $venue_table_pk = EEM_Venue::instance()->primary_key_name();
447
-            // Venue Meta table name
448
-            $venue_meta_table = EEM_Venue::instance()->second_table();
449
-            // generate JOIN clause for: Event <=> Event Venue
450
-            $venue_SQL = " LEFT JOIN $event_venue_table ON ( $event_to_event_venue_join )";
451
-            // generate JOIN clause for: Event Venue <=> Venue
452
-            $venue_SQL .= " LEFT JOIN $venue_table as Venue ON ( $event_venue_table.$venue_table_pk = Venue.ID )";
453
-            // generate JOIN clause for: Venue <=> Venue Meta
454
-            $venue_SQL .= " LEFT JOIN $venue_meta_table ON ( Venue.ID = $venue_meta_table.$venue_table_pk )";
455
-            unset($event_venue_table, $event_to_event_venue_join, $venue_table, $venue_table_pk, $venue_meta_table);
456
-            return $venue_SQL;
457
-        }
458
-        unset($event_venue_table, $event_to_event_venue_join);
459
-        return '';
460
-    }
461
-
462
-
463
-
464
-    /**
465
-     * @param string $SQL
466
-     * @return string
467
-     * @throws EE_Error
468
-     * @throws InvalidArgumentException
469
-     * @throws InvalidDataTypeException
470
-     * @throws InvalidInterfaceException
471
-     */
472
-    protected static function _posts_join_for_venue_state($SQL = '')
473
-    {
474
-        // Venue Meta table name
475
-        $venue_meta_table = EEM_Venue::instance()->second_table();
476
-        // State table name
477
-        $state_table = EEM_State::instance()->table();
478
-        // State table pk
479
-        $state_table_pk = EEM_State::instance()->primary_key_name();
480
-        // verify vars
481
-        if ($venue_meta_table && $state_table && $state_table_pk) {
482
-            // like: wp_esp_venue_meta.STA_ID = wp_esp_state.STA_ID
483
-            $join = "$venue_meta_table.$state_table_pk = $state_table.$state_table_pk";
484
-            // don't add join if it has already been added
485
-            if (strpos($SQL, $join) === false) {
486
-                unset($state_table_pk, $venue_meta_table, $venue_table_pk);
487
-                return " LEFT JOIN $state_table ON ( $join )";
488
-            }
489
-        }
490
-        unset($join, $state_table, $state_table_pk, $venue_meta_table, $venue_table_pk);
491
-        return '';
492
-    }
493
-
494
-
495
-
496
-    /**
497
-     * @param string   $SQL
498
-     * @param WP_Query $wp_query
499
-     * @return string
500
-     * @throws EE_Error
501
-     * @throws InvalidArgumentException
502
-     * @throws InvalidDataTypeException
503
-     * @throws InvalidInterfaceException
504
-     */
505
-    public static function posts_where($SQL = '', WP_Query $wp_query)
506
-    {
507
-        if (EEH_Event_Query::apply_query_filters($wp_query)) {
508
-            // Show Expired ?
509
-            $SQL .= EEH_Event_Query::posts_where_sql_for_show_expired(EEH_Event_Query::$_event_query_show_expired);
510
-            // Category
511
-            $SQL .= EEH_Event_Query::posts_where_sql_for_event_category_slug(EEH_Event_Query::$_event_query_category);
512
-            // Start Date
513
-            $SQL .= EEH_Event_Query::posts_where_sql_for_event_list_month(EEH_Event_Query::$_event_query_month);
514
-        }
515
-        return $SQL;
516
-    }
517
-
518
-
519
-
520
-    /**
521
-     * @param    boolean $show_expired if TRUE, then displayed past events
522
-     * @return string
523
-     * @throws EE_Error
524
-     * @throws InvalidArgumentException
525
-     * @throws InvalidDataTypeException
526
-     * @throws InvalidInterfaceException
527
-     */
528
-    public static function posts_where_sql_for_show_expired($show_expired = false)
529
-    {
530
-        return ! $show_expired
531
-            ? ' AND ' . EEM_Datetime::instance()->table() . '.DTT_EVT_end > \'' . current_time('mysql', true) . '\' '
532
-            : '';
533
-    }
534
-
535
-
536
-
537
-    /**
538
-     * @param boolean $event_category_slug
539
-     * @return string
540
-     */
541
-    public static function posts_where_sql_for_event_category_slug($event_category_slug = null)
542
-    {
543
-        global $wpdb;
544
-        if (! empty($event_category_slug)) {
545
-            $event_category_slugs_array = array_map('trim', explode(',', $event_category_slug));
546
-            $event_category_slugs_prepare = implode(', ', array_fill(0, count($event_category_slugs_array), '%s'));
547
-            return $wpdb->prepare(" AND {$wpdb->terms}.slug IN ({$event_category_slugs_prepare}) ", $event_category_slugs_array);
548
-        }
549
-        return '';
550
-    }
551
-
552
-
553
-
554
-    /**
555
-     * @param boolean $month
556
-     * @return string
557
-     * @throws EE_Error
558
-     * @throws InvalidArgumentException
559
-     * @throws InvalidDataTypeException
560
-     * @throws InvalidInterfaceException
561
-     */
562
-    public static function posts_where_sql_for_event_list_month($month = null)
563
-    {
564
-        $SQL = '';
565
-        if (! empty($month)) {
566
-            $datetime_table = EEM_Datetime::instance()->table();
567
-            // event start date is LESS than the end of the month ( so nothing that doesn't start until next month )
568
-            $SQL = " AND {$datetime_table}.DTT_EVT_start <= '";
569
-            $SQL .= date('Y-m-t 23:59:59', \EEH_DTT_Helper::first_of_month_timestamp($month)) . "'";
570
-            // event end date is GREATER than the start of the month ( so nothing that ended before this month )
571
-            $SQL .= " AND {$datetime_table}.DTT_EVT_end >= '";
572
-            $SQL .= date('Y-m-01 0:0:00', \EEH_DTT_Helper::first_of_month_timestamp($month)) . "' ";
573
-        }
574
-        return $SQL;
575
-    }
576
-
577
-
578
-
579
-    /**
580
-     * @param string $SQL
581
-     * @param WP_Query $wp_query
582
-     * @return string
583
-     * @throws EE_Error
584
-     * @throws InvalidArgumentException
585
-     * @throws InvalidDataTypeException
586
-     * @throws InvalidInterfaceException
587
-     */
588
-    public static function posts_orderby($SQL = '', WP_Query $wp_query)
589
-    {
590
-        if (EEH_Event_Query::apply_query_filters($wp_query)) {
591
-            $SQL = EEH_Event_Query::posts_orderby_sql(
592
-                EEH_Event_Query::$_event_query_orderby,
593
-                EEH_Event_Query::$_event_query_sort
594
-            );
595
-        }
596
-        return $SQL;
597
-    }
598
-
599
-
600
-
601
-    /**
602
-     *    posts_orderby_sql
603
-     *    possible parameters:
604
-     *    ID
605
-     *    start_date
606
-     *    end_date
607
-     *    event_name
608
-     *    category_slug
609
-     *    ticket_start
610
-     *    ticket_end
611
-     *    venue_title
612
-     *    city
613
-     *    state
614
-     *    **IMPORTANT**
615
-     *    make sure to also send the $orderby_params array to the posts_join_for_orderby() method
616
-     *    or else some of the table references below will result in MySQL errors
617
-     *
618
-     * @param array  $orderby_params
619
-     * @param string $sort
620
-     * @return string
621
-     * @throws EE_Error
622
-     * @throws InvalidArgumentException
623
-     * @throws InvalidDataTypeException
624
-     * @throws InvalidInterfaceException
625
-     */
626
-    public static function posts_orderby_sql(array $orderby_params = array(), $sort = 'ASC')
627
-    {
628
-        global $wpdb;
629
-        $SQL     = '';
630
-        $counter = 0;
631
-        $sort    = in_array($sort, array('ASC', 'asc', 'DESC', 'desc'), true)
632
-            ? strtoupper($sort)
633
-            : 'ASC';
634
-        // make sure 'orderby' is set in query params
635
-        if (! isset(self::$_query_params['orderby'])) {
636
-            self::$_query_params['orderby'] = array();
637
-        }
638
-        // loop thru $orderby_params (type cast as array)
639
-        foreach ($orderby_params as $orderby) {
640
-            // check if we have already added this param
641
-            if (isset(self::$_query_params['orderby'][ $orderby ])) {
642
-                // if so then remove from the $orderby_params so that the count() method below is accurate
643
-                unset($orderby_params[ $orderby ]);
644
-                // then bump ahead to the next param
645
-                continue;
646
-            }
647
-            // this will ad a comma depending on whether this is the first or last param
648
-            $glue = $counter === 0 || $counter === count($orderby_params) ? ' ' : ', ';
649
-            // ok what's we dealing with?
650
-            switch ($orderby) {
651
-                case 'id':
652
-                case 'ID':
653
-                    $SQL .= $glue . $wpdb->posts . '.ID ' . $sort;
654
-                    break;
655
-                case 'end_date':
656
-                    $SQL .= $glue . EEM_Datetime::instance()->table() . '.DTT_EVT_end ' . $sort;
657
-                    break;
658
-                case 'event_name':
659
-                    $SQL .= $glue . $wpdb->posts . '.post_title ' . $sort;
660
-                    break;
661
-                case 'category_slug':
662
-                    $SQL .= $glue . $wpdb->terms . '.slug ' . $sort;
663
-                    break;
664
-                case 'ticket_start':
665
-                    $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_start_date ' . $sort;
666
-                    break;
667
-                case 'ticket_end':
668
-                    $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_end_date ' . $sort;
669
-                    break;
670
-                case 'venue_title':
671
-                    $SQL .= $glue . 'venue_title ' . $sort;
672
-                    break;
673
-                case 'city':
674
-                    $SQL .= $glue . EEM_Venue::instance()->second_table() . '.VNU_city ' . $sort;
675
-                    break;
676
-                case 'state':
677
-                    $SQL .= $glue . EEM_State::instance()->table() . '.STA_name ' . $sort;
678
-                    break;
679
-                case 'start_date':
680
-                default:
681
-                    $SQL .= $glue . ' event_start_date ' . $sort;
682
-                    break;
683
-            }
684
-            // add to array of orderby params that have been added
685
-            self::$_query_params['orderby'][ $orderby ] = true;
686
-            $counter++;
687
-        }
688
-        return $SQL;
689
-    }
18
+	/**
19
+	 * Start Date
20
+	 *
21
+	 * @var $_event_query_month
22
+	 */
23
+	protected static $_event_query_month;
24
+
25
+	/**
26
+	 * Category
27
+	 *
28
+	 * @var $_event_query_category
29
+	 */
30
+	protected static $_event_query_category;
31
+
32
+	/**
33
+	 * whether to display expired events in the event list
34
+	 *
35
+	 * @var bool $_show_expired
36
+	 */
37
+	protected static $_event_query_show_expired = false;
38
+
39
+	/**
40
+	 * list of params for controlling how the query results are ordered
41
+	 *
42
+	 * @var array $_event_query_orderby
43
+	 */
44
+	protected static $_event_query_orderby = array();
45
+
46
+	/**
47
+	 * direction list is sorted
48
+	 *
49
+	 * @var string $_event_query_sort
50
+	 */
51
+	protected static $_event_query_sort;
52
+
53
+	/**
54
+	 * list of params used to build the query's various clauses
55
+	 *
56
+	 * @var $_query_params
57
+	 */
58
+	protected static $_query_params = array();
59
+
60
+
61
+
62
+	/**
63
+	 * @return void
64
+	 */
65
+	public static function add_query_filters()
66
+	{
67
+		// add query filters
68
+		add_action('pre_get_posts', array('EEH_Event_Query', 'filter_query_parts'), 10, 1);
69
+	}
70
+
71
+
72
+
73
+	/**
74
+	 * @param WP_Query $WP_Query
75
+	 * @return bool
76
+	 */
77
+	public static function apply_query_filters(WP_Query $WP_Query)
78
+	{
79
+		return (
80
+				   isset($WP_Query->query['post_type'])
81
+				   && $WP_Query->query['post_type'] === 'espresso_events'
82
+			   )
83
+			   || apply_filters('FHEE__EEH_Event_Query__apply_query_filters', false);
84
+	}
85
+
86
+
87
+	/**
88
+	 * @param WP_Query $WP_Query
89
+	 */
90
+	public static function filter_query_parts(WP_Query $WP_Query)
91
+	{
92
+		// ONLY add our filters if this isn't the main wp_query,
93
+		// because if this is the main wp_query we already have
94
+		// our cpt strategies take care of adding things in.
95
+		if ($WP_Query instanceof WP_Query && ! $WP_Query->is_main_query()) {
96
+			// build event list query
97
+			add_filter('posts_fields', array('EEH_Event_Query', 'posts_fields'), 10, 2);
98
+			add_filter('posts_join', array('EEH_Event_Query', 'posts_join'), 10, 2);
99
+			add_filter('posts_where', array('EEH_Event_Query', 'posts_where'), 10, 2);
100
+			add_filter('posts_orderby', array('EEH_Event_Query', 'posts_orderby'), 10, 2);
101
+			add_filter('posts_clauses_request', array('EEH_Event_Query', 'posts_clauses'), 10, 2);
102
+		}
103
+	}
104
+
105
+
106
+
107
+	/**
108
+	 * @param string $month
109
+	 * @param string $category
110
+	 * @param bool   $show_expired
111
+	 * @param string $orderby
112
+	 * @param string $sort
113
+	 * @throws InvalidArgumentException
114
+	 * @throws InvalidDataTypeException
115
+	 * @throws InvalidInterfaceException
116
+	 */
117
+	public static function set_query_params(
118
+		$month = '',
119
+		$category = '',
120
+		$show_expired = false,
121
+		$orderby = 'start_date',
122
+		$sort = 'ASC'
123
+	) {
124
+		self::$_query_params                        = array();
125
+		EEH_Event_Query::$_event_query_month        = EEH_Event_Query::_display_month($month);
126
+		EEH_Event_Query::$_event_query_category     = EEH_Event_Query::_event_category_slug($category);
127
+		EEH_Event_Query::$_event_query_show_expired = EEH_Event_Query::_show_expired($show_expired);
128
+		EEH_Event_Query::$_event_query_orderby      = EEH_Event_Query::_orderby($orderby);
129
+		EEH_Event_Query::$_event_query_sort         = EEH_Event_Query::_sort($sort);
130
+	}
131
+
132
+
133
+
134
+	/**
135
+	 * what month should the event list display events for?
136
+	 *
137
+	 * @param string $month
138
+	 * @return string
139
+	 * @throws InvalidArgumentException
140
+	 * @throws InvalidDataTypeException
141
+	 * @throws InvalidInterfaceException
142
+	 */
143
+	private static function _display_month($month = '')
144
+	{
145
+		return sanitize_text_field(EE_Registry::instance()->REQ->get('event_query_month', $month));
146
+	}
147
+
148
+
149
+
150
+	/**
151
+	 * @param string $category
152
+	 * @return string
153
+	 * @throws InvalidArgumentException
154
+	 * @throws InvalidDataTypeException
155
+	 * @throws InvalidInterfaceException
156
+	 */
157
+	private static function _event_category_slug($category = '')
158
+	{
159
+		return sanitize_text_field(EE_Registry::instance()->REQ->get('event_query_category', $category));
160
+	}
161
+
162
+
163
+
164
+	/**
165
+	 * @param bool $show_expired
166
+	 * @return bool
167
+	 * @throws InvalidArgumentException
168
+	 * @throws InvalidDataTypeException
169
+	 * @throws InvalidInterfaceException
170
+	 */
171
+	private static function _show_expired($show_expired = false)
172
+	{
173
+		// override default expired option if set via filter
174
+		return filter_var(
175
+			EE_Registry::instance()->REQ->get('event_query_show_expired', $show_expired),
176
+			FILTER_VALIDATE_BOOLEAN
177
+		);
178
+	}
179
+
180
+
181
+
182
+	/**
183
+	 * @param    string $orderby
184
+	 * @return array
185
+	 * @throws InvalidArgumentException
186
+	 * @throws InvalidDataTypeException
187
+	 * @throws InvalidInterfaceException
188
+	 */
189
+	private static function _orderby($orderby = 'start_date')
190
+	{
191
+		$event_query_orderby = EE_Registry::instance()->REQ->get('event_query_orderby', $orderby);
192
+		$event_query_orderby = is_array($event_query_orderby)
193
+			? $event_query_orderby
194
+			: explode(',', $event_query_orderby);
195
+		$event_query_orderby = array_map('trim', $event_query_orderby);
196
+		$event_query_orderby = array_map('sanitize_text_field', $event_query_orderby);
197
+		return $event_query_orderby;
198
+	}
199
+
200
+
201
+
202
+	/**
203
+	 * @param string $sort
204
+	 * @return string
205
+	 * @throws InvalidArgumentException
206
+	 * @throws InvalidDataTypeException
207
+	 * @throws InvalidInterfaceException
208
+	 */
209
+	private static function _sort($sort = 'ASC')
210
+	{
211
+		$sort = EE_Registry::instance()->REQ->get('event_query_sort', $sort);
212
+		return in_array($sort, array('ASC', 'asc', 'DESC', 'desc'), true)
213
+			? strtoupper($sort)
214
+			: 'ASC';
215
+	}
216
+
217
+
218
+
219
+	/**
220
+	 * Filters the clauses for the WP_Query object
221
+	 *
222
+	 * @param array    $clauses array of clauses
223
+	 * @param WP_Query $wp_query
224
+	 * @return array   array of clauses
225
+	 */
226
+	public static function posts_clauses($clauses, WP_Query $wp_query)
227
+	{
228
+		if (EEH_Event_Query::apply_query_filters($wp_query)) {
229
+			global $wpdb;
230
+			$clauses['groupby'] = $wpdb->posts . '.ID ';
231
+		}
232
+		return $clauses;
233
+	}
234
+
235
+
236
+
237
+	/**
238
+	 * @param string   $SQL
239
+	 * @param WP_Query $wp_query
240
+	 * @return string
241
+	 * @throws EE_Error
242
+	 * @throws InvalidArgumentException
243
+	 * @throws InvalidDataTypeException
244
+	 * @throws InvalidInterfaceException
245
+	 */
246
+	public static function posts_fields($SQL, WP_Query $wp_query)
247
+	{
248
+		if (EEH_Event_Query::apply_query_filters($wp_query)) {
249
+			// adds something like ", wp_esp_datetime.* " to WP Query SELECT statement
250
+			$SQL .= EEH_Event_Query::posts_fields_sql_for_orderby(EEH_Event_Query::$_event_query_orderby);
251
+		}
252
+		return $SQL;
253
+	}
254
+
255
+
256
+
257
+	/**
258
+	 * @param array $orderby_params
259
+	 * @return string
260
+	 * @throws EE_Error
261
+	 * @throws InvalidArgumentException
262
+	 * @throws InvalidDataTypeException
263
+	 * @throws InvalidInterfaceException
264
+	 */
265
+	public static function posts_fields_sql_for_orderby(array $orderby_params = array())
266
+	{
267
+		$SQL = ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date ';
268
+		foreach ($orderby_params as $orderby) {
269
+			switch ($orderby) {
270
+				case 'ticket_start':
271
+					$SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_start_date';
272
+					break;
273
+				case 'ticket_end':
274
+					$SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_end_date';
275
+					break;
276
+				case 'venue_title':
277
+					$SQL .= ', Venue.post_title AS venue_title';
278
+					break;
279
+				case 'city':
280
+					$SQL .= ', ' . EEM_Venue::instance()->second_table() . '.VNU_city';
281
+					break;
282
+				case 'state':
283
+					$SQL .= ', ' . EEM_State::instance()->table() . '.STA_name';
284
+					break;
285
+			}
286
+		}
287
+		return $SQL;
288
+	}
289
+
290
+
291
+
292
+	/**
293
+	 * @param string   $SQL
294
+	 * @param WP_Query $wp_query
295
+	 * @return string
296
+	 * @throws EE_Error
297
+	 * @throws InvalidArgumentException
298
+	 * @throws InvalidDataTypeException
299
+	 * @throws InvalidInterfaceException
300
+	 */
301
+	public static function posts_join($SQL = '', WP_Query $wp_query)
302
+	{
303
+		if (EEH_Event_Query::apply_query_filters($wp_query)) {
304
+			// Category
305
+			$SQL = EEH_Event_Query::posts_join_sql_for_show_expired($SQL, EEH_Event_Query::$_event_query_show_expired);
306
+			$SQL = EEH_Event_Query::posts_join_sql_for_terms($SQL, EEH_Event_Query::$_event_query_category);
307
+			$SQL = EEH_Event_Query::posts_join_for_orderby($SQL, EEH_Event_Query::$_event_query_orderby);
308
+		}
309
+		return $SQL;
310
+	}
311
+
312
+
313
+
314
+	/**
315
+	 * @param string  $SQL
316
+	 * @param boolean $show_expired if TRUE, then displayed past events
317
+	 * @return string
318
+	 * @throws EE_Error
319
+	 * @throws InvalidArgumentException
320
+	 * @throws InvalidDataTypeException
321
+	 * @throws InvalidInterfaceException
322
+	 */
323
+	public static function posts_join_sql_for_show_expired($SQL = '', $show_expired = false)
324
+	{
325
+		if (! $show_expired) {
326
+			$join = EEM_Event::instance()->table() . '.ID = ';
327
+			$join .= EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name();
328
+			// don't add if this is already in the SQL
329
+			if (strpos($SQL, $join) === false) {
330
+				$SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' ) ';
331
+			}
332
+		}
333
+		return $SQL;
334
+	}
335
+
336
+
337
+
338
+	/**
339
+	 * @param string $SQL
340
+	 * @param string $join_terms    pass TRUE or term string, doesn't really matter since this value doesn't really get
341
+	 *                              used for anything yet
342
+	 * @return string
343
+	 */
344
+	public static function posts_join_sql_for_terms($SQL = '', $join_terms = '')
345
+	{
346
+		if (! empty($join_terms)) {
347
+			global $wpdb;
348
+			$SQL .= " LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)";
349
+			$SQL .= " LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
350
+			$SQL .= " LEFT JOIN $wpdb->terms ON ($wpdb->terms.term_id = $wpdb->term_taxonomy.term_id) ";
351
+		}
352
+		return $SQL;
353
+	}
354
+
355
+
356
+
357
+	/**
358
+	 * usage:  $SQL .= EEH_Event_Query::posts_join_for_orderby( $orderby_params );
359
+	 *
360
+	 * @param    string $SQL
361
+	 * @param    array  $orderby_params
362
+	 * @return string
363
+	 * @throws EE_Error
364
+	 * @throws InvalidArgumentException
365
+	 * @throws InvalidDataTypeException
366
+	 * @throws InvalidInterfaceException
367
+	 */
368
+	public static function posts_join_for_orderby($SQL = '', array $orderby_params = array())
369
+	{
370
+		foreach ($orderby_params as $orderby) {
371
+			switch ($orderby) {
372
+				case 'ticket_start':
373
+				case 'ticket_end':
374
+					$SQL .= EEH_Event_Query::_posts_join_for_datetime(
375
+						$SQL,
376
+						EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Datetime::instance()->primary_key_name()
377
+					);
378
+					$SQL .= ' LEFT JOIN ' . EEM_Ticket::instance()->table();
379
+					$SQL .= ' ON (';
380
+					$SQL .= EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name();
381
+					$SQL .= ' = ';
382
+					$SQL .= EEM_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name();
383
+					$SQL .= ' )';
384
+					break;
385
+				case 'venue_title':
386
+				case 'city':
387
+					$SQL .= EEH_Event_Query::_posts_join_for_event_venue($SQL);
388
+					break;
389
+				case 'state':
390
+					$SQL .= EEH_Event_Query::_posts_join_for_event_venue($SQL);
391
+					$SQL .= EEH_Event_Query::_posts_join_for_venue_state($SQL);
392
+					break;
393
+				case 'start_date':
394
+				default:
395
+					$SQL .= EEH_Event_Query::_posts_join_for_datetime($SQL, EEM_Event::instance()->table() . '.ID');
396
+					break;
397
+			}
398
+		}
399
+		return $SQL;
400
+	}
401
+
402
+
403
+
404
+	/**
405
+	 * @param string $SQL
406
+	 * @param string $join
407
+	 * @return string
408
+	 * @throws EE_Error
409
+	 * @throws InvalidArgumentException
410
+	 * @throws InvalidDataTypeException
411
+	 * @throws InvalidInterfaceException
412
+	 */
413
+	protected static function _posts_join_for_datetime($SQL = '', $join = '')
414
+	{
415
+		if (! empty($join)) {
416
+			$join .= ' = ' . EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name();
417
+			if (strpos($SQL, $join) === false) {
418
+				return ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' )';
419
+			}
420
+		}
421
+		return '';
422
+	}
423
+
424
+
425
+
426
+	/**
427
+	 * @param string $SQL
428
+	 * @return string
429
+	 * @throws EE_Error
430
+	 * @throws InvalidArgumentException
431
+	 * @throws InvalidDataTypeException
432
+	 * @throws InvalidInterfaceException
433
+	 */
434
+	protected static function _posts_join_for_event_venue($SQL = '')
435
+	{
436
+		// Event Venue table name
437
+		$event_venue_table = EEM_Event_Venue::instance()->table();
438
+		// generate conditions for:  Event <=> Event Venue  JOIN clause
439
+		$event_to_event_venue_join = EEM_Event::instance()->table() . '.ID = ';
440
+		$event_to_event_venue_join .= $event_venue_table . '.' . EEM_Event::instance()->primary_key_name();
441
+		// don't add joins if they have already been added
442
+		if (strpos($SQL, $event_to_event_venue_join) === false) {
443
+			// Venue table name
444
+			$venue_table = EEM_Venue::instance()->table();
445
+			// Venue table pk
446
+			$venue_table_pk = EEM_Venue::instance()->primary_key_name();
447
+			// Venue Meta table name
448
+			$venue_meta_table = EEM_Venue::instance()->second_table();
449
+			// generate JOIN clause for: Event <=> Event Venue
450
+			$venue_SQL = " LEFT JOIN $event_venue_table ON ( $event_to_event_venue_join )";
451
+			// generate JOIN clause for: Event Venue <=> Venue
452
+			$venue_SQL .= " LEFT JOIN $venue_table as Venue ON ( $event_venue_table.$venue_table_pk = Venue.ID )";
453
+			// generate JOIN clause for: Venue <=> Venue Meta
454
+			$venue_SQL .= " LEFT JOIN $venue_meta_table ON ( Venue.ID = $venue_meta_table.$venue_table_pk )";
455
+			unset($event_venue_table, $event_to_event_venue_join, $venue_table, $venue_table_pk, $venue_meta_table);
456
+			return $venue_SQL;
457
+		}
458
+		unset($event_venue_table, $event_to_event_venue_join);
459
+		return '';
460
+	}
461
+
462
+
463
+
464
+	/**
465
+	 * @param string $SQL
466
+	 * @return string
467
+	 * @throws EE_Error
468
+	 * @throws InvalidArgumentException
469
+	 * @throws InvalidDataTypeException
470
+	 * @throws InvalidInterfaceException
471
+	 */
472
+	protected static function _posts_join_for_venue_state($SQL = '')
473
+	{
474
+		// Venue Meta table name
475
+		$venue_meta_table = EEM_Venue::instance()->second_table();
476
+		// State table name
477
+		$state_table = EEM_State::instance()->table();
478
+		// State table pk
479
+		$state_table_pk = EEM_State::instance()->primary_key_name();
480
+		// verify vars
481
+		if ($venue_meta_table && $state_table && $state_table_pk) {
482
+			// like: wp_esp_venue_meta.STA_ID = wp_esp_state.STA_ID
483
+			$join = "$venue_meta_table.$state_table_pk = $state_table.$state_table_pk";
484
+			// don't add join if it has already been added
485
+			if (strpos($SQL, $join) === false) {
486
+				unset($state_table_pk, $venue_meta_table, $venue_table_pk);
487
+				return " LEFT JOIN $state_table ON ( $join )";
488
+			}
489
+		}
490
+		unset($join, $state_table, $state_table_pk, $venue_meta_table, $venue_table_pk);
491
+		return '';
492
+	}
493
+
494
+
495
+
496
+	/**
497
+	 * @param string   $SQL
498
+	 * @param WP_Query $wp_query
499
+	 * @return string
500
+	 * @throws EE_Error
501
+	 * @throws InvalidArgumentException
502
+	 * @throws InvalidDataTypeException
503
+	 * @throws InvalidInterfaceException
504
+	 */
505
+	public static function posts_where($SQL = '', WP_Query $wp_query)
506
+	{
507
+		if (EEH_Event_Query::apply_query_filters($wp_query)) {
508
+			// Show Expired ?
509
+			$SQL .= EEH_Event_Query::posts_where_sql_for_show_expired(EEH_Event_Query::$_event_query_show_expired);
510
+			// Category
511
+			$SQL .= EEH_Event_Query::posts_where_sql_for_event_category_slug(EEH_Event_Query::$_event_query_category);
512
+			// Start Date
513
+			$SQL .= EEH_Event_Query::posts_where_sql_for_event_list_month(EEH_Event_Query::$_event_query_month);
514
+		}
515
+		return $SQL;
516
+	}
517
+
518
+
519
+
520
+	/**
521
+	 * @param    boolean $show_expired if TRUE, then displayed past events
522
+	 * @return string
523
+	 * @throws EE_Error
524
+	 * @throws InvalidArgumentException
525
+	 * @throws InvalidDataTypeException
526
+	 * @throws InvalidInterfaceException
527
+	 */
528
+	public static function posts_where_sql_for_show_expired($show_expired = false)
529
+	{
530
+		return ! $show_expired
531
+			? ' AND ' . EEM_Datetime::instance()->table() . '.DTT_EVT_end > \'' . current_time('mysql', true) . '\' '
532
+			: '';
533
+	}
534
+
535
+
536
+
537
+	/**
538
+	 * @param boolean $event_category_slug
539
+	 * @return string
540
+	 */
541
+	public static function posts_where_sql_for_event_category_slug($event_category_slug = null)
542
+	{
543
+		global $wpdb;
544
+		if (! empty($event_category_slug)) {
545
+			$event_category_slugs_array = array_map('trim', explode(',', $event_category_slug));
546
+			$event_category_slugs_prepare = implode(', ', array_fill(0, count($event_category_slugs_array), '%s'));
547
+			return $wpdb->prepare(" AND {$wpdb->terms}.slug IN ({$event_category_slugs_prepare}) ", $event_category_slugs_array);
548
+		}
549
+		return '';
550
+	}
551
+
552
+
553
+
554
+	/**
555
+	 * @param boolean $month
556
+	 * @return string
557
+	 * @throws EE_Error
558
+	 * @throws InvalidArgumentException
559
+	 * @throws InvalidDataTypeException
560
+	 * @throws InvalidInterfaceException
561
+	 */
562
+	public static function posts_where_sql_for_event_list_month($month = null)
563
+	{
564
+		$SQL = '';
565
+		if (! empty($month)) {
566
+			$datetime_table = EEM_Datetime::instance()->table();
567
+			// event start date is LESS than the end of the month ( so nothing that doesn't start until next month )
568
+			$SQL = " AND {$datetime_table}.DTT_EVT_start <= '";
569
+			$SQL .= date('Y-m-t 23:59:59', \EEH_DTT_Helper::first_of_month_timestamp($month)) . "'";
570
+			// event end date is GREATER than the start of the month ( so nothing that ended before this month )
571
+			$SQL .= " AND {$datetime_table}.DTT_EVT_end >= '";
572
+			$SQL .= date('Y-m-01 0:0:00', \EEH_DTT_Helper::first_of_month_timestamp($month)) . "' ";
573
+		}
574
+		return $SQL;
575
+	}
576
+
577
+
578
+
579
+	/**
580
+	 * @param string $SQL
581
+	 * @param WP_Query $wp_query
582
+	 * @return string
583
+	 * @throws EE_Error
584
+	 * @throws InvalidArgumentException
585
+	 * @throws InvalidDataTypeException
586
+	 * @throws InvalidInterfaceException
587
+	 */
588
+	public static function posts_orderby($SQL = '', WP_Query $wp_query)
589
+	{
590
+		if (EEH_Event_Query::apply_query_filters($wp_query)) {
591
+			$SQL = EEH_Event_Query::posts_orderby_sql(
592
+				EEH_Event_Query::$_event_query_orderby,
593
+				EEH_Event_Query::$_event_query_sort
594
+			);
595
+		}
596
+		return $SQL;
597
+	}
598
+
599
+
600
+
601
+	/**
602
+	 *    posts_orderby_sql
603
+	 *    possible parameters:
604
+	 *    ID
605
+	 *    start_date
606
+	 *    end_date
607
+	 *    event_name
608
+	 *    category_slug
609
+	 *    ticket_start
610
+	 *    ticket_end
611
+	 *    venue_title
612
+	 *    city
613
+	 *    state
614
+	 *    **IMPORTANT**
615
+	 *    make sure to also send the $orderby_params array to the posts_join_for_orderby() method
616
+	 *    or else some of the table references below will result in MySQL errors
617
+	 *
618
+	 * @param array  $orderby_params
619
+	 * @param string $sort
620
+	 * @return string
621
+	 * @throws EE_Error
622
+	 * @throws InvalidArgumentException
623
+	 * @throws InvalidDataTypeException
624
+	 * @throws InvalidInterfaceException
625
+	 */
626
+	public static function posts_orderby_sql(array $orderby_params = array(), $sort = 'ASC')
627
+	{
628
+		global $wpdb;
629
+		$SQL     = '';
630
+		$counter = 0;
631
+		$sort    = in_array($sort, array('ASC', 'asc', 'DESC', 'desc'), true)
632
+			? strtoupper($sort)
633
+			: 'ASC';
634
+		// make sure 'orderby' is set in query params
635
+		if (! isset(self::$_query_params['orderby'])) {
636
+			self::$_query_params['orderby'] = array();
637
+		}
638
+		// loop thru $orderby_params (type cast as array)
639
+		foreach ($orderby_params as $orderby) {
640
+			// check if we have already added this param
641
+			if (isset(self::$_query_params['orderby'][ $orderby ])) {
642
+				// if so then remove from the $orderby_params so that the count() method below is accurate
643
+				unset($orderby_params[ $orderby ]);
644
+				// then bump ahead to the next param
645
+				continue;
646
+			}
647
+			// this will ad a comma depending on whether this is the first or last param
648
+			$glue = $counter === 0 || $counter === count($orderby_params) ? ' ' : ', ';
649
+			// ok what's we dealing with?
650
+			switch ($orderby) {
651
+				case 'id':
652
+				case 'ID':
653
+					$SQL .= $glue . $wpdb->posts . '.ID ' . $sort;
654
+					break;
655
+				case 'end_date':
656
+					$SQL .= $glue . EEM_Datetime::instance()->table() . '.DTT_EVT_end ' . $sort;
657
+					break;
658
+				case 'event_name':
659
+					$SQL .= $glue . $wpdb->posts . '.post_title ' . $sort;
660
+					break;
661
+				case 'category_slug':
662
+					$SQL .= $glue . $wpdb->terms . '.slug ' . $sort;
663
+					break;
664
+				case 'ticket_start':
665
+					$SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_start_date ' . $sort;
666
+					break;
667
+				case 'ticket_end':
668
+					$SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_end_date ' . $sort;
669
+					break;
670
+				case 'venue_title':
671
+					$SQL .= $glue . 'venue_title ' . $sort;
672
+					break;
673
+				case 'city':
674
+					$SQL .= $glue . EEM_Venue::instance()->second_table() . '.VNU_city ' . $sort;
675
+					break;
676
+				case 'state':
677
+					$SQL .= $glue . EEM_State::instance()->table() . '.STA_name ' . $sort;
678
+					break;
679
+				case 'start_date':
680
+				default:
681
+					$SQL .= $glue . ' event_start_date ' . $sort;
682
+					break;
683
+			}
684
+			// add to array of orderby params that have been added
685
+			self::$_query_params['orderby'][ $orderby ] = true;
686
+			$counter++;
687
+		}
688
+		return $SQL;
689
+	}
690 690
 }
Please login to merge, or discard this patch.
Spacing   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -227,7 +227,7 @@  discard block
 block discarded – undo
227 227
     {
228 228
         if (EEH_Event_Query::apply_query_filters($wp_query)) {
229 229
             global $wpdb;
230
-            $clauses['groupby'] = $wpdb->posts . '.ID ';
230
+            $clauses['groupby'] = $wpdb->posts.'.ID ';
231 231
         }
232 232
         return $clauses;
233 233
     }
@@ -264,23 +264,23 @@  discard block
 block discarded – undo
264 264
      */
265 265
     public static function posts_fields_sql_for_orderby(array $orderby_params = array())
266 266
     {
267
-        $SQL = ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date ';
267
+        $SQL = ', MIN( '.EEM_Datetime::instance()->table().'.DTT_EVT_start ) as event_start_date ';
268 268
         foreach ($orderby_params as $orderby) {
269 269
             switch ($orderby) {
270 270
                 case 'ticket_start':
271
-                    $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_start_date';
271
+                    $SQL .= ', '.EEM_Ticket::instance()->table().'.TKT_start_date';
272 272
                     break;
273 273
                 case 'ticket_end':
274
-                    $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_end_date';
274
+                    $SQL .= ', '.EEM_Ticket::instance()->table().'.TKT_end_date';
275 275
                     break;
276 276
                 case 'venue_title':
277 277
                     $SQL .= ', Venue.post_title AS venue_title';
278 278
                     break;
279 279
                 case 'city':
280
-                    $SQL .= ', ' . EEM_Venue::instance()->second_table() . '.VNU_city';
280
+                    $SQL .= ', '.EEM_Venue::instance()->second_table().'.VNU_city';
281 281
                     break;
282 282
                 case 'state':
283
-                    $SQL .= ', ' . EEM_State::instance()->table() . '.STA_name';
283
+                    $SQL .= ', '.EEM_State::instance()->table().'.STA_name';
284 284
                     break;
285 285
             }
286 286
         }
@@ -322,12 +322,12 @@  discard block
 block discarded – undo
322 322
      */
323 323
     public static function posts_join_sql_for_show_expired($SQL = '', $show_expired = false)
324 324
     {
325
-        if (! $show_expired) {
326
-            $join = EEM_Event::instance()->table() . '.ID = ';
327
-            $join .= EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name();
325
+        if ( ! $show_expired) {
326
+            $join = EEM_Event::instance()->table().'.ID = ';
327
+            $join .= EEM_Datetime::instance()->table().'.'.EEM_Event::instance()->primary_key_name();
328 328
             // don't add if this is already in the SQL
329 329
             if (strpos($SQL, $join) === false) {
330
-                $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' ) ';
330
+                $SQL .= ' INNER JOIN '.EEM_Datetime::instance()->table().' ON ( '.$join.' ) ';
331 331
             }
332 332
         }
333 333
         return $SQL;
@@ -343,7 +343,7 @@  discard block
 block discarded – undo
343 343
      */
344 344
     public static function posts_join_sql_for_terms($SQL = '', $join_terms = '')
345 345
     {
346
-        if (! empty($join_terms)) {
346
+        if ( ! empty($join_terms)) {
347 347
             global $wpdb;
348 348
             $SQL .= " LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)";
349 349
             $SQL .= " LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
@@ -373,13 +373,13 @@  discard block
 block discarded – undo
373 373
                 case 'ticket_end':
374 374
                     $SQL .= EEH_Event_Query::_posts_join_for_datetime(
375 375
                         $SQL,
376
-                        EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Datetime::instance()->primary_key_name()
376
+                        EEM_Datetime_Ticket::instance()->table().'.'.EEM_Datetime::instance()->primary_key_name()
377 377
                     );
378
-                    $SQL .= ' LEFT JOIN ' . EEM_Ticket::instance()->table();
378
+                    $SQL .= ' LEFT JOIN '.EEM_Ticket::instance()->table();
379 379
                     $SQL .= ' ON (';
380
-                    $SQL .= EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name();
380
+                    $SQL .= EEM_Datetime_Ticket::instance()->table().'.'.EEM_Ticket::instance()->primary_key_name();
381 381
                     $SQL .= ' = ';
382
-                    $SQL .= EEM_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name();
382
+                    $SQL .= EEM_Ticket::instance()->table().'.'.EEM_Ticket::instance()->primary_key_name();
383 383
                     $SQL .= ' )';
384 384
                     break;
385 385
                 case 'venue_title':
@@ -392,7 +392,7 @@  discard block
 block discarded – undo
392 392
                     break;
393 393
                 case 'start_date':
394 394
                 default:
395
-                    $SQL .= EEH_Event_Query::_posts_join_for_datetime($SQL, EEM_Event::instance()->table() . '.ID');
395
+                    $SQL .= EEH_Event_Query::_posts_join_for_datetime($SQL, EEM_Event::instance()->table().'.ID');
396 396
                     break;
397 397
             }
398 398
         }
@@ -412,10 +412,10 @@  discard block
 block discarded – undo
412 412
      */
413 413
     protected static function _posts_join_for_datetime($SQL = '', $join = '')
414 414
     {
415
-        if (! empty($join)) {
416
-            $join .= ' = ' . EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name();
415
+        if ( ! empty($join)) {
416
+            $join .= ' = '.EEM_Datetime::instance()->table().'.'.EEM_Event::instance()->primary_key_name();
417 417
             if (strpos($SQL, $join) === false) {
418
-                return ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' )';
418
+                return ' INNER JOIN '.EEM_Datetime::instance()->table().' ON ( '.$join.' )';
419 419
             }
420 420
         }
421 421
         return '';
@@ -436,8 +436,8 @@  discard block
 block discarded – undo
436 436
         // Event Venue table name
437 437
         $event_venue_table = EEM_Event_Venue::instance()->table();
438 438
         // generate conditions for:  Event <=> Event Venue  JOIN clause
439
-        $event_to_event_venue_join = EEM_Event::instance()->table() . '.ID = ';
440
-        $event_to_event_venue_join .= $event_venue_table . '.' . EEM_Event::instance()->primary_key_name();
439
+        $event_to_event_venue_join = EEM_Event::instance()->table().'.ID = ';
440
+        $event_to_event_venue_join .= $event_venue_table.'.'.EEM_Event::instance()->primary_key_name();
441 441
         // don't add joins if they have already been added
442 442
         if (strpos($SQL, $event_to_event_venue_join) === false) {
443 443
             // Venue table name
@@ -528,7 +528,7 @@  discard block
 block discarded – undo
528 528
     public static function posts_where_sql_for_show_expired($show_expired = false)
529 529
     {
530 530
         return ! $show_expired
531
-            ? ' AND ' . EEM_Datetime::instance()->table() . '.DTT_EVT_end > \'' . current_time('mysql', true) . '\' '
531
+            ? ' AND '.EEM_Datetime::instance()->table().'.DTT_EVT_end > \''.current_time('mysql', true).'\' '
532 532
             : '';
533 533
     }
534 534
 
@@ -541,7 +541,7 @@  discard block
 block discarded – undo
541 541
     public static function posts_where_sql_for_event_category_slug($event_category_slug = null)
542 542
     {
543 543
         global $wpdb;
544
-        if (! empty($event_category_slug)) {
544
+        if ( ! empty($event_category_slug)) {
545 545
             $event_category_slugs_array = array_map('trim', explode(',', $event_category_slug));
546 546
             $event_category_slugs_prepare = implode(', ', array_fill(0, count($event_category_slugs_array), '%s'));
547 547
             return $wpdb->prepare(" AND {$wpdb->terms}.slug IN ({$event_category_slugs_prepare}) ", $event_category_slugs_array);
@@ -562,14 +562,14 @@  discard block
 block discarded – undo
562 562
     public static function posts_where_sql_for_event_list_month($month = null)
563 563
     {
564 564
         $SQL = '';
565
-        if (! empty($month)) {
565
+        if ( ! empty($month)) {
566 566
             $datetime_table = EEM_Datetime::instance()->table();
567 567
             // event start date is LESS than the end of the month ( so nothing that doesn't start until next month )
568 568
             $SQL = " AND {$datetime_table}.DTT_EVT_start <= '";
569
-            $SQL .= date('Y-m-t 23:59:59', \EEH_DTT_Helper::first_of_month_timestamp($month)) . "'";
569
+            $SQL .= date('Y-m-t 23:59:59', \EEH_DTT_Helper::first_of_month_timestamp($month))."'";
570 570
             // event end date is GREATER than the start of the month ( so nothing that ended before this month )
571 571
             $SQL .= " AND {$datetime_table}.DTT_EVT_end >= '";
572
-            $SQL .= date('Y-m-01 0:0:00', \EEH_DTT_Helper::first_of_month_timestamp($month)) . "' ";
572
+            $SQL .= date('Y-m-01 0:0:00', \EEH_DTT_Helper::first_of_month_timestamp($month))."' ";
573 573
         }
574 574
         return $SQL;
575 575
     }
@@ -632,15 +632,15 @@  discard block
 block discarded – undo
632 632
             ? strtoupper($sort)
633 633
             : 'ASC';
634 634
         // make sure 'orderby' is set in query params
635
-        if (! isset(self::$_query_params['orderby'])) {
635
+        if ( ! isset(self::$_query_params['orderby'])) {
636 636
             self::$_query_params['orderby'] = array();
637 637
         }
638 638
         // loop thru $orderby_params (type cast as array)
639 639
         foreach ($orderby_params as $orderby) {
640 640
             // check if we have already added this param
641
-            if (isset(self::$_query_params['orderby'][ $orderby ])) {
641
+            if (isset(self::$_query_params['orderby'][$orderby])) {
642 642
                 // if so then remove from the $orderby_params so that the count() method below is accurate
643
-                unset($orderby_params[ $orderby ]);
643
+                unset($orderby_params[$orderby]);
644 644
                 // then bump ahead to the next param
645 645
                 continue;
646 646
             }
@@ -650,39 +650,39 @@  discard block
 block discarded – undo
650 650
             switch ($orderby) {
651 651
                 case 'id':
652 652
                 case 'ID':
653
-                    $SQL .= $glue . $wpdb->posts . '.ID ' . $sort;
653
+                    $SQL .= $glue.$wpdb->posts.'.ID '.$sort;
654 654
                     break;
655 655
                 case 'end_date':
656
-                    $SQL .= $glue . EEM_Datetime::instance()->table() . '.DTT_EVT_end ' . $sort;
656
+                    $SQL .= $glue.EEM_Datetime::instance()->table().'.DTT_EVT_end '.$sort;
657 657
                     break;
658 658
                 case 'event_name':
659
-                    $SQL .= $glue . $wpdb->posts . '.post_title ' . $sort;
659
+                    $SQL .= $glue.$wpdb->posts.'.post_title '.$sort;
660 660
                     break;
661 661
                 case 'category_slug':
662
-                    $SQL .= $glue . $wpdb->terms . '.slug ' . $sort;
662
+                    $SQL .= $glue.$wpdb->terms.'.slug '.$sort;
663 663
                     break;
664 664
                 case 'ticket_start':
665
-                    $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_start_date ' . $sort;
665
+                    $SQL .= $glue.EEM_Ticket::instance()->table().'.TKT_start_date '.$sort;
666 666
                     break;
667 667
                 case 'ticket_end':
668
-                    $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_end_date ' . $sort;
668
+                    $SQL .= $glue.EEM_Ticket::instance()->table().'.TKT_end_date '.$sort;
669 669
                     break;
670 670
                 case 'venue_title':
671
-                    $SQL .= $glue . 'venue_title ' . $sort;
671
+                    $SQL .= $glue.'venue_title '.$sort;
672 672
                     break;
673 673
                 case 'city':
674
-                    $SQL .= $glue . EEM_Venue::instance()->second_table() . '.VNU_city ' . $sort;
674
+                    $SQL .= $glue.EEM_Venue::instance()->second_table().'.VNU_city '.$sort;
675 675
                     break;
676 676
                 case 'state':
677
-                    $SQL .= $glue . EEM_State::instance()->table() . '.STA_name ' . $sort;
677
+                    $SQL .= $glue.EEM_State::instance()->table().'.STA_name '.$sort;
678 678
                     break;
679 679
                 case 'start_date':
680 680
                 default:
681
-                    $SQL .= $glue . ' event_start_date ' . $sort;
681
+                    $SQL .= $glue.' event_start_date '.$sort;
682 682
                     break;
683 683
             }
684 684
             // add to array of orderby params that have been added
685
-            self::$_query_params['orderby'][ $orderby ] = true;
685
+            self::$_query_params['orderby'][$orderby] = true;
686 686
             $counter++;
687 687
         }
688 688
         return $SQL;
Please login to merge, or discard this patch.
languages/event_espresso-translations-js.php 1 patch
Spacing   +379 added lines, -379 removed lines patch added patch discarded remove patch
@@ -2,179 +2,179 @@  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: domains/blocks/src/components/AvatarImage.tsx:27
5
-	__( 'contact avatar', 'event_espresso' ),
5
+	__('contact avatar', 'event_espresso'),
6 6
 
7 7
 	// Reference: domains/blocks/src/components/OrderByControl.tsx:13
8
-	__( 'Order by', 'event_espresso' ),
8
+	__('Order by', 'event_espresso'),
9 9
 
10 10
 	// Reference: domains/blocks/src/components/RegStatusControl.tsx:18
11 11
 	// Reference: domains/blocks/src/event-attendees/controls/SelectStatus.tsx:12
12
-	__( 'Select Registration Status', 'event_espresso' ),
12
+	__('Select Registration Status', 'event_espresso'),
13 13
 
14 14
 	// Reference: domains/blocks/src/components/SortOrderControl.tsx:15
15
-	__( 'Ascending', 'event_espresso' ),
15
+	__('Ascending', 'event_espresso'),
16 16
 
17 17
 	// Reference: domains/blocks/src/components/SortOrderControl.tsx:19
18
-	__( 'Descending', 'event_espresso' ),
18
+	__('Descending', 'event_espresso'),
19 19
 
20 20
 	// Reference: domains/blocks/src/components/SortOrderControl.tsx:25
21
-	__( 'Sort order:', 'event_espresso' ),
21
+	__('Sort order:', 'event_espresso'),
22 22
 
23 23
 	// Reference: domains/blocks/src/event-attendees/AttendeesDisplay.tsx:40
24
-	__( 'There was some error fetching attendees list', 'event_espresso' ),
24
+	__('There was some error fetching attendees list', 'event_espresso'),
25 25
 
26 26
 	// Reference: domains/blocks/src/event-attendees/AttendeesDisplay.tsx:46
27
-	__( 'To get started, select what event you want to show attendees from in the block settings.', 'event_espresso' ),
27
+	__('To get started, select what event you want to show attendees from in the block settings.', 'event_espresso'),
28 28
 
29 29
 	// Reference: domains/blocks/src/event-attendees/AttendeesDisplay.tsx:52
30
-	__( 'There are no attendees for selected options.', 'event_espresso' ),
30
+	__('There are no attendees for selected options.', 'event_espresso'),
31 31
 
32 32
 	// Reference: domains/blocks/src/event-attendees/controls/ArchiveSettings.tsx:11
33
-	__( 'Display on Archives', 'event_espresso' ),
33
+	__('Display on Archives', 'event_espresso'),
34 34
 
35 35
 	// Reference: domains/blocks/src/event-attendees/controls/ArchiveSettings.tsx:16
36
-	__( 'Attendees are shown whenever this post is listed in an archive view.', 'event_espresso' ),
36
+	__('Attendees are shown whenever this post is listed in an archive view.', 'event_espresso'),
37 37
 
38 38
 	// Reference: domains/blocks/src/event-attendees/controls/ArchiveSettings.tsx:17
39
-	__( 'Attendees are hidden whenever this post is listed in an archive view.', 'event_espresso' ),
39
+	__('Attendees are hidden whenever this post is listed in an archive view.', 'event_espresso'),
40 40
 
41 41
 	// Reference: domains/blocks/src/event-attendees/controls/AttendeeLimit.tsx:28
42
-	__( 'Number of Attendees to Display:', 'event_espresso' ),
42
+	__('Number of Attendees to Display:', 'event_espresso'),
43 43
 
44 44
 	// Reference: domains/blocks/src/event-attendees/controls/AttendeeLimit.tsx:32
45
-	_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' ),
45
+	_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'),
46 46
 
47 47
 	// Reference: domains/blocks/src/event-attendees/controls/GravatarSettings.tsx:26
48
-	__( 'Display Gravatar', 'event_espresso' ),
48
+	__('Display Gravatar', 'event_espresso'),
49 49
 
50 50
 	// Reference: domains/blocks/src/event-attendees/controls/GravatarSettings.tsx:31
51
-	__( 'Gravatar images are shown for each attendee.', 'event_espresso' ),
51
+	__('Gravatar images are shown for each attendee.', 'event_espresso'),
52 52
 
53 53
 	// Reference: domains/blocks/src/event-attendees/controls/GravatarSettings.tsx:32
54
-	__( 'No gravatar images are shown for each attendee.', 'event_espresso' ),
54
+	__('No gravatar images are shown for each attendee.', 'event_espresso'),
55 55
 
56 56
 	// Reference: domains/blocks/src/event-attendees/controls/GravatarSettings.tsx:37
57
-	__( 'Size of Gravatar', 'event_espresso' ),
57
+	__('Size of Gravatar', 'event_espresso'),
58 58
 
59 59
 	// Reference: domains/blocks/src/event-attendees/controls/SelectDatetime.tsx:21
60
-	__( 'Select Datetime', 'event_espresso' ),
60
+	__('Select Datetime', 'event_espresso'),
61 61
 
62 62
 	// Reference: domains/blocks/src/event-attendees/controls/SelectEvent.tsx:21
63
-	__( 'Select Event', 'event_espresso' ),
63
+	__('Select Event', 'event_espresso'),
64 64
 
65 65
 	// Reference: domains/blocks/src/event-attendees/controls/SelectOrderBy.tsx:10
66
-	__( 'Attendee id', 'event_espresso' ),
66
+	__('Attendee id', 'event_espresso'),
67 67
 
68 68
 	// Reference: domains/blocks/src/event-attendees/controls/SelectOrderBy.tsx:14
69
-	__( 'Last name only', 'event_espresso' ),
69
+	__('Last name only', 'event_espresso'),
70 70
 
71 71
 	// Reference: domains/blocks/src/event-attendees/controls/SelectOrderBy.tsx:18
72
-	__( 'First name only', 'event_espresso' ),
72
+	__('First name only', 'event_espresso'),
73 73
 
74 74
 	// Reference: domains/blocks/src/event-attendees/controls/SelectOrderBy.tsx:22
75
-	__( 'First, then Last name', 'event_espresso' ),
75
+	__('First, then Last name', 'event_espresso'),
76 76
 
77 77
 	// Reference: domains/blocks/src/event-attendees/controls/SelectOrderBy.tsx:26
78
-	__( 'Last, then First name', 'event_espresso' ),
78
+	__('Last, then First name', 'event_espresso'),
79 79
 
80 80
 	// Reference: domains/blocks/src/event-attendees/controls/SelectOrderBy.tsx:40
81
-	__( 'Order Attendees by:', 'event_espresso' ),
81
+	__('Order Attendees by:', 'event_espresso'),
82 82
 
83 83
 	// Reference: domains/blocks/src/event-attendees/controls/SelectTicket.tsx:21
84
-	__( 'Select Ticket', 'event_espresso' ),
84
+	__('Select Ticket', 'event_espresso'),
85 85
 
86 86
 	// Reference: domains/blocks/src/event-attendees/controls/index.tsx:22
87
-	__( 'Filter By Settings', 'event_espresso' ),
87
+	__('Filter By Settings', 'event_espresso'),
88 88
 
89 89
 	// Reference: domains/blocks/src/event-attendees/controls/index.tsx:37
90
-	__( 'Gravatar Setttings', 'event_espresso' ),
90
+	__('Gravatar Setttings', 'event_espresso'),
91 91
 
92 92
 	// Reference: domains/blocks/src/event-attendees/controls/index.tsx:40
93
-	__( 'Archive Settings', 'event_espresso' ),
93
+	__('Archive Settings', 'event_espresso'),
94 94
 
95 95
 	// Reference: domains/blocks/src/event-attendees/index.tsx:10
96
-	__( 'Event Attendees', 'event_espresso' ),
96
+	__('Event Attendees', 'event_espresso'),
97 97
 
98 98
 	// Reference: domains/blocks/src/event-attendees/index.tsx:11
99
-	__( 'Displays a list of people that have registered for the specified event', 'event_espresso' ),
99
+	__('Displays a list of people that have registered for the specified event', 'event_espresso'),
100 100
 
101 101
 	// Reference: domains/blocks/src/event-attendees/index.tsx:14
102
-	__( 'event', 'event_espresso' ),
102
+	__('event', 'event_espresso'),
103 103
 
104 104
 	// Reference: domains/blocks/src/event-attendees/index.tsx:14
105
-	__( 'attendees', 'event_espresso' ),
105
+	__('attendees', 'event_espresso'),
106 106
 
107 107
 	// Reference: domains/blocks/src/event-attendees/index.tsx:14
108
-	__( 'list', 'event_espresso' ),
108
+	__('list', 'event_espresso'),
109 109
 
110 110
 	// Reference: domains/blocks/src/services/utils.ts:11
111
-	__( 'Loading...', 'event_espresso' ),
111
+	__('Loading...', 'event_espresso'),
112 112
 
113 113
 	// Reference: domains/blocks/src/services/utils.ts:19
114 114
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:32
115
-	__( 'Error', 'event_espresso' ),
115
+	__('Error', 'event_espresso'),
116 116
 
117 117
 	// Reference: domains/blocks/src/services/utils.ts:26
118
-	__( 'Select...', 'event_espresso' ),
118
+	__('Select...', 'event_espresso'),
119 119
 
120 120
 	// Reference: domains/eventEditor/src/ui/datetimes/DateRegistrationsLink.tsx:17
121
-	__( 'view ALL registrations for this date.', 'event_espresso' ),
121
+	__('view ALL registrations for this date.', 'event_espresso'),
122 122
 
123 123
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/formValidation.ts:15
124 124
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/formValidation.ts:15
125
-	__( 'Name is required', 'event_espresso' ),
125
+	__('Name is required', 'event_espresso'),
126 126
 
127 127
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/formValidation.ts:16
128 128
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/formValidation.ts:12
129 129
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/formValidation.ts:16
130 130
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/formValidation.ts:12
131
-	__( 'Name must be at least three characters', 'event_espresso' ),
131
+	__('Name must be at least three characters', 'event_espresso'),
132 132
 
133 133
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/Container.tsx:19
134
-	__( 'Edit datetime %s', 'event_espresso' ),
134
+	__('Edit datetime %s', 'event_espresso'),
135 135
 
136 136
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/Container.tsx:19
137
-	__( 'New Datetime', 'event_espresso' ),
137
+	__('New Datetime', 'event_espresso'),
138 138
 
139 139
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/ContentBody.tsx:40
140
-	__( 'Save and assign tickets', 'event_espresso' ),
140
+	__('Save and assign tickets', 'event_espresso'),
141 141
 
142 142
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:11
143
-	__( 'primary information about the date', 'event_espresso' ),
143
+	__('primary information about the date', 'event_espresso'),
144 144
 
145 145
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:11
146
-	__( 'Date Details', 'event_espresso' ),
146
+	__('Date Details', 'event_espresso'),
147 147
 
148 148
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:12
149 149
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:17
150
-	__( 'relations between tickets and dates', 'event_espresso' ),
150
+	__('relations between tickets and dates', 'event_espresso'),
151 151
 
152 152
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:12
153
-	__( 'Assign Tickets', 'event_espresso' ),
153
+	__('Assign Tickets', 'event_espresso'),
154 154
 
155 155
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:107
156 156
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:108
157 157
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:119
158 158
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:108
159
-	__( 'Details', 'event_espresso' ),
159
+	__('Details', 'event_espresso'),
160 160
 
161 161
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:111
162 162
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:112
163 163
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:74
164
-	__( 'Capacity', 'event_espresso' ),
164
+	__('Capacity', 'event_espresso'),
165 165
 
166 166
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:116
167
-	__( 'The maximum number of registrants that can attend the event at this particular date.%sSet to 0 to close registration or leave blank for no limit.', 'event_espresso' ),
167
+	__('The maximum number of registrants that can attend the event at this particular date.%sSet to 0 to close registration or leave blank for no limit.', 'event_espresso'),
168 168
 
169 169
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:125
170 170
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:198
171
-	__( 'Trash', 'event_espresso' ),
171
+	__('Trash', 'event_espresso'),
172 172
 
173 173
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:69
174 174
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:45
175 175
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:81
176 176
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:45
177
-	__( 'Basics', 'event_espresso' ),
177
+	__('Basics', 'event_espresso'),
178 178
 
179 179
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:73
180 180
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:49
@@ -182,219 +182,219 @@  discard block
 block discarded – undo
182 182
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:85
183 183
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:49
184 184
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:42
185
-	__( 'Name', 'event_espresso' ),
185
+	__('Name', 'event_espresso'),
186 186
 
187 187
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:80
188 188
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:55
189 189
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:92
190 190
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:55
191 191
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:41
192
-	__( 'Description', 'event_espresso' ),
192
+	__('Description', 'event_espresso'),
193 193
 
194 194
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:88
195 195
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:63
196 196
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:63
197
-	__( 'Dates', 'event_espresso' ),
197
+	__('Dates', 'event_espresso'),
198 198
 
199 199
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:92
200 200
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:51
201 201
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:104
202
-	__( 'Start Date', 'event_espresso' ),
202
+	__('Start Date', 'event_espresso'),
203 203
 
204 204
 	// Reference: domains/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:98
205 205
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:62
206 206
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:110
207
-	__( 'End Date', 'event_espresso' ),
207
+	__('End Date', 'event_espresso'),
208 208
 
209 209
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/DatesList.tsx:34
210 210
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/TableView.tsx:34
211
-	__( 'Event Dates', 'event_espresso' ),
211
+	__('Event Dates', 'event_espresso'),
212 212
 
213 213
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/DatesList.tsx:37
214
-	__( 'loading event dates...', 'event_espresso' ),
214
+	__('loading event dates...', 'event_espresso'),
215 215
 
216 216
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/DatesListButtons.tsx:22
217
-	__( 'Ticket Assignments', 'event_espresso' ),
217
+	__('Ticket Assignments', 'event_espresso'),
218 218
 
219 219
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:27
220
-	__( 'Number of related tickets', 'event_espresso' ),
220
+	__('Number of related tickets', 'event_espresso'),
221 221
 
222 222
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:28
223
-	__( 'There are no tickets assigned to this datetime. Please click the ticket icon to update the assignments.', 'event_espresso' ),
223
+	__('There are no tickets assigned to this datetime. Please click the ticket icon to update the assignments.', 'event_espresso'),
224 224
 
225 225
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:42
226
-	__( 'assign tickets', 'event_espresso' ),
226
+	__('assign tickets', 'event_espresso'),
227 227
 
228 228
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:18
229
-	__( 'Permanently delete Datetime?', 'event_espresso' ),
229
+	__('Permanently delete Datetime?', 'event_espresso'),
230 230
 
231 231
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:18
232
-	__( 'Move Datetime to Trash?', 'event_espresso' ),
232
+	__('Move Datetime to Trash?', 'event_espresso'),
233 233
 
234 234
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:20
235
-	__( 'Are you sure you want to permanently delete this datetime? This action is permanent and can not be undone.', 'event_espresso' ),
235
+	__('Are you sure you want to permanently delete this datetime? This action is permanent and can not be undone.', 'event_espresso'),
236 236
 
237 237
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:23
238
-	__( 'Are you sure you want to move this datetime to the trash? You can "untrash" this datetime later if you need to.', 'event_espresso' ),
238
+	__('Are you sure you want to move this datetime to the trash? You can "untrash" this datetime later if you need to.', 'event_espresso'),
239 239
 
240 240
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:33
241
-	__( 'event date main menu', 'event_espresso' ),
241
+	__('event date main menu', 'event_espresso'),
242 242
 
243 243
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:37
244 244
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:33
245
-	__( 'delete permanently', 'event_espresso' ),
245
+	__('delete permanently', 'event_espresso'),
246 246
 
247 247
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:37
248
-	__( 'trash datetime', 'event_espresso' ),
248
+	__('trash datetime', 'event_espresso'),
249 249
 
250 250
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:46
251
-	__( 'edit datetime', 'event_espresso' ),
251
+	__('edit datetime', 'event_espresso'),
252 252
 
253 253
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:47
254
-	__( 'copy datetime', 'event_espresso' ),
254
+	__('copy datetime', 'event_espresso'),
255 255
 
256 256
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:30
257
-	__( 'edit datetime details', 'event_espresso' ),
257
+	__('edit datetime details', 'event_espresso'),
258 258
 
259 259
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:34
260
-	__( 'delete datetimes', 'event_espresso' ),
260
+	__('delete datetimes', 'event_espresso'),
261 261
 
262 262
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:34
263
-	__( 'trash datetimes', 'event_espresso' ),
263
+	__('trash datetimes', 'event_espresso'),
264 264
 
265 265
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:13
266
-	__( 'Are you sure you want to permanently delete these datetimes? This action can NOT be undone!', 'event_espresso' ),
266
+	__('Are you sure you want to permanently delete these datetimes? This action can NOT be undone!', 'event_espresso'),
267 267
 
268 268
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:14
269
-	__( 'Are you sure you want to trash these datetimes?', 'event_espresso' ),
269
+	__('Are you sure you want to trash these datetimes?', 'event_espresso'),
270 270
 
271 271
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:15
272
-	__( 'Delete datetimes permanently', 'event_espresso' ),
272
+	__('Delete datetimes permanently', 'event_espresso'),
273 273
 
274 274
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:15
275
-	__( 'Trash datetimes', 'event_espresso' ),
275
+	__('Trash datetimes', 'event_espresso'),
276 276
 
277 277
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/EditDetails.tsx:22
278
-	__( 'Bulk edit date details', 'event_espresso' ),
278
+	__('Bulk edit date details', 'event_espresso'),
279 279
 
280 280
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/EditDetails.tsx:23
281
-	__( 'any changes will be applied to ALL of the selected dates.', 'event_espresso' ),
281
+	__('any changes will be applied to ALL of the selected dates.', 'event_espresso'),
282 282
 
283 283
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:67
284 284
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:67
285
-	__( 'Shift dates', 'event_espresso' ),
285
+	__('Shift dates', 'event_espresso'),
286 286
 
287 287
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:92
288 288
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:92
289
-	__( 'earlier', 'event_espresso' ),
289
+	__('earlier', 'event_espresso'),
290 290
 
291 291
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:96
292 292
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:96
293
-	__( 'later', 'event_espresso' ),
293
+	__('later', 'event_espresso'),
294 294
 
295 295
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/DateCapacity.tsx:35
296
-	__( 'edit capacity (registration limit)...', 'event_espresso' ),
296
+	__('edit capacity (registration limit)...', 'event_espresso'),
297 297
 
298 298
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:37
299
-	__( 'Edit Event Date', 'event_espresso' ),
299
+	__('Edit Event Date', 'event_espresso'),
300 300
 
301 301
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:40
302
-	__( 'edit start and end dates', 'event_espresso' ),
302
+	__('edit start and end dates', 'event_espresso'),
303 303
 
304 304
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:14
305 305
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:14
306
-	__( 'sold', 'event_espresso' ),
306
+	__('sold', 'event_espresso'),
307 307
 
308 308
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:27
309
-	__( 'capacity', 'event_espresso' ),
309
+	__('capacity', 'event_espresso'),
310 310
 
311 311
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:33
312 312
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:32
313
-	__( 'reg list', 'event_espresso' ),
313
+	__('reg list', 'event_espresso'),
314 314
 
315 315
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:40
316 316
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:40
317
-	__( 'Edit description', 'event_espresso' ),
317
+	__('Edit description', 'event_espresso'),
318 318
 
319 319
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:41
320 320
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:41
321
-	__( 'edit description...', 'event_espresso' ),
321
+	__('edit description...', 'event_espresso'),
322 322
 
323 323
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/config.ts:13
324
-	__( 'Active', 'event_espresso' ),
324
+	__('Active', 'event_espresso'),
325 325
 
326 326
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/config.ts:14
327 327
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/config.ts:13
328
-	__( 'Trashed', 'event_espresso' ),
328
+	__('Trashed', 'event_espresso'),
329 329
 
330 330
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/config.ts:15
331 331
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/config.ts:14
332
-	__( 'Expired', 'event_espresso' ),
332
+	__('Expired', 'event_espresso'),
333 333
 
334 334
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/config.ts:16
335 335
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/config.ts:16
336
-	__( 'Sold Out', 'event_espresso' ),
336
+	__('Sold Out', 'event_espresso'),
337 337
 
338 338
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/config.ts:17
339
-	__( 'Upcoming', 'event_espresso' ),
339
+	__('Upcoming', 'event_espresso'),
340 340
 
341 341
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/editable/EditableName.tsx:17
342 342
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/editable/EditableName.tsx:27
343
-	__( 'edit title...', 'event_espresso' ),
343
+	__('edit title...', 'event_espresso'),
344 344
 
345 345
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/ActiveDatesFilters.tsx:25
346 346
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/ActiveTicketsFilters.tsx:25
347
-	__( 'ON', 'event_espresso' ),
347
+	__('ON', 'event_espresso'),
348 348
 
349 349
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:10
350
-	__( 'start and end dates', 'event_espresso' ),
350
+	__('start and end dates', 'event_espresso'),
351 351
 
352 352
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:15
353
-	__( 'dates above 90% capacity', 'event_espresso' ),
353
+	__('dates above 90% capacity', 'event_espresso'),
354 354
 
355 355
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:16
356
-	__( 'dates above 75% capacity', 'event_espresso' ),
356
+	__('dates above 75% capacity', 'event_espresso'),
357 357
 
358 358
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:17
359
-	__( 'dates above 50% capacity', 'event_espresso' ),
359
+	__('dates above 50% capacity', 'event_espresso'),
360 360
 
361 361
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:18
362
-	__( 'dates below 50% capacity', 'event_espresso' ),
362
+	__('dates below 50% capacity', 'event_espresso'),
363 363
 
364 364
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:22
365
-	__( 'all dates', 'event_espresso' ),
365
+	__('all dates', 'event_espresso'),
366 366
 
367 367
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:23
368
-	__( 'all active and upcoming', 'event_espresso' ),
368
+	__('all active and upcoming', 'event_espresso'),
369 369
 
370 370
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:24
371
-	__( 'active dates only', 'event_espresso' ),
371
+	__('active dates only', 'event_espresso'),
372 372
 
373 373
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:25
374
-	__( 'upcoming dates only', 'event_espresso' ),
374
+	__('upcoming dates only', 'event_espresso'),
375 375
 
376 376
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:26
377
-	__( 'next active or upcoming only', 'event_espresso' ),
377
+	__('next active or upcoming only', 'event_espresso'),
378 378
 
379 379
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:27
380
-	__( 'sold out dates only', 'event_espresso' ),
380
+	__('sold out dates only', 'event_espresso'),
381 381
 
382 382
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:28
383
-	__( 'recently expired dates', 'event_espresso' ),
383
+	__('recently expired dates', 'event_espresso'),
384 384
 
385 385
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:29
386
-	__( 'all expired dates', 'event_espresso' ),
386
+	__('all expired dates', 'event_espresso'),
387 387
 
388 388
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:30
389
-	__( 'trashed dates only', 'event_espresso' ),
389
+	__('trashed dates only', 'event_espresso'),
390 390
 
391 391
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:34
392 392
 	// Reference: packages/dates/src/DateRangePicker.tsx:52
393 393
 	// Reference: packages/dates/src/DateRangePickerLegend.tsx:10
394
-	__( 'start date', 'event_espresso' ),
394
+	__('start date', 'event_espresso'),
395 395
 
396 396
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:35
397
-	__( 'name', 'event_espresso' ),
397
+	__('name', 'event_espresso'),
398 398
 
399 399
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:36
400 400
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:37
@@ -402,98 +402,98 @@  discard block
 block discarded – undo
402 402
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/table/HeaderCell.tsx:20
403 403
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:36
404 404
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:23
405
-	__( 'ID', 'event_espresso' ),
405
+	__('ID', 'event_espresso'),
406 406
 
407 407
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:37
408 408
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:46
409
-	__( 'custom order', 'event_espresso' ),
409
+	__('custom order', 'event_espresso'),
410 410
 
411 411
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:41
412 412
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:51
413
-	__( 'display', 'event_espresso' ),
413
+	__('display', 'event_espresso'),
414 414
 
415 415
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:42
416
-	__( 'recurrence', 'event_espresso' ),
416
+	__('recurrence', 'event_espresso'),
417 417
 
418 418
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:43
419 419
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:53
420
-	__( 'sales', 'event_espresso' ),
420
+	__('sales', 'event_espresso'),
421 421
 
422 422
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:44
423 423
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:55
424
-	__( 'sort by', 'event_espresso' ),
424
+	__('sort by', 'event_espresso'),
425 425
 
426 426
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:45
427 427
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:54
428 428
 	// Reference: packages/components/src/EntityList/filterBar/EntityListFilterBar.tsx:73
429
-	__( 'search', 'event_espresso' ),
429
+	__('search', 'event_espresso'),
430 430
 
431 431
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:46
432 432
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:56
433
-	__( 'status', 'event_espresso' ),
433
+	__('status', 'event_espresso'),
434 434
 
435 435
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:8
436
-	__( 'start dates only', 'event_espresso' ),
436
+	__('start dates only', 'event_espresso'),
437 437
 
438 438
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:9
439
-	__( 'end dates only', 'event_espresso' ),
439
+	__('end dates only', 'event_espresso'),
440 440
 
441 441
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:20
442 442
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/newDateOptions/OptionsPopover.tsx:14
443 443
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/newDateOptions/OptionsPopoverButton.tsx:11
444
-	__( 'Add New Date', 'event_espresso' ),
444
+	__('Add New Date', 'event_espresso'),
445 445
 
446 446
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:20
447
-	__( 'Add Single Date', 'event_espresso' ),
447
+	__('Add Single Date', 'event_espresso'),
448 448
 
449 449
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:34
450
-	__( 'Add a single date
451
-that only occurs once', 'event_espresso' ),
450
+	__('Add a single date
451
+that only occurs once', 'event_espresso'),
452 452
 
453 453
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:36
454
-	__( 'Single Date', 'event_espresso' ),
454
+	__('Single Date', 'event_espresso'),
455 455
 
456 456
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:104
457 457
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:103
458 458
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:53
459
-	__( 'Actions', 'event_espresso' ),
459
+	__('Actions', 'event_espresso'),
460 460
 
461 461
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:52
462
-	__( 'Start', 'event_espresso' ),
462
+	__('Start', 'event_espresso'),
463 463
 
464 464
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:63
465
-	__( 'End', 'event_espresso' ),
465
+	__('End', 'event_espresso'),
466 466
 
467 467
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:75
468
-	__( 'Cap', 'event_espresso' ),
468
+	__('Cap', 'event_espresso'),
469 469
 
470 470
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:83
471 471
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:85
472
-	__( 'Sold', 'event_espresso' ),
472
+	__('Sold', 'event_espresso'),
473 473
 
474 474
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:92
475
-	__( 'Reg list', 'event_espresso' ),
475
+	__('Reg list', 'event_espresso'),
476 476
 
477 477
 	// Reference: domains/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:93
478 478
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:95
479
-	__( 'Regs', 'event_espresso' ),
479
+	__('Regs', 'event_espresso'),
480 480
 
481 481
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:18
482
-	__( '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' ),
482
+	__('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'),
483 483
 
484 484
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:22
485
-	__( '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' ),
485
+	__('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'),
486 486
 
487 487
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:20
488
-	__( 'Ticket Assignment Manager for Datetime: %s - %s', 'event_espresso' ),
488
+	__('Ticket Assignment Manager for Datetime: %s - %s', 'event_espresso'),
489 489
 
490 490
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:22
491
-	__( 'Ticket Assignment Manager for Ticket: %s - %s', 'event_espresso' ),
491
+	__('Ticket Assignment Manager for Ticket: %s - %s', 'event_espresso'),
492 492
 
493 493
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/TicketAssignmentsManagerModal/buttons/useCancelButtonProps.tsx:18
494 494
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:16
495 495
 	// Reference: packages/components/src/Modal/useCancelButtonProps.tsx:10
496
-	__( 'Cancel', 'event_espresso' ),
496
+	__('Cancel', 'event_espresso'),
497 497
 
498 498
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/TicketAssignmentsManagerModal/buttons/useSubmitButtonProps.tsx:25
499 499
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:17
@@ -502,728 +502,728 @@  discard block
 block discarded – undo
502 502
 	// Reference: packages/components/src/bulkEdit/details/Submit.tsx:38
503 503
 	// Reference: packages/form/src/Submit.tsx:26
504 504
 	// Reference: packages/tpc/src/buttons/useSubmitButtonProps.tsx:25
505
-	__( 'Submit', 'event_espresso' ),
505
+	__('Submit', 'event_espresso'),
506 506
 
507 507
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/TicketAssignmentsManagerModal/index.tsx:32
508 508
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/table/Table.tsx:14
509
-	__( 'Ticket Assignment Manager', 'event_espresso' ),
509
+	__('Ticket Assignment Manager', 'event_espresso'),
510 510
 
511 511
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/components/table/BodyCell.tsx:24
512
-	__( 'assign ticket', 'event_espresso' ),
512
+	__('assign ticket', 'event_espresso'),
513 513
 
514 514
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/DatesByMonthControl.tsx:19
515
-	__( 'All Dates', 'event_espresso' ),
515
+	__('All Dates', 'event_espresso'),
516 516
 
517 517
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/DatesByMonthControl.tsx:26
518
-	__( 'dates by month', 'event_espresso' ),
518
+	__('dates by month', 'event_espresso'),
519 519
 
520 520
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowExpiredTicketsControl.tsx:15
521
-	__( 'show expired tickets', 'event_espresso' ),
521
+	__('show expired tickets', 'event_espresso'),
522 522
 
523 523
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowTrashedDatesControl.tsx:12
524
-	__( 'show trashed dates', 'event_espresso' ),
524
+	__('show trashed dates', 'event_espresso'),
525 525
 
526 526
 	// Reference: domains/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowTrashedTicketsControl.tsx:15
527
-	__( 'show trashed tickets', 'event_espresso' ),
527
+	__('show trashed tickets', 'event_espresso'),
528 528
 
529 529
 	// Reference: domains/eventEditor/src/ui/tickets/TicketRegistrationsLink.tsx:17
530
-	__( 'total registrations.', 'event_espresso' ),
530
+	__('total registrations.', 'event_espresso'),
531 531
 
532 532
 	// Reference: domains/eventEditor/src/ui/tickets/TicketRegistrationsLink.tsx:18
533
-	__( 'view ALL registrations for this ticket.', 'event_espresso' ),
533
+	__('view ALL registrations for this ticket.', 'event_espresso'),
534 534
 
535 535
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/Container.tsx:18
536
-	__( 'Edit ticket %s', 'event_espresso' ),
536
+	__('Edit ticket %s', 'event_espresso'),
537 537
 
538 538
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/Container.tsx:18
539
-	__( 'New Ticket Details', 'event_espresso' ),
539
+	__('New Ticket Details', 'event_espresso'),
540 540
 
541 541
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/ContentBody.tsx:44
542
-	__( 'Add ticket prices', 'event_espresso' ),
542
+	__('Add ticket prices', 'event_espresso'),
543 543
 
544 544
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/ContentBody.tsx:50
545
-	__( 'Skip prices - assign dates', 'event_espresso' ),
545
+	__('Skip prices - assign dates', 'event_espresso'),
546 546
 
547 547
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/ContentBody.tsx:66
548
-	__( 'Save and assign dates', 'event_espresso' ),
548
+	__('Save and assign dates', 'event_espresso'),
549 549
 
550 550
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/ContentBody.tsx:79
551
-	__( 'Ticket details', 'event_espresso' ),
551
+	__('Ticket details', 'event_espresso'),
552 552
 
553 553
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:11
554
-	__( 'primary information about the ticket', 'event_espresso' ),
554
+	__('primary information about the ticket', 'event_espresso'),
555 555
 
556 556
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:11
557
-	__( 'Ticket Details', 'event_espresso' ),
557
+	__('Ticket Details', 'event_espresso'),
558 558
 
559 559
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:13
560
-	__( 'apply ticket price modifiers and taxes', 'event_espresso' ),
560
+	__('apply ticket price modifiers and taxes', 'event_espresso'),
561 561
 
562 562
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:15
563
-	__( 'Price Calculator', 'event_espresso' ),
563
+	__('Price Calculator', 'event_espresso'),
564 564
 
565 565
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:17
566
-	__( 'Assign Dates', 'event_espresso' ),
566
+	__('Assign Dates', 'event_espresso'),
567 567
 
568 568
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:100
569
-	__( 'Ticket Sales', 'event_espresso' ),
569
+	__('Ticket Sales', 'event_espresso'),
570 570
 
571 571
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:123
572 572
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:112
573
-	__( 'Quantity For Sale', 'event_espresso' ),
573
+	__('Quantity For Sale', 'event_espresso'),
574 574
 
575 575
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:129
576
-	__( 'The maximum number of this ticket available for sale.%sSet to 0 to stop sales, or leave blank for no limit.', 'event_espresso' ),
576
+	__('The maximum number of this ticket available for sale.%sSet to 0 to stop sales, or leave blank for no limit.', 'event_espresso'),
577 577
 
578 578
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:138
579 579
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:121
580
-	__( 'Number of Uses', 'event_espresso' ),
580
+	__('Number of Uses', 'event_espresso'),
581 581
 
582 582
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:144
583
-	__( 'Controls the total number of times this ticket can be used, regardless of the number of dates it is assigned to.%sExample: 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' ),
583
+	__('Controls the total number of times this ticket can be used, regardless of the number of dates it is assigned to.%sExample: 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'),
584 584
 
585 585
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:153
586 586
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:129
587
-	__( 'Minimum Quantity', 'event_espresso' ),
587
+	__('Minimum Quantity', 'event_espresso'),
588 588
 
589 589
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:158
590
-	__( 'The minimum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.%sLeave blank for no minimum.', 'event_espresso' ),
590
+	__('The minimum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.%sLeave blank for no minimum.', 'event_espresso'),
591 591
 
592 592
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:167
593 593
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:137
594
-	__( 'Maximum Quantity', 'event_espresso' ),
594
+	__('Maximum Quantity', 'event_espresso'),
595 595
 
596 596
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:173
597
-	__( 'The maximum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.%sLeave blank for no maximum.', 'event_espresso' ),
597
+	__('The maximum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.%sLeave blank for no maximum.', 'event_espresso'),
598 598
 
599 599
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:182
600 600
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:146
601
-	__( 'Required Ticket', 'event_espresso' ),
601
+	__('Required Ticket', 'event_espresso'),
602 602
 
603 603
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:184
604
-	__( 'If enabled, the ticket must be selected and will appear first in frontend ticket lists.', 'event_espresso' ),
604
+	__('If enabled, the ticket must be selected and will appear first in frontend ticket lists.', 'event_espresso'),
605 605
 
606 606
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:191
607
-	__( 'Default Ticket', 'event_espresso' ),
607
+	__('Default Ticket', 'event_espresso'),
608 608
 
609 609
 	// Reference: domains/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.tsx:193
610
-	__( 'If enabled, the ticket will appear on all new events.', 'event_espresso' ),
610
+	__('If enabled, the ticket will appear on all new events.', 'event_espresso'),
611 611
 
612 612
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/TicketsList.tsx:34
613
-	__( 'Available Tickets', 'event_espresso' ),
613
+	__('Available Tickets', 'event_espresso'),
614 614
 
615 615
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/TicketsList.tsx:37
616
-	__( 'loading tickets...', 'event_espresso' ),
616
+	__('loading tickets...', 'event_espresso'),
617 617
 
618 618
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:27
619
-	__( 'Number of related dates', 'event_espresso' ),
619
+	__('Number of related dates', 'event_espresso'),
620 620
 
621 621
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:28
622
-	__( 'There are no event dates assigned to this ticket. Please click the calendar icon to update the assignments.', 'event_espresso' ),
622
+	__('There are no event dates assigned to this ticket. Please click the calendar icon to update the assignments.', 'event_espresso'),
623 623
 
624 624
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:44
625
-	__( 'assign dates', 'event_espresso' ),
625
+	__('assign dates', 'event_espresso'),
626 626
 
627 627
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:17
628
-	__( 'Permanently delete Ticket?', 'event_espresso' ),
628
+	__('Permanently delete Ticket?', 'event_espresso'),
629 629
 
630 630
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:17
631
-	__( 'Move Ticket to Trash?', 'event_espresso' ),
631
+	__('Move Ticket to Trash?', 'event_espresso'),
632 632
 
633 633
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:19
634
-	__( 'Are you sure you want to permanently delete this ticket? This action is permanent and can not be undone.', 'event_espresso' ),
634
+	__('Are you sure you want to permanently delete this ticket? This action is permanent and can not be undone.', 'event_espresso'),
635 635
 
636 636
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:20
637
-	__( 'Are you sure you want to move this ticket to the trash? You can "untrash" this ticket later if you need to.', 'event_espresso' ),
637
+	__('Are you sure you want to move this ticket to the trash? You can "untrash" this ticket later if you need to.', 'event_espresso'),
638 638
 
639 639
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:29
640
-	__( 'ticket main menu', 'event_espresso' ),
640
+	__('ticket main menu', 'event_espresso'),
641 641
 
642 642
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:33
643
-	__( 'trash ticket', 'event_espresso' ),
643
+	__('trash ticket', 'event_espresso'),
644 644
 
645 645
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:42
646
-	__( 'edit ticket', 'event_espresso' ),
646
+	__('edit ticket', 'event_espresso'),
647 647
 
648 648
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:43
649
-	__( 'copy ticket', 'event_espresso' ),
649
+	__('copy ticket', 'event_espresso'),
650 650
 
651 651
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:30
652 652
 	// Reference: packages/components/src/bulkEdit/BulkActions.tsx:43
653
-	__( 'bulk actions', 'event_espresso' ),
653
+	__('bulk actions', 'event_espresso'),
654 654
 
655 655
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:34
656
-	__( 'edit ticket details', 'event_espresso' ),
656
+	__('edit ticket details', 'event_espresso'),
657 657
 
658 658
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:38
659
-	__( 'delete tickets', 'event_espresso' ),
659
+	__('delete tickets', 'event_espresso'),
660 660
 
661 661
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:38
662
-	__( 'trash tickets', 'event_espresso' ),
662
+	__('trash tickets', 'event_espresso'),
663 663
 
664 664
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:42
665
-	__( 'edit ticket prices', 'event_espresso' ),
665
+	__('edit ticket prices', 'event_espresso'),
666 666
 
667 667
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:13
668
-	__( 'Are you sure you want to permanently delete these tickets? This action can NOT be undone!', 'event_espresso' ),
668
+	__('Are you sure you want to permanently delete these tickets? This action can NOT be undone!', 'event_espresso'),
669 669
 
670 670
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:14
671
-	__( 'Are you sure you want to trash these tickets?', 'event_espresso' ),
671
+	__('Are you sure you want to trash these tickets?', 'event_espresso'),
672 672
 
673 673
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:15
674
-	__( 'Delete tickets permanently', 'event_espresso' ),
674
+	__('Delete tickets permanently', 'event_espresso'),
675 675
 
676 676
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:15
677
-	__( 'Trash tickets', 'event_espresso' ),
677
+	__('Trash tickets', 'event_espresso'),
678 678
 
679 679
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/EditDetails.tsx:22
680
-	__( 'Bulk edit ticket details', 'event_espresso' ),
680
+	__('Bulk edit ticket details', 'event_espresso'),
681 681
 
682 682
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/EditDetails.tsx:23
683
-	__( 'any changes will be applied to ALL of the selected tickets.', 'event_espresso' ),
683
+	__('any changes will be applied to ALL of the selected tickets.', 'event_espresso'),
684 684
 
685 685
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/EditPrices.tsx:18
686
-	__( 'Bulk edit ticket prices', 'event_espresso' ),
686
+	__('Bulk edit ticket prices', 'event_espresso'),
687 687
 
688 688
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:18
689
-	__( 'Edit all prices together', 'event_espresso' ),
689
+	__('Edit all prices together', 'event_espresso'),
690 690
 
691 691
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:19
692
-	__( 'Edit all the selected ticket prices dynamically', 'event_espresso' ),
692
+	__('Edit all the selected ticket prices dynamically', 'event_espresso'),
693 693
 
694 694
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:23
695
-	__( 'Edit prices individually', 'event_espresso' ),
695
+	__('Edit prices individually', 'event_espresso'),
696 696
 
697 697
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:24
698
-	__( 'Edit prices for each ticket individually', 'event_espresso' ),
698
+	__('Edit prices for each ticket individually', 'event_espresso'),
699 699
 
700 700
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:15
701 701
 	// Reference: packages/components/src/bulkEdit/details/Submit.tsx:45
702 702
 	// Reference: packages/form/src/ResetButton.tsx:17
703 703
 	// Reference: packages/tpc/src/buttons/useResetButtonProps.tsx:12
704
-	__( 'Reset', 'event_espresso' ),
704
+	__('Reset', 'event_espresso'),
705 705
 
706 706
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/editSeparately/TPCInstance.tsx:22
707
-	__( 'Edit prices for Ticket: %s', 'event_espresso' ),
707
+	__('Edit prices for Ticket: %s', 'event_espresso'),
708 708
 
709 709
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:36
710
-	__( 'Edit Ticket Sale Dates', 'event_espresso' ),
710
+	__('Edit Ticket Sale Dates', 'event_espresso'),
711 711
 
712 712
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:38
713
-	__( 'edit ticket sales start and end dates', 'event_espresso' ),
713
+	__('edit ticket sales start and end dates', 'event_espresso'),
714 714
 
715 715
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:27
716
-	__( 'quantity', 'event_espresso' ),
716
+	__('quantity', 'event_espresso'),
717 717
 
718 718
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/cardView/TicketQuantity.tsx:26
719
-	__( 'edit quantity of tickets available...', 'event_espresso' ),
719
+	__('edit quantity of tickets available...', 'event_espresso'),
720 720
 
721 721
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/config.ts:15
722 722
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:51
723
-	__( 'On Sale', 'event_espresso' ),
723
+	__('On Sale', 'event_espresso'),
724 724
 
725 725
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/config.ts:17
726
-	__( 'Pending', 'event_espresso' ),
726
+	__('Pending', 'event_espresso'),
727 727
 
728 728
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/editable/EditablePrice.tsx:31
729
-	__( 'set price...', 'event_espresso' ),
729
+	__('set price...', 'event_espresso'),
730 730
 
731 731
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/editable/EditablePrice.tsx:35
732
-	__( 'edit ticket total...', 'event_espresso' ),
732
+	__('edit ticket total...', 'event_espresso'),
733 733
 
734 734
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/IsChainedButton.tsx:24
735
-	__( 'tickets list is linked to dates list and is showing tickets for above dates only', 'event_espresso' ),
735
+	__('tickets list is linked to dates list and is showing tickets for above dates only', 'event_espresso'),
736 736
 
737 737
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/IsChainedButton.tsx:25
738
-	__( 'tickets list is unlinked and is showing tickets for all event dates', 'event_espresso' ),
738
+	__('tickets list is unlinked and is showing tickets for all event dates', 'event_espresso'),
739 739
 
740 740
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:10
741
-	__( 'ticket sales start and end dates', 'event_espresso' ),
741
+	__('ticket sales start and end dates', 'event_espresso'),
742 742
 
743 743
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:15
744
-	__( 'tickets with 90% or more sold', 'event_espresso' ),
744
+	__('tickets with 90% or more sold', 'event_espresso'),
745 745
 
746 746
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:16
747
-	__( 'tickets with 75% or more sold', 'event_espresso' ),
747
+	__('tickets with 75% or more sold', 'event_espresso'),
748 748
 
749 749
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:17
750
-	__( 'tickets with 50% or more sold', 'event_espresso' ),
750
+	__('tickets with 50% or more sold', 'event_espresso'),
751 751
 
752 752
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:18
753
-	__( 'tickets with less than 50% sold', 'event_espresso' ),
753
+	__('tickets with less than 50% sold', 'event_espresso'),
754 754
 
755 755
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:27
756
-	__( 'all tickets for all dates', 'event_espresso' ),
756
+	__('all tickets for all dates', 'event_espresso'),
757 757
 
758 758
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:28
759
-	__( 'all on sale and sale pending', 'event_espresso' ),
759
+	__('all on sale and sale pending', 'event_espresso'),
760 760
 
761 761
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:29
762
-	__( 'on sale tickets only', 'event_espresso' ),
762
+	__('on sale tickets only', 'event_espresso'),
763 763
 
764 764
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:30
765
-	__( 'sale pending tickets only', 'event_espresso' ),
765
+	__('sale pending tickets only', 'event_espresso'),
766 766
 
767 767
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:31
768
-	__( 'next on sale or sale pending only', 'event_espresso' ),
768
+	__('next on sale or sale pending only', 'event_espresso'),
769 769
 
770 770
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:32
771
-	__( 'sold out tickets only', 'event_espresso' ),
771
+	__('sold out tickets only', 'event_espresso'),
772 772
 
773 773
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:33
774
-	__( 'expired tickets only', 'event_espresso' ),
774
+	__('expired tickets only', 'event_espresso'),
775 775
 
776 776
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:34
777
-	__( 'trashed tickets only', 'event_espresso' ),
777
+	__('trashed tickets only', 'event_espresso'),
778 778
 
779 779
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:39
780
-	__( 'all tickets for above dates', 'event_espresso' ),
780
+	__('all tickets for above dates', 'event_espresso'),
781 781
 
782 782
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:43
783
-	__( 'ticket sale date', 'event_espresso' ),
783
+	__('ticket sale date', 'event_espresso'),
784 784
 
785 785
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:44
786
-	__( 'ticket name', 'event_espresso' ),
786
+	__('ticket name', 'event_espresso'),
787 787
 
788 788
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:45
789
-	__( 'ticket ID', 'event_espresso' ),
789
+	__('ticket ID', 'event_espresso'),
790 790
 
791 791
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:52
792
-	__( 'link', 'event_espresso' ),
792
+	__('link', 'event_espresso'),
793 793
 
794 794
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:8
795
-	__( 'ticket sales start date only', 'event_espresso' ),
795
+	__('ticket sales start date only', 'event_espresso'),
796 796
 
797 797
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:9
798
-	__( 'ticket sales end date only', 'event_espresso' ),
798
+	__('ticket sales end date only', 'event_espresso'),
799 799
 
800 800
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:19
801
-	__( 'Add New Ticket', 'event_espresso' ),
801
+	__('Add New Ticket', 'event_espresso'),
802 802
 
803 803
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:31
804
-	__( 'Single Ticket', 'event_espresso' ),
804
+	__('Single Ticket', 'event_espresso'),
805 805
 
806 806
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:33
807
-	__( 'Add a single ticket and assign the dates to it', 'event_espresso' ),
807
+	__('Add a single ticket and assign the dates to it', 'event_espresso'),
808 808
 
809 809
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/TableView.tsx:32
810
-	__( 'Tickets', 'event_espresso' ),
810
+	__('Tickets', 'event_espresso'),
811 811
 
812 812
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:50
813
-	__( 'Goes on Sale', 'event_espresso' ),
813
+	__('Goes on Sale', 'event_espresso'),
814 814
 
815 815
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:61
816
-	__( 'Sale Ends', 'event_espresso' ),
816
+	__('Sale Ends', 'event_espresso'),
817 817
 
818 818
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:62
819
-	__( 'Ends', 'event_espresso' ),
819
+	__('Ends', 'event_espresso'),
820 820
 
821 821
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:71
822
-	__( 'Price', 'event_espresso' ),
822
+	__('Price', 'event_espresso'),
823 823
 
824 824
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:78
825
-	__( 'Quantity', 'event_espresso' ),
825
+	__('Quantity', 'event_espresso'),
826 826
 
827 827
 	// Reference: domains/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:94
828
-	__( 'Registrations', 'event_espresso' ),
828
+	__('Registrations', 'event_espresso'),
829 829
 
830 830
 	// Reference: domains/wpPluginsPage/src/exitSurvey/Popup.tsx:28
831
-	__( 'Do you have a moment to share why you are deactivating Event Espresso?', 'event_espresso' ),
831
+	__('Do you have a moment to share why you are deactivating Event Espresso?', 'event_espresso'),
832 832
 
833 833
 	// Reference: domains/wpPluginsPage/src/exitSurvey/Popup.tsx:39
834
-	__( 'Skip', 'event_espresso' ),
834
+	__('Skip', 'event_espresso'),
835 835
 
836 836
 	// Reference: domains/wpPluginsPage/src/exitSurvey/Popup.tsx:41
837
-	__( 'Sure I\'ll help', 'event_espresso' ),
837
+	__('Sure I\'ll help', 'event_espresso'),
838 838
 
839 839
 	// Reference: packages/adapters/src/Pagination/PerPage.tsx:38
840
-	__( 'items per page', 'event_espresso' ),
840
+	__('items per page', 'event_espresso'),
841 841
 
842 842
 	// Reference: packages/adapters/src/Steps/Steps.tsx:30
843
-	__( 'Steps', 'event_espresso' ),
843
+	__('Steps', 'event_espresso'),
844 844
 
845 845
 	// Reference: packages/components/src/ActiveFilters/ActiveFilters.tsx:8
846
-	__( 'active filters:', 'event_espresso' ),
846
+	__('active filters:', 'event_espresso'),
847 847
 
848 848
 	// Reference: packages/components/src/ActiveFilters/FilterTag.tsx:12
849
-	__( 'remove filter', 'event_espresso' ),
849
+	__('remove filter', 'event_espresso'),
850 850
 
851 851
 	// Reference: packages/components/src/CalendarDateRange/CalendarDateRange.tsx:39
852
-	__( 'to', 'event_espresso' ),
852
+	__('to', 'event_espresso'),
853 853
 
854 854
 	// Reference: packages/components/src/CalendarDateSwitcher/CalendarDateSwitcher.tsx:33
855
-	__( 'starts', 'event_espresso' ),
855
+	__('starts', 'event_espresso'),
856 856
 
857 857
 	// Reference: packages/components/src/CalendarDateSwitcher/CalendarDateSwitcher.tsx:45
858
-	__( 'ends', 'event_espresso' ),
858
+	__('ends', 'event_espresso'),
859 859
 
860 860
 	// Reference: packages/components/src/CalendarPageDate/CalendarPageDate.tsx:57
861
-	__( 'TO', 'event_espresso' ),
861
+	__('TO', 'event_espresso'),
862 862
 
863 863
 	// Reference: packages/components/src/Confirm/ConfirmClose.tsx:8
864 864
 	// Reference: packages/components/src/Modal/ModalWithAlert.tsx:23
865
-	__( 'Are you sure you want to close this?', 'event_espresso' ),
865
+	__('Are you sure you want to close this?', 'event_espresso'),
866 866
 
867 867
 	// Reference: packages/components/src/Confirm/ConfirmDelete.tsx:8
868
-	__( 'Are you sure you want to delete this?', 'event_espresso' ),
868
+	__('Are you sure you want to delete this?', 'event_espresso'),
869 869
 
870 870
 	// Reference: packages/components/src/Confirm/useConfirmWithButton.tsx:11
871
-	__( 'Please confirm this action.', 'event_espresso' ),
871
+	__('Please confirm this action.', 'event_espresso'),
872 872
 
873 873
 	// Reference: packages/components/src/Confirm/useConfirmationDialog.tsx:35
874
-	__( 'No', 'event_espresso' ),
874
+	__('No', 'event_espresso'),
875 875
 
876 876
 	// Reference: packages/components/src/Confirm/useConfirmationDialog.tsx:36
877
-	__( 'Yes', 'event_espresso' ),
877
+	__('Yes', 'event_espresso'),
878 878
 
879 879
 	// Reference: packages/components/src/DateTimeRangePicker/index.tsx:33
880
-	__( 'save', 'event_espresso' ),
880
+	__('save', 'event_espresso'),
881 881
 
882 882
 	// Reference: packages/components/src/DebugInfo/DebugInfo.tsx:36
883
-	__( 'Hide Debug Info', 'event_espresso' ),
883
+	__('Hide Debug Info', 'event_espresso'),
884 884
 
885 885
 	// Reference: packages/components/src/DebugInfo/DebugInfo.tsx:36
886
-	__( 'Show Debug Info', 'event_espresso' ),
886
+	__('Show Debug Info', 'event_espresso'),
887 887
 
888 888
 	// Reference: packages/components/src/EditDateRangeButton/index.tsx:41
889
-	__( 'Edit Start and End Dates and Times', 'event_espresso' ),
889
+	__('Edit Start and End Dates and Times', 'event_espresso'),
890 890
 
891 891
 	// Reference: packages/components/src/EntityActionsMenu/entityMenuItems/Copy.tsx:9
892
-	__( 'copy', 'event_espresso' ),
892
+	__('copy', 'event_espresso'),
893 893
 
894 894
 	// Reference: packages/components/src/EntityActionsMenu/entityMenuItems/Edit.tsx:9
895
-	__( 'edit', 'event_espresso' ),
895
+	__('edit', 'event_espresso'),
896 896
 
897 897
 	// Reference: packages/components/src/EntityActionsMenu/entityMenuItems/Trash.tsx:9
898
-	__( 'trash', 'event_espresso' ),
898
+	__('trash', 'event_espresso'),
899 899
 
900 900
 	// Reference: packages/components/src/EntityDetailsPanel/EntityDetailsPanelSold.tsx:36
901
-	__( 'view approved registrations for this date.', 'event_espresso' ),
901
+	__('view approved registrations for this date.', 'event_espresso'),
902 902
 
903 903
 	// Reference: packages/components/src/EntityDetailsPanel/EntityDetailsPanelSold.tsx:37
904
-	__( 'view approved registrations for this ticket.', 'event_espresso' ),
904
+	__('view approved registrations for this ticket.', 'event_espresso'),
905 905
 
906 906
 	// Reference: packages/components/src/EntityList/EntityList.tsx:38
907
-	__( 'no results found', 'event_espresso' ),
907
+	__('no results found', 'event_espresso'),
908 908
 
909 909
 	// Reference: packages/components/src/EntityList/EntityList.tsx:39
910
-	__( 'try changing filter settings', 'event_espresso' ),
910
+	__('try changing filter settings', 'event_espresso'),
911 911
 
912 912
 	// Reference: packages/components/src/EntityList/filterBar/buttons/CardViewFilterButton.tsx:22
913
-	__( 'card view', 'event_espresso' ),
913
+	__('card view', 'event_espresso'),
914 914
 
915 915
 	// Reference: packages/components/src/EntityList/filterBar/buttons/TableViewFilterButton.tsx:22
916
-	__( 'table view', 'event_espresso' ),
916
+	__('table view', 'event_espresso'),
917 917
 
918 918
 	// Reference: packages/components/src/EntityList/filterBar/buttons/ToggleFiltersButton.tsx:11
919
-	__( 'hide filters', 'event_espresso' ),
919
+	__('hide filters', 'event_espresso'),
920 920
 
921 921
 	// Reference: packages/components/src/EntityList/filterBar/buttons/ToggleFiltersButton.tsx:11
922
-	__( 'show filters', 'event_espresso' ),
922
+	__('show filters', 'event_espresso'),
923 923
 
924 924
 	// Reference: packages/components/src/EntityList/filterBar/buttons/ToggleSortingButton.tsx:28
925
-	__( 'disable sorting', 'event_espresso' ),
925
+	__('disable sorting', 'event_espresso'),
926 926
 
927 927
 	// Reference: packages/components/src/EntityList/filterBar/buttons/ToggleSortingButton.tsx:28
928
-	__( 'enable sorting', 'event_espresso' ),
928
+	__('enable sorting', 'event_espresso'),
929 929
 
930 930
 	// Reference: packages/components/src/Legend/ToggleLegendButton.tsx:27
931
-	__( 'hide legend', 'event_espresso' ),
931
+	__('hide legend', 'event_espresso'),
932 932
 
933 933
 	// Reference: packages/components/src/Legend/ToggleLegendButton.tsx:27
934
-	__( 'show legend', 'event_espresso' ),
934
+	__('show legend', 'event_espresso'),
935 935
 
936 936
 	// Reference: packages/components/src/LoadingIndicator/LoadingIndicator.tsx:7
937
-	__( 'loading ...', 'event_espresso' ),
937
+	__('loading ...', 'event_espresso'),
938 938
 
939 939
 	// Reference: packages/components/src/Modal/modalCloseButtonProps/index.ts:8
940
-	__( 'close modal', 'event_espresso' ),
940
+	__('close modal', 'event_espresso'),
941 941
 
942 942
 	// Reference: packages/components/src/PercentSign/index.tsx:11
943
-	__( '%', 'event_espresso' ),
943
+	__('%', 'event_espresso'),
944 944
 
945 945
 	// Reference: packages/components/src/Stepper/buttons/Next.tsx:12
946
-	__( 'Next', 'event_espresso' ),
946
+	__('Next', 'event_espresso'),
947 947
 
948 948
 	// Reference: packages/components/src/Stepper/buttons/Previous.tsx:12
949
-	__( 'Previous', 'event_espresso' ),
949
+	__('Previous', 'event_espresso'),
950 950
 
951 951
 	// Reference: packages/components/src/TabbableText/index.tsx:12
952
-	__( 'Click to edit...', 'event_espresso' ),
952
+	__('Click to edit...', 'event_espresso'),
953 953
 
954 954
 	// Reference: packages/components/src/TimezoneTimeInfo/Content.tsx:16
955
-	__( 'Your Local Time Zone', 'event_espresso' ),
955
+	__('Your Local Time Zone', 'event_espresso'),
956 956
 
957 957
 	// Reference: packages/components/src/TimezoneTimeInfo/Content.tsx:21
958
-	__( 'The Website\'s Time Zone', 'event_espresso' ),
958
+	__('The Website\'s Time Zone', 'event_espresso'),
959 959
 
960 960
 	// Reference: packages/components/src/TimezoneTimeInfo/Content.tsx:26
961
-	__( 'UTC (Greenwich Mean Time)', 'event_espresso' ),
961
+	__('UTC (Greenwich Mean Time)', 'event_espresso'),
962 962
 
963 963
 	// Reference: packages/components/src/TimezoneTimeInfo/TimezoneTimeInfo.tsx:23
964
-	__( 'This Date Converted To:', 'event_espresso' ),
964
+	__('This Date Converted To:', 'event_espresso'),
965 965
 
966 966
 	// Reference: packages/components/src/TimezoneTimeInfo/TimezoneTimeInfo.tsx:24
967
-	__( 'click for timezone
968
-information', 'event_espresso' ),
967
+	__('click for timezone
968
+information', 'event_espresso'),
969 969
 
970 970
 	// Reference: packages/components/src/bulkEdit/ActionCheckbox.tsx:40
971
-	__( 'select entity', 'event_espresso' ),
971
+	__('select entity', 'event_espresso'),
972 972
 
973 973
 	// Reference: packages/components/src/bulkEdit/BulkActions.tsx:51
974
-	__( 'select all', 'event_espresso' ),
974
+	__('select all', 'event_espresso'),
975 975
 
976 976
 	// Reference: packages/components/src/bulkEdit/BulkActions.tsx:53
977
-	__( 'apply', 'event_espresso' ),
977
+	__('apply', 'event_espresso'),
978 978
 
979 979
 	// Reference: packages/components/src/bulkEdit/details/BulkEditDetailsProps.tsx:22
980
-	__( 'Note: ', 'event_espresso' ),
980
+	__('Note: ', 'event_espresso'),
981 981
 
982 982
 	// Reference: packages/components/src/bulkEdit/details/BulkEditDetailsProps.tsx:22
983
-	__( 'any changes will be applied to ALL of the selected entities.', 'event_espresso' ),
983
+	__('any changes will be applied to ALL of the selected entities.', 'event_espresso'),
984 984
 
985 985
 	// Reference: packages/components/src/bulkEdit/details/BulkEditDetailsProps.tsx:28
986
-	__( 'Bulk edit details', 'event_espresso' ),
986
+	__('Bulk edit details', 'event_espresso'),
987 987
 
988 988
 	// Reference: packages/components/src/bulkEdit/details/Submit.tsx:28
989
-	__( 'Are you sure you want to bulk update the details?', 'event_espresso' ),
989
+	__('Are you sure you want to bulk update the details?', 'event_espresso'),
990 990
 
991 991
 	// Reference: packages/components/src/bulkEdit/details/Submit.tsx:29
992
-	__( 'Bulk update details', 'event_espresso' ),
992
+	__('Bulk update details', 'event_espresso'),
993 993
 
994 994
 	// Reference: packages/dates/src/DateRangePicker.tsx:66
995 995
 	// Reference: packages/dates/src/DateRangePickerLegend.tsx:18
996
-	__( 'end date', 'event_espresso' ),
996
+	__('end date', 'event_espresso'),
997 997
 
998 998
 	// Reference: packages/dates/src/DateRangePickerLegend.tsx:14
999
-	__( 'day in range', 'event_espresso' ),
999
+	__('day in range', 'event_espresso'),
1000 1000
 
1001 1001
 	// Reference: packages/dates/src/DateTimePicker.tsx:9
1002 1002
 	// Reference: packages/dates/src/TimePicker.tsx:13
1003
-	__( 'time', 'event_espresso' ),
1003
+	__('time', 'event_espresso'),
1004 1004
 
1005 1005
 	// Reference: packages/dates/src/utils/misc.ts:13
1006
-	__( 'month(s)', 'event_espresso' ),
1006
+	__('month(s)', 'event_espresso'),
1007 1007
 
1008 1008
 	// Reference: packages/dates/src/utils/misc.ts:14
1009
-	__( 'week(s)', 'event_espresso' ),
1009
+	__('week(s)', 'event_espresso'),
1010 1010
 
1011 1011
 	// Reference: packages/dates/src/utils/misc.ts:15
1012
-	__( 'day(s)', 'event_espresso' ),
1012
+	__('day(s)', 'event_espresso'),
1013 1013
 
1014 1014
 	// Reference: packages/dates/src/utils/misc.ts:16
1015
-	__( 'hour(s)', 'event_espresso' ),
1015
+	__('hour(s)', 'event_espresso'),
1016 1016
 
1017 1017
 	// Reference: packages/dates/src/utils/misc.ts:17
1018
-	__( 'minute(s)', 'event_espresso' ),
1018
+	__('minute(s)', 'event_espresso'),
1019 1019
 
1020 1020
 	// Reference: packages/edtr-services/src/apollo/queries/datetimes/useFetchDatetimes.ts:27
1021
-	__( 'datetimes initialized', 'event_espresso' ),
1021
+	__('datetimes initialized', 'event_espresso'),
1022 1022
 
1023 1023
 	// Reference: packages/edtr-services/src/apollo/queries/datetimes/useFetchDatetimes.ts:43
1024
-	__( 'initializing datetimes', 'event_espresso' ),
1024
+	__('initializing datetimes', 'event_espresso'),
1025 1025
 
1026 1026
 	// Reference: packages/edtr-services/src/apollo/queries/priceTypes/useFetchPriceTypes.ts:26
1027
-	__( 'price types initialized', 'event_espresso' ),
1027
+	__('price types initialized', 'event_espresso'),
1028 1028
 
1029 1029
 	// Reference: packages/edtr-services/src/apollo/queries/priceTypes/useFetchPriceTypes.ts:41
1030
-	__( 'initializing  price types', 'event_espresso' ),
1030
+	__('initializing  price types', 'event_espresso'),
1031 1031
 
1032 1032
 	// Reference: packages/edtr-services/src/apollo/queries/prices/useFetchPrices.ts:36
1033
-	__( 'prices initialized', 'event_espresso' ),
1033
+	__('prices initialized', 'event_espresso'),
1034 1034
 
1035 1035
 	// Reference: packages/edtr-services/src/apollo/queries/prices/useFetchPrices.ts:70
1036
-	__( 'initializing prices', 'event_espresso' ),
1036
+	__('initializing prices', 'event_espresso'),
1037 1037
 
1038 1038
 	// Reference: packages/edtr-services/src/apollo/queries/tickets/useFetchTickets.ts:32
1039
-	__( 'tickets initialized', 'event_espresso' ),
1039
+	__('tickets initialized', 'event_espresso'),
1040 1040
 
1041 1041
 	// Reference: packages/edtr-services/src/apollo/queries/tickets/useFetchTickets.ts:47
1042
-	__( 'initializing tickets', 'event_espresso' ),
1042
+	__('initializing tickets', 'event_espresso'),
1043 1043
 
1044 1044
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:11
1045
-	__( 'Start Date is required', 'event_espresso' ),
1045
+	__('Start Date is required', 'event_espresso'),
1046 1046
 
1047 1047
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:15
1048
-	__( 'End Date is required', 'event_espresso' ),
1048
+	__('End Date is required', 'event_espresso'),
1049 1049
 
1050 1050
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:5
1051
-	__( 'End Date & Time must be set later than the Start Date & Time', 'event_espresso' ),
1051
+	__('End Date & Time must be set later than the Start Date & Time', 'event_espresso'),
1052 1052
 
1053 1053
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:6
1054
-	__( 'Required', 'event_espresso' ),
1054
+	__('Required', 'event_espresso'),
1055 1055
 
1056 1056
 	// Reference: packages/form/src/renderers/RepeatableRenderer.tsx:33
1057
-	__( 'Entry %d', 'event_espresso' ),
1057
+	__('Entry %d', 'event_espresso'),
1058 1058
 
1059 1059
 	// Reference: packages/form/src/renderers/RepeatableRenderer.tsx:47
1060
-	__( 'Add', 'event_espresso' ),
1060
+	__('Add', 'event_espresso'),
1061 1061
 
1062 1062
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:11
1063 1063
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:17
1064
-	__( 'sold out', 'event_espresso' ),
1064
+	__('sold out', 'event_espresso'),
1065 1065
 
1066 1066
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:14
1067 1067
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:14
1068
-	__( 'expired', 'event_espresso' ),
1068
+	__('expired', 'event_espresso'),
1069 1069
 
1070 1070
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:17
1071
-	__( 'upcoming', 'event_espresso' ),
1071
+	__('upcoming', 'event_espresso'),
1072 1072
 
1073 1073
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:20
1074
-	__( 'active', 'event_espresso' ),
1074
+	__('active', 'event_espresso'),
1075 1075
 
1076 1076
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:23
1077 1077
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:11
1078
-	__( 'trashed', 'event_espresso' ),
1078
+	__('trashed', 'event_espresso'),
1079 1079
 
1080 1080
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:26
1081
-	__( 'cancelled', 'event_espresso' ),
1081
+	__('cancelled', 'event_espresso'),
1082 1082
 
1083 1083
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:29
1084
-	__( 'postponed', 'event_espresso' ),
1084
+	__('postponed', 'event_espresso'),
1085 1085
 
1086 1086
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:33
1087
-	__( 'inactive', 'event_espresso' ),
1087
+	__('inactive', 'event_espresso'),
1088 1088
 
1089 1089
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:20
1090
-	__( 'pending', 'event_espresso' ),
1090
+	__('pending', 'event_espresso'),
1091 1091
 
1092 1092
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:23
1093
-	__( 'on sale', 'event_espresso' ),
1093
+	__('on sale', 'event_espresso'),
1094 1094
 
1095 1095
 	// Reference: packages/predicates/src/registration/statusOptions.ts:10
1096
-	__( 'Cancelled', 'event_espresso' ),
1096
+	__('Cancelled', 'event_espresso'),
1097 1097
 
1098 1098
 	// Reference: packages/predicates/src/registration/statusOptions.ts:14
1099
-	__( 'Declined', 'event_espresso' ),
1099
+	__('Declined', 'event_espresso'),
1100 1100
 
1101 1101
 	// Reference: packages/predicates/src/registration/statusOptions.ts:18
1102
-	__( 'Incomplete', 'event_espresso' ),
1102
+	__('Incomplete', 'event_espresso'),
1103 1103
 
1104 1104
 	// Reference: packages/predicates/src/registration/statusOptions.ts:22
1105
-	__( 'Not Approved', 'event_espresso' ),
1105
+	__('Not Approved', 'event_espresso'),
1106 1106
 
1107 1107
 	// Reference: packages/predicates/src/registration/statusOptions.ts:26
1108
-	__( 'Pending Payment', 'event_espresso' ),
1108
+	__('Pending Payment', 'event_espresso'),
1109 1109
 
1110 1110
 	// Reference: packages/predicates/src/registration/statusOptions.ts:30
1111
-	__( 'Wait List', 'event_espresso' ),
1111
+	__('Wait List', 'event_espresso'),
1112 1112
 
1113 1113
 	// Reference: packages/predicates/src/registration/statusOptions.ts:6
1114
-	__( 'Approved', 'event_espresso' ),
1114
+	__('Approved', 'event_espresso'),
1115 1115
 
1116 1116
 	// Reference: packages/rich-text-editor/src/components/ToolbarControls/HeadingControls.tsx:23
1117
-	__( 'heading selector', 'event_espresso' ),
1117
+	__('heading selector', 'event_espresso'),
1118 1118
 
1119 1119
 	// Reference: packages/tpc/src/buttons/AddPriceModifierButton.tsx:15
1120
-	__( 'add new price modifier after this row', 'event_espresso' ),
1120
+	__('add new price modifier after this row', 'event_espresso'),
1121 1121
 
1122 1122
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:13
1123
-	__( 'Delete all prices', 'event_espresso' ),
1123
+	__('Delete all prices', 'event_espresso'),
1124 1124
 
1125 1125
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:26
1126
-	__( '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' ),
1126
+	__('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'),
1127 1127
 
1128 1128
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:30
1129
-	__( 'Delete all prices?', 'event_espresso' ),
1129
+	__('Delete all prices?', 'event_espresso'),
1130 1130
 
1131 1131
 	// Reference: packages/tpc/src/buttons/DeletePriceModifierButton.tsx:12
1132
-	__( 'delete price modifier', 'event_espresso' ),
1132
+	__('delete price modifier', 'event_espresso'),
1133 1133
 
1134 1134
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:15
1135
-	__( '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' ),
1135
+	__('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'),
1136 1136
 
1137 1137
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:18
1138
-	__( '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' ),
1138
+	__('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'),
1139 1139
 
1140 1140
 	// Reference: packages/tpc/src/buttons/TicketPriceCalculatorButton.tsx:30
1141
-	__( 'ticket price calculator', 'event_espresso' ),
1141
+	__('ticket price calculator', 'event_espresso'),
1142 1142
 
1143 1143
 	// Reference: packages/tpc/src/buttons/taxes/AddDefaultTaxesButton.tsx:10
1144 1144
 	// Reference: packages/tpc/src/components/DefaultTaxesInfo.tsx:30
1145
-	__( 'Add default taxes', 'event_espresso' ),
1145
+	__('Add default taxes', 'event_espresso'),
1146 1146
 
1147 1147
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:11
1148
-	__( 'Are you sure you want to remove all of this ticket\'s taxes?', 'event_espresso' ),
1148
+	__('Are you sure you want to remove all of this ticket\'s taxes?', 'event_espresso'),
1149 1149
 
1150 1150
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:15
1151
-	__( 'Remove all taxes?', 'event_espresso' ),
1151
+	__('Remove all taxes?', 'event_espresso'),
1152 1152
 
1153 1153
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:8
1154
-	__( 'Remove taxes', 'event_espresso' ),
1154
+	__('Remove taxes', 'event_espresso'),
1155 1155
 
1156 1156
 	// Reference: packages/tpc/src/components/DefaultPricesInfo.tsx:28
1157
-	__( 'Modify default prices.', 'event_espresso' ),
1157
+	__('Modify default prices.', 'event_espresso'),
1158 1158
 
1159 1159
 	// Reference: packages/tpc/src/components/DefaultTaxesInfo.tsx:29
1160
-	__( 'New default taxes are available. Click the "%s" button to add them now.', 'event_espresso' ),
1160
+	__('New default taxes are available. Click the "%s" button to add them now.', 'event_espresso'),
1161 1161
 
1162 1162
 	// Reference: packages/tpc/src/components/NoPricesBanner/AddDefaultPricesButton.tsx:10
1163
-	__( 'Add default prices', 'event_espresso' ),
1163
+	__('Add default prices', 'event_espresso'),
1164 1164
 
1165 1165
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:14
1166
-	__( 'This Ticket is Currently Free', 'event_espresso' ),
1166
+	__('This Ticket is Currently Free', 'event_espresso'),
1167 1167
 
1168 1168
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:22
1169 1169
 	/* translators: %s default prices */
1170
-	__( 'Click the button below to load your %s into the calculator.', 'event_espresso' ),
1170
+	__('Click the button below to load your %s into the calculator.', 'event_espresso'),
1171 1171
 
1172 1172
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:23
1173
-	__( 'default prices', 'event_espresso' ),
1173
+	__('default prices', 'event_espresso'),
1174 1174
 
1175 1175
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:30
1176
-	__( 'Additional ticket price modifiers can be added or removed.', 'event_espresso' ),
1176
+	__('Additional ticket price modifiers can be added or removed.', 'event_espresso'),
1177 1177
 
1178 1178
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:33
1179
-	__( 'Click the save button below to assign which dates this ticket will be available for purchase on.', 'event_espresso' ),
1179
+	__('Click the save button below to assign which dates this ticket will be available for purchase on.', 'event_espresso'),
1180 1180
 
1181 1181
 	// Reference: packages/tpc/src/components/TicketPriceCalculatorModal.tsx:30
1182
-	__( 'Price Calculator for Ticket: %s', 'event_espresso' ),
1182
+	__('Price Calculator for Ticket: %s', 'event_espresso'),
1183 1183
 
1184 1184
 	// Reference: packages/tpc/src/components/table/Table.tsx:43
1185
-	__( 'Ticket Price Calculator', 'event_espresso' ),
1185
+	__('Ticket Price Calculator', 'event_espresso'),
1186 1186
 
1187 1187
 	// Reference: packages/tpc/src/components/table/useFooterRowGenerator.tsx:41
1188
-	__( 'Total', 'event_espresso' ),
1188
+	__('Total', 'event_espresso'),
1189 1189
 
1190 1190
 	// Reference: packages/tpc/src/components/table/useFooterRowGenerator.tsx:50
1191
-	__( 'ticket total', 'event_espresso' ),
1191
+	__('ticket total', 'event_espresso'),
1192 1192
 
1193 1193
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:29
1194
-	__( 'Price Type', 'event_espresso' ),
1194
+	__('Price Type', 'event_espresso'),
1195 1195
 
1196 1196
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:35
1197
-	__( 'Label', 'event_espresso' ),
1197
+	__('Label', 'event_espresso'),
1198 1198
 
1199 1199
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:47
1200
-	__( 'Amount', 'event_espresso' ),
1200
+	__('Amount', 'event_espresso'),
1201 1201
 
1202 1202
 	// Reference: packages/tpc/src/inputs/PriceAmountInput.tsx:34
1203
-	__( 'amount', 'event_espresso' ),
1203
+	__('amount', 'event_espresso'),
1204 1204
 
1205 1205
 	// Reference: packages/tpc/src/inputs/PriceAmountInput.tsx:45
1206
-	__( 'amount...', 'event_espresso' ),
1206
+	__('amount...', 'event_espresso'),
1207 1207
 
1208 1208
 	// Reference: packages/tpc/src/inputs/PriceDescriptionInput.tsx:10
1209
-	__( 'price description', 'event_espresso' ),
1209
+	__('price description', 'event_espresso'),
1210 1210
 
1211 1211
 	// Reference: packages/tpc/src/inputs/PriceDescriptionInput.tsx:15
1212
-	__( 'description...', 'event_espresso' ),
1212
+	__('description...', 'event_espresso'),
1213 1213
 
1214 1214
 	// Reference: packages/tpc/src/inputs/PriceIdInput.tsx:9
1215
-	__( 'price id', 'event_espresso' ),
1215
+	__('price id', 'event_espresso'),
1216 1216
 
1217 1217
 	// Reference: packages/tpc/src/inputs/PriceNameInput.tsx:10
1218
-	__( 'price name', 'event_espresso' ),
1218
+	__('price name', 'event_espresso'),
1219 1219
 
1220 1220
 	// Reference: packages/tpc/src/inputs/PriceNameInput.tsx:15
1221
-	__( 'label...', 'event_espresso' ),
1221
+	__('label...', 'event_espresso'),
1222 1222
 
1223 1223
 	// Reference: packages/tpc/src/inputs/PriceTypeInput.tsx:16
1224
-	__( 'price type', 'event_espresso' ),
1224
+	__('price type', 'event_espresso'),
1225 1225
 
1226 1226
 	// Reference: packages/components/src/LoadingNotice/LoadingNotice.tsx:16
1227
-	_x( 'loading%s', 'loading...', 'event_espresso' )
1227
+	_x('loading%s', 'loading...', 'event_espresso')
1228 1228
 );
1229 1229
 /* THIS IS THE END OF THE GENERATED FILE */
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +97 added lines, -97 removed lines patch added patch discarded remove patch
@@ -37,122 +37,122 @@
 block discarded – undo
37 37
  * @since           4.0
38 38
  */
39 39
 if (function_exists('espresso_version')) {
40
-    if (! function_exists('espresso_duplicate_plugin_error')) {
41
-        /**
42
-         *    espresso_duplicate_plugin_error
43
-         *    displays if more than one version of EE is activated at the same time
44
-         */
45
-        function espresso_duplicate_plugin_error()
46
-        {
47
-            ?>
40
+	if (! function_exists('espresso_duplicate_plugin_error')) {
41
+		/**
42
+		 *    espresso_duplicate_plugin_error
43
+		 *    displays if more than one version of EE is activated at the same time
44
+		 */
45
+		function espresso_duplicate_plugin_error()
46
+		{
47
+			?>
48 48
             <div class="error">
49 49
                 <p>
50 50
                     <?php
51
-                    echo esc_html__(
52
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
53
-                        'event_espresso'
54
-                    ); ?>
51
+					echo esc_html__(
52
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
53
+						'event_espresso'
54
+					); ?>
55 55
                 </p>
56 56
             </div>
57 57
             <?php
58
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
59
-        }
60
-    }
61
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
58
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
59
+		}
60
+	}
61
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
62 62
 } else {
63
-    define('EE_MIN_PHP_VER_REQUIRED', '7.1.0');
64
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
65
-        /**
66
-         * espresso_minimum_php_version_error
67
-         *
68
-         * @return void
69
-         */
70
-        function espresso_minimum_php_version_error()
71
-        {
72
-            ?>
63
+	define('EE_MIN_PHP_VER_REQUIRED', '7.1.0');
64
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
65
+		/**
66
+		 * espresso_minimum_php_version_error
67
+		 *
68
+		 * @return void
69
+		 */
70
+		function espresso_minimum_php_version_error()
71
+		{
72
+			?>
73 73
             <div class="error">
74 74
                 <p>
75 75
                     <?php
76
-                    printf(
77
-                        esc_html__(
78
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
79
-                            'event_espresso'
80
-                        ),
81
-                        EE_MIN_PHP_VER_REQUIRED,
82
-                        PHP_VERSION,
83
-                        '<br/>',
84
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
85
-                    );
86
-                    ?>
76
+					printf(
77
+						esc_html__(
78
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
79
+							'event_espresso'
80
+						),
81
+						EE_MIN_PHP_VER_REQUIRED,
82
+						PHP_VERSION,
83
+						'<br/>',
84
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
85
+					);
86
+					?>
87 87
                 </p>
88 88
             </div>
89 89
             <?php
90
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
91
-        }
90
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
91
+		}
92 92
 
93
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
94
-    } else {
95
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
96
-        /**
97
-         * espresso_version
98
-         * Returns the plugin version
99
-         *
100
-         * @return string
101
-         */
102
-        function espresso_version()
103
-        {
104
-            return apply_filters('FHEE__espresso__espresso_version', '4.10.9.rc.002');
105
-        }
93
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
94
+	} else {
95
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
96
+		/**
97
+		 * espresso_version
98
+		 * Returns the plugin version
99
+		 *
100
+		 * @return string
101
+		 */
102
+		function espresso_version()
103
+		{
104
+			return apply_filters('FHEE__espresso__espresso_version', '4.10.9.rc.002');
105
+		}
106 106
 
107
-        /**
108
-         * espresso_plugin_activation
109
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
110
-         */
111
-        function espresso_plugin_activation()
112
-        {
113
-            update_option('ee_espresso_activation', true);
107
+		/**
108
+		 * espresso_plugin_activation
109
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
110
+		 */
111
+		function espresso_plugin_activation()
112
+		{
113
+			update_option('ee_espresso_activation', true);
114 114
 
115
-            // Run WP GraphQL activation callback
116
-            if (! class_exists('WPGraphQL')) {
117
-                require_once EE_THIRD_PARTY . 'wp-graphql/wp-graphql.php';
118
-            }
119
-            graphql_init()->activate();
120
-        }
115
+			// Run WP GraphQL activation callback
116
+			if (! class_exists('WPGraphQL')) {
117
+				require_once EE_THIRD_PARTY . 'wp-graphql/wp-graphql.php';
118
+			}
119
+			graphql_init()->activate();
120
+		}
121 121
 
122
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
122
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
123 123
 
124
-        /**
125
-         * espresso_plugin_deactivation
126
-         */
127
-        function espresso_plugin_deactivation()
128
-        {
129
-            // Run WP GraphQL deactivation callback
130
-            if (! class_exists('WPGraphQL')) {
131
-                require_once EE_THIRD_PARTY . 'wp-graphql/wp-graphql.php';
132
-            }
133
-            graphql_init()->deactivate();
134
-        }
135
-        register_deactivation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_deactivation');
124
+		/**
125
+		 * espresso_plugin_deactivation
126
+		 */
127
+		function espresso_plugin_deactivation()
128
+		{
129
+			// Run WP GraphQL deactivation callback
130
+			if (! class_exists('WPGraphQL')) {
131
+				require_once EE_THIRD_PARTY . 'wp-graphql/wp-graphql.php';
132
+			}
133
+			graphql_init()->deactivate();
134
+		}
135
+		register_deactivation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_deactivation');
136 136
 
137
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
138
-        bootstrap_espresso();
139
-    }
137
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
138
+		bootstrap_espresso();
139
+	}
140 140
 }
141 141
 if (! function_exists('espresso_deactivate_plugin')) {
142
-    /**
143
-     *    deactivate_plugin
144
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
145
-     *
146
-     * @access public
147
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
148
-     * @return    void
149
-     */
150
-    function espresso_deactivate_plugin($plugin_basename = '')
151
-    {
152
-        if (! function_exists('deactivate_plugins')) {
153
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
154
-        }
155
-        unset($_GET['activate'], $_REQUEST['activate']);
156
-        deactivate_plugins($plugin_basename);
157
-    }
142
+	/**
143
+	 *    deactivate_plugin
144
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
145
+	 *
146
+	 * @access public
147
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
148
+	 * @return    void
149
+	 */
150
+	function espresso_deactivate_plugin($plugin_basename = '')
151
+	{
152
+		if (! function_exists('deactivate_plugins')) {
153
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
154
+		}
155
+		unset($_GET['activate'], $_REQUEST['activate']);
156
+		deactivate_plugins($plugin_basename);
157
+	}
158 158
 }
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')) {
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')) {
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')) {
155
-                require_once(ABSPATH . 'wp-admin/includes/file.php');
156
-                require_once(ABSPATH . 'wp-admin/includes/template.php');
154
+            if ( ! function_exists('WP_Filesystem')) {
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.