Completed
Branch Gutenberg/espresso-cpt-editor (d57906)
by
unknown
78:21 queued 69:49
created
core/db_models/EEM_Datetime.model.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -529,7 +529,7 @@
 block discarded – undo
529 529
     /**
530 530
      * This returns an array of counts of datetimes in the database for each Datetime status that can be queried.
531 531
      *
532
-     * @param  array $stati_to_include If included you can restrict the statuses we return counts for by including the
532
+     * @param  string[] $stati_to_include If included you can restrict the statuses we return counts for by including the
533 533
      *                                 stati you want counts for as values in the array.  An empty array returns counts
534 534
      *                                 for all valid stati.
535 535
      * @param  array $query_params     If included can be used to refine the conditions for returning the count (i.e.
Please login to merge, or discard this patch.
Indentation   +652 added lines, -652 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if (! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -14,657 +14,657 @@  discard block
 block discarded – undo
14 14
 class EEM_Datetime extends EEM_Soft_Delete_Base
15 15
 {
16 16
 
17
-    /**
18
-     * @var EEM_Datetime $_instance
19
-     */
20
-    protected static $_instance;
21
-
22
-
23
-    /**
24
-     * private constructor to prevent direct creation
25
-     *
26
-     * @param string $timezone A string representing the timezone we want to set for returned Date Time Strings
27
-     *                         (and any incoming timezone data that gets saved).
28
-     *                         Note this just sends the timezone info to the date time model field objects.
29
-     *                         Default is NULL
30
-     *                         (and will be assumed using the set timezone in the 'timezone_string' wp option)
31
-     * @throws EE_Error
32
-     * @throws InvalidArgumentException
33
-     * @throws InvalidArgumentException
34
-     */
35
-    protected function __construct($timezone)
36
-    {
37
-        $this->singular_item           = esc_html__('Datetime', 'event_espresso');
38
-        $this->plural_item             = esc_html__('Datetimes', 'event_espresso');
39
-        $this->_tables                 = array(
40
-            'Datetime' => new EE_Primary_Table('esp_datetime', 'DTT_ID'),
41
-        );
42
-        $this->_fields                 = array(
43
-            'Datetime' => array(
44
-                'DTT_ID'          => new EE_Primary_Key_Int_Field(
45
-                    'DTT_ID',
46
-                    esc_html__('Datetime ID', 'event_espresso')
47
-                ),
48
-                'EVT_ID'          => new EE_Foreign_Key_Int_Field(
49
-                    'EVT_ID',
50
-                    esc_html__('Event ID', 'event_espresso'),
51
-                    false,
52
-                    0,
53
-                    'Event'
54
-                ),
55
-                'DTT_name'        => new EE_Plain_Text_Field(
56
-                    'DTT_name',
57
-                    esc_html__('Datetime Name', 'event_espresso'),
58
-                    false,
59
-                    ''
60
-                ),
61
-                'DTT_description' => new EE_Post_Content_Field(
62
-                    'DTT_description',
63
-                    esc_html__('Description for Datetime', 'event_espresso'),
64
-                    false,
65
-                    ''
66
-                ),
67
-                'DTT_EVT_start'   => new EE_Datetime_Field(
68
-                    'DTT_EVT_start',
69
-                    esc_html__('Start time/date of Event', 'event_espresso'),
70
-                    false,
71
-                    EE_Datetime_Field::now,
72
-                    $timezone
73
-                ),
74
-                'DTT_EVT_end'     => new EE_Datetime_Field(
75
-                    'DTT_EVT_end',
76
-                    esc_html__('End time/date of Event', 'event_espresso'),
77
-                    false,
78
-                    EE_Datetime_Field::now,
79
-                    $timezone
80
-                ),
81
-                'DTT_reg_limit'   => new EE_Infinite_Integer_Field(
82
-                    'DTT_reg_limit',
83
-                    esc_html__('Registration Limit for this time', 'event_espresso'),
84
-                    true,
85
-                    EE_INF
86
-                ),
87
-                'DTT_sold'        => new EE_Integer_Field(
88
-                    'DTT_sold',
89
-                    esc_html__('How many sales for this Datetime that have occurred', 'event_espresso'),
90
-                    true,
91
-                    0
92
-                ),
93
-                'DTT_reserved'    => new EE_Integer_Field(
94
-                    'DTT_reserved',
95
-                    esc_html__('Quantity of tickets reserved, but not yet fully purchased', 'event_espresso'),
96
-                    false,
97
-                    0
98
-                ),
99
-                'DTT_is_primary'  => new EE_Boolean_Field(
100
-                    'DTT_is_primary',
101
-                    esc_html__('Flag indicating datetime is primary one for event', 'event_espresso'),
102
-                    false,
103
-                    false
104
-                ),
105
-                'DTT_order'       => new EE_Integer_Field(
106
-                    'DTT_order',
107
-                    esc_html__('The order in which the Datetime is displayed', 'event_espresso'),
108
-                    false,
109
-                    0
110
-                ),
111
-                'DTT_parent'      => new EE_Integer_Field(
112
-                    'DTT_parent',
113
-                    esc_html__('Indicates what DTT_ID is the parent of this DTT_ID'),
114
-                    true,
115
-                    0
116
-                ),
117
-                'DTT_deleted'     => new EE_Trashed_Flag_Field(
118
-                    'DTT_deleted',
119
-                    esc_html__('Flag indicating datetime is archived', 'event_espresso'),
120
-                    false,
121
-                    false
122
-                ),
123
-            ),
124
-        );
125
-        $this->_model_relations        = array(
126
-            'Ticket'  => new EE_HABTM_Relation('Datetime_Ticket'),
127
-            'Event'   => new EE_Belongs_To_Relation(),
128
-            'Checkin' => new EE_Has_Many_Relation(),
129
-        );
130
-        $this->_model_chain_to_wp_user = 'Event';
131
-        //this model is generally available for reading
132
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ]       = new EE_Restriction_Generator_Event_Related_Public(
133
-            'Event'
134
-        );
135
-        $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = new EE_Restriction_Generator_Event_Related_Protected(
136
-            'Event'
137
-        );
138
-        $this->_cap_restriction_generators[ EEM_Base::caps_edit ]       = new EE_Restriction_Generator_Event_Related_Protected(
139
-            'Event'
140
-        );
141
-        $this->_cap_restriction_generators[ EEM_Base::caps_delete ]     = new EE_Restriction_Generator_Event_Related_Protected(
142
-            'Event',
143
-            EEM_Base::caps_edit
144
-        );
145
-        parent::__construct($timezone);
146
-    }
147
-
148
-
149
-    /**
150
-     * create new blank datetime
151
-     *
152
-     * @access public
153
-     * @return EE_Datetime[] array on success, FALSE on fail
154
-     * @throws EE_Error
155
-     */
156
-    public function create_new_blank_datetime()
157
-    {
158
-        //makes sure timezone is always set.
159
-        $timezone_string = $this->get_timezone();
160
-        $blank_datetime  = EE_Datetime::new_instance(
161
-            array(
162
-                'DTT_EVT_start' => $this->current_time_for_query('DTT_EVT_start', true) + MONTH_IN_SECONDS,
163
-                'DTT_EVT_end'   => $this->current_time_for_query('DTT_EVT_end', true) + MONTH_IN_SECONDS,
164
-                'DTT_order'     => 1,
165
-                'DTT_reg_limit' => EE_INF,
166
-            ),
167
-            $timezone_string
168
-        );
169
-        $blank_datetime->set_start_time(
170
-            $this->convert_datetime_for_query(
171
-                'DTT_EVT_start',
172
-                '8am',
173
-                'ga',
174
-                $timezone_string
175
-            )
176
-        );
177
-        $blank_datetime->set_end_time(
178
-            $this->convert_datetime_for_query(
179
-                'DTT_EVT_end',
180
-                '5pm',
181
-                'ga',
182
-                $timezone_string
183
-            )
184
-        );
185
-        return array($blank_datetime);
186
-    }
187
-
188
-
189
-    /**
190
-     * get event start date from db
191
-     *
192
-     * @access public
193
-     * @param  int $EVT_ID
194
-     * @return EE_Datetime[] array on success, FALSE on fail
195
-     * @throws EE_Error
196
-     */
197
-    public function get_all_event_dates($EVT_ID = 0)
198
-    {
199
-        if (! $EVT_ID) { // on add_new_event event_id gets set to 0
200
-            return $this->create_new_blank_datetime();
201
-        }
202
-        $results = $this->get_datetimes_for_event_ordered_by_DTT_order($EVT_ID);
203
-        if (empty($results)) {
204
-            return $this->create_new_blank_datetime();
205
-        }
206
-        return $results;
207
-    }
208
-
209
-
210
-    /**
211
-     * get all datetimes attached to an event ordered by the DTT_order field
212
-     *
213
-     * @public
214
-     * @param  int    $EVT_ID     event id
215
-     * @param boolean $include_expired
216
-     * @param boolean $include_deleted
217
-     * @param  int    $limit      If included then limit the count of results by
218
-     *                            the given number
219
-     * @return EE_Datetime[]
220
-     * @throws EE_Error
221
-     */
222
-    public function get_datetimes_for_event_ordered_by_DTT_order(
223
-        $EVT_ID,
224
-        $include_expired = true,
225
-        $include_deleted = true,
226
-        $limit = null
227
-    ) {
228
-        //sanitize EVT_ID
229
-        $EVT_ID         = absint($EVT_ID);
230
-        $old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
231
-        $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
232
-        $where_params = array('Event.EVT_ID' => $EVT_ID);
233
-        $query_params = ! empty($limit)
234
-            ? array(
235
-                $where_params,
236
-                'limit'                    => $limit,
237
-                'order_by'                 => array('DTT_order' => 'ASC'),
238
-                'default_where_conditions' => 'none',
239
-            )
240
-            : array(
241
-                $where_params,
242
-                'order_by'                 => array('DTT_order' => 'ASC'),
243
-                'default_where_conditions' => 'none',
244
-            );
245
-        if (! $include_expired) {
246
-            $query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
247
-        }
248
-        if ($include_deleted) {
249
-            $query_params[0]['DTT_deleted'] = array('IN', array(true, false));
250
-        }
251
-        /** @var EE_Datetime[] $result */
252
-        $result = $this->get_all($query_params);
253
-        $this->assume_values_already_prepared_by_model_object($old_assumption);
254
-        return $result;
255
-    }
256
-
257
-
258
-    /**
259
-     * Gets the datetimes for the event (with the given limit), and orders them by "importance".
260
-     * By importance, we mean that the primary datetimes are most important (DEPRECATED FOR NOW),
261
-     * and then the earlier datetimes are the most important.
262
-     * Maybe we'll want this to take into account datetimes that haven't already passed, but we don't yet.
263
-     *
264
-     * @param int $EVT_ID
265
-     * @param int $limit
266
-     * @return EE_Datetime[]|EE_Base_Class[]
267
-     * @throws EE_Error
268
-     */
269
-    public function get_datetimes_for_event_ordered_by_importance($EVT_ID = 0, $limit = null)
270
-    {
271
-        return $this->get_all(
272
-            array(
273
-                array('Event.EVT_ID' => $EVT_ID),
274
-                'limit'                    => $limit,
275
-                'order_by'                 => array('DTT_EVT_start' => 'ASC'),
276
-                'default_where_conditions' => 'none',
277
-            )
278
-        );
279
-    }
280
-
281
-
282
-    /**
283
-     * @param int     $EVT_ID
284
-     * @param boolean $include_expired
285
-     * @param boolean $include_deleted
286
-     * @return EE_Datetime
287
-     * @throws EE_Error
288
-     */
289
-    public function get_oldest_datetime_for_event($EVT_ID, $include_expired = false, $include_deleted = false)
290
-    {
291
-        $results = $this->get_datetimes_for_event_ordered_by_start_time(
292
-            $EVT_ID,
293
-            $include_expired,
294
-            $include_deleted,
295
-            1
296
-        );
297
-        if ($results) {
298
-            return array_shift($results);
299
-        }
300
-        return null;
301
-    }
302
-
303
-
304
-    /**
305
-     * Gets the 'primary' datetime for an event.
306
-     *
307
-     * @param int  $EVT_ID
308
-     * @param bool $try_to_exclude_expired
309
-     * @param bool $try_to_exclude_deleted
310
-     * @return \EE_Datetime
311
-     * @throws EE_Error
312
-     */
313
-    public function get_primary_datetime_for_event(
314
-        $EVT_ID,
315
-        $try_to_exclude_expired = true,
316
-        $try_to_exclude_deleted = true
317
-    ) {
318
-        if ($try_to_exclude_expired) {
319
-            $non_expired = $this->get_oldest_datetime_for_event($EVT_ID, false, false);
320
-            if ($non_expired) {
321
-                return $non_expired;
322
-            }
323
-        }
324
-        if ($try_to_exclude_deleted) {
325
-            $expired_even = $this->get_oldest_datetime_for_event($EVT_ID, true);
326
-            if ($expired_even) {
327
-                return $expired_even;
328
-            }
329
-        }
330
-        return $this->get_oldest_datetime_for_event($EVT_ID, true, true);
331
-    }
332
-
333
-
334
-    /**
335
-     * Gets ALL the datetimes for an event (including trashed ones, for now), ordered
336
-     * only by start date
337
-     *
338
-     * @param int     $EVT_ID
339
-     * @param boolean $include_expired
340
-     * @param boolean $include_deleted
341
-     * @param int     $limit
342
-     * @return EE_Datetime[]
343
-     * @throws EE_Error
344
-     */
345
-    public function get_datetimes_for_event_ordered_by_start_time(
346
-        $EVT_ID,
347
-        $include_expired = true,
348
-        $include_deleted = true,
349
-        $limit = null
350
-    ) {
351
-        //sanitize EVT_ID
352
-        $EVT_ID         = absint($EVT_ID);
353
-        $old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
354
-        $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
355
-        $query_params = array(array('Event.EVT_ID' => $EVT_ID), 'order_by' => array('DTT_EVT_start' => 'asc'));
356
-        if (! $include_expired) {
357
-            $query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
358
-        }
359
-        if ($include_deleted) {
360
-            $query_params[0]['DTT_deleted'] = array('IN', array(true, false));
361
-        }
362
-        if ($limit) {
363
-            $query_params['limit'] = $limit;
364
-        }
365
-        /** @var EE_Datetime[] $result */
366
-        $result = $this->get_all($query_params);
367
-        $this->assume_values_already_prepared_by_model_object($old_assumption);
368
-        return $result;
369
-    }
370
-
371
-
372
-    /**
373
-     * Gets ALL the datetimes for an ticket (including trashed ones, for now), ordered
374
-     * only by start date
375
-     *
376
-     * @param int     $TKT_ID
377
-     * @param boolean $include_expired
378
-     * @param boolean $include_deleted
379
-     * @param int     $limit
380
-     * @return EE_Datetime[]
381
-     * @throws EE_Error
382
-     */
383
-    public function get_datetimes_for_ticket_ordered_by_start_time(
384
-        $TKT_ID,
385
-        $include_expired = true,
386
-        $include_deleted = true,
387
-        $limit = null
388
-    ) {
389
-        //sanitize TKT_ID
390
-        $TKT_ID         = absint($TKT_ID);
391
-        $old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
392
-        $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
393
-        $query_params = array(array('Ticket.TKT_ID' => $TKT_ID), 'order_by' => array('DTT_EVT_start' => 'asc'));
394
-        if (! $include_expired) {
395
-            $query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
396
-        }
397
-        if ($include_deleted) {
398
-            $query_params[0]['DTT_deleted'] = array('IN', array(true, false));
399
-        }
400
-        if ($limit) {
401
-            $query_params['limit'] = $limit;
402
-        }
403
-        /** @var EE_Datetime[] $result */
404
-        $result = $this->get_all($query_params);
405
-        $this->assume_values_already_prepared_by_model_object($old_assumption);
406
-        return $result;
407
-    }
408
-
409
-
410
-    /**
411
-     * Gets all the datetimes for a ticket (including trashed ones, for now), ordered by the DTT_order for the
412
-     * datetimes.
413
-     *
414
-     * @param  int      $TKT_ID          ID of ticket to retrieve the datetimes for
415
-     * @param  boolean  $include_expired whether to include expired datetimes or not
416
-     * @param  boolean  $include_deleted whether to include trashed datetimes or not.
417
-     * @param  int|null $limit           if null, no limit, if int then limit results by
418
-     *                                   that number
419
-     * @return EE_Datetime[]
420
-     * @throws EE_Error
421
-     */
422
-    public function get_datetimes_for_ticket_ordered_by_DTT_order(
423
-        $TKT_ID,
424
-        $include_expired = true,
425
-        $include_deleted = true,
426
-        $limit = null
427
-    ) {
428
-        //sanitize id.
429
-        $TKT_ID         = absint($TKT_ID);
430
-        $old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
431
-        $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
432
-        $where_params = array('Ticket.TKT_ID' => $TKT_ID);
433
-        $query_params = array($where_params, 'order_by' => array('DTT_order' => 'ASC'));
434
-        if (! $include_expired) {
435
-            $query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
436
-        }
437
-        if ($include_deleted) {
438
-            $query_params[0]['DTT_deleted'] = array('IN', array(true, false));
439
-        }
440
-        if ($limit) {
441
-            $query_params['limit'] = $limit;
442
-        }
443
-        /** @var EE_Datetime[] $result */
444
-        $result = $this->get_all($query_params);
445
-        $this->assume_values_already_prepared_by_model_object($old_assumption);
446
-        return $result;
447
-    }
448
-
449
-
450
-    /**
451
-     * Gets the most important datetime for a particular event (ie, the primary event usually. But if for some WACK
452
-     * reason it doesn't exist, we consider the earliest event the most important)
453
-     *
454
-     * @param int $EVT_ID
455
-     * @return EE_Datetime
456
-     * @throws EE_Error
457
-     */
458
-    public function get_most_important_datetime_for_event($EVT_ID)
459
-    {
460
-        $results = $this->get_datetimes_for_event_ordered_by_importance($EVT_ID, 1);
461
-        if ($results) {
462
-            return array_shift($results);
463
-        }
464
-        return null;
465
-    }
466
-
467
-
468
-    /**
469
-     * This returns a wpdb->results        Array of all DTT month and years matching the incoming query params and
470
-     * grouped by month and year.
471
-     *
472
-     * @param  array  $where_params      Array of query_params as described in the comments for EEM_Base::get_all()
473
-     * @param  string $evt_active_status A string representing the evt active status to filter the months by.
474
-     *                                   Can be:
475
-     *                                   - '' = no filter
476
-     *                                   - upcoming = Published events with at least one upcoming datetime.
477
-     *                                   - expired = Events with all datetimes expired.
478
-     *                                   - active = Events that are published and have at least one datetime that
479
-     *                                   starts before now and ends after now.
480
-     *                                   - inactive = Events that are either not published.
481
-     * @return EE_Base_Class[]
482
-     * @throws EE_Error
483
-     * @throws InvalidArgumentException
484
-     * @throws InvalidArgumentException
485
-     */
486
-    public function get_dtt_months_and_years($where_params, $evt_active_status = '')
487
-    {
488
-        $current_time_for_DTT_EVT_start = $this->current_time_for_query('DTT_EVT_start');
489
-        $current_time_for_DTT_EVT_end   = $this->current_time_for_query('DTT_EVT_end');
490
-        switch ($evt_active_status) {
491
-            case 'upcoming' :
492
-                $where_params['Event.status'] = 'publish';
493
-                //if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
494
-                if (isset($where_params['DTT_EVT_start'])) {
495
-                    $where_params['DTT_EVT_start*****'] = $where_params['DTT_EVT_start'];
496
-                }
497
-                $where_params['DTT_EVT_start'] = array('>', $current_time_for_DTT_EVT_start);
498
-                break;
499
-            case 'expired' :
500
-                if (isset($where_params['Event.status'])) {
501
-                    unset($where_params['Event.status']);
502
-                }
503
-                //get events to exclude
504
-                $exclude_query[0] = array_merge($where_params,
505
-                    array('DTT_EVT_end' => array('>', $current_time_for_DTT_EVT_end)));
506
-                //first get all events that have datetimes where its not expired.
507
-                $event_ids = $this->_get_all_wpdb_results(
508
-                    $exclude_query,
509
-                    OBJECT_K,
510
-                    'Datetime.EVT_ID'
511
-                );
512
-                $event_ids = array_keys($event_ids);
513
-                if (isset($where_params['DTT_EVT_end'])) {
514
-                    $where_params['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
515
-                }
516
-                $where_params['DTT_EVT_end']  = array('<', $current_time_for_DTT_EVT_end);
517
-                $where_params['Event.EVT_ID'] = array('NOT IN', $event_ids);
518
-                break;
519
-            case 'active' :
520
-                $where_params['Event.status'] = 'publish';
521
-                if (isset($where_params['DTT_EVT_start'])) {
522
-                    $where_params['Datetime.DTT_EVT_start******'] = $where_params['DTT_EVT_start'];
523
-                }
524
-                if (isset($where_params['Datetime.DTT_EVT_end'])) {
525
-                    $where_params['Datetime.DTT_EVT_end*****'] = $where_params['DTT_EVT_end'];
526
-                }
527
-                $where_params['DTT_EVT_start'] = array('<', $current_time_for_DTT_EVT_start);
528
-                $where_params['DTT_EVT_end']   = array('>', $current_time_for_DTT_EVT_end);
529
-                break;
530
-            case 'inactive' :
531
-                if (isset($where_params['Event.status'])) {
532
-                    unset($where_params['Event.status']);
533
-                }
534
-                if (isset($where_params['OR'])) {
535
-                    $where_params['AND']['OR'] = $where_params['OR'];
536
-                }
537
-                if (isset($where_params['DTT_EVT_end'])) {
538
-                    $where_params['AND']['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
539
-                    unset($where_params['DTT_EVT_end']);
540
-                }
541
-                if (isset($where_params['DTT_EVT_start'])) {
542
-                    $where_params['AND']['DTT_EVT_start'] = $where_params['DTT_EVT_start'];
543
-                    unset($where_params['DTT_EVT_start']);
544
-                }
545
-                $where_params['AND']['Event.status'] = array('!=', 'publish');
546
-                break;
547
-        }
548
-        $query_params[0]          = $where_params;
549
-        $query_params['group_by'] = array('dtt_year', 'dtt_month');
550
-        $query_params['order_by'] = array('DTT_EVT_start' => 'DESC');
551
-        $query_interval           = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(),
552
-            'DTT_EVT_start');
553
-        $columns_to_select        = array(
554
-            'dtt_year'      => array('YEAR(' . $query_interval . ')', '%s'),
555
-            'dtt_month'     => array('MONTHNAME(' . $query_interval . ')', '%s'),
556
-            'dtt_month_num' => array('MONTH(' . $query_interval . ')', '%s'),
557
-        );
558
-        return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
559
-    }
560
-
561
-
562
-    /**
563
-     * Updates the DTT_sold attribute on each datetime (based on the registrations
564
-     * for the tickets for each datetime)
565
-     *
566
-     * @param EE_Base_Class[]|EE_Datetime[] $datetimes
567
-     * @throws EE_Error
568
-     */
569
-    public function update_sold($datetimes)
570
-    {
571
-        EE_Error::doing_it_wrong(
572
-            __FUNCTION__,
573
-            esc_html__(
574
-                'Please use \EEM_Ticket::update_tickets_sold() instead which will in turn correctly update both the Ticket AND Datetime counts.',
575
-                'event_espresso'
576
-            ),
577
-            '4.9.32.rc.005'
578
-        );
579
-        foreach ($datetimes as $datetime) {
580
-            $datetime->update_sold();
581
-        }
582
-    }
583
-
584
-
585
-    /**
586
-     *    Gets the total number of tickets available at a particular datetime
587
-     *    (does NOT take into account the datetime's spaces available)
588
-     *
589
-     * @param int   $DTT_ID
590
-     * @param array $query_params
591
-     * @return int of tickets available. If sold out, return less than 1. If infinite, returns EE_INF,  IF there are NO
592
-     *             tickets attached to datetime then FALSE is returned.
593
-     */
594
-    public function sum_tickets_currently_available_at_datetime($DTT_ID, array $query_params = array())
595
-    {
596
-        $datetime = $this->get_one_by_ID($DTT_ID);
597
-        if ($datetime instanceof EE_Datetime) {
598
-            return $datetime->tickets_remaining($query_params);
599
-        }
600
-        return 0;
601
-    }
602
-
603
-
604
-    /**
605
-     * This returns an array of counts of datetimes in the database for each Datetime status that can be queried.
606
-     *
607
-     * @param  array $stati_to_include If included you can restrict the statuses we return counts for by including the
608
-     *                                 stati you want counts for as values in the array.  An empty array returns counts
609
-     *                                 for all valid stati.
610
-     * @param  array $query_params     If included can be used to refine the conditions for returning the count (i.e.
611
-     *                                 only for Datetimes connected to a specific event, or specific ticket.
612
-     * @return array  The value returned is an array indexed by Datetime Status and the values are the counts.  The
613
-     * @throws EE_Error
614
-     *                                 stati used as index keys are: EE_Datetime::active EE_Datetime::upcoming
615
-     *                                 EE_Datetime::expired
616
-     */
617
-    public function get_datetime_counts_by_status(array $stati_to_include = array(), array $query_params = array())
618
-    {
619
-        //only accept where conditions for this query.
620
-        $_where            = isset($query_params[0]) ? $query_params[0] : array();
621
-        $status_query_args = array(
622
-            EE_Datetime::active   => array_merge(
623
-                $_where,
624
-                array('DTT_EVT_start' => array('<', time()), 'DTT_EVT_end' => array('>', time()))
625
-            ),
626
-            EE_Datetime::upcoming => array_merge(
627
-                $_where,
628
-                array('DTT_EVT_start' => array('>', time()))
629
-            ),
630
-            EE_Datetime::expired  => array_merge(
631
-                $_where,
632
-                array('DTT_EVT_end' => array('<', time()))
633
-            ),
634
-        );
635
-        if (! empty($stati_to_include)) {
636
-            foreach (array_keys($status_query_args) as $status) {
637
-                if (! in_array($status, $stati_to_include, true)) {
638
-                    unset($status_query_args[ $status ]);
639
-                }
640
-            }
641
-        }
642
-        //loop through and query counts for each stati.
643
-        $status_query_results = array();
644
-        foreach ($status_query_args as $status => $status_where_conditions) {
645
-            $status_query_results[ $status ] = EEM_Datetime::count(
646
-                array($status_where_conditions),
647
-                'DTT_ID',
648
-                true
649
-            );
650
-        }
651
-        return $status_query_results;
652
-    }
653
-
654
-
655
-    /**
656
-     * Returns the specific count for a given Datetime status matching any given query_params.
657
-     *
658
-     * @param string $status Valid string representation for Datetime status requested. (Defaults to Active).
659
-     * @param array  $query_params
660
-     * @return int
661
-     * @throws EE_Error
662
-     */
663
-    public function get_datetime_count_for_status($status = EE_Datetime::active, array $query_params = array())
664
-    {
665
-        $count = $this->get_datetime_counts_by_status(array($status), $query_params);
666
-        return ! empty($count[ $status ]) ? $count[ $status ] : 0;
667
-    }
17
+	/**
18
+	 * @var EEM_Datetime $_instance
19
+	 */
20
+	protected static $_instance;
21
+
22
+
23
+	/**
24
+	 * private constructor to prevent direct creation
25
+	 *
26
+	 * @param string $timezone A string representing the timezone we want to set for returned Date Time Strings
27
+	 *                         (and any incoming timezone data that gets saved).
28
+	 *                         Note this just sends the timezone info to the date time model field objects.
29
+	 *                         Default is NULL
30
+	 *                         (and will be assumed using the set timezone in the 'timezone_string' wp option)
31
+	 * @throws EE_Error
32
+	 * @throws InvalidArgumentException
33
+	 * @throws InvalidArgumentException
34
+	 */
35
+	protected function __construct($timezone)
36
+	{
37
+		$this->singular_item           = esc_html__('Datetime', 'event_espresso');
38
+		$this->plural_item             = esc_html__('Datetimes', 'event_espresso');
39
+		$this->_tables                 = array(
40
+			'Datetime' => new EE_Primary_Table('esp_datetime', 'DTT_ID'),
41
+		);
42
+		$this->_fields                 = array(
43
+			'Datetime' => array(
44
+				'DTT_ID'          => new EE_Primary_Key_Int_Field(
45
+					'DTT_ID',
46
+					esc_html__('Datetime ID', 'event_espresso')
47
+				),
48
+				'EVT_ID'          => new EE_Foreign_Key_Int_Field(
49
+					'EVT_ID',
50
+					esc_html__('Event ID', 'event_espresso'),
51
+					false,
52
+					0,
53
+					'Event'
54
+				),
55
+				'DTT_name'        => new EE_Plain_Text_Field(
56
+					'DTT_name',
57
+					esc_html__('Datetime Name', 'event_espresso'),
58
+					false,
59
+					''
60
+				),
61
+				'DTT_description' => new EE_Post_Content_Field(
62
+					'DTT_description',
63
+					esc_html__('Description for Datetime', 'event_espresso'),
64
+					false,
65
+					''
66
+				),
67
+				'DTT_EVT_start'   => new EE_Datetime_Field(
68
+					'DTT_EVT_start',
69
+					esc_html__('Start time/date of Event', 'event_espresso'),
70
+					false,
71
+					EE_Datetime_Field::now,
72
+					$timezone
73
+				),
74
+				'DTT_EVT_end'     => new EE_Datetime_Field(
75
+					'DTT_EVT_end',
76
+					esc_html__('End time/date of Event', 'event_espresso'),
77
+					false,
78
+					EE_Datetime_Field::now,
79
+					$timezone
80
+				),
81
+				'DTT_reg_limit'   => new EE_Infinite_Integer_Field(
82
+					'DTT_reg_limit',
83
+					esc_html__('Registration Limit for this time', 'event_espresso'),
84
+					true,
85
+					EE_INF
86
+				),
87
+				'DTT_sold'        => new EE_Integer_Field(
88
+					'DTT_sold',
89
+					esc_html__('How many sales for this Datetime that have occurred', 'event_espresso'),
90
+					true,
91
+					0
92
+				),
93
+				'DTT_reserved'    => new EE_Integer_Field(
94
+					'DTT_reserved',
95
+					esc_html__('Quantity of tickets reserved, but not yet fully purchased', 'event_espresso'),
96
+					false,
97
+					0
98
+				),
99
+				'DTT_is_primary'  => new EE_Boolean_Field(
100
+					'DTT_is_primary',
101
+					esc_html__('Flag indicating datetime is primary one for event', 'event_espresso'),
102
+					false,
103
+					false
104
+				),
105
+				'DTT_order'       => new EE_Integer_Field(
106
+					'DTT_order',
107
+					esc_html__('The order in which the Datetime is displayed', 'event_espresso'),
108
+					false,
109
+					0
110
+				),
111
+				'DTT_parent'      => new EE_Integer_Field(
112
+					'DTT_parent',
113
+					esc_html__('Indicates what DTT_ID is the parent of this DTT_ID'),
114
+					true,
115
+					0
116
+				),
117
+				'DTT_deleted'     => new EE_Trashed_Flag_Field(
118
+					'DTT_deleted',
119
+					esc_html__('Flag indicating datetime is archived', 'event_espresso'),
120
+					false,
121
+					false
122
+				),
123
+			),
124
+		);
125
+		$this->_model_relations        = array(
126
+			'Ticket'  => new EE_HABTM_Relation('Datetime_Ticket'),
127
+			'Event'   => new EE_Belongs_To_Relation(),
128
+			'Checkin' => new EE_Has_Many_Relation(),
129
+		);
130
+		$this->_model_chain_to_wp_user = 'Event';
131
+		//this model is generally available for reading
132
+		$this->_cap_restriction_generators[ EEM_Base::caps_read ]       = new EE_Restriction_Generator_Event_Related_Public(
133
+			'Event'
134
+		);
135
+		$this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = new EE_Restriction_Generator_Event_Related_Protected(
136
+			'Event'
137
+		);
138
+		$this->_cap_restriction_generators[ EEM_Base::caps_edit ]       = new EE_Restriction_Generator_Event_Related_Protected(
139
+			'Event'
140
+		);
141
+		$this->_cap_restriction_generators[ EEM_Base::caps_delete ]     = new EE_Restriction_Generator_Event_Related_Protected(
142
+			'Event',
143
+			EEM_Base::caps_edit
144
+		);
145
+		parent::__construct($timezone);
146
+	}
147
+
148
+
149
+	/**
150
+	 * create new blank datetime
151
+	 *
152
+	 * @access public
153
+	 * @return EE_Datetime[] array on success, FALSE on fail
154
+	 * @throws EE_Error
155
+	 */
156
+	public function create_new_blank_datetime()
157
+	{
158
+		//makes sure timezone is always set.
159
+		$timezone_string = $this->get_timezone();
160
+		$blank_datetime  = EE_Datetime::new_instance(
161
+			array(
162
+				'DTT_EVT_start' => $this->current_time_for_query('DTT_EVT_start', true) + MONTH_IN_SECONDS,
163
+				'DTT_EVT_end'   => $this->current_time_for_query('DTT_EVT_end', true) + MONTH_IN_SECONDS,
164
+				'DTT_order'     => 1,
165
+				'DTT_reg_limit' => EE_INF,
166
+			),
167
+			$timezone_string
168
+		);
169
+		$blank_datetime->set_start_time(
170
+			$this->convert_datetime_for_query(
171
+				'DTT_EVT_start',
172
+				'8am',
173
+				'ga',
174
+				$timezone_string
175
+			)
176
+		);
177
+		$blank_datetime->set_end_time(
178
+			$this->convert_datetime_for_query(
179
+				'DTT_EVT_end',
180
+				'5pm',
181
+				'ga',
182
+				$timezone_string
183
+			)
184
+		);
185
+		return array($blank_datetime);
186
+	}
187
+
188
+
189
+	/**
190
+	 * get event start date from db
191
+	 *
192
+	 * @access public
193
+	 * @param  int $EVT_ID
194
+	 * @return EE_Datetime[] array on success, FALSE on fail
195
+	 * @throws EE_Error
196
+	 */
197
+	public function get_all_event_dates($EVT_ID = 0)
198
+	{
199
+		if (! $EVT_ID) { // on add_new_event event_id gets set to 0
200
+			return $this->create_new_blank_datetime();
201
+		}
202
+		$results = $this->get_datetimes_for_event_ordered_by_DTT_order($EVT_ID);
203
+		if (empty($results)) {
204
+			return $this->create_new_blank_datetime();
205
+		}
206
+		return $results;
207
+	}
208
+
209
+
210
+	/**
211
+	 * get all datetimes attached to an event ordered by the DTT_order field
212
+	 *
213
+	 * @public
214
+	 * @param  int    $EVT_ID     event id
215
+	 * @param boolean $include_expired
216
+	 * @param boolean $include_deleted
217
+	 * @param  int    $limit      If included then limit the count of results by
218
+	 *                            the given number
219
+	 * @return EE_Datetime[]
220
+	 * @throws EE_Error
221
+	 */
222
+	public function get_datetimes_for_event_ordered_by_DTT_order(
223
+		$EVT_ID,
224
+		$include_expired = true,
225
+		$include_deleted = true,
226
+		$limit = null
227
+	) {
228
+		//sanitize EVT_ID
229
+		$EVT_ID         = absint($EVT_ID);
230
+		$old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
231
+		$this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
232
+		$where_params = array('Event.EVT_ID' => $EVT_ID);
233
+		$query_params = ! empty($limit)
234
+			? array(
235
+				$where_params,
236
+				'limit'                    => $limit,
237
+				'order_by'                 => array('DTT_order' => 'ASC'),
238
+				'default_where_conditions' => 'none',
239
+			)
240
+			: array(
241
+				$where_params,
242
+				'order_by'                 => array('DTT_order' => 'ASC'),
243
+				'default_where_conditions' => 'none',
244
+			);
245
+		if (! $include_expired) {
246
+			$query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
247
+		}
248
+		if ($include_deleted) {
249
+			$query_params[0]['DTT_deleted'] = array('IN', array(true, false));
250
+		}
251
+		/** @var EE_Datetime[] $result */
252
+		$result = $this->get_all($query_params);
253
+		$this->assume_values_already_prepared_by_model_object($old_assumption);
254
+		return $result;
255
+	}
256
+
257
+
258
+	/**
259
+	 * Gets the datetimes for the event (with the given limit), and orders them by "importance".
260
+	 * By importance, we mean that the primary datetimes are most important (DEPRECATED FOR NOW),
261
+	 * and then the earlier datetimes are the most important.
262
+	 * Maybe we'll want this to take into account datetimes that haven't already passed, but we don't yet.
263
+	 *
264
+	 * @param int $EVT_ID
265
+	 * @param int $limit
266
+	 * @return EE_Datetime[]|EE_Base_Class[]
267
+	 * @throws EE_Error
268
+	 */
269
+	public function get_datetimes_for_event_ordered_by_importance($EVT_ID = 0, $limit = null)
270
+	{
271
+		return $this->get_all(
272
+			array(
273
+				array('Event.EVT_ID' => $EVT_ID),
274
+				'limit'                    => $limit,
275
+				'order_by'                 => array('DTT_EVT_start' => 'ASC'),
276
+				'default_where_conditions' => 'none',
277
+			)
278
+		);
279
+	}
280
+
281
+
282
+	/**
283
+	 * @param int     $EVT_ID
284
+	 * @param boolean $include_expired
285
+	 * @param boolean $include_deleted
286
+	 * @return EE_Datetime
287
+	 * @throws EE_Error
288
+	 */
289
+	public function get_oldest_datetime_for_event($EVT_ID, $include_expired = false, $include_deleted = false)
290
+	{
291
+		$results = $this->get_datetimes_for_event_ordered_by_start_time(
292
+			$EVT_ID,
293
+			$include_expired,
294
+			$include_deleted,
295
+			1
296
+		);
297
+		if ($results) {
298
+			return array_shift($results);
299
+		}
300
+		return null;
301
+	}
302
+
303
+
304
+	/**
305
+	 * Gets the 'primary' datetime for an event.
306
+	 *
307
+	 * @param int  $EVT_ID
308
+	 * @param bool $try_to_exclude_expired
309
+	 * @param bool $try_to_exclude_deleted
310
+	 * @return \EE_Datetime
311
+	 * @throws EE_Error
312
+	 */
313
+	public function get_primary_datetime_for_event(
314
+		$EVT_ID,
315
+		$try_to_exclude_expired = true,
316
+		$try_to_exclude_deleted = true
317
+	) {
318
+		if ($try_to_exclude_expired) {
319
+			$non_expired = $this->get_oldest_datetime_for_event($EVT_ID, false, false);
320
+			if ($non_expired) {
321
+				return $non_expired;
322
+			}
323
+		}
324
+		if ($try_to_exclude_deleted) {
325
+			$expired_even = $this->get_oldest_datetime_for_event($EVT_ID, true);
326
+			if ($expired_even) {
327
+				return $expired_even;
328
+			}
329
+		}
330
+		return $this->get_oldest_datetime_for_event($EVT_ID, true, true);
331
+	}
332
+
333
+
334
+	/**
335
+	 * Gets ALL the datetimes for an event (including trashed ones, for now), ordered
336
+	 * only by start date
337
+	 *
338
+	 * @param int     $EVT_ID
339
+	 * @param boolean $include_expired
340
+	 * @param boolean $include_deleted
341
+	 * @param int     $limit
342
+	 * @return EE_Datetime[]
343
+	 * @throws EE_Error
344
+	 */
345
+	public function get_datetimes_for_event_ordered_by_start_time(
346
+		$EVT_ID,
347
+		$include_expired = true,
348
+		$include_deleted = true,
349
+		$limit = null
350
+	) {
351
+		//sanitize EVT_ID
352
+		$EVT_ID         = absint($EVT_ID);
353
+		$old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
354
+		$this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
355
+		$query_params = array(array('Event.EVT_ID' => $EVT_ID), 'order_by' => array('DTT_EVT_start' => 'asc'));
356
+		if (! $include_expired) {
357
+			$query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
358
+		}
359
+		if ($include_deleted) {
360
+			$query_params[0]['DTT_deleted'] = array('IN', array(true, false));
361
+		}
362
+		if ($limit) {
363
+			$query_params['limit'] = $limit;
364
+		}
365
+		/** @var EE_Datetime[] $result */
366
+		$result = $this->get_all($query_params);
367
+		$this->assume_values_already_prepared_by_model_object($old_assumption);
368
+		return $result;
369
+	}
370
+
371
+
372
+	/**
373
+	 * Gets ALL the datetimes for an ticket (including trashed ones, for now), ordered
374
+	 * only by start date
375
+	 *
376
+	 * @param int     $TKT_ID
377
+	 * @param boolean $include_expired
378
+	 * @param boolean $include_deleted
379
+	 * @param int     $limit
380
+	 * @return EE_Datetime[]
381
+	 * @throws EE_Error
382
+	 */
383
+	public function get_datetimes_for_ticket_ordered_by_start_time(
384
+		$TKT_ID,
385
+		$include_expired = true,
386
+		$include_deleted = true,
387
+		$limit = null
388
+	) {
389
+		//sanitize TKT_ID
390
+		$TKT_ID         = absint($TKT_ID);
391
+		$old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
392
+		$this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
393
+		$query_params = array(array('Ticket.TKT_ID' => $TKT_ID), 'order_by' => array('DTT_EVT_start' => 'asc'));
394
+		if (! $include_expired) {
395
+			$query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
396
+		}
397
+		if ($include_deleted) {
398
+			$query_params[0]['DTT_deleted'] = array('IN', array(true, false));
399
+		}
400
+		if ($limit) {
401
+			$query_params['limit'] = $limit;
402
+		}
403
+		/** @var EE_Datetime[] $result */
404
+		$result = $this->get_all($query_params);
405
+		$this->assume_values_already_prepared_by_model_object($old_assumption);
406
+		return $result;
407
+	}
408
+
409
+
410
+	/**
411
+	 * Gets all the datetimes for a ticket (including trashed ones, for now), ordered by the DTT_order for the
412
+	 * datetimes.
413
+	 *
414
+	 * @param  int      $TKT_ID          ID of ticket to retrieve the datetimes for
415
+	 * @param  boolean  $include_expired whether to include expired datetimes or not
416
+	 * @param  boolean  $include_deleted whether to include trashed datetimes or not.
417
+	 * @param  int|null $limit           if null, no limit, if int then limit results by
418
+	 *                                   that number
419
+	 * @return EE_Datetime[]
420
+	 * @throws EE_Error
421
+	 */
422
+	public function get_datetimes_for_ticket_ordered_by_DTT_order(
423
+		$TKT_ID,
424
+		$include_expired = true,
425
+		$include_deleted = true,
426
+		$limit = null
427
+	) {
428
+		//sanitize id.
429
+		$TKT_ID         = absint($TKT_ID);
430
+		$old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
431
+		$this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
432
+		$where_params = array('Ticket.TKT_ID' => $TKT_ID);
433
+		$query_params = array($where_params, 'order_by' => array('DTT_order' => 'ASC'));
434
+		if (! $include_expired) {
435
+			$query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
436
+		}
437
+		if ($include_deleted) {
438
+			$query_params[0]['DTT_deleted'] = array('IN', array(true, false));
439
+		}
440
+		if ($limit) {
441
+			$query_params['limit'] = $limit;
442
+		}
443
+		/** @var EE_Datetime[] $result */
444
+		$result = $this->get_all($query_params);
445
+		$this->assume_values_already_prepared_by_model_object($old_assumption);
446
+		return $result;
447
+	}
448
+
449
+
450
+	/**
451
+	 * Gets the most important datetime for a particular event (ie, the primary event usually. But if for some WACK
452
+	 * reason it doesn't exist, we consider the earliest event the most important)
453
+	 *
454
+	 * @param int $EVT_ID
455
+	 * @return EE_Datetime
456
+	 * @throws EE_Error
457
+	 */
458
+	public function get_most_important_datetime_for_event($EVT_ID)
459
+	{
460
+		$results = $this->get_datetimes_for_event_ordered_by_importance($EVT_ID, 1);
461
+		if ($results) {
462
+			return array_shift($results);
463
+		}
464
+		return null;
465
+	}
466
+
467
+
468
+	/**
469
+	 * This returns a wpdb->results        Array of all DTT month and years matching the incoming query params and
470
+	 * grouped by month and year.
471
+	 *
472
+	 * @param  array  $where_params      Array of query_params as described in the comments for EEM_Base::get_all()
473
+	 * @param  string $evt_active_status A string representing the evt active status to filter the months by.
474
+	 *                                   Can be:
475
+	 *                                   - '' = no filter
476
+	 *                                   - upcoming = Published events with at least one upcoming datetime.
477
+	 *                                   - expired = Events with all datetimes expired.
478
+	 *                                   - active = Events that are published and have at least one datetime that
479
+	 *                                   starts before now and ends after now.
480
+	 *                                   - inactive = Events that are either not published.
481
+	 * @return EE_Base_Class[]
482
+	 * @throws EE_Error
483
+	 * @throws InvalidArgumentException
484
+	 * @throws InvalidArgumentException
485
+	 */
486
+	public function get_dtt_months_and_years($where_params, $evt_active_status = '')
487
+	{
488
+		$current_time_for_DTT_EVT_start = $this->current_time_for_query('DTT_EVT_start');
489
+		$current_time_for_DTT_EVT_end   = $this->current_time_for_query('DTT_EVT_end');
490
+		switch ($evt_active_status) {
491
+			case 'upcoming' :
492
+				$where_params['Event.status'] = 'publish';
493
+				//if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
494
+				if (isset($where_params['DTT_EVT_start'])) {
495
+					$where_params['DTT_EVT_start*****'] = $where_params['DTT_EVT_start'];
496
+				}
497
+				$where_params['DTT_EVT_start'] = array('>', $current_time_for_DTT_EVT_start);
498
+				break;
499
+			case 'expired' :
500
+				if (isset($where_params['Event.status'])) {
501
+					unset($where_params['Event.status']);
502
+				}
503
+				//get events to exclude
504
+				$exclude_query[0] = array_merge($where_params,
505
+					array('DTT_EVT_end' => array('>', $current_time_for_DTT_EVT_end)));
506
+				//first get all events that have datetimes where its not expired.
507
+				$event_ids = $this->_get_all_wpdb_results(
508
+					$exclude_query,
509
+					OBJECT_K,
510
+					'Datetime.EVT_ID'
511
+				);
512
+				$event_ids = array_keys($event_ids);
513
+				if (isset($where_params['DTT_EVT_end'])) {
514
+					$where_params['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
515
+				}
516
+				$where_params['DTT_EVT_end']  = array('<', $current_time_for_DTT_EVT_end);
517
+				$where_params['Event.EVT_ID'] = array('NOT IN', $event_ids);
518
+				break;
519
+			case 'active' :
520
+				$where_params['Event.status'] = 'publish';
521
+				if (isset($where_params['DTT_EVT_start'])) {
522
+					$where_params['Datetime.DTT_EVT_start******'] = $where_params['DTT_EVT_start'];
523
+				}
524
+				if (isset($where_params['Datetime.DTT_EVT_end'])) {
525
+					$where_params['Datetime.DTT_EVT_end*****'] = $where_params['DTT_EVT_end'];
526
+				}
527
+				$where_params['DTT_EVT_start'] = array('<', $current_time_for_DTT_EVT_start);
528
+				$where_params['DTT_EVT_end']   = array('>', $current_time_for_DTT_EVT_end);
529
+				break;
530
+			case 'inactive' :
531
+				if (isset($where_params['Event.status'])) {
532
+					unset($where_params['Event.status']);
533
+				}
534
+				if (isset($where_params['OR'])) {
535
+					$where_params['AND']['OR'] = $where_params['OR'];
536
+				}
537
+				if (isset($where_params['DTT_EVT_end'])) {
538
+					$where_params['AND']['DTT_EVT_end****'] = $where_params['DTT_EVT_end'];
539
+					unset($where_params['DTT_EVT_end']);
540
+				}
541
+				if (isset($where_params['DTT_EVT_start'])) {
542
+					$where_params['AND']['DTT_EVT_start'] = $where_params['DTT_EVT_start'];
543
+					unset($where_params['DTT_EVT_start']);
544
+				}
545
+				$where_params['AND']['Event.status'] = array('!=', 'publish');
546
+				break;
547
+		}
548
+		$query_params[0]          = $where_params;
549
+		$query_params['group_by'] = array('dtt_year', 'dtt_month');
550
+		$query_params['order_by'] = array('DTT_EVT_start' => 'DESC');
551
+		$query_interval           = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(),
552
+			'DTT_EVT_start');
553
+		$columns_to_select        = array(
554
+			'dtt_year'      => array('YEAR(' . $query_interval . ')', '%s'),
555
+			'dtt_month'     => array('MONTHNAME(' . $query_interval . ')', '%s'),
556
+			'dtt_month_num' => array('MONTH(' . $query_interval . ')', '%s'),
557
+		);
558
+		return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
559
+	}
560
+
561
+
562
+	/**
563
+	 * Updates the DTT_sold attribute on each datetime (based on the registrations
564
+	 * for the tickets for each datetime)
565
+	 *
566
+	 * @param EE_Base_Class[]|EE_Datetime[] $datetimes
567
+	 * @throws EE_Error
568
+	 */
569
+	public function update_sold($datetimes)
570
+	{
571
+		EE_Error::doing_it_wrong(
572
+			__FUNCTION__,
573
+			esc_html__(
574
+				'Please use \EEM_Ticket::update_tickets_sold() instead which will in turn correctly update both the Ticket AND Datetime counts.',
575
+				'event_espresso'
576
+			),
577
+			'4.9.32.rc.005'
578
+		);
579
+		foreach ($datetimes as $datetime) {
580
+			$datetime->update_sold();
581
+		}
582
+	}
583
+
584
+
585
+	/**
586
+	 *    Gets the total number of tickets available at a particular datetime
587
+	 *    (does NOT take into account the datetime's spaces available)
588
+	 *
589
+	 * @param int   $DTT_ID
590
+	 * @param array $query_params
591
+	 * @return int of tickets available. If sold out, return less than 1. If infinite, returns EE_INF,  IF there are NO
592
+	 *             tickets attached to datetime then FALSE is returned.
593
+	 */
594
+	public function sum_tickets_currently_available_at_datetime($DTT_ID, array $query_params = array())
595
+	{
596
+		$datetime = $this->get_one_by_ID($DTT_ID);
597
+		if ($datetime instanceof EE_Datetime) {
598
+			return $datetime->tickets_remaining($query_params);
599
+		}
600
+		return 0;
601
+	}
602
+
603
+
604
+	/**
605
+	 * This returns an array of counts of datetimes in the database for each Datetime status that can be queried.
606
+	 *
607
+	 * @param  array $stati_to_include If included you can restrict the statuses we return counts for by including the
608
+	 *                                 stati you want counts for as values in the array.  An empty array returns counts
609
+	 *                                 for all valid stati.
610
+	 * @param  array $query_params     If included can be used to refine the conditions for returning the count (i.e.
611
+	 *                                 only for Datetimes connected to a specific event, or specific ticket.
612
+	 * @return array  The value returned is an array indexed by Datetime Status and the values are the counts.  The
613
+	 * @throws EE_Error
614
+	 *                                 stati used as index keys are: EE_Datetime::active EE_Datetime::upcoming
615
+	 *                                 EE_Datetime::expired
616
+	 */
617
+	public function get_datetime_counts_by_status(array $stati_to_include = array(), array $query_params = array())
618
+	{
619
+		//only accept where conditions for this query.
620
+		$_where            = isset($query_params[0]) ? $query_params[0] : array();
621
+		$status_query_args = array(
622
+			EE_Datetime::active   => array_merge(
623
+				$_where,
624
+				array('DTT_EVT_start' => array('<', time()), 'DTT_EVT_end' => array('>', time()))
625
+			),
626
+			EE_Datetime::upcoming => array_merge(
627
+				$_where,
628
+				array('DTT_EVT_start' => array('>', time()))
629
+			),
630
+			EE_Datetime::expired  => array_merge(
631
+				$_where,
632
+				array('DTT_EVT_end' => array('<', time()))
633
+			),
634
+		);
635
+		if (! empty($stati_to_include)) {
636
+			foreach (array_keys($status_query_args) as $status) {
637
+				if (! in_array($status, $stati_to_include, true)) {
638
+					unset($status_query_args[ $status ]);
639
+				}
640
+			}
641
+		}
642
+		//loop through and query counts for each stati.
643
+		$status_query_results = array();
644
+		foreach ($status_query_args as $status => $status_where_conditions) {
645
+			$status_query_results[ $status ] = EEM_Datetime::count(
646
+				array($status_where_conditions),
647
+				'DTT_ID',
648
+				true
649
+			);
650
+		}
651
+		return $status_query_results;
652
+	}
653
+
654
+
655
+	/**
656
+	 * Returns the specific count for a given Datetime status matching any given query_params.
657
+	 *
658
+	 * @param string $status Valid string representation for Datetime status requested. (Defaults to Active).
659
+	 * @param array  $query_params
660
+	 * @return int
661
+	 * @throws EE_Error
662
+	 */
663
+	public function get_datetime_count_for_status($status = EE_Datetime::active, array $query_params = array())
664
+	{
665
+		$count = $this->get_datetime_counts_by_status(array($status), $query_params);
666
+		return ! empty($count[ $status ]) ? $count[ $status ] : 0;
667
+	}
668 668
 }
669 669
 // End of file EEM_Datetime.model.php
670 670
 // Location: /includes/models/EEM_Datetime.model.php
Please login to merge, or discard this patch.
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -1,4 +1,4 @@  discard block
 block discarded – undo
1
-<?php if (! defined('EVENT_ESPRESSO_VERSION')) {
1
+<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2 2
     exit('No direct script access allowed');
3 3
 }
4 4
 
@@ -122,23 +122,23 @@  discard block
 block discarded – undo
122 122
                 ),
123 123
             ),
124 124
         );
125
-        $this->_model_relations        = array(
125
+        $this->_model_relations = array(
126 126
             'Ticket'  => new EE_HABTM_Relation('Datetime_Ticket'),
127 127
             'Event'   => new EE_Belongs_To_Relation(),
128 128
             'Checkin' => new EE_Has_Many_Relation(),
129 129
         );
130 130
         $this->_model_chain_to_wp_user = 'Event';
131 131
         //this model is generally available for reading
132
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ]       = new EE_Restriction_Generator_Event_Related_Public(
132
+        $this->_cap_restriction_generators[EEM_Base::caps_read]       = new EE_Restriction_Generator_Event_Related_Public(
133 133
             'Event'
134 134
         );
135
-        $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = new EE_Restriction_Generator_Event_Related_Protected(
135
+        $this->_cap_restriction_generators[EEM_Base::caps_read_admin] = new EE_Restriction_Generator_Event_Related_Protected(
136 136
             'Event'
137 137
         );
138
-        $this->_cap_restriction_generators[ EEM_Base::caps_edit ]       = new EE_Restriction_Generator_Event_Related_Protected(
138
+        $this->_cap_restriction_generators[EEM_Base::caps_edit]       = new EE_Restriction_Generator_Event_Related_Protected(
139 139
             'Event'
140 140
         );
141
-        $this->_cap_restriction_generators[ EEM_Base::caps_delete ]     = new EE_Restriction_Generator_Event_Related_Protected(
141
+        $this->_cap_restriction_generators[EEM_Base::caps_delete]     = new EE_Restriction_Generator_Event_Related_Protected(
142 142
             'Event',
143 143
             EEM_Base::caps_edit
144 144
         );
@@ -196,7 +196,7 @@  discard block
 block discarded – undo
196 196
      */
197 197
     public function get_all_event_dates($EVT_ID = 0)
198 198
     {
199
-        if (! $EVT_ID) { // on add_new_event event_id gets set to 0
199
+        if ( ! $EVT_ID) { // on add_new_event event_id gets set to 0
200 200
             return $this->create_new_blank_datetime();
201 201
         }
202 202
         $results = $this->get_datetimes_for_event_ordered_by_DTT_order($EVT_ID);
@@ -242,7 +242,7 @@  discard block
 block discarded – undo
242 242
                 'order_by'                 => array('DTT_order' => 'ASC'),
243 243
                 'default_where_conditions' => 'none',
244 244
             );
245
-        if (! $include_expired) {
245
+        if ( ! $include_expired) {
246 246
             $query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
247 247
         }
248 248
         if ($include_deleted) {
@@ -353,7 +353,7 @@  discard block
 block discarded – undo
353 353
         $old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
354 354
         $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
355 355
         $query_params = array(array('Event.EVT_ID' => $EVT_ID), 'order_by' => array('DTT_EVT_start' => 'asc'));
356
-        if (! $include_expired) {
356
+        if ( ! $include_expired) {
357 357
             $query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
358 358
         }
359 359
         if ($include_deleted) {
@@ -391,7 +391,7 @@  discard block
 block discarded – undo
391 391
         $old_assumption = $this->get_assumption_concerning_values_already_prepared_by_model_object();
392 392
         $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
393 393
         $query_params = array(array('Ticket.TKT_ID' => $TKT_ID), 'order_by' => array('DTT_EVT_start' => 'asc'));
394
-        if (! $include_expired) {
394
+        if ( ! $include_expired) {
395 395
             $query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
396 396
         }
397 397
         if ($include_deleted) {
@@ -431,7 +431,7 @@  discard block
 block discarded – undo
431 431
         $this->assume_values_already_prepared_by_model_object(EEM_Base::prepared_for_use_in_db);
432 432
         $where_params = array('Ticket.TKT_ID' => $TKT_ID);
433 433
         $query_params = array($where_params, 'order_by' => array('DTT_order' => 'ASC'));
434
-        if (! $include_expired) {
434
+        if ( ! $include_expired) {
435 435
             $query_params[0]['DTT_EVT_end'] = array('>=', current_time('mysql', true));
436 436
         }
437 437
         if ($include_deleted) {
@@ -551,9 +551,9 @@  discard block
 block discarded – undo
551 551
         $query_interval           = EEH_DTT_Helper::get_sql_query_interval_for_offset($this->get_timezone(),
552 552
             'DTT_EVT_start');
553 553
         $columns_to_select        = array(
554
-            'dtt_year'      => array('YEAR(' . $query_interval . ')', '%s'),
555
-            'dtt_month'     => array('MONTHNAME(' . $query_interval . ')', '%s'),
556
-            'dtt_month_num' => array('MONTH(' . $query_interval . ')', '%s'),
554
+            'dtt_year'      => array('YEAR('.$query_interval.')', '%s'),
555
+            'dtt_month'     => array('MONTHNAME('.$query_interval.')', '%s'),
556
+            'dtt_month_num' => array('MONTH('.$query_interval.')', '%s'),
557 557
         );
558 558
         return $this->_get_all_wpdb_results($query_params, OBJECT, $columns_to_select);
559 559
     }
@@ -632,17 +632,17 @@  discard block
 block discarded – undo
632 632
                 array('DTT_EVT_end' => array('<', time()))
633 633
             ),
634 634
         );
635
-        if (! empty($stati_to_include)) {
635
+        if ( ! empty($stati_to_include)) {
636 636
             foreach (array_keys($status_query_args) as $status) {
637
-                if (! in_array($status, $stati_to_include, true)) {
638
-                    unset($status_query_args[ $status ]);
637
+                if ( ! in_array($status, $stati_to_include, true)) {
638
+                    unset($status_query_args[$status]);
639 639
                 }
640 640
             }
641 641
         }
642 642
         //loop through and query counts for each stati.
643 643
         $status_query_results = array();
644 644
         foreach ($status_query_args as $status => $status_where_conditions) {
645
-            $status_query_results[ $status ] = EEM_Datetime::count(
645
+            $status_query_results[$status] = EEM_Datetime::count(
646 646
                 array($status_where_conditions),
647 647
                 'DTT_ID',
648 648
                 true
@@ -663,7 +663,7 @@  discard block
 block discarded – undo
663 663
     public function get_datetime_count_for_status($status = EE_Datetime::active, array $query_params = array())
664 664
     {
665 665
         $count = $this->get_datetime_counts_by_status(array($status), $query_params);
666
-        return ! empty($count[ $status ]) ? $count[ $status ] : 0;
666
+        return ! empty($count[$status]) ? $count[$status] : 0;
667 667
     }
668 668
 }
669 669
 // End of file EEM_Datetime.model.php
Please login to merge, or discard this patch.
public/Espresso_Arabica_2014/content-espresso_events-datetimes.php 1 patch
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -1,15 +1,15 @@
 block discarded – undo
1 1
 <?php
2 2
 //echo '<br/><h6 style="color:#2EA2CC;">'. __FILE__ . ' &nbsp; <span style="font-weight:normal;color:#E76700"> Line #: ' . __LINE__ . '</span></h6>';
3 3
 
4
-if ( is_single() || ( is_archive() && espresso_display_datetimes_in_event_list() ) ) :
4
+if (is_single() || (is_archive() && espresso_display_datetimes_in_event_list())) :
5 5
 global $post;
6
-do_action( 'AHEE_event_details_before_event_date', $post );
6
+do_action('AHEE_event_details_before_event_date', $post);
7 7
 ?>
8 8
 	<div class="event-datetimes">
9
-		<?php espresso_list_of_event_dates( $post->ID );?>
9
+		<?php espresso_list_of_event_dates($post->ID); ?>
10 10
 	</div>
11 11
 	<!-- .event-datetimes -->
12 12
 <?php
13
-do_action( 'AHEE_event_details_after_event_date', $post );
13
+do_action('AHEE_event_details_after_event_date', $post);
14 14
 endif;
15 15
 ?>
16 16
\ No newline at end of file
Please login to merge, or discard this patch.
core/db_models/helpers/EE_Table_Base.php 2 patches
Indentation   +160 added lines, -160 removed lines patch added patch discarded remove patch
@@ -9,164 +9,164 @@
 block discarded – undo
9 9
 abstract class EE_Table_Base
10 10
 {
11 11
 
12
-    /**
13
-     * This holds the table_name without the table prefix.
14
-     *
15
-     * @var string
16
-     */
17
-    var $_table_name;
18
-
19
-
20
-    /**
21
-     * This holds what is used as the alias for the table in queries.
22
-     *
23
-     * @var string
24
-     */
25
-    var $_table_alias;
26
-
27
-
28
-    /**
29
-     * Table's private key column
30
-     *
31
-     * @var string
32
-     */
33
-    protected $_pk_column;
34
-
35
-
36
-    /**
37
-     * Whether this table is a global table (in multisite) or specific to site.
38
-     *
39
-     * @var bool
40
-     */
41
-    protected $_global;
42
-
43
-
44
-
45
-    /**
46
-     * @global wpdb   $wpdb
47
-     * @param string  $table_name with or without wpdb prefix
48
-     * @param string  $pk_column
49
-     * @param boolean $global     whether the table is "global" as in there is only 1 table on an entire multisite
50
-     *                            install, or whether each site on a multisite install has a copy of this table
51
-     */
52
-    function __construct($table_name, $pk_column, $global = false)
53
-    {
54
-        $this->_global = $global;
55
-        $prefix = $this->get_table_prefix();
56
-        //if they added the prefix, let's remove it because we delay adding the prefix until right when its needed.
57
-        if (strpos($table_name, $prefix) === 0) {
58
-            $table_name = ltrim($table_name, $prefix);
59
-        }
60
-        $this->_table_name = $table_name;
61
-        $this->_pk_column = $pk_column;
62
-    }
63
-
64
-
65
-
66
-    /**
67
-     * This returns the table prefix for the current model state.
68
-     *
69
-     * @global wpdb $wpdb
70
-     * @return string
71
-     */
72
-    public function get_table_prefix()
73
-    {
74
-        global $wpdb;
75
-        if ($this->_global) {
76
-            $prefix = $wpdb->base_prefix;
77
-        } else {
78
-            $prefix = $wpdb->get_blog_prefix(EEM_Base::get_model_query_blog_id());
79
-        }
80
-        return $prefix;
81
-    }
82
-
83
-
84
-
85
-    /**
86
-     * Used to set the table_alias property
87
-     *
88
-     * @param string $table_alias
89
-     */
90
-    function _construct_finalize_with_alias($table_alias)
91
-    {
92
-        $this->_table_alias = $table_alias;
93
-    }
94
-
95
-
96
-
97
-    /**
98
-     * Returns the fully qualified table name for the database (includes the table prefix current for the blog).
99
-     *
100
-     * @return string
101
-     */
102
-    function get_table_name()
103
-    {
104
-        return $this->get_table_prefix() . $this->_table_name;
105
-    }
106
-
107
-
108
-
109
-    /**
110
-     * Provides what is currently set as the alias for the table to be used in queries.
111
-     *
112
-     * @return string
113
-     * @throws EE_Error
114
-     */
115
-    function get_table_alias()
116
-    {
117
-        if ( ! $this->_table_alias) {
118
-            throw new EE_Error("You must call _construct_finalize_with_alias before using the EE_Table_Base. Did you forget to call parent::__construct at the end of your EEMerimental_Base child's __construct?");
119
-        }
120
-        return $this->_table_alias;
121
-    }
122
-
123
-
124
-
125
-    /**
126
-     * @return string name of column of PK
127
-     */
128
-    function get_pk_column()
129
-    {
130
-        return $this->_pk_column;
131
-    }
132
-
133
-
134
-
135
-    /**
136
-     * returns a string with the table alias, a period, and the private key's column.
137
-     *
138
-     * @return string
139
-     */
140
-    function get_fully_qualified_pk_column()
141
-    {
142
-        $sql = $this->get_table_alias() . "." . $this->get_pk_column();
143
-        return $sql;
144
-    }
145
-
146
-
147
-
148
-    /**
149
-     * returns the special sql for a inner select with a limit.
150
-     *
151
-     * @return string    SQL select
152
-     */
153
-    public function get_select_join_limit($limit)
154
-    {
155
-        $limit = is_array($limit) ? 'LIMIT ' . implode(',', array_map('intval', $limit)) : 'LIMIT ' . (int)$limit;
156
-        $SQL = SP . '(SELECT * FROM ' . $this->_table_name . SP . $limit . ') AS ' . $this->_table_alias;
157
-        return $SQL;
158
-    }
159
-
160
-
161
-
162
-    /**
163
-     * Returns whether or not htis is a global table (ie, on multisite there's
164
-     * only one of these tables, on the main blog)
165
-     *
166
-     * @return boolean
167
-     */
168
-    public function is_global()
169
-    {
170
-        return $this->_global;
171
-    }
12
+	/**
13
+	 * This holds the table_name without the table prefix.
14
+	 *
15
+	 * @var string
16
+	 */
17
+	var $_table_name;
18
+
19
+
20
+	/**
21
+	 * This holds what is used as the alias for the table in queries.
22
+	 *
23
+	 * @var string
24
+	 */
25
+	var $_table_alias;
26
+
27
+
28
+	/**
29
+	 * Table's private key column
30
+	 *
31
+	 * @var string
32
+	 */
33
+	protected $_pk_column;
34
+
35
+
36
+	/**
37
+	 * Whether this table is a global table (in multisite) or specific to site.
38
+	 *
39
+	 * @var bool
40
+	 */
41
+	protected $_global;
42
+
43
+
44
+
45
+	/**
46
+	 * @global wpdb   $wpdb
47
+	 * @param string  $table_name with or without wpdb prefix
48
+	 * @param string  $pk_column
49
+	 * @param boolean $global     whether the table is "global" as in there is only 1 table on an entire multisite
50
+	 *                            install, or whether each site on a multisite install has a copy of this table
51
+	 */
52
+	function __construct($table_name, $pk_column, $global = false)
53
+	{
54
+		$this->_global = $global;
55
+		$prefix = $this->get_table_prefix();
56
+		//if they added the prefix, let's remove it because we delay adding the prefix until right when its needed.
57
+		if (strpos($table_name, $prefix) === 0) {
58
+			$table_name = ltrim($table_name, $prefix);
59
+		}
60
+		$this->_table_name = $table_name;
61
+		$this->_pk_column = $pk_column;
62
+	}
63
+
64
+
65
+
66
+	/**
67
+	 * This returns the table prefix for the current model state.
68
+	 *
69
+	 * @global wpdb $wpdb
70
+	 * @return string
71
+	 */
72
+	public function get_table_prefix()
73
+	{
74
+		global $wpdb;
75
+		if ($this->_global) {
76
+			$prefix = $wpdb->base_prefix;
77
+		} else {
78
+			$prefix = $wpdb->get_blog_prefix(EEM_Base::get_model_query_blog_id());
79
+		}
80
+		return $prefix;
81
+	}
82
+
83
+
84
+
85
+	/**
86
+	 * Used to set the table_alias property
87
+	 *
88
+	 * @param string $table_alias
89
+	 */
90
+	function _construct_finalize_with_alias($table_alias)
91
+	{
92
+		$this->_table_alias = $table_alias;
93
+	}
94
+
95
+
96
+
97
+	/**
98
+	 * Returns the fully qualified table name for the database (includes the table prefix current for the blog).
99
+	 *
100
+	 * @return string
101
+	 */
102
+	function get_table_name()
103
+	{
104
+		return $this->get_table_prefix() . $this->_table_name;
105
+	}
106
+
107
+
108
+
109
+	/**
110
+	 * Provides what is currently set as the alias for the table to be used in queries.
111
+	 *
112
+	 * @return string
113
+	 * @throws EE_Error
114
+	 */
115
+	function get_table_alias()
116
+	{
117
+		if ( ! $this->_table_alias) {
118
+			throw new EE_Error("You must call _construct_finalize_with_alias before using the EE_Table_Base. Did you forget to call parent::__construct at the end of your EEMerimental_Base child's __construct?");
119
+		}
120
+		return $this->_table_alias;
121
+	}
122
+
123
+
124
+
125
+	/**
126
+	 * @return string name of column of PK
127
+	 */
128
+	function get_pk_column()
129
+	{
130
+		return $this->_pk_column;
131
+	}
132
+
133
+
134
+
135
+	/**
136
+	 * returns a string with the table alias, a period, and the private key's column.
137
+	 *
138
+	 * @return string
139
+	 */
140
+	function get_fully_qualified_pk_column()
141
+	{
142
+		$sql = $this->get_table_alias() . "." . $this->get_pk_column();
143
+		return $sql;
144
+	}
145
+
146
+
147
+
148
+	/**
149
+	 * returns the special sql for a inner select with a limit.
150
+	 *
151
+	 * @return string    SQL select
152
+	 */
153
+	public function get_select_join_limit($limit)
154
+	{
155
+		$limit = is_array($limit) ? 'LIMIT ' . implode(',', array_map('intval', $limit)) : 'LIMIT ' . (int)$limit;
156
+		$SQL = SP . '(SELECT * FROM ' . $this->_table_name . SP . $limit . ') AS ' . $this->_table_alias;
157
+		return $SQL;
158
+	}
159
+
160
+
161
+
162
+	/**
163
+	 * Returns whether or not htis is a global table (ie, on multisite there's
164
+	 * only one of these tables, on the main blog)
165
+	 *
166
+	 * @return boolean
167
+	 */
168
+	public function is_global()
169
+	{
170
+		return $this->_global;
171
+	}
172 172
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -101,7 +101,7 @@  discard block
 block discarded – undo
101 101
      */
102 102
     function get_table_name()
103 103
     {
104
-        return $this->get_table_prefix() . $this->_table_name;
104
+        return $this->get_table_prefix().$this->_table_name;
105 105
     }
106 106
 
107 107
 
@@ -139,7 +139,7 @@  discard block
 block discarded – undo
139 139
      */
140 140
     function get_fully_qualified_pk_column()
141 141
     {
142
-        $sql = $this->get_table_alias() . "." . $this->get_pk_column();
142
+        $sql = $this->get_table_alias().".".$this->get_pk_column();
143 143
         return $sql;
144 144
     }
145 145
 
@@ -152,8 +152,8 @@  discard block
 block discarded – undo
152 152
      */
153 153
     public function get_select_join_limit($limit)
154 154
     {
155
-        $limit = is_array($limit) ? 'LIMIT ' . implode(',', array_map('intval', $limit)) : 'LIMIT ' . (int)$limit;
156
-        $SQL = SP . '(SELECT * FROM ' . $this->_table_name . SP . $limit . ') AS ' . $this->_table_alias;
155
+        $limit = is_array($limit) ? 'LIMIT '.implode(',', array_map('intval', $limit)) : 'LIMIT '.(int) $limit;
156
+        $SQL = SP.'(SELECT * FROM '.$this->_table_name.SP.$limit.') AS '.$this->_table_alias;
157 157
         return $SQL;
158 158
     }
159 159
 
Please login to merge, or discard this patch.
admin_pages/registrations/Registrations_Admin_Page.core.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1247,7 +1247,7 @@
 block discarded – undo
1247 1247
     /**
1248 1248
      * Sets up the limit for the registrations query.
1249 1249
      *
1250
-     * @param $per_page
1250
+     * @param integer $per_page
1251 1251
      * @return array
1252 1252
      */
1253 1253
     protected function _get_limit($per_page)
Please login to merge, or discard this patch.
Indentation   +3722 added lines, -3722 removed lines patch added patch discarded remove patch
@@ -30,2339 +30,2339 @@  discard block
 block discarded – undo
30 30
 class Registrations_Admin_Page extends EE_Admin_Page_CPT
31 31
 {
32 32
 
33
-    /**
34
-     * @var EE_Registration
35
-     */
36
-    private $_registration;
37
-
38
-    /**
39
-     * @var EE_Event
40
-     */
41
-    private $_reg_event;
42
-
43
-    /**
44
-     * @var EE_Session
45
-     */
46
-    private $_session;
47
-
48
-    private static $_reg_status;
49
-
50
-    /**
51
-     * Form for displaying the custom questions for this registration.
52
-     * This gets used a few times throughout the request so its best to cache it
53
-     *
54
-     * @var EE_Registration_Custom_Questions_Form
55
-     */
56
-    protected $_reg_custom_questions_form = null;
57
-
58
-
59
-    /**
60
-     *        constructor
61
-     *
62
-     * @Constructor
63
-     * @access public
64
-     * @param bool $routing
65
-     * @return Registrations_Admin_Page
66
-     */
67
-    public function __construct($routing = true)
68
-    {
69
-        parent::__construct($routing);
70
-        add_action('wp_loaded', array($this, 'wp_loaded'));
71
-    }
72
-
73
-
74
-    public function wp_loaded()
75
-    {
76
-        // when adding a new registration...
77
-        if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
78
-            EE_System::do_not_cache();
79
-            if (! isset($this->_req_data['processing_registration'])
80
-                 || absint($this->_req_data['processing_registration']) !== 1
81
-            ) {
82
-                // and it's NOT the attendee information reg step
83
-                // force cookie expiration by setting time to last week
84
-                setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
85
-                // and update the global
86
-                $_COOKIE['ee_registration_added'] = 0;
87
-            }
88
-        }
89
-    }
90
-
91
-
92
-    protected function _init_page_props()
93
-    {
94
-        $this->page_slug        = REG_PG_SLUG;
95
-        $this->_admin_base_url  = REG_ADMIN_URL;
96
-        $this->_admin_base_path = REG_ADMIN;
97
-        $this->page_label       = esc_html__('Registrations', 'event_espresso');
98
-        $this->_cpt_routes      = array(
99
-            'add_new_attendee' => 'espresso_attendees',
100
-            'edit_attendee'    => 'espresso_attendees',
101
-            'insert_attendee'  => 'espresso_attendees',
102
-            'update_attendee'  => 'espresso_attendees',
103
-        );
104
-        $this->_cpt_model_names = array(
105
-            'add_new_attendee' => 'EEM_Attendee',
106
-            'edit_attendee'    => 'EEM_Attendee',
107
-        );
108
-        $this->_cpt_edit_routes = array(
109
-            'espresso_attendees' => 'edit_attendee',
110
-        );
111
-        $this->_pagenow_map     = array(
112
-            'add_new_attendee' => 'post-new.php',
113
-            'edit_attendee'    => 'post.php',
114
-            'trash'            => 'post.php',
115
-        );
116
-        add_action('edit_form_after_title', array($this, 'after_title_form_fields'), 10);
117
-        //add filters so that the comment urls don't take users to a confusing 404 page
118
-        add_filter('get_comment_link', array($this, 'clear_comment_link'), 10, 3);
119
-    }
120
-
121
-
122
-    public function clear_comment_link($link, $comment, $args)
123
-    {
124
-        //gotta make sure this only happens on this route
125
-        $post_type = get_post_type($comment->comment_post_ID);
126
-        if ($post_type === 'espresso_attendees') {
127
-            return '#commentsdiv';
128
-        }
129
-        return $link;
130
-    }
131
-
132
-
133
-    protected function _ajax_hooks()
134
-    {
135
-        //todo: all hooks for registrations ajax goes in here
136
-        add_action('wp_ajax_toggle_checkin_status', array($this, 'toggle_checkin_status'));
137
-    }
138
-
139
-
140
-    protected function _define_page_props()
141
-    {
142
-        $this->_admin_page_title = $this->page_label;
143
-        $this->_labels           = array(
144
-            'buttons'                      => array(
145
-                'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
146
-                'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
147
-                'edit'                => esc_html__('Edit Contact', 'event_espresso'),
148
-                'report'              => esc_html__("Event Registrations CSV Report", "event_espresso"),
149
-                'report_all'          => esc_html__('All Registrations CSV Report', 'event_espresso'),
150
-                'report_filtered'     => esc_html__('Filtered CSV Report', 'event_espresso'),
151
-                'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
152
-                'contact_list_export' => esc_html__("Export Data", "event_espresso"),
153
-            ),
154
-            'publishbox'                   => array(
155
-                'add_new_attendee' => esc_html__("Add Contact Record", 'event_espresso'),
156
-                'edit_attendee'    => esc_html__("Update Contact Record", 'event_espresso'),
157
-            ),
158
-            'hide_add_button_on_cpt_route' => array(
159
-                'edit_attendee' => true,
160
-            ),
161
-        );
162
-    }
163
-
164
-
165
-    /**
166
-     *        grab url requests and route them
167
-     *
168
-     * @access private
169
-     * @return void
170
-     */
171
-    public function _set_page_routes()
172
-    {
173
-        $this->_get_registration_status_array();
174
-        $reg_id             = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
175
-            ? $this->_req_data['_REG_ID'] : 0;
176
-        $reg_id = empty($reg_id) && ! empty($this->_req_data['reg_status_change_form']['REG_ID'])
177
-            ? $this->_req_data['reg_status_change_form']['REG_ID']
178
-            : $reg_id;
179
-        $att_id             = ! empty($this->_req_data['ATT_ID']) && ! is_array($this->_req_data['ATT_ID'])
180
-            ? $this->_req_data['ATT_ID'] : 0;
181
-        $att_id             = ! empty($this->_req_data['post']) && ! is_array($this->_req_data['post'])
182
-            ? $this->_req_data['post']
183
-            : $att_id;
184
-        $this->_page_routes = array(
185
-            'default'                            => array(
186
-                'func'       => '_registrations_overview_list_table',
187
-                'capability' => 'ee_read_registrations',
188
-            ),
189
-            'view_registration'                  => array(
190
-                'func'       => '_registration_details',
191
-                'capability' => 'ee_read_registration',
192
-                'obj_id'     => $reg_id,
193
-            ),
194
-            'edit_registration'                  => array(
195
-                'func'               => '_update_attendee_registration_form',
196
-                'noheader'           => true,
197
-                'headers_sent_route' => 'view_registration',
198
-                'capability'         => 'ee_edit_registration',
199
-                'obj_id'             => $reg_id,
200
-                '_REG_ID'            => $reg_id,
201
-            ),
202
-            'trash_registrations'                => array(
203
-                'func'       => '_trash_or_restore_registrations',
204
-                'args'       => array('trash' => true),
205
-                'noheader'   => true,
206
-                'capability' => 'ee_delete_registrations',
207
-            ),
208
-            'restore_registrations'              => array(
209
-                'func'       => '_trash_or_restore_registrations',
210
-                'args'       => array('trash' => false),
211
-                'noheader'   => true,
212
-                'capability' => 'ee_delete_registrations',
213
-            ),
214
-            'delete_registrations'               => array(
215
-                'func'       => '_delete_registrations',
216
-                'noheader'   => true,
217
-                'capability' => 'ee_delete_registrations',
218
-            ),
219
-            'new_registration'                   => array(
220
-                'func'       => 'new_registration',
221
-                'capability' => 'ee_edit_registrations',
222
-            ),
223
-            'process_reg_step'                   => array(
224
-                'func'       => 'process_reg_step',
225
-                'noheader'   => true,
226
-                'capability' => 'ee_edit_registrations',
227
-            ),
228
-            'redirect_to_txn'                    => array(
229
-                'func'       => 'redirect_to_txn',
230
-                'noheader'   => true,
231
-                'capability' => 'ee_edit_registrations',
232
-            ),
233
-            'change_reg_status'                  => array(
234
-                'func'       => '_change_reg_status',
235
-                'noheader'   => true,
236
-                'capability' => 'ee_edit_registration',
237
-                'obj_id'     => $reg_id,
238
-            ),
239
-            'approve_registration'               => array(
240
-                'func'       => 'approve_registration',
241
-                'noheader'   => true,
242
-                'capability' => 'ee_edit_registration',
243
-                'obj_id'     => $reg_id,
244
-            ),
245
-            'approve_and_notify_registration'    => array(
246
-                'func'       => 'approve_registration',
247
-                'noheader'   => true,
248
-                'args'       => array(true),
249
-                'capability' => 'ee_edit_registration',
250
-                'obj_id'     => $reg_id,
251
-            ),
252
-            'approve_registrations'               => array(
253
-                'func'       => 'bulk_action_on_registrations',
254
-                'noheader'   => true,
255
-                'capability' => 'ee_edit_registrations',
256
-                'args' => array('approve')
257
-            ),
258
-            'approve_and_notify_registrations'               => array(
259
-                'func'       => 'bulk_action_on_registrations',
260
-                'noheader'   => true,
261
-                'capability' => 'ee_edit_registrations',
262
-                'args' => array('approve', true)
263
-            ),
264
-            'decline_registration'               => array(
265
-                'func'       => 'decline_registration',
266
-                'noheader'   => true,
267
-                'capability' => 'ee_edit_registration',
268
-                'obj_id'     => $reg_id,
269
-            ),
270
-            'decline_and_notify_registration'    => array(
271
-                'func'       => 'decline_registration',
272
-                'noheader'   => true,
273
-                'args'       => array(true),
274
-                'capability' => 'ee_edit_registration',
275
-                'obj_id'     => $reg_id,
276
-            ),
277
-            'decline_registrations'               => array(
278
-                'func'       => 'bulk_action_on_registrations',
279
-                'noheader'   => true,
280
-                'capability' => 'ee_edit_registrations',
281
-                'args' => array('decline')
282
-            ),
283
-            'decline_and_notify_registrations'    => array(
284
-                'func'       => 'bulk_action_on_registrations',
285
-                'noheader'   => true,
286
-                'capability' => 'ee_edit_registrations',
287
-                'args' => array('decline', true)
288
-            ),
289
-            'pending_registration'               => array(
290
-                'func'       => 'pending_registration',
291
-                'noheader'   => true,
292
-                'capability' => 'ee_edit_registration',
293
-                'obj_id'     => $reg_id,
294
-            ),
295
-            'pending_and_notify_registration'    => array(
296
-                'func'       => 'pending_registration',
297
-                'noheader'   => true,
298
-                'args'       => array(true),
299
-                'capability' => 'ee_edit_registration',
300
-                'obj_id'     => $reg_id,
301
-            ),
302
-            'pending_registrations'               => array(
303
-                'func'       => 'bulk_action_on_registrations',
304
-                'noheader'   => true,
305
-                'capability' => 'ee_edit_registrations',
306
-                'args' => array('pending')
307
-            ),
308
-            'pending_and_notify_registrations'    => array(
309
-                'func'       => 'bulk_action_on_registrations',
310
-                'noheader'   => true,
311
-                'capability' => 'ee_edit_registrations',
312
-                'args' => array('pending', true)
313
-            ),
314
-            'no_approve_registration'            => array(
315
-                'func'       => 'not_approve_registration',
316
-                'noheader'   => true,
317
-                'capability' => 'ee_edit_registration',
318
-                'obj_id'     => $reg_id,
319
-            ),
320
-            'no_approve_and_notify_registration' => array(
321
-                'func'       => 'not_approve_registration',
322
-                'noheader'   => true,
323
-                'args'       => array(true),
324
-                'capability' => 'ee_edit_registration',
325
-                'obj_id'     => $reg_id,
326
-            ),
327
-            'no_approve_registrations'            => array(
328
-                'func'       => 'bulk_action_on_registrations',
329
-                'noheader'   => true,
330
-                'capability' => 'ee_edit_registrations',
331
-                'args' => array('not_approve')
332
-            ),
333
-            'no_approve_and_notify_registrations' => array(
334
-                'func'       => 'bulk_action_on_registrations',
335
-                'noheader'   => true,
336
-                'capability' => 'ee_edit_registrations',
337
-                'args' => array('not_approve', true)
338
-            ),
339
-            'cancel_registration'                => array(
340
-                'func'       => 'cancel_registration',
341
-                'noheader'   => true,
342
-                'capability' => 'ee_edit_registration',
343
-                'obj_id'     => $reg_id,
344
-            ),
345
-            'cancel_and_notify_registration'     => array(
346
-                'func'       => 'cancel_registration',
347
-                'noheader'   => true,
348
-                'args'       => array(true),
349
-                'capability' => 'ee_edit_registration',
350
-                'obj_id'     => $reg_id,
351
-            ),
352
-            'cancel_registrations'                => array(
353
-                'func'       => 'bulk_action_on_registrations',
354
-                'noheader'   => true,
355
-                'capability' => 'ee_edit_registrations',
356
-                'args' => array('cancel')
357
-            ),
358
-            'cancel_and_notify_registrations'     => array(
359
-                'func'       => 'bulk_action_on_registrations',
360
-                'noheader'   => true,
361
-                'capability' => 'ee_edit_registrations',
362
-                'args' => array('cancel', true)
363
-            ),
364
-            'wait_list_registration' => array(
365
-                'func'       => 'wait_list_registration',
366
-                'noheader'   => true,
367
-                'capability' => 'ee_edit_registration',
368
-                'obj_id'     => $reg_id,
369
-            ),
370
-            'wait_list_and_notify_registration' => array(
371
-                'func'       => 'wait_list_registration',
372
-                'noheader'   => true,
373
-                'args'       => array(true),
374
-                'capability' => 'ee_edit_registration',
375
-                'obj_id'     => $reg_id,
376
-            ),
377
-            'contact_list'                       => array(
378
-                'func'       => '_attendee_contact_list_table',
379
-                'capability' => 'ee_read_contacts',
380
-            ),
381
-            'add_new_attendee'                   => array(
382
-                'func' => '_create_new_cpt_item',
383
-                'args' => array(
384
-                    'new_attendee' => true,
385
-                    'capability'   => 'ee_edit_contacts',
386
-                ),
387
-            ),
388
-            'edit_attendee'                      => array(
389
-                'func'       => '_edit_cpt_item',
390
-                'capability' => 'ee_edit_contacts',
391
-                'obj_id'     => $att_id,
392
-            ),
393
-            'duplicate_attendee'                 => array(
394
-                'func'       => '_duplicate_attendee',
395
-                'noheader'   => true,
396
-                'capability' => 'ee_edit_contacts',
397
-                'obj_id'     => $att_id,
398
-            ),
399
-            'insert_attendee'                    => array(
400
-                'func'       => '_insert_or_update_attendee',
401
-                'args'       => array(
402
-                    'new_attendee' => true,
403
-                ),
404
-                'noheader'   => true,
405
-                'capability' => 'ee_edit_contacts',
406
-            ),
407
-            'update_attendee'                    => array(
408
-                'func'       => '_insert_or_update_attendee',
409
-                'args'       => array(
410
-                    'new_attendee' => false,
411
-                ),
412
-                'noheader'   => true,
413
-                'capability' => 'ee_edit_contacts',
414
-                'obj_id'     => $att_id,
415
-            ),
416
-            'trash_attendees' => array(
417
-                'func' => '_trash_or_restore_attendees',
418
-                'args' => array(
419
-                    'trash' => 'true'
420
-                ),
421
-                'noheader' => true,
422
-                'capability' => 'ee_delete_contacts'
423
-            ),
424
-            'trash_attendee'                    => array(
425
-                'func'       => '_trash_or_restore_attendees',
426
-                'args'       => array(
427
-                    'trash' => true,
428
-                ),
429
-                'noheader'   => true,
430
-                'capability' => 'ee_delete_contacts',
431
-                'obj_id'     => $att_id,
432
-            ),
433
-            'restore_attendees'                  => array(
434
-                'func'       => '_trash_or_restore_attendees',
435
-                'args'       => array(
436
-                    'trash' => false,
437
-                ),
438
-                'noheader'   => true,
439
-                'capability' => 'ee_delete_contacts',
440
-                'obj_id'     => $att_id,
441
-            ),
442
-            'resend_registration'                => array(
443
-                'func'       => '_resend_registration',
444
-                'noheader'   => true,
445
-                'capability' => 'ee_send_message',
446
-            ),
447
-            'registrations_report'               => array(
448
-                'func'       => '_registrations_report',
449
-                'noheader'   => true,
450
-                'capability' => 'ee_read_registrations',
451
-            ),
452
-            'contact_list_export'                => array(
453
-                'func'       => '_contact_list_export',
454
-                'noheader'   => true,
455
-                'capability' => 'export',
456
-            ),
457
-            'contact_list_report'                => array(
458
-                'func'       => '_contact_list_report',
459
-                'noheader'   => true,
460
-                'capability' => 'ee_read_contacts',
461
-            ),
462
-        );
463
-    }
464
-
465
-
466
-    protected function _set_page_config()
467
-    {
468
-        $this->_page_config = array(
469
-            'default'           => array(
470
-                'nav'           => array(
471
-                    'label' => esc_html__('Overview', 'event_espresso'),
472
-                    'order' => 5,
473
-                ),
474
-                'help_tabs'     => array(
475
-                    'registrations_overview_help_tab'                       => array(
476
-                        'title'    => esc_html__('Registrations Overview', 'event_espresso'),
477
-                        'filename' => 'registrations_overview',
478
-                    ),
479
-                    'registrations_overview_table_column_headings_help_tab' => array(
480
-                        'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
481
-                        'filename' => 'registrations_overview_table_column_headings',
482
-                    ),
483
-                    'registrations_overview_filters_help_tab'               => array(
484
-                        'title'    => esc_html__('Registration Filters', 'event_espresso'),
485
-                        'filename' => 'registrations_overview_filters',
486
-                    ),
487
-                    'registrations_overview_views_help_tab'                 => array(
488
-                        'title'    => esc_html__('Registration Views', 'event_espresso'),
489
-                        'filename' => 'registrations_overview_views',
490
-                    ),
491
-                    'registrations_regoverview_other_help_tab'              => array(
492
-                        'title'    => esc_html__('Registrations Other', 'event_espresso'),
493
-                        'filename' => 'registrations_overview_other',
494
-                    ),
495
-                ),
496
-                'help_tour'     => array('Registration_Overview_Help_Tour'),
497
-                'qtips'         => array('Registration_List_Table_Tips'),
498
-                'list_table'    => 'EE_Registrations_List_Table',
499
-                'require_nonce' => false,
500
-            ),
501
-            'view_registration' => array(
502
-                'nav'           => array(
503
-                    'label'      => esc_html__('REG Details', 'event_espresso'),
504
-                    'order'      => 15,
505
-                    'url'        => isset($this->_req_data['_REG_ID'])
506
-                        ? add_query_arg(array('_REG_ID' => $this->_req_data['_REG_ID']), $this->_current_page_view_url)
507
-                        : $this->_admin_base_url,
508
-                    'persistent' => false,
509
-                ),
510
-                'help_tabs'     => array(
511
-                    'registrations_details_help_tab'                    => array(
512
-                        'title'    => esc_html__('Registration Details', 'event_espresso'),
513
-                        'filename' => 'registrations_details',
514
-                    ),
515
-                    'registrations_details_table_help_tab'              => array(
516
-                        'title'    => esc_html__('Registration Details Table', 'event_espresso'),
517
-                        'filename' => 'registrations_details_table',
518
-                    ),
519
-                    'registrations_details_form_answers_help_tab'       => array(
520
-                        'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
521
-                        'filename' => 'registrations_details_form_answers',
522
-                    ),
523
-                    'registrations_details_registrant_details_help_tab' => array(
524
-                        'title'    => esc_html__('Contact Details', 'event_espresso'),
525
-                        'filename' => 'registrations_details_registrant_details',
526
-                    ),
527
-                ),
528
-                'help_tour'     => array('Registration_Details_Help_Tour'),
529
-                'metaboxes'     => array_merge(
530
-                    $this->_default_espresso_metaboxes,
531
-                    array('_registration_details_metaboxes')
532
-                ),
533
-                'require_nonce' => false,
534
-            ),
535
-            'new_registration'  => array(
536
-                'nav'           => array(
537
-                    'label'      => esc_html__('Add New Registration', 'event_espresso'),
538
-                    'url'        => '#',
539
-                    'order'      => 15,
540
-                    'persistent' => false,
541
-                ),
542
-                'metaboxes'     => $this->_default_espresso_metaboxes,
543
-                'labels'        => array(
544
-                    'publishbox' => esc_html__('Save Registration', 'event_espresso'),
545
-                ),
546
-                'require_nonce' => false,
547
-            ),
548
-            'add_new_attendee'  => array(
549
-                'nav'           => array(
550
-                    'label'      => esc_html__('Add Contact', 'event_espresso'),
551
-                    'order'      => 15,
552
-                    'persistent' => false,
553
-                ),
554
-                'metaboxes'     => array_merge(
555
-                    $this->_default_espresso_metaboxes,
556
-                    array('_publish_post_box', 'attendee_editor_metaboxes')
557
-                ),
558
-                'require_nonce' => false,
559
-            ),
560
-            'edit_attendee'     => array(
561
-                'nav'           => array(
562
-                    'label'      => esc_html__('Edit Contact', 'event_espresso'),
563
-                    'order'      => 15,
564
-                    'persistent' => false,
565
-                    'url'        => isset($this->_req_data['ATT_ID'])
566
-                        ? add_query_arg(array('ATT_ID' => $this->_req_data['ATT_ID']), $this->_current_page_view_url)
567
-                        : $this->_admin_base_url,
568
-                ),
569
-                'metaboxes'     => array('attendee_editor_metaboxes'),
570
-                'require_nonce' => false,
571
-            ),
572
-            'contact_list'      => array(
573
-                'nav'           => array(
574
-                    'label' => esc_html__('Contact List', 'event_espresso'),
575
-                    'order' => 20,
576
-                ),
577
-                'list_table'    => 'EE_Attendee_Contact_List_Table',
578
-                'help_tabs'     => array(
579
-                    'registrations_contact_list_help_tab'                       => array(
580
-                        'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
581
-                        'filename' => 'registrations_contact_list',
582
-                    ),
583
-                    'registrations_contact-list_table_column_headings_help_tab' => array(
584
-                        'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
585
-                        'filename' => 'registrations_contact_list_table_column_headings',
586
-                    ),
587
-                    'registrations_contact_list_views_help_tab'                 => array(
588
-                        'title'    => esc_html__('Contact List Views', 'event_espresso'),
589
-                        'filename' => 'registrations_contact_list_views',
590
-                    ),
591
-                    'registrations_contact_list_other_help_tab'                 => array(
592
-                        'title'    => esc_html__('Contact List Other', 'event_espresso'),
593
-                        'filename' => 'registrations_contact_list_other',
594
-                    ),
595
-                ),
596
-                'help_tour'     => array('Contact_List_Help_Tour'),
597
-                'metaboxes'     => array(),
598
-                'require_nonce' => false,
599
-            ),
600
-            //override default cpt routes
601
-            'create_new'        => '',
602
-            'edit'              => '',
603
-        );
604
-    }
605
-
606
-
607
-    /**
608
-     * The below methods aren't used by this class currently
609
-     */
610
-    protected function _add_screen_options()
611
-    {
612
-    }
613
-
614
-
615
-    protected function _add_feature_pointers()
616
-    {
617
-    }
618
-
619
-
620
-    public function admin_init()
621
-    {
622
-        EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
623
-            'click "Update Registration Questions" to save your changes',
624
-            'event_espresso'
625
-        );
626
-    }
627
-
628
-
629
-    public function admin_notices()
630
-    {
631
-    }
632
-
633
-
634
-    public function admin_footer_scripts()
635
-    {
636
-    }
637
-
638
-
639
-    /**
640
-     *        get list of registration statuses
641
-     *
642
-     * @access private
643
-     * @return void
644
-     * @throws EE_Error
645
-     */
646
-    private function _get_registration_status_array()
647
-    {
648
-        self::$_reg_status = EEM_Registration::reg_status_array(array(), true);
649
-    }
650
-
651
-
652
-    protected function _add_screen_options_default()
653
-    {
654
-        $this->_per_page_screen_option();
655
-    }
656
-
657
-
658
-    protected function _add_screen_options_contact_list()
659
-    {
660
-        $page_title              = $this->_admin_page_title;
661
-        $this->_admin_page_title = esc_html__("Contacts", 'event_espresso');
662
-        $this->_per_page_screen_option();
663
-        $this->_admin_page_title = $page_title;
664
-    }
665
-
666
-
667
-    public function load_scripts_styles()
668
-    {
669
-        //style
670
-        wp_register_style(
671
-            'espresso_reg',
672
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
673
-            array('ee-admin-css'),
674
-            EVENT_ESPRESSO_VERSION
675
-        );
676
-        wp_enqueue_style('espresso_reg');
677
-        //script
678
-        wp_register_script(
679
-            'espresso_reg',
680
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
681
-            array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'),
682
-            EVENT_ESPRESSO_VERSION,
683
-            true
684
-        );
685
-        wp_enqueue_script('espresso_reg');
686
-    }
687
-
688
-
689
-    public function load_scripts_styles_edit_attendee()
690
-    {
691
-        //stuff to only show up on our attendee edit details page.
692
-        $attendee_details_translations = array(
693
-            'att_publish_text' => sprintf(
694
-                esc_html__('Created on: <b>%1$s</b>', 'event_espresso'),
695
-                $this->_cpt_model_obj->get_datetime('ATT_created')
696
-            ),
697
-        );
698
-        wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
699
-        wp_enqueue_script('jquery-validate');
700
-    }
701
-
702
-
703
-    public function load_scripts_styles_view_registration()
704
-    {
705
-        //styles
706
-        wp_enqueue_style('espresso-ui-theme');
707
-        //scripts
708
-        $this->_get_reg_custom_questions_form($this->_registration->ID());
709
-        $this->_reg_custom_questions_form->wp_enqueue_scripts(true);
710
-    }
711
-
712
-
713
-    public function load_scripts_styles_contact_list()
714
-    {
715
-        wp_dequeue_style('espresso_reg');
716
-        wp_register_style(
717
-            'espresso_att',
718
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
719
-            array('ee-admin-css'),
720
-            EVENT_ESPRESSO_VERSION
721
-        );
722
-        wp_enqueue_style('espresso_att');
723
-    }
724
-
725
-
726
-    public function load_scripts_styles_new_registration()
727
-    {
728
-        wp_register_script(
729
-            'ee-spco-for-admin',
730
-            REG_ASSETS_URL . 'spco_for_admin.js',
731
-            array('underscore', 'jquery'),
732
-            EVENT_ESPRESSO_VERSION,
733
-            true
734
-        );
735
-        wp_enqueue_script('ee-spco-for-admin');
736
-        add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
737
-        EE_Form_Section_Proper::wp_enqueue_scripts();
738
-        EED_Ticket_Selector::load_tckt_slctr_assets();
739
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
740
-    }
741
-
742
-
743
-    public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
744
-    {
745
-        add_filter('FHEE_load_EE_messages', '__return_true');
746
-    }
747
-
748
-
749
-    public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
750
-    {
751
-        add_filter('FHEE_load_EE_messages', '__return_true');
752
-    }
753
-
754
-
755
-    protected function _set_list_table_views_default()
756
-    {
757
-        //for notification related bulk actions we need to make sure only active messengers have an option.
758
-        EED_Messages::set_autoloaders();
759
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
760
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
761
-        $active_mts               = $message_resource_manager->list_of_active_message_types();
762
-        //key= bulk_action_slug, value= message type.
763
-        $match_array = array(
764
-            'approve_registrations'    => 'registration',
765
-            'decline_registrations'    => 'declined_registration',
766
-            'pending_registrations'    => 'pending_approval',
767
-            'no_approve_registrations' => 'not_approved_registration',
768
-            'cancel_registrations'     => 'cancelled_registration',
769
-        );
770
-        $can_send = EE_Registry::instance()->CAP->current_user_can(
771
-            'ee_send_message',
772
-            'batch_send_messages'
773
-        );
774
-        /** setup reg status bulk actions **/
775
-        $def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
776
-        if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
777
-                $def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
778
-                    'Approve and Notify Registrations',
779
-                    'event_espresso'
780
-                );
781
-        }
782
-        $def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
783
-        if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
784
-                $def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
785
-                    'Decline and Notify Registrations',
786
-                    'event_espresso'
787
-                );
788
-        }
789
-        $def_reg_status_actions['pending_registrations'] = esc_html__(
790
-            'Set Registrations to Pending Payment',
791
-            'event_espresso'
792
-        );
793
-        if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
794
-                $def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
795
-                    'Set Registrations to Pending Payment and Notify',
796
-                    'event_espresso'
797
-                );
798
-        }
799
-        $def_reg_status_actions['no_approve_registrations'] = esc_html__(
800
-            'Set Registrations to Not Approved',
801
-            'event_espresso'
802
-        );
803
-        if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
804
-                $def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
805
-                    'Set Registrations to Not Approved and Notify',
806
-                    'event_espresso'
807
-                );
808
-        }
809
-        $def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
810
-        if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
811
-                $def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
812
-                    'Cancel Registrations and Notify',
813
-                    'event_espresso'
814
-                );
815
-        }
816
-        $def_reg_status_actions = apply_filters(
817
-            'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
818
-            $def_reg_status_actions,
819
-            $active_mts,
820
-            $can_send
821
-        );
822
-
823
-        $this->_views = array(
824
-            'all'   => array(
825
-                'slug'        => 'all',
826
-                'label'       => esc_html__('View All Registrations', 'event_espresso'),
827
-                'count'       => 0,
828
-                'bulk_action' => array_merge($def_reg_status_actions, array(
829
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
830
-                )),
831
-            ),
832
-            'month' => array(
833
-                'slug'        => 'month',
834
-                'label'       => esc_html__('This Month', 'event_espresso'),
835
-                'count'       => 0,
836
-                'bulk_action' => array_merge($def_reg_status_actions, array(
837
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
838
-                )),
839
-            ),
840
-            'today' => array(
841
-                'slug'        => 'today',
842
-                'label'       => sprintf(
843
-                    esc_html__('Today - %s', 'event_espresso'),
844
-                    date('M d, Y', current_time('timestamp'))
845
-                ),
846
-                'count'       => 0,
847
-                'bulk_action' => array_merge($def_reg_status_actions, array(
848
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
849
-                )),
850
-            ),
851
-        );
852
-        if (EE_Registry::instance()->CAP->current_user_can(
853
-            'ee_delete_registrations',
854
-            'espresso_registrations_delete_registration'
855
-        )) {
856
-            $this->_views['incomplete'] = array(
857
-                'slug'        => 'incomplete',
858
-                'label'       => esc_html__('Incomplete', 'event_espresso'),
859
-                'count'       => 0,
860
-                'bulk_action' => array(
861
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
862
-                ),
863
-            );
864
-            $this->_views['trash']      = array(
865
-                'slug'        => 'trash',
866
-                'label'       => esc_html__('Trash', 'event_espresso'),
867
-                'count'       => 0,
868
-                'bulk_action' => array(
869
-                    'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
870
-                    'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
871
-                ),
872
-            );
873
-        }
874
-    }
875
-
876
-
877
-    protected function _set_list_table_views_contact_list()
878
-    {
879
-        $this->_views = array(
880
-            'in_use' => array(
881
-                'slug'        => 'in_use',
882
-                'label'       => esc_html__('In Use', 'event_espresso'),
883
-                'count'       => 0,
884
-                'bulk_action' => array(
885
-                    'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
886
-                ),
887
-            ),
888
-        );
889
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_contacts',
890
-            'espresso_registrations_trash_attendees')
891
-        ) {
892
-            $this->_views['trash'] = array(
893
-                'slug'        => 'trash',
894
-                'label'       => esc_html__('Trash', 'event_espresso'),
895
-                'count'       => 0,
896
-                'bulk_action' => array(
897
-                    'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
898
-                ),
899
-            );
900
-        }
901
-    }
902
-
903
-
904
-    protected function _registration_legend_items()
905
-    {
906
-        $fc_items = array(
907
-            'star-icon'        => array(
908
-                'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8',
909
-                'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
910
-            ),
911
-            'view_details'     => array(
912
-                'class' => 'dashicons dashicons-clipboard',
913
-                'desc'  => esc_html__('View Registration Details', 'event_espresso'),
914
-            ),
915
-            'edit_attendee'    => array(
916
-                'class' => 'ee-icon ee-icon-user-edit ee-icon-size-16',
917
-                'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
918
-            ),
919
-            'view_transaction' => array(
920
-                'class' => 'dashicons dashicons-cart',
921
-                'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
922
-            ),
923
-            'view_invoice'     => array(
924
-                'class' => 'dashicons dashicons-media-spreadsheet',
925
-                'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
926
-            ),
927
-        );
928
-        if (EE_Registry::instance()->CAP->current_user_can(
929
-            'ee_send_message',
930
-            'espresso_registrations_resend_registration'
931
-        )) {
932
-            $fc_items['resend_registration'] = array(
933
-                'class' => 'dashicons dashicons-email-alt',
934
-                'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
935
-            );
936
-        } else {
937
-            $fc_items['blank'] = array('class' => 'blank', 'desc' => '');
938
-        }
939
-        if (EE_Registry::instance()->CAP->current_user_can(
940
-            'ee_read_global_messages',
941
-            'view_filtered_messages'
942
-        )) {
943
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
944
-            if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
945
-                $fc_items['view_related_messages'] = array(
946
-                    'class' => $related_for_icon['css_class'],
947
-                    'desc'  => $related_for_icon['label'],
948
-                );
949
-            }
950
-        }
951
-        $sc_items = array(
952
-            'approved_status'   => array(
953
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
954
-                'desc'  => EEH_Template::pretty_status(
955
-                    EEM_Registration::status_id_approved,
956
-                    false,
957
-                    'sentence'
958
-                ),
959
-            ),
960
-            'pending_status'    => array(
961
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
962
-                'desc'  => EEH_Template::pretty_status(
963
-                    EEM_Registration::status_id_pending_payment,
964
-                    false,
965
-                    'sentence'
966
-                ),
967
-            ),
968
-            'wait_list'         => array(
969
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
970
-                'desc'  => EEH_Template::pretty_status(
971
-                    EEM_Registration::status_id_wait_list,
972
-                    false,
973
-                    'sentence'
974
-                ),
975
-            ),
976
-            'incomplete_status' => array(
977
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
978
-                'desc'  => EEH_Template::pretty_status(
979
-                    EEM_Registration::status_id_incomplete,
980
-                    false,
981
-                    'sentence'
982
-                ),
983
-            ),
984
-            'not_approved'      => array(
985
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
986
-                'desc'  => EEH_Template::pretty_status(
987
-                    EEM_Registration::status_id_not_approved,
988
-                    false,
989
-                    'sentence'
990
-                ),
991
-            ),
992
-            'declined_status'   => array(
993
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
994
-                'desc'  => EEH_Template::pretty_status(
995
-                    EEM_Registration::status_id_declined,
996
-                    false,
997
-                    'sentence'
998
-                ),
999
-            ),
1000
-            'cancelled_status'  => array(
1001
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
1002
-                'desc'  => EEH_Template::pretty_status(
1003
-                    EEM_Registration::status_id_cancelled,
1004
-                    false,
1005
-                    'sentence'
1006
-                ),
1007
-            ),
1008
-        );
1009
-        return array_merge($fc_items, $sc_items);
1010
-    }
1011
-
1012
-
1013
-
1014
-    /***************************************        REGISTRATION OVERVIEW        **************************************/
1015
-    /**
1016
-     * @throws \EE_Error
1017
-     */
1018
-    protected function _registrations_overview_list_table()
1019
-    {
1020
-        $this->_template_args['admin_page_header'] = '';
1021
-        $EVT_ID                                    = ! empty($this->_req_data['event_id'])
1022
-            ? absint($this->_req_data['event_id'])
1023
-            : 0;
1024
-        $ATT_ID = !empty($this->_req_data['ATT_ID'])
1025
-            ? absint($this->_req_data['ATT_ID'])
1026
-            : 0;
1027
-        if ($ATT_ID) {
1028
-            $attendee = EEM_Attendee::instance()->get_one_by_ID($ATT_ID);
1029
-            if ($attendee instanceof EE_Attendee) {
1030
-                $this->_template_args['admin_page_header'] = sprintf(
1031
-                    esc_html__(
1032
-                        '%1$s Viewing registrations for %2$s%3$s',
1033
-                        'event_espresso'
1034
-                    ),
1035
-                    '<h3 style="line-height:1.5em;">',
1036
-                    '<a href="' . EE_Admin_Page::add_query_args_and_nonce(
1037
-                        array(
1038
-                            'action' => 'edit_attendee',
1039
-                            'post' => $ATT_ID
1040
-                        ),
1041
-                        REG_ADMIN_URL
1042
-                    ) . '">' . $attendee->full_name() . '</a>',
1043
-                    '</h3>'
1044
-                );
1045
-            }
1046
-        }
1047
-        if ($EVT_ID) {
1048
-            if (EE_Registry::instance()->CAP->current_user_can(
1049
-                'ee_edit_registrations',
1050
-                'espresso_registrations_new_registration',
1051
-                $EVT_ID
1052
-            )) {
1053
-                $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1054
-                    'new_registration',
1055
-                    'add-registrant',
1056
-                    array('event_id' => $EVT_ID),
1057
-                    'add-new-h2'
1058
-                );
1059
-            }
1060
-            $event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
1061
-            if ($event instanceof EE_Event) {
1062
-                $this->_template_args['admin_page_header'] = sprintf(
1063
-                    esc_html__(
1064
-                        '%s Viewing registrations for the event: %s%s',
1065
-                        'event_espresso'
1066
-                    ),
1067
-                    '<h3 style="line-height:1.5em;">',
1068
-                    '<br /><a href="'
1069
-                        . EE_Admin_Page::add_query_args_and_nonce(
1070
-                            array(
1071
-                                'action' => 'edit',
1072
-                                'post'   => $event->ID(),
1073
-                            ),
1074
-                            EVENTS_ADMIN_URL
1075
-                        )
1076
-                        . '">&nbsp;'
1077
-                        . $event->get('EVT_name')
1078
-                        . '&nbsp;</a>&nbsp;',
1079
-                    '</h3>'
1080
-                );
1081
-            }
1082
-            $DTT_ID   = ! empty($this->_req_data['datetime_id']) ? absint($this->_req_data['datetime_id']) : 0;
1083
-            $datetime = EEM_Datetime::instance()->get_one_by_ID($DTT_ID);
1084
-            if ($datetime instanceof EE_Datetime && $this->_template_args['admin_page_header'] !== '') {
1085
-                $this->_template_args['admin_page_header'] = substr(
1086
-                    $this->_template_args['admin_page_header'],
1087
-                    0,
1088
-                    -5
1089
-                );
1090
-                $this->_template_args['admin_page_header'] .= ' &nbsp;<span class="drk-grey-text">';
1091
-                $this->_template_args['admin_page_header'] .= '<span class="dashicons dashicons-calendar"></span>';
1092
-                $this->_template_args['admin_page_header'] .= $datetime->name();
1093
-                $this->_template_args['admin_page_header'] .= ' ( ' . $datetime->start_date() . ' )';
1094
-                $this->_template_args['admin_page_header'] .= '</span></h3>';
1095
-            }
1096
-        }
1097
-        $this->_template_args['after_list_table'] = $this->_display_legend($this->_registration_legend_items());
1098
-        $this->display_admin_list_table_page_with_no_sidebar();
1099
-    }
1100
-
1101
-
1102
-    /**
1103
-     * This sets the _registration property for the registration details screen
1104
-     *
1105
-     * @access private
1106
-     * @return bool
1107
-     * @throws EE_Error
1108
-     * @throws InvalidArgumentException
1109
-     * @throws InvalidDataTypeException
1110
-     * @throws InvalidInterfaceException
1111
-     */
1112
-    private function _set_registration_object()
1113
-    {
1114
-        //get out if we've already set the object
1115
-        if ($this->_registration instanceof EE_Registration) {
1116
-            return true;
1117
-        }
1118
-        $REG    = EEM_Registration::instance();
1119
-        $REG_ID = ( ! empty($this->_req_data['_REG_ID'])) ? absint($this->_req_data['_REG_ID']) : false;
1120
-        if ($this->_registration = $REG->get_one_by_ID($REG_ID)) {
1121
-            return true;
1122
-        } else {
1123
-            $error_msg = sprintf(
1124
-                esc_html__(
1125
-                    'An error occurred and the details for Registration ID #%s could not be retrieved.',
1126
-                    'event_espresso'
1127
-                ),
1128
-                $REG_ID
1129
-            );
1130
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1131
-            $this->_registration = null;
1132
-            return false;
1133
-        }
1134
-    }
1135
-
1136
-
1137
-    /**
1138
-     * Used to retrieve registrations for the list table.
1139
-     *
1140
-     * @param int  $per_page
1141
-     * @param bool $count
1142
-     * @param bool $this_month
1143
-     * @param bool $today
1144
-     * @return EE_Registration[]|int
1145
-     * @throws EE_Error
1146
-     * @throws InvalidArgumentException
1147
-     * @throws InvalidDataTypeException
1148
-     * @throws InvalidInterfaceException
1149
-     */
1150
-    public function get_registrations(
1151
-        $per_page = 10,
1152
-        $count = false,
1153
-        $this_month = false,
1154
-        $today = false
1155
-    ) {
1156
-        if ($this_month) {
1157
-            $this->_req_data['status'] = 'month';
1158
-        }
1159
-        if ($today) {
1160
-            $this->_req_data['status'] = 'today';
1161
-        }
1162
-        $query_params = $this->_get_registration_query_parameters($this->_req_data, $per_page, $count);
1163
-        /**
1164
-         * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1165
-         * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1166
-         * @see EEM_Base::get_all()
1167
-         */
1168
-        $query_params['group_by'] = '';
1169
-
1170
-        return $count
1171
-            ? EEM_Registration::instance()->count($query_params)
1172
-            /** @type EE_Registration[] */
1173
-            : EEM_Registration::instance()->get_all($query_params);
1174
-    }
1175
-
1176
-
1177
-    /**
1178
-     * Retrieves the query parameters to be used by the Registration model for getting registrations.
1179
-     * Note: this listens to values on the request for some of the query parameters.
1180
-     *
1181
-     * @param array $request
1182
-     * @param int   $per_page
1183
-     * @param bool  $count
1184
-     * @return array
1185
-     * @throws EE_Error
1186
-     */
1187
-    protected function _get_registration_query_parameters(
1188
-        $request = array(),
1189
-        $per_page = 10,
1190
-        $count = false
1191
-    ) {
1192
-
1193
-        $query_params = array(
1194
-            0                          => $this->_get_where_conditions_for_registrations_query(
1195
-                $request
1196
-            ),
1197
-            'caps'                     => EEM_Registration::caps_read_admin,
1198
-            'default_where_conditions' => 'this_model_only',
1199
-        );
1200
-        if (! $count) {
1201
-            $query_params = array_merge(
1202
-                $query_params,
1203
-                $this->_get_orderby_for_registrations_query(),
1204
-                $this->_get_limit($per_page)
1205
-            );
1206
-        }
1207
-
1208
-        return $query_params;
1209
-    }
1210
-
1211
-
1212
-    /**
1213
-     * This will add ATT_ID to the provided $where array for EE model query parameters.
1214
-     *
1215
-     * @param array $request usually the same as $this->_req_data but not necessarily
1216
-     * @return array
1217
-     */
1218
-    protected function addAttendeeIdToWhereConditions(array $request)
1219
-    {
1220
-        $where = array();
1221
-        if (! empty($request['ATT_ID'])) {
1222
-            $where['ATT_ID'] = absint($request['ATT_ID']);
1223
-        }
1224
-        return $where;
1225
-    }
1226
-
1227
-
1228
-    /**
1229
-     * This will add EVT_ID to the provided $where array for EE model query parameters.
1230
-     *
1231
-     * @param array $request usually the same as $this->_req_data but not necessarily
1232
-     * @return array
1233
-     */
1234
-    protected function _add_event_id_to_where_conditions(array $request)
1235
-    {
1236
-        $where = array();
1237
-        if (! empty($request['event_id'])) {
1238
-            $where['EVT_ID'] = absint($request['event_id']);
1239
-        }
1240
-        return $where;
1241
-    }
1242
-
1243
-
1244
-    /**
1245
-     * Adds category ID if it exists in the request to the where conditions for the registrations query.
1246
-     *
1247
-     * @param array $request usually the same as $this->_req_data but not necessarily
1248
-     * @return array
1249
-     */
1250
-    protected function _add_category_id_to_where_conditions(array $request)
1251
-    {
1252
-        $where = array();
1253
-        if (! empty($request['EVT_CAT']) && (int)$request['EVT_CAT'] !== -1) {
1254
-            $where['Event.Term_Taxonomy.term_id'] = absint($request['EVT_CAT']);
1255
-        }
1256
-        return $where;
1257
-    }
1258
-
1259
-
1260
-    /**
1261
-     * Adds the datetime ID if it exists in the request to the where conditions for the registrations query.
1262
-     *
1263
-     * @param array $request usually the same as $this->_req_data but not necessarily
1264
-     * @return array
1265
-     */
1266
-    protected function _add_datetime_id_to_where_conditions(array $request)
1267
-    {
1268
-        $where = array();
1269
-        if (! empty($request['datetime_id'])) {
1270
-            $where['Ticket.Datetime.DTT_ID'] = absint($request['datetime_id']);
1271
-        }
1272
-        if (! empty($request['DTT_ID'])) {
1273
-            $where['Ticket.Datetime.DTT_ID'] = absint($request['DTT_ID']);
1274
-        }
1275
-        return $where;
1276
-    }
1277
-
1278
-
1279
-    /**
1280
-     * Adds the correct registration status to the where conditions for the registrations query.
1281
-     *
1282
-     * @param array $request usually the same as $this->_req_data but not necessarily
1283
-     * @return array
1284
-     */
1285
-    protected function _add_registration_status_to_where_conditions(array $request)
1286
-    {
1287
-        $where = array();
1288
-        $view = EEH_Array::is_set($request, 'status', '');
1289
-        $registration_status = ! empty($request['_reg_status'])
1290
-            ? sanitize_text_field($request['_reg_status'])
1291
-            : '';
1292
-
1293
-        /*
33
+	/**
34
+	 * @var EE_Registration
35
+	 */
36
+	private $_registration;
37
+
38
+	/**
39
+	 * @var EE_Event
40
+	 */
41
+	private $_reg_event;
42
+
43
+	/**
44
+	 * @var EE_Session
45
+	 */
46
+	private $_session;
47
+
48
+	private static $_reg_status;
49
+
50
+	/**
51
+	 * Form for displaying the custom questions for this registration.
52
+	 * This gets used a few times throughout the request so its best to cache it
53
+	 *
54
+	 * @var EE_Registration_Custom_Questions_Form
55
+	 */
56
+	protected $_reg_custom_questions_form = null;
57
+
58
+
59
+	/**
60
+	 *        constructor
61
+	 *
62
+	 * @Constructor
63
+	 * @access public
64
+	 * @param bool $routing
65
+	 * @return Registrations_Admin_Page
66
+	 */
67
+	public function __construct($routing = true)
68
+	{
69
+		parent::__construct($routing);
70
+		add_action('wp_loaded', array($this, 'wp_loaded'));
71
+	}
72
+
73
+
74
+	public function wp_loaded()
75
+	{
76
+		// when adding a new registration...
77
+		if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
78
+			EE_System::do_not_cache();
79
+			if (! isset($this->_req_data['processing_registration'])
80
+				 || absint($this->_req_data['processing_registration']) !== 1
81
+			) {
82
+				// and it's NOT the attendee information reg step
83
+				// force cookie expiration by setting time to last week
84
+				setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
85
+				// and update the global
86
+				$_COOKIE['ee_registration_added'] = 0;
87
+			}
88
+		}
89
+	}
90
+
91
+
92
+	protected function _init_page_props()
93
+	{
94
+		$this->page_slug        = REG_PG_SLUG;
95
+		$this->_admin_base_url  = REG_ADMIN_URL;
96
+		$this->_admin_base_path = REG_ADMIN;
97
+		$this->page_label       = esc_html__('Registrations', 'event_espresso');
98
+		$this->_cpt_routes      = array(
99
+			'add_new_attendee' => 'espresso_attendees',
100
+			'edit_attendee'    => 'espresso_attendees',
101
+			'insert_attendee'  => 'espresso_attendees',
102
+			'update_attendee'  => 'espresso_attendees',
103
+		);
104
+		$this->_cpt_model_names = array(
105
+			'add_new_attendee' => 'EEM_Attendee',
106
+			'edit_attendee'    => 'EEM_Attendee',
107
+		);
108
+		$this->_cpt_edit_routes = array(
109
+			'espresso_attendees' => 'edit_attendee',
110
+		);
111
+		$this->_pagenow_map     = array(
112
+			'add_new_attendee' => 'post-new.php',
113
+			'edit_attendee'    => 'post.php',
114
+			'trash'            => 'post.php',
115
+		);
116
+		add_action('edit_form_after_title', array($this, 'after_title_form_fields'), 10);
117
+		//add filters so that the comment urls don't take users to a confusing 404 page
118
+		add_filter('get_comment_link', array($this, 'clear_comment_link'), 10, 3);
119
+	}
120
+
121
+
122
+	public function clear_comment_link($link, $comment, $args)
123
+	{
124
+		//gotta make sure this only happens on this route
125
+		$post_type = get_post_type($comment->comment_post_ID);
126
+		if ($post_type === 'espresso_attendees') {
127
+			return '#commentsdiv';
128
+		}
129
+		return $link;
130
+	}
131
+
132
+
133
+	protected function _ajax_hooks()
134
+	{
135
+		//todo: all hooks for registrations ajax goes in here
136
+		add_action('wp_ajax_toggle_checkin_status', array($this, 'toggle_checkin_status'));
137
+	}
138
+
139
+
140
+	protected function _define_page_props()
141
+	{
142
+		$this->_admin_page_title = $this->page_label;
143
+		$this->_labels           = array(
144
+			'buttons'                      => array(
145
+				'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
146
+				'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
147
+				'edit'                => esc_html__('Edit Contact', 'event_espresso'),
148
+				'report'              => esc_html__("Event Registrations CSV Report", "event_espresso"),
149
+				'report_all'          => esc_html__('All Registrations CSV Report', 'event_espresso'),
150
+				'report_filtered'     => esc_html__('Filtered CSV Report', 'event_espresso'),
151
+				'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
152
+				'contact_list_export' => esc_html__("Export Data", "event_espresso"),
153
+			),
154
+			'publishbox'                   => array(
155
+				'add_new_attendee' => esc_html__("Add Contact Record", 'event_espresso'),
156
+				'edit_attendee'    => esc_html__("Update Contact Record", 'event_espresso'),
157
+			),
158
+			'hide_add_button_on_cpt_route' => array(
159
+				'edit_attendee' => true,
160
+			),
161
+		);
162
+	}
163
+
164
+
165
+	/**
166
+	 *        grab url requests and route them
167
+	 *
168
+	 * @access private
169
+	 * @return void
170
+	 */
171
+	public function _set_page_routes()
172
+	{
173
+		$this->_get_registration_status_array();
174
+		$reg_id             = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
175
+			? $this->_req_data['_REG_ID'] : 0;
176
+		$reg_id = empty($reg_id) && ! empty($this->_req_data['reg_status_change_form']['REG_ID'])
177
+			? $this->_req_data['reg_status_change_form']['REG_ID']
178
+			: $reg_id;
179
+		$att_id             = ! empty($this->_req_data['ATT_ID']) && ! is_array($this->_req_data['ATT_ID'])
180
+			? $this->_req_data['ATT_ID'] : 0;
181
+		$att_id             = ! empty($this->_req_data['post']) && ! is_array($this->_req_data['post'])
182
+			? $this->_req_data['post']
183
+			: $att_id;
184
+		$this->_page_routes = array(
185
+			'default'                            => array(
186
+				'func'       => '_registrations_overview_list_table',
187
+				'capability' => 'ee_read_registrations',
188
+			),
189
+			'view_registration'                  => array(
190
+				'func'       => '_registration_details',
191
+				'capability' => 'ee_read_registration',
192
+				'obj_id'     => $reg_id,
193
+			),
194
+			'edit_registration'                  => array(
195
+				'func'               => '_update_attendee_registration_form',
196
+				'noheader'           => true,
197
+				'headers_sent_route' => 'view_registration',
198
+				'capability'         => 'ee_edit_registration',
199
+				'obj_id'             => $reg_id,
200
+				'_REG_ID'            => $reg_id,
201
+			),
202
+			'trash_registrations'                => array(
203
+				'func'       => '_trash_or_restore_registrations',
204
+				'args'       => array('trash' => true),
205
+				'noheader'   => true,
206
+				'capability' => 'ee_delete_registrations',
207
+			),
208
+			'restore_registrations'              => array(
209
+				'func'       => '_trash_or_restore_registrations',
210
+				'args'       => array('trash' => false),
211
+				'noheader'   => true,
212
+				'capability' => 'ee_delete_registrations',
213
+			),
214
+			'delete_registrations'               => array(
215
+				'func'       => '_delete_registrations',
216
+				'noheader'   => true,
217
+				'capability' => 'ee_delete_registrations',
218
+			),
219
+			'new_registration'                   => array(
220
+				'func'       => 'new_registration',
221
+				'capability' => 'ee_edit_registrations',
222
+			),
223
+			'process_reg_step'                   => array(
224
+				'func'       => 'process_reg_step',
225
+				'noheader'   => true,
226
+				'capability' => 'ee_edit_registrations',
227
+			),
228
+			'redirect_to_txn'                    => array(
229
+				'func'       => 'redirect_to_txn',
230
+				'noheader'   => true,
231
+				'capability' => 'ee_edit_registrations',
232
+			),
233
+			'change_reg_status'                  => array(
234
+				'func'       => '_change_reg_status',
235
+				'noheader'   => true,
236
+				'capability' => 'ee_edit_registration',
237
+				'obj_id'     => $reg_id,
238
+			),
239
+			'approve_registration'               => array(
240
+				'func'       => 'approve_registration',
241
+				'noheader'   => true,
242
+				'capability' => 'ee_edit_registration',
243
+				'obj_id'     => $reg_id,
244
+			),
245
+			'approve_and_notify_registration'    => array(
246
+				'func'       => 'approve_registration',
247
+				'noheader'   => true,
248
+				'args'       => array(true),
249
+				'capability' => 'ee_edit_registration',
250
+				'obj_id'     => $reg_id,
251
+			),
252
+			'approve_registrations'               => array(
253
+				'func'       => 'bulk_action_on_registrations',
254
+				'noheader'   => true,
255
+				'capability' => 'ee_edit_registrations',
256
+				'args' => array('approve')
257
+			),
258
+			'approve_and_notify_registrations'               => array(
259
+				'func'       => 'bulk_action_on_registrations',
260
+				'noheader'   => true,
261
+				'capability' => 'ee_edit_registrations',
262
+				'args' => array('approve', true)
263
+			),
264
+			'decline_registration'               => array(
265
+				'func'       => 'decline_registration',
266
+				'noheader'   => true,
267
+				'capability' => 'ee_edit_registration',
268
+				'obj_id'     => $reg_id,
269
+			),
270
+			'decline_and_notify_registration'    => array(
271
+				'func'       => 'decline_registration',
272
+				'noheader'   => true,
273
+				'args'       => array(true),
274
+				'capability' => 'ee_edit_registration',
275
+				'obj_id'     => $reg_id,
276
+			),
277
+			'decline_registrations'               => array(
278
+				'func'       => 'bulk_action_on_registrations',
279
+				'noheader'   => true,
280
+				'capability' => 'ee_edit_registrations',
281
+				'args' => array('decline')
282
+			),
283
+			'decline_and_notify_registrations'    => array(
284
+				'func'       => 'bulk_action_on_registrations',
285
+				'noheader'   => true,
286
+				'capability' => 'ee_edit_registrations',
287
+				'args' => array('decline', true)
288
+			),
289
+			'pending_registration'               => array(
290
+				'func'       => 'pending_registration',
291
+				'noheader'   => true,
292
+				'capability' => 'ee_edit_registration',
293
+				'obj_id'     => $reg_id,
294
+			),
295
+			'pending_and_notify_registration'    => array(
296
+				'func'       => 'pending_registration',
297
+				'noheader'   => true,
298
+				'args'       => array(true),
299
+				'capability' => 'ee_edit_registration',
300
+				'obj_id'     => $reg_id,
301
+			),
302
+			'pending_registrations'               => array(
303
+				'func'       => 'bulk_action_on_registrations',
304
+				'noheader'   => true,
305
+				'capability' => 'ee_edit_registrations',
306
+				'args' => array('pending')
307
+			),
308
+			'pending_and_notify_registrations'    => array(
309
+				'func'       => 'bulk_action_on_registrations',
310
+				'noheader'   => true,
311
+				'capability' => 'ee_edit_registrations',
312
+				'args' => array('pending', true)
313
+			),
314
+			'no_approve_registration'            => array(
315
+				'func'       => 'not_approve_registration',
316
+				'noheader'   => true,
317
+				'capability' => 'ee_edit_registration',
318
+				'obj_id'     => $reg_id,
319
+			),
320
+			'no_approve_and_notify_registration' => array(
321
+				'func'       => 'not_approve_registration',
322
+				'noheader'   => true,
323
+				'args'       => array(true),
324
+				'capability' => 'ee_edit_registration',
325
+				'obj_id'     => $reg_id,
326
+			),
327
+			'no_approve_registrations'            => array(
328
+				'func'       => 'bulk_action_on_registrations',
329
+				'noheader'   => true,
330
+				'capability' => 'ee_edit_registrations',
331
+				'args' => array('not_approve')
332
+			),
333
+			'no_approve_and_notify_registrations' => array(
334
+				'func'       => 'bulk_action_on_registrations',
335
+				'noheader'   => true,
336
+				'capability' => 'ee_edit_registrations',
337
+				'args' => array('not_approve', true)
338
+			),
339
+			'cancel_registration'                => array(
340
+				'func'       => 'cancel_registration',
341
+				'noheader'   => true,
342
+				'capability' => 'ee_edit_registration',
343
+				'obj_id'     => $reg_id,
344
+			),
345
+			'cancel_and_notify_registration'     => array(
346
+				'func'       => 'cancel_registration',
347
+				'noheader'   => true,
348
+				'args'       => array(true),
349
+				'capability' => 'ee_edit_registration',
350
+				'obj_id'     => $reg_id,
351
+			),
352
+			'cancel_registrations'                => array(
353
+				'func'       => 'bulk_action_on_registrations',
354
+				'noheader'   => true,
355
+				'capability' => 'ee_edit_registrations',
356
+				'args' => array('cancel')
357
+			),
358
+			'cancel_and_notify_registrations'     => array(
359
+				'func'       => 'bulk_action_on_registrations',
360
+				'noheader'   => true,
361
+				'capability' => 'ee_edit_registrations',
362
+				'args' => array('cancel', true)
363
+			),
364
+			'wait_list_registration' => array(
365
+				'func'       => 'wait_list_registration',
366
+				'noheader'   => true,
367
+				'capability' => 'ee_edit_registration',
368
+				'obj_id'     => $reg_id,
369
+			),
370
+			'wait_list_and_notify_registration' => array(
371
+				'func'       => 'wait_list_registration',
372
+				'noheader'   => true,
373
+				'args'       => array(true),
374
+				'capability' => 'ee_edit_registration',
375
+				'obj_id'     => $reg_id,
376
+			),
377
+			'contact_list'                       => array(
378
+				'func'       => '_attendee_contact_list_table',
379
+				'capability' => 'ee_read_contacts',
380
+			),
381
+			'add_new_attendee'                   => array(
382
+				'func' => '_create_new_cpt_item',
383
+				'args' => array(
384
+					'new_attendee' => true,
385
+					'capability'   => 'ee_edit_contacts',
386
+				),
387
+			),
388
+			'edit_attendee'                      => array(
389
+				'func'       => '_edit_cpt_item',
390
+				'capability' => 'ee_edit_contacts',
391
+				'obj_id'     => $att_id,
392
+			),
393
+			'duplicate_attendee'                 => array(
394
+				'func'       => '_duplicate_attendee',
395
+				'noheader'   => true,
396
+				'capability' => 'ee_edit_contacts',
397
+				'obj_id'     => $att_id,
398
+			),
399
+			'insert_attendee'                    => array(
400
+				'func'       => '_insert_or_update_attendee',
401
+				'args'       => array(
402
+					'new_attendee' => true,
403
+				),
404
+				'noheader'   => true,
405
+				'capability' => 'ee_edit_contacts',
406
+			),
407
+			'update_attendee'                    => array(
408
+				'func'       => '_insert_or_update_attendee',
409
+				'args'       => array(
410
+					'new_attendee' => false,
411
+				),
412
+				'noheader'   => true,
413
+				'capability' => 'ee_edit_contacts',
414
+				'obj_id'     => $att_id,
415
+			),
416
+			'trash_attendees' => array(
417
+				'func' => '_trash_or_restore_attendees',
418
+				'args' => array(
419
+					'trash' => 'true'
420
+				),
421
+				'noheader' => true,
422
+				'capability' => 'ee_delete_contacts'
423
+			),
424
+			'trash_attendee'                    => array(
425
+				'func'       => '_trash_or_restore_attendees',
426
+				'args'       => array(
427
+					'trash' => true,
428
+				),
429
+				'noheader'   => true,
430
+				'capability' => 'ee_delete_contacts',
431
+				'obj_id'     => $att_id,
432
+			),
433
+			'restore_attendees'                  => array(
434
+				'func'       => '_trash_or_restore_attendees',
435
+				'args'       => array(
436
+					'trash' => false,
437
+				),
438
+				'noheader'   => true,
439
+				'capability' => 'ee_delete_contacts',
440
+				'obj_id'     => $att_id,
441
+			),
442
+			'resend_registration'                => array(
443
+				'func'       => '_resend_registration',
444
+				'noheader'   => true,
445
+				'capability' => 'ee_send_message',
446
+			),
447
+			'registrations_report'               => array(
448
+				'func'       => '_registrations_report',
449
+				'noheader'   => true,
450
+				'capability' => 'ee_read_registrations',
451
+			),
452
+			'contact_list_export'                => array(
453
+				'func'       => '_contact_list_export',
454
+				'noheader'   => true,
455
+				'capability' => 'export',
456
+			),
457
+			'contact_list_report'                => array(
458
+				'func'       => '_contact_list_report',
459
+				'noheader'   => true,
460
+				'capability' => 'ee_read_contacts',
461
+			),
462
+		);
463
+	}
464
+
465
+
466
+	protected function _set_page_config()
467
+	{
468
+		$this->_page_config = array(
469
+			'default'           => array(
470
+				'nav'           => array(
471
+					'label' => esc_html__('Overview', 'event_espresso'),
472
+					'order' => 5,
473
+				),
474
+				'help_tabs'     => array(
475
+					'registrations_overview_help_tab'                       => array(
476
+						'title'    => esc_html__('Registrations Overview', 'event_espresso'),
477
+						'filename' => 'registrations_overview',
478
+					),
479
+					'registrations_overview_table_column_headings_help_tab' => array(
480
+						'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
481
+						'filename' => 'registrations_overview_table_column_headings',
482
+					),
483
+					'registrations_overview_filters_help_tab'               => array(
484
+						'title'    => esc_html__('Registration Filters', 'event_espresso'),
485
+						'filename' => 'registrations_overview_filters',
486
+					),
487
+					'registrations_overview_views_help_tab'                 => array(
488
+						'title'    => esc_html__('Registration Views', 'event_espresso'),
489
+						'filename' => 'registrations_overview_views',
490
+					),
491
+					'registrations_regoverview_other_help_tab'              => array(
492
+						'title'    => esc_html__('Registrations Other', 'event_espresso'),
493
+						'filename' => 'registrations_overview_other',
494
+					),
495
+				),
496
+				'help_tour'     => array('Registration_Overview_Help_Tour'),
497
+				'qtips'         => array('Registration_List_Table_Tips'),
498
+				'list_table'    => 'EE_Registrations_List_Table',
499
+				'require_nonce' => false,
500
+			),
501
+			'view_registration' => array(
502
+				'nav'           => array(
503
+					'label'      => esc_html__('REG Details', 'event_espresso'),
504
+					'order'      => 15,
505
+					'url'        => isset($this->_req_data['_REG_ID'])
506
+						? add_query_arg(array('_REG_ID' => $this->_req_data['_REG_ID']), $this->_current_page_view_url)
507
+						: $this->_admin_base_url,
508
+					'persistent' => false,
509
+				),
510
+				'help_tabs'     => array(
511
+					'registrations_details_help_tab'                    => array(
512
+						'title'    => esc_html__('Registration Details', 'event_espresso'),
513
+						'filename' => 'registrations_details',
514
+					),
515
+					'registrations_details_table_help_tab'              => array(
516
+						'title'    => esc_html__('Registration Details Table', 'event_espresso'),
517
+						'filename' => 'registrations_details_table',
518
+					),
519
+					'registrations_details_form_answers_help_tab'       => array(
520
+						'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
521
+						'filename' => 'registrations_details_form_answers',
522
+					),
523
+					'registrations_details_registrant_details_help_tab' => array(
524
+						'title'    => esc_html__('Contact Details', 'event_espresso'),
525
+						'filename' => 'registrations_details_registrant_details',
526
+					),
527
+				),
528
+				'help_tour'     => array('Registration_Details_Help_Tour'),
529
+				'metaboxes'     => array_merge(
530
+					$this->_default_espresso_metaboxes,
531
+					array('_registration_details_metaboxes')
532
+				),
533
+				'require_nonce' => false,
534
+			),
535
+			'new_registration'  => array(
536
+				'nav'           => array(
537
+					'label'      => esc_html__('Add New Registration', 'event_espresso'),
538
+					'url'        => '#',
539
+					'order'      => 15,
540
+					'persistent' => false,
541
+				),
542
+				'metaboxes'     => $this->_default_espresso_metaboxes,
543
+				'labels'        => array(
544
+					'publishbox' => esc_html__('Save Registration', 'event_espresso'),
545
+				),
546
+				'require_nonce' => false,
547
+			),
548
+			'add_new_attendee'  => array(
549
+				'nav'           => array(
550
+					'label'      => esc_html__('Add Contact', 'event_espresso'),
551
+					'order'      => 15,
552
+					'persistent' => false,
553
+				),
554
+				'metaboxes'     => array_merge(
555
+					$this->_default_espresso_metaboxes,
556
+					array('_publish_post_box', 'attendee_editor_metaboxes')
557
+				),
558
+				'require_nonce' => false,
559
+			),
560
+			'edit_attendee'     => array(
561
+				'nav'           => array(
562
+					'label'      => esc_html__('Edit Contact', 'event_espresso'),
563
+					'order'      => 15,
564
+					'persistent' => false,
565
+					'url'        => isset($this->_req_data['ATT_ID'])
566
+						? add_query_arg(array('ATT_ID' => $this->_req_data['ATT_ID']), $this->_current_page_view_url)
567
+						: $this->_admin_base_url,
568
+				),
569
+				'metaboxes'     => array('attendee_editor_metaboxes'),
570
+				'require_nonce' => false,
571
+			),
572
+			'contact_list'      => array(
573
+				'nav'           => array(
574
+					'label' => esc_html__('Contact List', 'event_espresso'),
575
+					'order' => 20,
576
+				),
577
+				'list_table'    => 'EE_Attendee_Contact_List_Table',
578
+				'help_tabs'     => array(
579
+					'registrations_contact_list_help_tab'                       => array(
580
+						'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
581
+						'filename' => 'registrations_contact_list',
582
+					),
583
+					'registrations_contact-list_table_column_headings_help_tab' => array(
584
+						'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
585
+						'filename' => 'registrations_contact_list_table_column_headings',
586
+					),
587
+					'registrations_contact_list_views_help_tab'                 => array(
588
+						'title'    => esc_html__('Contact List Views', 'event_espresso'),
589
+						'filename' => 'registrations_contact_list_views',
590
+					),
591
+					'registrations_contact_list_other_help_tab'                 => array(
592
+						'title'    => esc_html__('Contact List Other', 'event_espresso'),
593
+						'filename' => 'registrations_contact_list_other',
594
+					),
595
+				),
596
+				'help_tour'     => array('Contact_List_Help_Tour'),
597
+				'metaboxes'     => array(),
598
+				'require_nonce' => false,
599
+			),
600
+			//override default cpt routes
601
+			'create_new'        => '',
602
+			'edit'              => '',
603
+		);
604
+	}
605
+
606
+
607
+	/**
608
+	 * The below methods aren't used by this class currently
609
+	 */
610
+	protected function _add_screen_options()
611
+	{
612
+	}
613
+
614
+
615
+	protected function _add_feature_pointers()
616
+	{
617
+	}
618
+
619
+
620
+	public function admin_init()
621
+	{
622
+		EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
623
+			'click "Update Registration Questions" to save your changes',
624
+			'event_espresso'
625
+		);
626
+	}
627
+
628
+
629
+	public function admin_notices()
630
+	{
631
+	}
632
+
633
+
634
+	public function admin_footer_scripts()
635
+	{
636
+	}
637
+
638
+
639
+	/**
640
+	 *        get list of registration statuses
641
+	 *
642
+	 * @access private
643
+	 * @return void
644
+	 * @throws EE_Error
645
+	 */
646
+	private function _get_registration_status_array()
647
+	{
648
+		self::$_reg_status = EEM_Registration::reg_status_array(array(), true);
649
+	}
650
+
651
+
652
+	protected function _add_screen_options_default()
653
+	{
654
+		$this->_per_page_screen_option();
655
+	}
656
+
657
+
658
+	protected function _add_screen_options_contact_list()
659
+	{
660
+		$page_title              = $this->_admin_page_title;
661
+		$this->_admin_page_title = esc_html__("Contacts", 'event_espresso');
662
+		$this->_per_page_screen_option();
663
+		$this->_admin_page_title = $page_title;
664
+	}
665
+
666
+
667
+	public function load_scripts_styles()
668
+	{
669
+		//style
670
+		wp_register_style(
671
+			'espresso_reg',
672
+			REG_ASSETS_URL . 'espresso_registrations_admin.css',
673
+			array('ee-admin-css'),
674
+			EVENT_ESPRESSO_VERSION
675
+		);
676
+		wp_enqueue_style('espresso_reg');
677
+		//script
678
+		wp_register_script(
679
+			'espresso_reg',
680
+			REG_ASSETS_URL . 'espresso_registrations_admin.js',
681
+			array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'),
682
+			EVENT_ESPRESSO_VERSION,
683
+			true
684
+		);
685
+		wp_enqueue_script('espresso_reg');
686
+	}
687
+
688
+
689
+	public function load_scripts_styles_edit_attendee()
690
+	{
691
+		//stuff to only show up on our attendee edit details page.
692
+		$attendee_details_translations = array(
693
+			'att_publish_text' => sprintf(
694
+				esc_html__('Created on: <b>%1$s</b>', 'event_espresso'),
695
+				$this->_cpt_model_obj->get_datetime('ATT_created')
696
+			),
697
+		);
698
+		wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
699
+		wp_enqueue_script('jquery-validate');
700
+	}
701
+
702
+
703
+	public function load_scripts_styles_view_registration()
704
+	{
705
+		//styles
706
+		wp_enqueue_style('espresso-ui-theme');
707
+		//scripts
708
+		$this->_get_reg_custom_questions_form($this->_registration->ID());
709
+		$this->_reg_custom_questions_form->wp_enqueue_scripts(true);
710
+	}
711
+
712
+
713
+	public function load_scripts_styles_contact_list()
714
+	{
715
+		wp_dequeue_style('espresso_reg');
716
+		wp_register_style(
717
+			'espresso_att',
718
+			REG_ASSETS_URL . 'espresso_attendees_admin.css',
719
+			array('ee-admin-css'),
720
+			EVENT_ESPRESSO_VERSION
721
+		);
722
+		wp_enqueue_style('espresso_att');
723
+	}
724
+
725
+
726
+	public function load_scripts_styles_new_registration()
727
+	{
728
+		wp_register_script(
729
+			'ee-spco-for-admin',
730
+			REG_ASSETS_URL . 'spco_for_admin.js',
731
+			array('underscore', 'jquery'),
732
+			EVENT_ESPRESSO_VERSION,
733
+			true
734
+		);
735
+		wp_enqueue_script('ee-spco-for-admin');
736
+		add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
737
+		EE_Form_Section_Proper::wp_enqueue_scripts();
738
+		EED_Ticket_Selector::load_tckt_slctr_assets();
739
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
740
+	}
741
+
742
+
743
+	public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
744
+	{
745
+		add_filter('FHEE_load_EE_messages', '__return_true');
746
+	}
747
+
748
+
749
+	public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
750
+	{
751
+		add_filter('FHEE_load_EE_messages', '__return_true');
752
+	}
753
+
754
+
755
+	protected function _set_list_table_views_default()
756
+	{
757
+		//for notification related bulk actions we need to make sure only active messengers have an option.
758
+		EED_Messages::set_autoloaders();
759
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
760
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
761
+		$active_mts               = $message_resource_manager->list_of_active_message_types();
762
+		//key= bulk_action_slug, value= message type.
763
+		$match_array = array(
764
+			'approve_registrations'    => 'registration',
765
+			'decline_registrations'    => 'declined_registration',
766
+			'pending_registrations'    => 'pending_approval',
767
+			'no_approve_registrations' => 'not_approved_registration',
768
+			'cancel_registrations'     => 'cancelled_registration',
769
+		);
770
+		$can_send = EE_Registry::instance()->CAP->current_user_can(
771
+			'ee_send_message',
772
+			'batch_send_messages'
773
+		);
774
+		/** setup reg status bulk actions **/
775
+		$def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
776
+		if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
777
+				$def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
778
+					'Approve and Notify Registrations',
779
+					'event_espresso'
780
+				);
781
+		}
782
+		$def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
783
+		if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
784
+				$def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
785
+					'Decline and Notify Registrations',
786
+					'event_espresso'
787
+				);
788
+		}
789
+		$def_reg_status_actions['pending_registrations'] = esc_html__(
790
+			'Set Registrations to Pending Payment',
791
+			'event_espresso'
792
+		);
793
+		if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
794
+				$def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
795
+					'Set Registrations to Pending Payment and Notify',
796
+					'event_espresso'
797
+				);
798
+		}
799
+		$def_reg_status_actions['no_approve_registrations'] = esc_html__(
800
+			'Set Registrations to Not Approved',
801
+			'event_espresso'
802
+		);
803
+		if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
804
+				$def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
805
+					'Set Registrations to Not Approved and Notify',
806
+					'event_espresso'
807
+				);
808
+		}
809
+		$def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
810
+		if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
811
+				$def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
812
+					'Cancel Registrations and Notify',
813
+					'event_espresso'
814
+				);
815
+		}
816
+		$def_reg_status_actions = apply_filters(
817
+			'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
818
+			$def_reg_status_actions,
819
+			$active_mts,
820
+			$can_send
821
+		);
822
+
823
+		$this->_views = array(
824
+			'all'   => array(
825
+				'slug'        => 'all',
826
+				'label'       => esc_html__('View All Registrations', 'event_espresso'),
827
+				'count'       => 0,
828
+				'bulk_action' => array_merge($def_reg_status_actions, array(
829
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
830
+				)),
831
+			),
832
+			'month' => array(
833
+				'slug'        => 'month',
834
+				'label'       => esc_html__('This Month', 'event_espresso'),
835
+				'count'       => 0,
836
+				'bulk_action' => array_merge($def_reg_status_actions, array(
837
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
838
+				)),
839
+			),
840
+			'today' => array(
841
+				'slug'        => 'today',
842
+				'label'       => sprintf(
843
+					esc_html__('Today - %s', 'event_espresso'),
844
+					date('M d, Y', current_time('timestamp'))
845
+				),
846
+				'count'       => 0,
847
+				'bulk_action' => array_merge($def_reg_status_actions, array(
848
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
849
+				)),
850
+			),
851
+		);
852
+		if (EE_Registry::instance()->CAP->current_user_can(
853
+			'ee_delete_registrations',
854
+			'espresso_registrations_delete_registration'
855
+		)) {
856
+			$this->_views['incomplete'] = array(
857
+				'slug'        => 'incomplete',
858
+				'label'       => esc_html__('Incomplete', 'event_espresso'),
859
+				'count'       => 0,
860
+				'bulk_action' => array(
861
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
862
+				),
863
+			);
864
+			$this->_views['trash']      = array(
865
+				'slug'        => 'trash',
866
+				'label'       => esc_html__('Trash', 'event_espresso'),
867
+				'count'       => 0,
868
+				'bulk_action' => array(
869
+					'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
870
+					'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
871
+				),
872
+			);
873
+		}
874
+	}
875
+
876
+
877
+	protected function _set_list_table_views_contact_list()
878
+	{
879
+		$this->_views = array(
880
+			'in_use' => array(
881
+				'slug'        => 'in_use',
882
+				'label'       => esc_html__('In Use', 'event_espresso'),
883
+				'count'       => 0,
884
+				'bulk_action' => array(
885
+					'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
886
+				),
887
+			),
888
+		);
889
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_contacts',
890
+			'espresso_registrations_trash_attendees')
891
+		) {
892
+			$this->_views['trash'] = array(
893
+				'slug'        => 'trash',
894
+				'label'       => esc_html__('Trash', 'event_espresso'),
895
+				'count'       => 0,
896
+				'bulk_action' => array(
897
+					'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
898
+				),
899
+			);
900
+		}
901
+	}
902
+
903
+
904
+	protected function _registration_legend_items()
905
+	{
906
+		$fc_items = array(
907
+			'star-icon'        => array(
908
+				'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8',
909
+				'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
910
+			),
911
+			'view_details'     => array(
912
+				'class' => 'dashicons dashicons-clipboard',
913
+				'desc'  => esc_html__('View Registration Details', 'event_espresso'),
914
+			),
915
+			'edit_attendee'    => array(
916
+				'class' => 'ee-icon ee-icon-user-edit ee-icon-size-16',
917
+				'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
918
+			),
919
+			'view_transaction' => array(
920
+				'class' => 'dashicons dashicons-cart',
921
+				'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
922
+			),
923
+			'view_invoice'     => array(
924
+				'class' => 'dashicons dashicons-media-spreadsheet',
925
+				'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
926
+			),
927
+		);
928
+		if (EE_Registry::instance()->CAP->current_user_can(
929
+			'ee_send_message',
930
+			'espresso_registrations_resend_registration'
931
+		)) {
932
+			$fc_items['resend_registration'] = array(
933
+				'class' => 'dashicons dashicons-email-alt',
934
+				'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
935
+			);
936
+		} else {
937
+			$fc_items['blank'] = array('class' => 'blank', 'desc' => '');
938
+		}
939
+		if (EE_Registry::instance()->CAP->current_user_can(
940
+			'ee_read_global_messages',
941
+			'view_filtered_messages'
942
+		)) {
943
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
944
+			if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
945
+				$fc_items['view_related_messages'] = array(
946
+					'class' => $related_for_icon['css_class'],
947
+					'desc'  => $related_for_icon['label'],
948
+				);
949
+			}
950
+		}
951
+		$sc_items = array(
952
+			'approved_status'   => array(
953
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
954
+				'desc'  => EEH_Template::pretty_status(
955
+					EEM_Registration::status_id_approved,
956
+					false,
957
+					'sentence'
958
+				),
959
+			),
960
+			'pending_status'    => array(
961
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
962
+				'desc'  => EEH_Template::pretty_status(
963
+					EEM_Registration::status_id_pending_payment,
964
+					false,
965
+					'sentence'
966
+				),
967
+			),
968
+			'wait_list'         => array(
969
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
970
+				'desc'  => EEH_Template::pretty_status(
971
+					EEM_Registration::status_id_wait_list,
972
+					false,
973
+					'sentence'
974
+				),
975
+			),
976
+			'incomplete_status' => array(
977
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
978
+				'desc'  => EEH_Template::pretty_status(
979
+					EEM_Registration::status_id_incomplete,
980
+					false,
981
+					'sentence'
982
+				),
983
+			),
984
+			'not_approved'      => array(
985
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
986
+				'desc'  => EEH_Template::pretty_status(
987
+					EEM_Registration::status_id_not_approved,
988
+					false,
989
+					'sentence'
990
+				),
991
+			),
992
+			'declined_status'   => array(
993
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
994
+				'desc'  => EEH_Template::pretty_status(
995
+					EEM_Registration::status_id_declined,
996
+					false,
997
+					'sentence'
998
+				),
999
+			),
1000
+			'cancelled_status'  => array(
1001
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
1002
+				'desc'  => EEH_Template::pretty_status(
1003
+					EEM_Registration::status_id_cancelled,
1004
+					false,
1005
+					'sentence'
1006
+				),
1007
+			),
1008
+		);
1009
+		return array_merge($fc_items, $sc_items);
1010
+	}
1011
+
1012
+
1013
+
1014
+	/***************************************        REGISTRATION OVERVIEW        **************************************/
1015
+	/**
1016
+	 * @throws \EE_Error
1017
+	 */
1018
+	protected function _registrations_overview_list_table()
1019
+	{
1020
+		$this->_template_args['admin_page_header'] = '';
1021
+		$EVT_ID                                    = ! empty($this->_req_data['event_id'])
1022
+			? absint($this->_req_data['event_id'])
1023
+			: 0;
1024
+		$ATT_ID = !empty($this->_req_data['ATT_ID'])
1025
+			? absint($this->_req_data['ATT_ID'])
1026
+			: 0;
1027
+		if ($ATT_ID) {
1028
+			$attendee = EEM_Attendee::instance()->get_one_by_ID($ATT_ID);
1029
+			if ($attendee instanceof EE_Attendee) {
1030
+				$this->_template_args['admin_page_header'] = sprintf(
1031
+					esc_html__(
1032
+						'%1$s Viewing registrations for %2$s%3$s',
1033
+						'event_espresso'
1034
+					),
1035
+					'<h3 style="line-height:1.5em;">',
1036
+					'<a href="' . EE_Admin_Page::add_query_args_and_nonce(
1037
+						array(
1038
+							'action' => 'edit_attendee',
1039
+							'post' => $ATT_ID
1040
+						),
1041
+						REG_ADMIN_URL
1042
+					) . '">' . $attendee->full_name() . '</a>',
1043
+					'</h3>'
1044
+				);
1045
+			}
1046
+		}
1047
+		if ($EVT_ID) {
1048
+			if (EE_Registry::instance()->CAP->current_user_can(
1049
+				'ee_edit_registrations',
1050
+				'espresso_registrations_new_registration',
1051
+				$EVT_ID
1052
+			)) {
1053
+				$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1054
+					'new_registration',
1055
+					'add-registrant',
1056
+					array('event_id' => $EVT_ID),
1057
+					'add-new-h2'
1058
+				);
1059
+			}
1060
+			$event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
1061
+			if ($event instanceof EE_Event) {
1062
+				$this->_template_args['admin_page_header'] = sprintf(
1063
+					esc_html__(
1064
+						'%s Viewing registrations for the event: %s%s',
1065
+						'event_espresso'
1066
+					),
1067
+					'<h3 style="line-height:1.5em;">',
1068
+					'<br /><a href="'
1069
+						. EE_Admin_Page::add_query_args_and_nonce(
1070
+							array(
1071
+								'action' => 'edit',
1072
+								'post'   => $event->ID(),
1073
+							),
1074
+							EVENTS_ADMIN_URL
1075
+						)
1076
+						. '">&nbsp;'
1077
+						. $event->get('EVT_name')
1078
+						. '&nbsp;</a>&nbsp;',
1079
+					'</h3>'
1080
+				);
1081
+			}
1082
+			$DTT_ID   = ! empty($this->_req_data['datetime_id']) ? absint($this->_req_data['datetime_id']) : 0;
1083
+			$datetime = EEM_Datetime::instance()->get_one_by_ID($DTT_ID);
1084
+			if ($datetime instanceof EE_Datetime && $this->_template_args['admin_page_header'] !== '') {
1085
+				$this->_template_args['admin_page_header'] = substr(
1086
+					$this->_template_args['admin_page_header'],
1087
+					0,
1088
+					-5
1089
+				);
1090
+				$this->_template_args['admin_page_header'] .= ' &nbsp;<span class="drk-grey-text">';
1091
+				$this->_template_args['admin_page_header'] .= '<span class="dashicons dashicons-calendar"></span>';
1092
+				$this->_template_args['admin_page_header'] .= $datetime->name();
1093
+				$this->_template_args['admin_page_header'] .= ' ( ' . $datetime->start_date() . ' )';
1094
+				$this->_template_args['admin_page_header'] .= '</span></h3>';
1095
+			}
1096
+		}
1097
+		$this->_template_args['after_list_table'] = $this->_display_legend($this->_registration_legend_items());
1098
+		$this->display_admin_list_table_page_with_no_sidebar();
1099
+	}
1100
+
1101
+
1102
+	/**
1103
+	 * This sets the _registration property for the registration details screen
1104
+	 *
1105
+	 * @access private
1106
+	 * @return bool
1107
+	 * @throws EE_Error
1108
+	 * @throws InvalidArgumentException
1109
+	 * @throws InvalidDataTypeException
1110
+	 * @throws InvalidInterfaceException
1111
+	 */
1112
+	private function _set_registration_object()
1113
+	{
1114
+		//get out if we've already set the object
1115
+		if ($this->_registration instanceof EE_Registration) {
1116
+			return true;
1117
+		}
1118
+		$REG    = EEM_Registration::instance();
1119
+		$REG_ID = ( ! empty($this->_req_data['_REG_ID'])) ? absint($this->_req_data['_REG_ID']) : false;
1120
+		if ($this->_registration = $REG->get_one_by_ID($REG_ID)) {
1121
+			return true;
1122
+		} else {
1123
+			$error_msg = sprintf(
1124
+				esc_html__(
1125
+					'An error occurred and the details for Registration ID #%s could not be retrieved.',
1126
+					'event_espresso'
1127
+				),
1128
+				$REG_ID
1129
+			);
1130
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1131
+			$this->_registration = null;
1132
+			return false;
1133
+		}
1134
+	}
1135
+
1136
+
1137
+	/**
1138
+	 * Used to retrieve registrations for the list table.
1139
+	 *
1140
+	 * @param int  $per_page
1141
+	 * @param bool $count
1142
+	 * @param bool $this_month
1143
+	 * @param bool $today
1144
+	 * @return EE_Registration[]|int
1145
+	 * @throws EE_Error
1146
+	 * @throws InvalidArgumentException
1147
+	 * @throws InvalidDataTypeException
1148
+	 * @throws InvalidInterfaceException
1149
+	 */
1150
+	public function get_registrations(
1151
+		$per_page = 10,
1152
+		$count = false,
1153
+		$this_month = false,
1154
+		$today = false
1155
+	) {
1156
+		if ($this_month) {
1157
+			$this->_req_data['status'] = 'month';
1158
+		}
1159
+		if ($today) {
1160
+			$this->_req_data['status'] = 'today';
1161
+		}
1162
+		$query_params = $this->_get_registration_query_parameters($this->_req_data, $per_page, $count);
1163
+		/**
1164
+		 * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1165
+		 * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1166
+		 * @see EEM_Base::get_all()
1167
+		 */
1168
+		$query_params['group_by'] = '';
1169
+
1170
+		return $count
1171
+			? EEM_Registration::instance()->count($query_params)
1172
+			/** @type EE_Registration[] */
1173
+			: EEM_Registration::instance()->get_all($query_params);
1174
+	}
1175
+
1176
+
1177
+	/**
1178
+	 * Retrieves the query parameters to be used by the Registration model for getting registrations.
1179
+	 * Note: this listens to values on the request for some of the query parameters.
1180
+	 *
1181
+	 * @param array $request
1182
+	 * @param int   $per_page
1183
+	 * @param bool  $count
1184
+	 * @return array
1185
+	 * @throws EE_Error
1186
+	 */
1187
+	protected function _get_registration_query_parameters(
1188
+		$request = array(),
1189
+		$per_page = 10,
1190
+		$count = false
1191
+	) {
1192
+
1193
+		$query_params = array(
1194
+			0                          => $this->_get_where_conditions_for_registrations_query(
1195
+				$request
1196
+			),
1197
+			'caps'                     => EEM_Registration::caps_read_admin,
1198
+			'default_where_conditions' => 'this_model_only',
1199
+		);
1200
+		if (! $count) {
1201
+			$query_params = array_merge(
1202
+				$query_params,
1203
+				$this->_get_orderby_for_registrations_query(),
1204
+				$this->_get_limit($per_page)
1205
+			);
1206
+		}
1207
+
1208
+		return $query_params;
1209
+	}
1210
+
1211
+
1212
+	/**
1213
+	 * This will add ATT_ID to the provided $where array for EE model query parameters.
1214
+	 *
1215
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1216
+	 * @return array
1217
+	 */
1218
+	protected function addAttendeeIdToWhereConditions(array $request)
1219
+	{
1220
+		$where = array();
1221
+		if (! empty($request['ATT_ID'])) {
1222
+			$where['ATT_ID'] = absint($request['ATT_ID']);
1223
+		}
1224
+		return $where;
1225
+	}
1226
+
1227
+
1228
+	/**
1229
+	 * This will add EVT_ID to the provided $where array for EE model query parameters.
1230
+	 *
1231
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1232
+	 * @return array
1233
+	 */
1234
+	protected function _add_event_id_to_where_conditions(array $request)
1235
+	{
1236
+		$where = array();
1237
+		if (! empty($request['event_id'])) {
1238
+			$where['EVT_ID'] = absint($request['event_id']);
1239
+		}
1240
+		return $where;
1241
+	}
1242
+
1243
+
1244
+	/**
1245
+	 * Adds category ID if it exists in the request to the where conditions for the registrations query.
1246
+	 *
1247
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1248
+	 * @return array
1249
+	 */
1250
+	protected function _add_category_id_to_where_conditions(array $request)
1251
+	{
1252
+		$where = array();
1253
+		if (! empty($request['EVT_CAT']) && (int)$request['EVT_CAT'] !== -1) {
1254
+			$where['Event.Term_Taxonomy.term_id'] = absint($request['EVT_CAT']);
1255
+		}
1256
+		return $where;
1257
+	}
1258
+
1259
+
1260
+	/**
1261
+	 * Adds the datetime ID if it exists in the request to the where conditions for the registrations query.
1262
+	 *
1263
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1264
+	 * @return array
1265
+	 */
1266
+	protected function _add_datetime_id_to_where_conditions(array $request)
1267
+	{
1268
+		$where = array();
1269
+		if (! empty($request['datetime_id'])) {
1270
+			$where['Ticket.Datetime.DTT_ID'] = absint($request['datetime_id']);
1271
+		}
1272
+		if (! empty($request['DTT_ID'])) {
1273
+			$where['Ticket.Datetime.DTT_ID'] = absint($request['DTT_ID']);
1274
+		}
1275
+		return $where;
1276
+	}
1277
+
1278
+
1279
+	/**
1280
+	 * Adds the correct registration status to the where conditions for the registrations query.
1281
+	 *
1282
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1283
+	 * @return array
1284
+	 */
1285
+	protected function _add_registration_status_to_where_conditions(array $request)
1286
+	{
1287
+		$where = array();
1288
+		$view = EEH_Array::is_set($request, 'status', '');
1289
+		$registration_status = ! empty($request['_reg_status'])
1290
+			? sanitize_text_field($request['_reg_status'])
1291
+			: '';
1292
+
1293
+		/*
1294 1294
          * If filtering by registration status, then we show registrations matching that status.
1295 1295
          * If not filtering by specified status, then we show all registrations excluding incomplete registrations
1296 1296
          * UNLESS viewing trashed registrations.
1297 1297
          */
1298
-        if (! empty($registration_status)) {
1299
-            $where['STS_ID'] = $registration_status;
1300
-        } else {
1301
-            //make sure we exclude incomplete registrations, but only if not trashed.
1302
-            if ($view === 'trash') {
1303
-                $where['REG_deleted'] = true;
1304
-            } elseif ($view === 'incomplete') {
1305
-                $where['STS_ID'] = EEM_Registration::status_id_incomplete;
1306
-            } else {
1307
-                $where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete);
1308
-            }
1309
-        }
1310
-        return $where;
1311
-    }
1312
-
1313
-
1314
-    /**
1315
-     * Adds any provided date restraints to the where conditions for the registrations query.
1316
-     *
1317
-     * @param array $request usually the same as $this->_req_data but not necessarily
1318
-     * @return array
1319
-     * @throws EE_Error
1320
-     * @throws InvalidArgumentException
1321
-     * @throws InvalidDataTypeException
1322
-     * @throws InvalidInterfaceException
1323
-     */
1324
-    protected function _add_date_to_where_conditions(array $request)
1325
-    {
1326
-        $where = array();
1327
-        $view = EEH_Array::is_set($request, 'status', '');
1328
-        $month_range             = ! empty($request['month_range'])
1329
-            ? sanitize_text_field($request['month_range'])
1330
-            : '';
1331
-        $retrieve_for_today      = $view === 'today';
1332
-        $retrieve_for_this_month = $view === 'month';
1333
-
1334
-        if ($retrieve_for_today) {
1335
-            $now               = date('Y-m-d', current_time('timestamp'));
1336
-            $where['REG_date'] = array(
1337
-                'BETWEEN',
1338
-                array(
1339
-                    EEM_Registration::instance()->convert_datetime_for_query(
1340
-                        'REG_date',
1341
-                        $now . ' 00:00:00',
1342
-                        'Y-m-d H:i:s'
1343
-                    ),
1344
-                    EEM_Registration::instance()->convert_datetime_for_query(
1345
-                        'REG_date',
1346
-                        $now . ' 23:59:59',
1347
-                        'Y-m-d H:i:s'
1348
-                    ),
1349
-                ),
1350
-            );
1351
-        } elseif ($retrieve_for_this_month) {
1352
-            $current_year_and_month = date('Y-m', current_time('timestamp'));
1353
-            $days_this_month        = date('t', current_time('timestamp'));
1354
-            $where['REG_date']      = array(
1355
-                'BETWEEN',
1356
-                array(
1357
-                    EEM_Registration::instance()->convert_datetime_for_query(
1358
-                        'REG_date',
1359
-                        $current_year_and_month . '-01 00:00:00',
1360
-                        'Y-m-d H:i:s'
1361
-                    ),
1362
-                    EEM_Registration::instance()->convert_datetime_for_query(
1363
-                        'REG_date',
1364
-                        $current_year_and_month . '-' . $days_this_month . ' 23:59:59',
1365
-                        'Y-m-d H:i:s'
1366
-                    ),
1367
-                ),
1368
-            );
1369
-        } elseif ($month_range) {
1370
-            $pieces          = explode(' ', $month_range, 3);
1371
-            $month_requested = ! empty($pieces[0])
1372
-                ? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0]))
1373
-                : '';
1374
-            $year_requested  = ! empty($pieces[1])
1375
-                ? $pieces[1]
1376
-                : '';
1377
-            //if there is not a month or year then we can't go further
1378
-            if ($month_requested && $year_requested) {
1379
-                $days_in_month     = date('t', strtotime($year_requested . '-' . $month_requested . '-' . '01'));
1380
-                $where['REG_date'] = array(
1381
-                    'BETWEEN',
1382
-                    array(
1383
-                        EEM_Registration::instance()->convert_datetime_for_query(
1384
-                            'REG_date',
1385
-                            $year_requested . '-' . $month_requested . '-01 00:00:00',
1386
-                            'Y-m-d H:i:s'
1387
-                        ),
1388
-                        EEM_Registration::instance()->convert_datetime_for_query(
1389
-                            'REG_date',
1390
-                            $year_requested . '-' . $month_requested . '-' . $days_in_month . ' 23:59:59',
1391
-                            'Y-m-d H:i:s'
1392
-                        ),
1393
-                    ),
1394
-                );
1395
-            }
1396
-        }
1397
-        return $where;
1398
-    }
1399
-
1400
-
1401
-    /**
1402
-     * Adds any provided search restraints to the where conditions for the registrations query
1403
-     *
1404
-     * @param array $request usually the same as $this->_req_data but not necessarily
1405
-     * @return array
1406
-     */
1407
-    protected function _add_search_to_where_conditions(array $request)
1408
-    {
1409
-        $where = array();
1410
-        if (! empty($request['s'])) {
1411
-            $search_string = '%' . sanitize_text_field($request['s']) . '%';
1412
-            $where['OR*search_conditions'] = array(
1413
-                'Event.EVT_name'                          => array('LIKE', $search_string),
1414
-                'Event.EVT_desc'                          => array('LIKE', $search_string),
1415
-                'Event.EVT_short_desc'                    => array('LIKE', $search_string),
1416
-                'Attendee.ATT_full_name'                  => array('LIKE', $search_string),
1417
-                'Attendee.ATT_fname'                      => array('LIKE', $search_string),
1418
-                'Attendee.ATT_lname'                      => array('LIKE', $search_string),
1419
-                'Attendee.ATT_short_bio'                  => array('LIKE', $search_string),
1420
-                'Attendee.ATT_email'                      => array('LIKE', $search_string),
1421
-                'Attendee.ATT_address'                    => array('LIKE', $search_string),
1422
-                'Attendee.ATT_address2'                   => array('LIKE', $search_string),
1423
-                'Attendee.ATT_city'                       => array('LIKE', $search_string),
1424
-                'REG_final_price'                         => array('LIKE', $search_string),
1425
-                'REG_code'                                => array('LIKE', $search_string),
1426
-                'REG_count'                               => array('LIKE', $search_string),
1427
-                'REG_group_size'                          => array('LIKE', $search_string),
1428
-                'Ticket.TKT_name'                         => array('LIKE', $search_string),
1429
-                'Ticket.TKT_description'                  => array('LIKE', $search_string),
1430
-                'Transaction.Payment.PAY_txn_id_chq_nmbr' => array('LIKE', $search_string),
1431
-            );
1432
-        }
1433
-        return $where;
1434
-    }
1435
-
1436
-
1437
-    /**
1438
-     * Sets up the where conditions for the registrations query.
1439
-     *
1440
-     * @param array $request
1441
-     * @return array
1442
-     * @throws EE_Error
1443
-     */
1444
-    protected function _get_where_conditions_for_registrations_query($request)
1445
-    {
1446
-        return apply_filters(
1447
-            'FHEE__Registrations_Admin_Page___get_where_conditions_for_registrations_query',
1448
-            array_merge(
1449
-                $this->addAttendeeIdToWhereConditions($request),
1450
-                $this->_add_event_id_to_where_conditions($request),
1451
-                $this->_add_category_id_to_where_conditions($request),
1452
-                $this->_add_datetime_id_to_where_conditions($request),
1453
-                $this->_add_registration_status_to_where_conditions($request),
1454
-                $this->_add_date_to_where_conditions($request),
1455
-                $this->_add_search_to_where_conditions($request)
1456
-            ),
1457
-            $request
1458
-        );
1459
-    }
1460
-
1461
-
1462
-    /**
1463
-     * Sets up the orderby for the registrations query.
1464
-     *
1465
-     * @return array
1466
-     */
1467
-    protected function _get_orderby_for_registrations_query()
1468
-    {
1469
-        $orderby_field = ! empty($this->_req_data['orderby'])
1470
-            ? sanitize_text_field($this->_req_data['orderby'])
1471
-            : '';
1472
-        switch ($orderby_field) {
1473
-            case '_REG_ID':
1474
-                $orderby = array('REG_ID');
1475
-                break;
1476
-            case '_Reg_status':
1477
-                $orderby = array('STS_ID');
1478
-                break;
1479
-            case 'ATT_fname':
1480
-                $orderby = array('Attendee.ATT_fname', 'Attendee.ATT_lname');
1481
-                break;
1482
-            case 'ATT_lname':
1483
-                $orderby = array('Attendee.ATT_lname', 'Attendee.ATT_fname');
1484
-                break;
1485
-            case 'event_name':
1486
-                $orderby = array('Event.EVT_name');
1487
-                break;
1488
-            case 'DTT_EVT_start':
1489
-                $orderby = array('Event.Datetime.DTT_EVT_start');
1490
-                break;
1491
-            default: //'REG_date'
1492
-                $orderby = array('REG_date');
1493
-        }
1494
-
1495
-        //order
1496
-        $order = ! empty($this->_req_data['order'])
1497
-            ? sanitize_text_field($this->_req_data['order'])
1498
-            : 'DESC';
1499
-        $orderby = array_combine(
1500
-            $orderby,
1501
-            array_fill(0, count($orderby), $order)
1502
-        );
1503
-        //because there are many registrations with the same date, define
1504
-        //a secondary way to order them, otherwise MySQL seems to be a bit random
1505
-        if (empty($orderby['REG_ID'])) {
1506
-            $orderby['REG_ID'] = $order;
1507
-        }
1508
-        return array('order_by' => $orderby);
1509
-    }
1510
-
1511
-
1512
-    /**
1513
-     * Sets up the limit for the registrations query.
1514
-     *
1515
-     * @param $per_page
1516
-     * @return array
1517
-     */
1518
-    protected function _get_limit($per_page)
1519
-    {
1520
-        $current_page = ! empty($this->_req_data['paged'])
1521
-            ? absint($this->_req_data['paged'])
1522
-            : 1;
1523
-        $per_page     = ! empty($this->_req_data['perpage'])
1524
-            ? $this->_req_data['perpage']
1525
-            : $per_page;
1526
-
1527
-        //-1 means return all results so get out if that's set.
1528
-        if ((int)$per_page === -1) {
1529
-            return array();
1530
-        }
1531
-        $per_page = absint($per_page);
1532
-        $offset   = ($current_page - 1) * $per_page;
1533
-        return array('limit' => array($offset, $per_page));
1534
-    }
1535
-
1536
-
1537
-    public function get_registration_status_array()
1538
-    {
1539
-        return self::$_reg_status;
1540
-    }
1541
-
1542
-
1543
-
1544
-
1545
-    /***************************************        REGISTRATION DETAILS        ***************************************/
1546
-    /**
1547
-     *        generates HTML for the View Registration Details Admin page
1548
-     *
1549
-     * @access protected
1550
-     * @return void
1551
-     * @throws DomainException
1552
-     * @throws EE_Error
1553
-     * @throws InvalidArgumentException
1554
-     * @throws InvalidDataTypeException
1555
-     * @throws InvalidInterfaceException
1556
-     * @throws EntityNotFoundException
1557
-     */
1558
-    protected function _registration_details()
1559
-    {
1560
-        $this->_template_args = array();
1561
-        $this->_set_registration_object();
1562
-        if (is_object($this->_registration)) {
1563
-            $transaction                                   = $this->_registration->transaction()
1564
-                ? $this->_registration->transaction()
1565
-                : EE_Transaction::new_instance();
1566
-            $this->_session                                = $transaction->session_data();
1567
-            $event_id                                      = $this->_registration->event_ID();
1568
-            $this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1569
-            $this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1570
-            $this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1571
-            $this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1572
-            $this->_template_args['grand_total']           = $transaction->total();
1573
-            $this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1574
-            // link back to overview
1575
-            $this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1576
-            $this->_template_args['registration']                = $this->_registration;
1577
-            $this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1578
-                array(
1579
-                    'action'   => 'default',
1580
-                    'event_id' => $event_id,
1581
-                ),
1582
-                REG_ADMIN_URL
1583
-            );
1584
-            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1585
-                array(
1586
-                    'action' => 'default',
1587
-                    'EVT_ID' => $event_id,
1588
-                    'page'   => 'espresso_transactions',
1589
-                ),
1590
-                admin_url('admin.php')
1591
-            );
1592
-            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1593
-                array(
1594
-                    'page'   => 'espresso_events',
1595
-                    'action' => 'edit',
1596
-                    'post'   => $event_id,
1597
-                ),
1598
-                admin_url('admin.php')
1599
-            );
1600
-            //next and previous links
1601
-            $next_reg                                      = $this->_registration->next(
1602
-                null,
1603
-                array(),
1604
-                'REG_ID'
1605
-            );
1606
-            $this->_template_args['next_registration']     = $next_reg
1607
-                ? $this->_next_link(
1608
-                    EE_Admin_Page::add_query_args_and_nonce(
1609
-                        array(
1610
-                            'action'  => 'view_registration',
1611
-                            '_REG_ID' => $next_reg['REG_ID'],
1612
-                        ),
1613
-                        REG_ADMIN_URL
1614
-                    ),
1615
-                    'dashicons dashicons-arrow-right ee-icon-size-22'
1616
-                )
1617
-                : '';
1618
-            $previous_reg                                  = $this->_registration->previous(
1619
-                null,
1620
-                array(),
1621
-                'REG_ID'
1622
-            );
1623
-            $this->_template_args['previous_registration'] = $previous_reg
1624
-                ? $this->_previous_link(
1625
-                    EE_Admin_Page::add_query_args_and_nonce(
1626
-                        array(
1627
-                            'action'  => 'view_registration',
1628
-                            '_REG_ID' => $previous_reg['REG_ID'],
1629
-                        ),
1630
-                        REG_ADMIN_URL
1631
-                    ),
1632
-                    'dashicons dashicons-arrow-left ee-icon-size-22'
1633
-                )
1634
-                : '';
1635
-            // grab header
1636
-            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1637
-            $this->_template_args['REG_ID']            = $this->_registration->ID();
1638
-            $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1639
-                $template_path,
1640
-                $this->_template_args,
1641
-                true
1642
-            );
1643
-        } else {
1644
-            $this->_template_args['admin_page_header'] = $this->display_espresso_notices();
1645
-        }
1646
-        // the details template wrapper
1647
-        $this->display_admin_page_with_sidebar();
1648
-    }
1649
-
1650
-
1651
-    protected function _registration_details_metaboxes()
1652
-    {
1653
-        do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1654
-        $this->_set_registration_object();
1655
-        $attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1656
-        add_meta_box('edit-reg-status-mbox', esc_html__('Registration Status', 'event_espresso'),
1657
-            array($this, 'set_reg_status_buttons_metabox'), $this->wp_page_slug, 'normal', 'high');
1658
-        add_meta_box('edit-reg-details-mbox', esc_html__('Registration Details', 'event_espresso'),
1659
-            array($this, '_reg_details_meta_box'), $this->wp_page_slug, 'normal', 'high');
1660
-        if ($attendee instanceof EE_Attendee
1661
-            && EE_Registry::instance()->CAP->current_user_can(
1662
-                'ee_edit_registration',
1663
-                'edit-reg-questions-mbox',
1664
-                $this->_registration->ID()
1665
-            )
1666
-        ) {
1667
-            add_meta_box(
1668
-                'edit-reg-questions-mbox',
1669
-                esc_html__('Registration Form Answers', 'event_espresso'),
1670
-                array($this, '_reg_questions_meta_box'),
1671
-                $this->wp_page_slug,
1672
-                'normal',
1673
-                'high'
1674
-            );
1675
-        }
1676
-        add_meta_box(
1677
-            'edit-reg-registrant-mbox',
1678
-            esc_html__('Contact Details', 'event_espresso'),
1679
-            array($this, '_reg_registrant_side_meta_box'),
1680
-            $this->wp_page_slug,
1681
-            'side',
1682
-            'high'
1683
-        );
1684
-        if ($this->_registration->group_size() > 1) {
1685
-            add_meta_box(
1686
-                'edit-reg-attendees-mbox',
1687
-                esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1688
-                array($this, '_reg_attendees_meta_box'),
1689
-                $this->wp_page_slug,
1690
-                'normal',
1691
-                'high'
1692
-            );
1693
-        }
1694
-    }
1695
-
1696
-
1697
-    /**
1698
-     * set_reg_status_buttons_metabox
1699
-     *
1700
-     * @access protected
1701
-     * @return string
1702
-     * @throws \EE_Error
1703
-     */
1704
-    public function set_reg_status_buttons_metabox()
1705
-    {
1706
-        $this->_set_registration_object();
1707
-        $change_reg_status_form = $this->_generate_reg_status_change_form();
1708
-        echo $change_reg_status_form->form_open(
1709
-            self::add_query_args_and_nonce(
1710
-                array(
1711
-                    'action' => 'change_reg_status',
1712
-                ),
1713
-                REG_ADMIN_URL
1714
-            )
1715
-        );
1716
-        echo $change_reg_status_form->get_html();
1717
-        echo $change_reg_status_form->form_close();
1718
-    }
1719
-
1720
-
1721
-    /**
1722
-     * @return EE_Form_Section_Proper
1723
-     * @throws EE_Error
1724
-     * @throws InvalidArgumentException
1725
-     * @throws InvalidDataTypeException
1726
-     * @throws InvalidInterfaceException
1727
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1728
-     */
1729
-    protected function _generate_reg_status_change_form()
1730
-    {
1731
-        return new EE_Form_Section_Proper(array(
1732
-            'name'            => 'reg_status_change_form',
1733
-            'html_id'         => 'reg-status-change-form',
1734
-            'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1735
-            'subsections'     => array(
1736
-                'return'             => new EE_Hidden_Input(array(
1737
-                    'name'    => 'return',
1738
-                    'default' => 'view_registration',
1739
-                )),
1740
-                'REG_ID'             => new EE_Hidden_Input(array(
1741
-                    'name'    => 'REG_ID',
1742
-                    'default' => $this->_registration->ID(),
1743
-                )),
1744
-                'current_status'     => new EE_Form_Section_HTML(
1745
-                    EEH_HTML::tr(
1746
-                        EEH_HTML::th(
1747
-                            EEH_HTML::label(
1748
-                                EEH_HTML::strong(esc_html__('Current Registration Status', 'event_espresso')
1749
-                                )
1750
-                            )
1751
-                        )
1752
-                        . EEH_HTML::td(
1753
-                            EEH_HTML::strong(
1754
-                                $this->_registration->pretty_status(),
1755
-                                '',
1756
-                                'status-' . $this->_registration->status_ID(),
1757
-                                'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1758
-                            )
1759
-                        )
1760
-                    )
1761
-                ),
1762
-                'reg_status'         => new EE_Select_Input(
1763
-                    $this->_get_reg_statuses(),
1764
-                    array(
1765
-                        'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1766
-                        'default'         => $this->_registration->status_ID(),
1767
-                    )
1768
-                ),
1769
-                'send_notifications' => new EE_Yes_No_Input(
1770
-                    array(
1771
-                        'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1772
-                        'default'         => false,
1773
-                        'html_help_text'  => esc_html__(
1774
-                            'If set to "Yes", then the related messages will be sent to the registrant.',
1775
-                            'event_espresso'
1776
-                        ),
1777
-                    )
1778
-                ),
1779
-                'submit'             => new EE_Submit_Input(
1780
-                    array(
1781
-                        'html_class'      => 'button-primary',
1782
-                        'html_label_text' => '&nbsp;',
1783
-                        'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1784
-                    )
1785
-                ),
1786
-            ),
1787
-        ));
1788
-    }
1789
-
1790
-
1791
-    /**
1792
-     * Returns an array of all the buttons for the various statuses and switch status actions
1793
-     *
1794
-     * @return array
1795
-     * @throws EE_Error
1796
-     * @throws InvalidArgumentException
1797
-     * @throws InvalidDataTypeException
1798
-     * @throws InvalidInterfaceException
1799
-     * @throws EntityNotFoundException
1800
-     */
1801
-    protected function _get_reg_statuses()
1802
-    {
1803
-        $reg_status_array = EEM_Registration::instance()->reg_status_array();
1804
-        unset ($reg_status_array[EEM_Registration::status_id_incomplete]);
1805
-        // get current reg status
1806
-        $current_status = $this->_registration->status_ID();
1807
-        // is registration for free event? This will determine whether to display the pending payment option
1808
-        if (
1809
-            $current_status !== EEM_Registration::status_id_pending_payment
1810
-            && EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1811
-        ) {
1812
-            unset($reg_status_array[EEM_Registration::status_id_pending_payment]);
1813
-        }
1814
-        return EEM_Status::instance()->localized_status($reg_status_array, false, 'sentence');
1815
-    }
1816
-
1817
-
1818
-    /**
1819
-     * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1820
-     *
1821
-     * @param bool $status REG status given for changing registrations to.
1822
-     * @param bool $notify Whether to send messages notifications or not.
1823
-     * @return array (array with reg_id(s) updated and whether update was successful.
1824
-     * @throws EE_Error
1825
-     * @throws InvalidArgumentException
1826
-     * @throws InvalidDataTypeException
1827
-     * @throws InvalidInterfaceException
1828
-     * @throws ReflectionException
1829
-     * @throws RuntimeException
1830
-     * @throws EntityNotFoundException
1831
-     */
1832
-    protected function _set_registration_status_from_request($status = false, $notify = false)
1833
-    {
1834
-        if (isset($this->_req_data['reg_status_change_form'])) {
1835
-            $REG_IDs = isset($this->_req_data['reg_status_change_form']['REG_ID'])
1836
-                ? (array)$this->_req_data['reg_status_change_form']['REG_ID']
1837
-                : array();
1838
-        } else {
1839
-            $REG_IDs = isset($this->_req_data['_REG_ID'])
1840
-                ? (array)$this->_req_data['_REG_ID']
1841
-                : array();
1842
-        }
1843
-        // sanitize $REG_IDs
1844
-        $REG_IDs = array_map('absint', $REG_IDs);
1845
-        // and remove empty entries
1846
-        $REG_IDs = array_filter($REG_IDs);
1847
-
1848
-        $result = $this->_set_registration_status($REG_IDs, $status, $notify);
1849
-
1850
-        /**
1851
-         * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1852
-         * Currently this value is used downstream by the _process_resend_registration method.
1853
-         *
1854
-         * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1855
-         * @param bool                     $status           The status registrations were changed to.
1856
-         * @param bool                     $success          If the status was changed successfully for all registrations.
1857
-         * @param Registrations_Admin_Page $admin_page_object
1858
-         */
1859
-        $this->_req_data['_REG_ID'] = apply_filters(
1860
-            'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1861
-            $result['REG_ID'],
1862
-            $status,
1863
-            $result['success'],
1864
-            $this
1865
-        );
1866
-
1867
-        //notify?
1868
-        if ($notify
1869
-            && $result['success']
1870
-            && ! empty($this->_req_data['_REG_ID'])
1871
-            && EE_Registry::instance()->CAP->current_user_can(
1872
-                'ee_send_message',
1873
-                'espresso_registrations_resend_registration'
1874
-            )
1875
-        ) {
1876
-            $this->_process_resend_registration();
1877
-        }
1878
-        return $result;
1879
-    }
1880
-
1881
-
1882
-    /**
1883
-     * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1884
-     * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1885
-     *
1886
-     * @param array  $REG_IDs
1887
-     * @param string $status
1888
-     * @param bool   $notify  Used to indicate whether notification was requested or not.  This determines the context
1889
-     *                        slug sent with setting the registration status.
1890
-     * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1891
-     * @throws EE_Error
1892
-     * @throws InvalidArgumentException
1893
-     * @throws InvalidDataTypeException
1894
-     * @throws InvalidInterfaceException
1895
-     * @throws ReflectionException
1896
-     * @throws RuntimeException
1897
-     * @throws EntityNotFoundException
1898
-     */
1899
-    protected function _set_registration_status($REG_IDs = array(), $status = '', $notify = false)
1900
-    {
1901
-        $success = false;
1902
-        // typecast $REG_IDs
1903
-        $REG_IDs = (array)$REG_IDs;
1904
-        if ( ! empty($REG_IDs)) {
1905
-            $success = true;
1906
-            // set default status if none is passed
1907
-            $status = $status ? $status : EEM_Registration::status_id_pending_payment;
1908
-            $status_context = $notify
1909
-                ? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1910
-                : Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1911
-            //loop through REG_ID's and change status
1912
-            foreach ($REG_IDs as $REG_ID) {
1913
-                $registration = EEM_Registration::instance()->get_one_by_ID($REG_ID);
1914
-                if ($registration instanceof EE_Registration) {
1915
-                    $registration->set_status(
1916
-                        $status,
1917
-                        false,
1918
-                        new Context(
1919
-                            $status_context,
1920
-                            esc_html__(
1921
-                                'Manually triggered status change on a Registration Admin Page route.',
1922
-                                'event_espresso'
1923
-                            )
1924
-                        )
1925
-                    );
1926
-                    $result = $registration->save();
1927
-                    // verifying explicit fails because update *may* just return 0 for 0 rows affected
1928
-                    $success = $result !== false ? $success : false;
1929
-                }
1930
-            }
1931
-        }
1932
-
1933
-        //return $success and processed registrations
1934
-        return array('REG_ID' => $REG_IDs, 'success' => $success);
1935
-    }
1936
-
1937
-
1938
-    /**
1939
-     * Common logic for setting up success message and redirecting to appropriate route
1940
-     *
1941
-     * @param  string $STS_ID status id for the registration changed to
1942
-     * @param   bool  $notify indicates whether the _set_registration_status_from_request does notifications or not.
1943
-     * @return void
1944
-     * @throws EE_Error
1945
-     */
1946
-    protected function _reg_status_change_return($STS_ID, $notify = false)
1947
-    {
1948
-        $result  = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1949
-            : array('success' => false);
1950
-        $success = isset($result['success']) && $result['success'];
1951
-        //setup success message
1952
-        if ($success) {
1953
-            if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1954
-                $msg = sprintf(esc_html__('Registration status has been set to %s', 'event_espresso'),
1955
-                    EEH_Template::pretty_status($STS_ID, false, 'lower'));
1956
-            } else {
1957
-                $msg = sprintf(esc_html__('Registrations have been set to %s.', 'event_espresso'),
1958
-                    EEH_Template::pretty_status($STS_ID, false, 'lower'));
1959
-            }
1960
-            EE_Error::add_success($msg);
1961
-        } else {
1962
-            EE_Error::add_error(
1963
-                esc_html__(
1964
-                    'Something went wrong, and the status was not changed',
1965
-                    'event_espresso'
1966
-                ), __FILE__, __LINE__, __FUNCTION__
1967
-            );
1968
-        }
1969
-        if (isset($this->_req_data['return']) && $this->_req_data['return'] == 'view_registration') {
1970
-            $route = array('action' => 'view_registration', '_REG_ID' => reset($result['REG_ID']));
1971
-        } else {
1972
-            $route = array('action' => 'default');
1973
-        }
1974
-        //unset nonces
1975
-        foreach ($this->_req_data as $ref => $value) {
1976
-            if (strpos($ref, 'nonce') !== false) {
1977
-                unset($this->_req_data[$ref]);
1978
-                continue;
1979
-            }
1980
-            $value                 = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
1981
-            $this->_req_data[$ref] = $value;
1982
-        }
1983
-        //merge request vars so that the reloaded list table contains any existing filter query params
1984
-        $route = array_merge($this->_req_data, $route);
1985
-        $this->_redirect_after_action($success, '', '', $route, true);
1986
-    }
1987
-
1988
-
1989
-    /**
1990
-     * incoming reg status change from reg details page.
1991
-     *
1992
-     * @return void
1993
-     */
1994
-    protected function _change_reg_status()
1995
-    {
1996
-        $this->_req_data['return'] = 'view_registration';
1997
-        //set notify based on whether the send notifications toggle is set or not
1998
-        $notify = ! empty($this->_req_data['reg_status_change_form']['send_notifications']);
1999
-        //$notify = ! empty( $this->_req_data['txn_reg_status_change']['send_notifications'] );
2000
-        $this->_req_data['reg_status_change_form']['reg_status'] = isset($this->_req_data['reg_status_change_form']['reg_status'])
2001
-            ? $this->_req_data['reg_status_change_form']['reg_status'] : '';
2002
-        switch ($this->_req_data['reg_status_change_form']['reg_status']) {
2003
-            case EEM_Registration::status_id_approved :
2004
-            case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence') :
2005
-                $this->approve_registration($notify);
2006
-                break;
2007
-            case EEM_Registration::status_id_pending_payment :
2008
-            case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence') :
2009
-                $this->pending_registration($notify);
2010
-                break;
2011
-            case EEM_Registration::status_id_not_approved :
2012
-            case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence') :
2013
-                $this->not_approve_registration($notify);
2014
-                break;
2015
-            case EEM_Registration::status_id_declined :
2016
-            case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence') :
2017
-                $this->decline_registration($notify);
2018
-                break;
2019
-            case EEM_Registration::status_id_cancelled :
2020
-            case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence') :
2021
-                $this->cancel_registration($notify);
2022
-                break;
2023
-            case EEM_Registration::status_id_wait_list :
2024
-            case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence') :
2025
-                $this->wait_list_registration($notify);
2026
-                break;
2027
-            case EEM_Registration::status_id_incomplete :
2028
-            default :
2029
-                $result['success'] = false;
2030
-                unset($this->_req_data['return']);
2031
-                $this->_reg_status_change_return('', false);
2032
-                break;
2033
-        }
2034
-    }
2035
-
2036
-
2037
-    /**
2038
-     * Callback for bulk action routes.
2039
-     * Note: although we could just register the singular route callbacks for each bulk action route as well, this
2040
-     * method was chosen so there is one central place all the registration status bulk actions are going through.
2041
-     * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
2042
-     * when an action is happening on just a single registration).
2043
-     * @param      $action
2044
-     * @param bool $notify
2045
-     */
2046
-    protected function bulk_action_on_registrations($action, $notify = false) {
2047
-        do_action(
2048
-            'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
2049
-            $this,
2050
-            $action,
2051
-            $notify
2052
-        );
2053
-        $method = $action . '_registration';
2054
-        if (method_exists($this, $method)) {
2055
-            $this->$method($notify);
2056
-        }
2057
-    }
2058
-
2059
-
2060
-    /**
2061
-     * approve_registration
2062
-     *
2063
-     * @access protected
2064
-     * @param bool $notify whether or not to notify the registrant about their approval.
2065
-     * @return void
2066
-     */
2067
-    protected function approve_registration($notify = false)
2068
-    {
2069
-        $this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
2070
-    }
2071
-
2072
-
2073
-    /**
2074
-     *        decline_registration
2075
-     *
2076
-     * @access protected
2077
-     * @param bool $notify whether or not to notify the registrant about their status change.
2078
-     * @return void
2079
-     */
2080
-    protected function decline_registration($notify = false)
2081
-    {
2082
-        $this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
2083
-    }
2084
-
2085
-
2086
-    /**
2087
-     *        cancel_registration
2088
-     *
2089
-     * @access protected
2090
-     * @param bool $notify whether or not to notify the registrant about their status change.
2091
-     * @return void
2092
-     */
2093
-    protected function cancel_registration($notify = false)
2094
-    {
2095
-        $this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
2096
-    }
2097
-
2098
-
2099
-    /**
2100
-     *        not_approve_registration
2101
-     *
2102
-     * @access protected
2103
-     * @param bool $notify whether or not to notify the registrant about their status change.
2104
-     * @return void
2105
-     */
2106
-    protected function not_approve_registration($notify = false)
2107
-    {
2108
-        $this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
2109
-    }
2110
-
2111
-
2112
-    /**
2113
-     *        decline_registration
2114
-     *
2115
-     * @access protected
2116
-     * @param bool $notify whether or not to notify the registrant about their status change.
2117
-     * @return void
2118
-     */
2119
-    protected function pending_registration($notify = false)
2120
-    {
2121
-        $this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
2122
-    }
2123
-
2124
-
2125
-    /**
2126
-     * waitlist_registration
2127
-     *
2128
-     * @access protected
2129
-     * @param bool $notify whether or not to notify the registrant about their status change.
2130
-     * @return void
2131
-     */
2132
-    protected function wait_list_registration($notify = false)
2133
-    {
2134
-        $this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
2135
-    }
2136
-
2137
-
2138
-    /**
2139
-     *        generates HTML for the Registration main meta box
2140
-     *
2141
-     * @access public
2142
-     * @return void
2143
-     * @throws DomainException
2144
-     * @throws EE_Error
2145
-     * @throws InvalidArgumentException
2146
-     * @throws InvalidDataTypeException
2147
-     * @throws InvalidInterfaceException
2148
-     * @throws ReflectionException
2149
-     * @throws EntityNotFoundException
2150
-     */
2151
-    public function _reg_details_meta_box()
2152
-    {
2153
-        EEH_Autoloader::register_line_item_display_autoloaders();
2154
-        EEH_Autoloader::register_line_item_filter_autoloaders();
2155
-        EE_Registry::instance()->load_helper('Line_Item');
2156
-        $transaction    = $this->_registration->transaction() ? $this->_registration->transaction()
2157
-            : EE_Transaction::new_instance();
2158
-        $this->_session = $transaction->session_data();
2159
-        $filters        = new EE_Line_Item_Filter_Collection();
2160
-        //$filters->add( new EE_Non_Zero_Line_Item_Filter() );
2161
-        $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2162
-        $line_item_filter_processor              = new EE_Line_Item_Filter_Processor($filters,
2163
-            $transaction->total_line_item());
2164
-        $filtered_line_item_tree                 = $line_item_filter_processor->process();
2165
-        $line_item_display                       = new EE_Line_Item_Display('reg_admin_table',
2166
-            'EE_Admin_Table_Registration_Line_Item_Display_Strategy');
2167
-        $this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2168
-            $filtered_line_item_tree,
2169
-            array('EE_Registration' => $this->_registration)
2170
-        );
2171
-        $attendee                                = $this->_registration->attendee();
2172
-        if (EE_Registry::instance()->CAP->current_user_can(
2173
-            'ee_read_transaction',
2174
-            'espresso_transactions_view_transaction'
2175
-        )) {
2176
-            $this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2177
-                EE_Admin_Page::add_query_args_and_nonce(
2178
-                    array(
2179
-                        'action' => 'view_transaction',
2180
-                        'TXN_ID' => $transaction->ID(),
2181
-                    ),
2182
-                    TXN_ADMIN_URL
2183
-                ),
2184
-                esc_html__(' View Transaction', 'event_espresso'),
2185
-                'button secondary-button right',
2186
-                'dashicons dashicons-cart'
2187
-            );
2188
-        } else {
2189
-            $this->_template_args['view_transaction_button'] = '';
2190
-        }
2191
-        if ($attendee instanceof EE_Attendee
2192
-            && EE_Registry::instance()->CAP->current_user_can(
2193
-                'ee_send_message',
2194
-                'espresso_registrations_resend_registration'
2195
-            )
2196
-        ) {
2197
-            $this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2198
-                EE_Admin_Page::add_query_args_and_nonce(
2199
-                    array(
2200
-                        'action'      => 'resend_registration',
2201
-                        '_REG_ID'     => $this->_registration->ID(),
2202
-                        'redirect_to' => 'view_registration',
2203
-                    ),
2204
-                    REG_ADMIN_URL
2205
-                ),
2206
-                esc_html__(' Resend Registration', 'event_espresso'),
2207
-                'button secondary-button right',
2208
-                'dashicons dashicons-email-alt'
2209
-            );
2210
-        } else {
2211
-            $this->_template_args['resend_registration_button'] = '';
2212
-        }
2213
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2214
-        $payment                               = $transaction->get_first_related('Payment');
2215
-        $payment                               = ! $payment instanceof EE_Payment
2216
-            ? EE_Payment::new_instance()
2217
-            : $payment;
2218
-        $payment_method                        = $payment->get_first_related('Payment_Method');
2219
-        $payment_method                        = ! $payment_method instanceof EE_Payment_Method
2220
-            ? EE_Payment_Method::new_instance()
2221
-            : $payment_method;
2222
-        $reg_details                           = array(
2223
-            'payment_method'       => $payment_method->name(),
2224
-            'response_msg'         => $payment->gateway_response(),
2225
-            'registration_id'      => $this->_registration->get('REG_code'),
2226
-            'registration_session' => $this->_registration->session_ID(),
2227
-            'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2228
-            'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2229
-        );
2230
-        if (isset($reg_details['registration_id'])) {
2231
-            $this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2232
-            $this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2233
-                'Registration ID',
2234
-                'event_espresso'
2235
-            );
2236
-            $this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2237
-        }
2238
-        if (isset($reg_details['payment_method'])) {
2239
-            $this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2240
-            $this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2241
-                'Most Recent Payment Method',
2242
-                'event_espresso'
2243
-            );
2244
-            $this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2245
-            $this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2246
-            $this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2247
-                'Payment method response',
2248
-                'event_espresso'
2249
-            );
2250
-            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2251
-        }
2252
-        $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2253
-        $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2254
-            'Registration Session',
2255
-            'event_espresso'
2256
-        );
2257
-        $this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2258
-        $this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2259
-        $this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2260
-            'Registration placed from IP',
2261
-            'event_espresso'
2262
-        );
2263
-        $this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2264
-        $this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2265
-        $this->_template_args['reg_details']['user_agent']['label']           = esc_html__('Registrant User Agent',
2266
-            'event_espresso');
2267
-        $this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2268
-        $this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2269
-            array(
2270
-                'action'   => 'default',
2271
-                'event_id' => $this->_registration->event_ID(),
2272
-            ),
2273
-            REG_ADMIN_URL
2274
-        );
2275
-        $this->_template_args['REG_ID']                                       = $this->_registration->ID();
2276
-        $this->_template_args['event_id']                                     = $this->_registration->event_ID();
2277
-        $template_path                                                        =
2278
-            REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2279
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2280
-    }
2281
-
2282
-
2283
-    /**
2284
-     * generates HTML for the Registration Questions meta box.
2285
-     * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2286
-     * otherwise uses new forms system
2287
-     *
2288
-     * @access public
2289
-     * @return void
2290
-     * @throws DomainException
2291
-     * @throws EE_Error
2292
-     */
2293
-    public function _reg_questions_meta_box()
2294
-    {
2295
-        //allow someone to override this method entirely
2296
-        if (apply_filters('FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default', true, $this,
2297
-            $this->_registration)) {
2298
-            $form                                              = $this->_get_reg_custom_questions_form(
2299
-                $this->_registration->ID()
2300
-            );
2301
-            $this->_template_args['att_questions']             = count($form->subforms()) > 0
2302
-                ? $form->get_html_and_js()
2303
-                : '';
2304
-            $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2305
-            $this->_template_args['REG_ID']                    = $this->_registration->ID();
2306
-            $template_path                                     =
2307
-                REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2308
-            echo EEH_Template::display_template($template_path, $this->_template_args, true);
2309
-        }
2310
-    }
2311
-
2312
-
2313
-    /**
2314
-     * form_before_question_group
2315
-     *
2316
-     * @deprecated    as of 4.8.32.rc.000
2317
-     * @access        public
2318
-     * @param        string $output
2319
-     * @return        string
2320
-     */
2321
-    public function form_before_question_group($output)
2322
-    {
2323
-        EE_Error::doing_it_wrong(
2324
-            __CLASS__ . '::' . __FUNCTION__,
2325
-            esc_html__(
2326
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2327
-                'event_espresso'
2328
-            ),
2329
-            '4.8.32.rc.000'
2330
-        );
2331
-        return '
1298
+		if (! empty($registration_status)) {
1299
+			$where['STS_ID'] = $registration_status;
1300
+		} else {
1301
+			//make sure we exclude incomplete registrations, but only if not trashed.
1302
+			if ($view === 'trash') {
1303
+				$where['REG_deleted'] = true;
1304
+			} elseif ($view === 'incomplete') {
1305
+				$where['STS_ID'] = EEM_Registration::status_id_incomplete;
1306
+			} else {
1307
+				$where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete);
1308
+			}
1309
+		}
1310
+		return $where;
1311
+	}
1312
+
1313
+
1314
+	/**
1315
+	 * Adds any provided date restraints to the where conditions for the registrations query.
1316
+	 *
1317
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1318
+	 * @return array
1319
+	 * @throws EE_Error
1320
+	 * @throws InvalidArgumentException
1321
+	 * @throws InvalidDataTypeException
1322
+	 * @throws InvalidInterfaceException
1323
+	 */
1324
+	protected function _add_date_to_where_conditions(array $request)
1325
+	{
1326
+		$where = array();
1327
+		$view = EEH_Array::is_set($request, 'status', '');
1328
+		$month_range             = ! empty($request['month_range'])
1329
+			? sanitize_text_field($request['month_range'])
1330
+			: '';
1331
+		$retrieve_for_today      = $view === 'today';
1332
+		$retrieve_for_this_month = $view === 'month';
1333
+
1334
+		if ($retrieve_for_today) {
1335
+			$now               = date('Y-m-d', current_time('timestamp'));
1336
+			$where['REG_date'] = array(
1337
+				'BETWEEN',
1338
+				array(
1339
+					EEM_Registration::instance()->convert_datetime_for_query(
1340
+						'REG_date',
1341
+						$now . ' 00:00:00',
1342
+						'Y-m-d H:i:s'
1343
+					),
1344
+					EEM_Registration::instance()->convert_datetime_for_query(
1345
+						'REG_date',
1346
+						$now . ' 23:59:59',
1347
+						'Y-m-d H:i:s'
1348
+					),
1349
+				),
1350
+			);
1351
+		} elseif ($retrieve_for_this_month) {
1352
+			$current_year_and_month = date('Y-m', current_time('timestamp'));
1353
+			$days_this_month        = date('t', current_time('timestamp'));
1354
+			$where['REG_date']      = array(
1355
+				'BETWEEN',
1356
+				array(
1357
+					EEM_Registration::instance()->convert_datetime_for_query(
1358
+						'REG_date',
1359
+						$current_year_and_month . '-01 00:00:00',
1360
+						'Y-m-d H:i:s'
1361
+					),
1362
+					EEM_Registration::instance()->convert_datetime_for_query(
1363
+						'REG_date',
1364
+						$current_year_and_month . '-' . $days_this_month . ' 23:59:59',
1365
+						'Y-m-d H:i:s'
1366
+					),
1367
+				),
1368
+			);
1369
+		} elseif ($month_range) {
1370
+			$pieces          = explode(' ', $month_range, 3);
1371
+			$month_requested = ! empty($pieces[0])
1372
+				? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0]))
1373
+				: '';
1374
+			$year_requested  = ! empty($pieces[1])
1375
+				? $pieces[1]
1376
+				: '';
1377
+			//if there is not a month or year then we can't go further
1378
+			if ($month_requested && $year_requested) {
1379
+				$days_in_month     = date('t', strtotime($year_requested . '-' . $month_requested . '-' . '01'));
1380
+				$where['REG_date'] = array(
1381
+					'BETWEEN',
1382
+					array(
1383
+						EEM_Registration::instance()->convert_datetime_for_query(
1384
+							'REG_date',
1385
+							$year_requested . '-' . $month_requested . '-01 00:00:00',
1386
+							'Y-m-d H:i:s'
1387
+						),
1388
+						EEM_Registration::instance()->convert_datetime_for_query(
1389
+							'REG_date',
1390
+							$year_requested . '-' . $month_requested . '-' . $days_in_month . ' 23:59:59',
1391
+							'Y-m-d H:i:s'
1392
+						),
1393
+					),
1394
+				);
1395
+			}
1396
+		}
1397
+		return $where;
1398
+	}
1399
+
1400
+
1401
+	/**
1402
+	 * Adds any provided search restraints to the where conditions for the registrations query
1403
+	 *
1404
+	 * @param array $request usually the same as $this->_req_data but not necessarily
1405
+	 * @return array
1406
+	 */
1407
+	protected function _add_search_to_where_conditions(array $request)
1408
+	{
1409
+		$where = array();
1410
+		if (! empty($request['s'])) {
1411
+			$search_string = '%' . sanitize_text_field($request['s']) . '%';
1412
+			$where['OR*search_conditions'] = array(
1413
+				'Event.EVT_name'                          => array('LIKE', $search_string),
1414
+				'Event.EVT_desc'                          => array('LIKE', $search_string),
1415
+				'Event.EVT_short_desc'                    => array('LIKE', $search_string),
1416
+				'Attendee.ATT_full_name'                  => array('LIKE', $search_string),
1417
+				'Attendee.ATT_fname'                      => array('LIKE', $search_string),
1418
+				'Attendee.ATT_lname'                      => array('LIKE', $search_string),
1419
+				'Attendee.ATT_short_bio'                  => array('LIKE', $search_string),
1420
+				'Attendee.ATT_email'                      => array('LIKE', $search_string),
1421
+				'Attendee.ATT_address'                    => array('LIKE', $search_string),
1422
+				'Attendee.ATT_address2'                   => array('LIKE', $search_string),
1423
+				'Attendee.ATT_city'                       => array('LIKE', $search_string),
1424
+				'REG_final_price'                         => array('LIKE', $search_string),
1425
+				'REG_code'                                => array('LIKE', $search_string),
1426
+				'REG_count'                               => array('LIKE', $search_string),
1427
+				'REG_group_size'                          => array('LIKE', $search_string),
1428
+				'Ticket.TKT_name'                         => array('LIKE', $search_string),
1429
+				'Ticket.TKT_description'                  => array('LIKE', $search_string),
1430
+				'Transaction.Payment.PAY_txn_id_chq_nmbr' => array('LIKE', $search_string),
1431
+			);
1432
+		}
1433
+		return $where;
1434
+	}
1435
+
1436
+
1437
+	/**
1438
+	 * Sets up the where conditions for the registrations query.
1439
+	 *
1440
+	 * @param array $request
1441
+	 * @return array
1442
+	 * @throws EE_Error
1443
+	 */
1444
+	protected function _get_where_conditions_for_registrations_query($request)
1445
+	{
1446
+		return apply_filters(
1447
+			'FHEE__Registrations_Admin_Page___get_where_conditions_for_registrations_query',
1448
+			array_merge(
1449
+				$this->addAttendeeIdToWhereConditions($request),
1450
+				$this->_add_event_id_to_where_conditions($request),
1451
+				$this->_add_category_id_to_where_conditions($request),
1452
+				$this->_add_datetime_id_to_where_conditions($request),
1453
+				$this->_add_registration_status_to_where_conditions($request),
1454
+				$this->_add_date_to_where_conditions($request),
1455
+				$this->_add_search_to_where_conditions($request)
1456
+			),
1457
+			$request
1458
+		);
1459
+	}
1460
+
1461
+
1462
+	/**
1463
+	 * Sets up the orderby for the registrations query.
1464
+	 *
1465
+	 * @return array
1466
+	 */
1467
+	protected function _get_orderby_for_registrations_query()
1468
+	{
1469
+		$orderby_field = ! empty($this->_req_data['orderby'])
1470
+			? sanitize_text_field($this->_req_data['orderby'])
1471
+			: '';
1472
+		switch ($orderby_field) {
1473
+			case '_REG_ID':
1474
+				$orderby = array('REG_ID');
1475
+				break;
1476
+			case '_Reg_status':
1477
+				$orderby = array('STS_ID');
1478
+				break;
1479
+			case 'ATT_fname':
1480
+				$orderby = array('Attendee.ATT_fname', 'Attendee.ATT_lname');
1481
+				break;
1482
+			case 'ATT_lname':
1483
+				$orderby = array('Attendee.ATT_lname', 'Attendee.ATT_fname');
1484
+				break;
1485
+			case 'event_name':
1486
+				$orderby = array('Event.EVT_name');
1487
+				break;
1488
+			case 'DTT_EVT_start':
1489
+				$orderby = array('Event.Datetime.DTT_EVT_start');
1490
+				break;
1491
+			default: //'REG_date'
1492
+				$orderby = array('REG_date');
1493
+		}
1494
+
1495
+		//order
1496
+		$order = ! empty($this->_req_data['order'])
1497
+			? sanitize_text_field($this->_req_data['order'])
1498
+			: 'DESC';
1499
+		$orderby = array_combine(
1500
+			$orderby,
1501
+			array_fill(0, count($orderby), $order)
1502
+		);
1503
+		//because there are many registrations with the same date, define
1504
+		//a secondary way to order them, otherwise MySQL seems to be a bit random
1505
+		if (empty($orderby['REG_ID'])) {
1506
+			$orderby['REG_ID'] = $order;
1507
+		}
1508
+		return array('order_by' => $orderby);
1509
+	}
1510
+
1511
+
1512
+	/**
1513
+	 * Sets up the limit for the registrations query.
1514
+	 *
1515
+	 * @param $per_page
1516
+	 * @return array
1517
+	 */
1518
+	protected function _get_limit($per_page)
1519
+	{
1520
+		$current_page = ! empty($this->_req_data['paged'])
1521
+			? absint($this->_req_data['paged'])
1522
+			: 1;
1523
+		$per_page     = ! empty($this->_req_data['perpage'])
1524
+			? $this->_req_data['perpage']
1525
+			: $per_page;
1526
+
1527
+		//-1 means return all results so get out if that's set.
1528
+		if ((int)$per_page === -1) {
1529
+			return array();
1530
+		}
1531
+		$per_page = absint($per_page);
1532
+		$offset   = ($current_page - 1) * $per_page;
1533
+		return array('limit' => array($offset, $per_page));
1534
+	}
1535
+
1536
+
1537
+	public function get_registration_status_array()
1538
+	{
1539
+		return self::$_reg_status;
1540
+	}
1541
+
1542
+
1543
+
1544
+
1545
+	/***************************************        REGISTRATION DETAILS        ***************************************/
1546
+	/**
1547
+	 *        generates HTML for the View Registration Details Admin page
1548
+	 *
1549
+	 * @access protected
1550
+	 * @return void
1551
+	 * @throws DomainException
1552
+	 * @throws EE_Error
1553
+	 * @throws InvalidArgumentException
1554
+	 * @throws InvalidDataTypeException
1555
+	 * @throws InvalidInterfaceException
1556
+	 * @throws EntityNotFoundException
1557
+	 */
1558
+	protected function _registration_details()
1559
+	{
1560
+		$this->_template_args = array();
1561
+		$this->_set_registration_object();
1562
+		if (is_object($this->_registration)) {
1563
+			$transaction                                   = $this->_registration->transaction()
1564
+				? $this->_registration->transaction()
1565
+				: EE_Transaction::new_instance();
1566
+			$this->_session                                = $transaction->session_data();
1567
+			$event_id                                      = $this->_registration->event_ID();
1568
+			$this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1569
+			$this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1570
+			$this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1571
+			$this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1572
+			$this->_template_args['grand_total']           = $transaction->total();
1573
+			$this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1574
+			// link back to overview
1575
+			$this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1576
+			$this->_template_args['registration']                = $this->_registration;
1577
+			$this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1578
+				array(
1579
+					'action'   => 'default',
1580
+					'event_id' => $event_id,
1581
+				),
1582
+				REG_ADMIN_URL
1583
+			);
1584
+			$this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1585
+				array(
1586
+					'action' => 'default',
1587
+					'EVT_ID' => $event_id,
1588
+					'page'   => 'espresso_transactions',
1589
+				),
1590
+				admin_url('admin.php')
1591
+			);
1592
+			$this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1593
+				array(
1594
+					'page'   => 'espresso_events',
1595
+					'action' => 'edit',
1596
+					'post'   => $event_id,
1597
+				),
1598
+				admin_url('admin.php')
1599
+			);
1600
+			//next and previous links
1601
+			$next_reg                                      = $this->_registration->next(
1602
+				null,
1603
+				array(),
1604
+				'REG_ID'
1605
+			);
1606
+			$this->_template_args['next_registration']     = $next_reg
1607
+				? $this->_next_link(
1608
+					EE_Admin_Page::add_query_args_and_nonce(
1609
+						array(
1610
+							'action'  => 'view_registration',
1611
+							'_REG_ID' => $next_reg['REG_ID'],
1612
+						),
1613
+						REG_ADMIN_URL
1614
+					),
1615
+					'dashicons dashicons-arrow-right ee-icon-size-22'
1616
+				)
1617
+				: '';
1618
+			$previous_reg                                  = $this->_registration->previous(
1619
+				null,
1620
+				array(),
1621
+				'REG_ID'
1622
+			);
1623
+			$this->_template_args['previous_registration'] = $previous_reg
1624
+				? $this->_previous_link(
1625
+					EE_Admin_Page::add_query_args_and_nonce(
1626
+						array(
1627
+							'action'  => 'view_registration',
1628
+							'_REG_ID' => $previous_reg['REG_ID'],
1629
+						),
1630
+						REG_ADMIN_URL
1631
+					),
1632
+					'dashicons dashicons-arrow-left ee-icon-size-22'
1633
+				)
1634
+				: '';
1635
+			// grab header
1636
+			$template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1637
+			$this->_template_args['REG_ID']            = $this->_registration->ID();
1638
+			$this->_template_args['admin_page_header'] = EEH_Template::display_template(
1639
+				$template_path,
1640
+				$this->_template_args,
1641
+				true
1642
+			);
1643
+		} else {
1644
+			$this->_template_args['admin_page_header'] = $this->display_espresso_notices();
1645
+		}
1646
+		// the details template wrapper
1647
+		$this->display_admin_page_with_sidebar();
1648
+	}
1649
+
1650
+
1651
+	protected function _registration_details_metaboxes()
1652
+	{
1653
+		do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1654
+		$this->_set_registration_object();
1655
+		$attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1656
+		add_meta_box('edit-reg-status-mbox', esc_html__('Registration Status', 'event_espresso'),
1657
+			array($this, 'set_reg_status_buttons_metabox'), $this->wp_page_slug, 'normal', 'high');
1658
+		add_meta_box('edit-reg-details-mbox', esc_html__('Registration Details', 'event_espresso'),
1659
+			array($this, '_reg_details_meta_box'), $this->wp_page_slug, 'normal', 'high');
1660
+		if ($attendee instanceof EE_Attendee
1661
+			&& EE_Registry::instance()->CAP->current_user_can(
1662
+				'ee_edit_registration',
1663
+				'edit-reg-questions-mbox',
1664
+				$this->_registration->ID()
1665
+			)
1666
+		) {
1667
+			add_meta_box(
1668
+				'edit-reg-questions-mbox',
1669
+				esc_html__('Registration Form Answers', 'event_espresso'),
1670
+				array($this, '_reg_questions_meta_box'),
1671
+				$this->wp_page_slug,
1672
+				'normal',
1673
+				'high'
1674
+			);
1675
+		}
1676
+		add_meta_box(
1677
+			'edit-reg-registrant-mbox',
1678
+			esc_html__('Contact Details', 'event_espresso'),
1679
+			array($this, '_reg_registrant_side_meta_box'),
1680
+			$this->wp_page_slug,
1681
+			'side',
1682
+			'high'
1683
+		);
1684
+		if ($this->_registration->group_size() > 1) {
1685
+			add_meta_box(
1686
+				'edit-reg-attendees-mbox',
1687
+				esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1688
+				array($this, '_reg_attendees_meta_box'),
1689
+				$this->wp_page_slug,
1690
+				'normal',
1691
+				'high'
1692
+			);
1693
+		}
1694
+	}
1695
+
1696
+
1697
+	/**
1698
+	 * set_reg_status_buttons_metabox
1699
+	 *
1700
+	 * @access protected
1701
+	 * @return string
1702
+	 * @throws \EE_Error
1703
+	 */
1704
+	public function set_reg_status_buttons_metabox()
1705
+	{
1706
+		$this->_set_registration_object();
1707
+		$change_reg_status_form = $this->_generate_reg_status_change_form();
1708
+		echo $change_reg_status_form->form_open(
1709
+			self::add_query_args_and_nonce(
1710
+				array(
1711
+					'action' => 'change_reg_status',
1712
+				),
1713
+				REG_ADMIN_URL
1714
+			)
1715
+		);
1716
+		echo $change_reg_status_form->get_html();
1717
+		echo $change_reg_status_form->form_close();
1718
+	}
1719
+
1720
+
1721
+	/**
1722
+	 * @return EE_Form_Section_Proper
1723
+	 * @throws EE_Error
1724
+	 * @throws InvalidArgumentException
1725
+	 * @throws InvalidDataTypeException
1726
+	 * @throws InvalidInterfaceException
1727
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1728
+	 */
1729
+	protected function _generate_reg_status_change_form()
1730
+	{
1731
+		return new EE_Form_Section_Proper(array(
1732
+			'name'            => 'reg_status_change_form',
1733
+			'html_id'         => 'reg-status-change-form',
1734
+			'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1735
+			'subsections'     => array(
1736
+				'return'             => new EE_Hidden_Input(array(
1737
+					'name'    => 'return',
1738
+					'default' => 'view_registration',
1739
+				)),
1740
+				'REG_ID'             => new EE_Hidden_Input(array(
1741
+					'name'    => 'REG_ID',
1742
+					'default' => $this->_registration->ID(),
1743
+				)),
1744
+				'current_status'     => new EE_Form_Section_HTML(
1745
+					EEH_HTML::tr(
1746
+						EEH_HTML::th(
1747
+							EEH_HTML::label(
1748
+								EEH_HTML::strong(esc_html__('Current Registration Status', 'event_espresso')
1749
+								)
1750
+							)
1751
+						)
1752
+						. EEH_HTML::td(
1753
+							EEH_HTML::strong(
1754
+								$this->_registration->pretty_status(),
1755
+								'',
1756
+								'status-' . $this->_registration->status_ID(),
1757
+								'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1758
+							)
1759
+						)
1760
+					)
1761
+				),
1762
+				'reg_status'         => new EE_Select_Input(
1763
+					$this->_get_reg_statuses(),
1764
+					array(
1765
+						'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1766
+						'default'         => $this->_registration->status_ID(),
1767
+					)
1768
+				),
1769
+				'send_notifications' => new EE_Yes_No_Input(
1770
+					array(
1771
+						'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1772
+						'default'         => false,
1773
+						'html_help_text'  => esc_html__(
1774
+							'If set to "Yes", then the related messages will be sent to the registrant.',
1775
+							'event_espresso'
1776
+						),
1777
+					)
1778
+				),
1779
+				'submit'             => new EE_Submit_Input(
1780
+					array(
1781
+						'html_class'      => 'button-primary',
1782
+						'html_label_text' => '&nbsp;',
1783
+						'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1784
+					)
1785
+				),
1786
+			),
1787
+		));
1788
+	}
1789
+
1790
+
1791
+	/**
1792
+	 * Returns an array of all the buttons for the various statuses and switch status actions
1793
+	 *
1794
+	 * @return array
1795
+	 * @throws EE_Error
1796
+	 * @throws InvalidArgumentException
1797
+	 * @throws InvalidDataTypeException
1798
+	 * @throws InvalidInterfaceException
1799
+	 * @throws EntityNotFoundException
1800
+	 */
1801
+	protected function _get_reg_statuses()
1802
+	{
1803
+		$reg_status_array = EEM_Registration::instance()->reg_status_array();
1804
+		unset ($reg_status_array[EEM_Registration::status_id_incomplete]);
1805
+		// get current reg status
1806
+		$current_status = $this->_registration->status_ID();
1807
+		// is registration for free event? This will determine whether to display the pending payment option
1808
+		if (
1809
+			$current_status !== EEM_Registration::status_id_pending_payment
1810
+			&& EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1811
+		) {
1812
+			unset($reg_status_array[EEM_Registration::status_id_pending_payment]);
1813
+		}
1814
+		return EEM_Status::instance()->localized_status($reg_status_array, false, 'sentence');
1815
+	}
1816
+
1817
+
1818
+	/**
1819
+	 * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1820
+	 *
1821
+	 * @param bool $status REG status given for changing registrations to.
1822
+	 * @param bool $notify Whether to send messages notifications or not.
1823
+	 * @return array (array with reg_id(s) updated and whether update was successful.
1824
+	 * @throws EE_Error
1825
+	 * @throws InvalidArgumentException
1826
+	 * @throws InvalidDataTypeException
1827
+	 * @throws InvalidInterfaceException
1828
+	 * @throws ReflectionException
1829
+	 * @throws RuntimeException
1830
+	 * @throws EntityNotFoundException
1831
+	 */
1832
+	protected function _set_registration_status_from_request($status = false, $notify = false)
1833
+	{
1834
+		if (isset($this->_req_data['reg_status_change_form'])) {
1835
+			$REG_IDs = isset($this->_req_data['reg_status_change_form']['REG_ID'])
1836
+				? (array)$this->_req_data['reg_status_change_form']['REG_ID']
1837
+				: array();
1838
+		} else {
1839
+			$REG_IDs = isset($this->_req_data['_REG_ID'])
1840
+				? (array)$this->_req_data['_REG_ID']
1841
+				: array();
1842
+		}
1843
+		// sanitize $REG_IDs
1844
+		$REG_IDs = array_map('absint', $REG_IDs);
1845
+		// and remove empty entries
1846
+		$REG_IDs = array_filter($REG_IDs);
1847
+
1848
+		$result = $this->_set_registration_status($REG_IDs, $status, $notify);
1849
+
1850
+		/**
1851
+		 * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1852
+		 * Currently this value is used downstream by the _process_resend_registration method.
1853
+		 *
1854
+		 * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1855
+		 * @param bool                     $status           The status registrations were changed to.
1856
+		 * @param bool                     $success          If the status was changed successfully for all registrations.
1857
+		 * @param Registrations_Admin_Page $admin_page_object
1858
+		 */
1859
+		$this->_req_data['_REG_ID'] = apply_filters(
1860
+			'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1861
+			$result['REG_ID'],
1862
+			$status,
1863
+			$result['success'],
1864
+			$this
1865
+		);
1866
+
1867
+		//notify?
1868
+		if ($notify
1869
+			&& $result['success']
1870
+			&& ! empty($this->_req_data['_REG_ID'])
1871
+			&& EE_Registry::instance()->CAP->current_user_can(
1872
+				'ee_send_message',
1873
+				'espresso_registrations_resend_registration'
1874
+			)
1875
+		) {
1876
+			$this->_process_resend_registration();
1877
+		}
1878
+		return $result;
1879
+	}
1880
+
1881
+
1882
+	/**
1883
+	 * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1884
+	 * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1885
+	 *
1886
+	 * @param array  $REG_IDs
1887
+	 * @param string $status
1888
+	 * @param bool   $notify  Used to indicate whether notification was requested or not.  This determines the context
1889
+	 *                        slug sent with setting the registration status.
1890
+	 * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1891
+	 * @throws EE_Error
1892
+	 * @throws InvalidArgumentException
1893
+	 * @throws InvalidDataTypeException
1894
+	 * @throws InvalidInterfaceException
1895
+	 * @throws ReflectionException
1896
+	 * @throws RuntimeException
1897
+	 * @throws EntityNotFoundException
1898
+	 */
1899
+	protected function _set_registration_status($REG_IDs = array(), $status = '', $notify = false)
1900
+	{
1901
+		$success = false;
1902
+		// typecast $REG_IDs
1903
+		$REG_IDs = (array)$REG_IDs;
1904
+		if ( ! empty($REG_IDs)) {
1905
+			$success = true;
1906
+			// set default status if none is passed
1907
+			$status = $status ? $status : EEM_Registration::status_id_pending_payment;
1908
+			$status_context = $notify
1909
+				? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1910
+				: Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1911
+			//loop through REG_ID's and change status
1912
+			foreach ($REG_IDs as $REG_ID) {
1913
+				$registration = EEM_Registration::instance()->get_one_by_ID($REG_ID);
1914
+				if ($registration instanceof EE_Registration) {
1915
+					$registration->set_status(
1916
+						$status,
1917
+						false,
1918
+						new Context(
1919
+							$status_context,
1920
+							esc_html__(
1921
+								'Manually triggered status change on a Registration Admin Page route.',
1922
+								'event_espresso'
1923
+							)
1924
+						)
1925
+					);
1926
+					$result = $registration->save();
1927
+					// verifying explicit fails because update *may* just return 0 for 0 rows affected
1928
+					$success = $result !== false ? $success : false;
1929
+				}
1930
+			}
1931
+		}
1932
+
1933
+		//return $success and processed registrations
1934
+		return array('REG_ID' => $REG_IDs, 'success' => $success);
1935
+	}
1936
+
1937
+
1938
+	/**
1939
+	 * Common logic for setting up success message and redirecting to appropriate route
1940
+	 *
1941
+	 * @param  string $STS_ID status id for the registration changed to
1942
+	 * @param   bool  $notify indicates whether the _set_registration_status_from_request does notifications or not.
1943
+	 * @return void
1944
+	 * @throws EE_Error
1945
+	 */
1946
+	protected function _reg_status_change_return($STS_ID, $notify = false)
1947
+	{
1948
+		$result  = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1949
+			: array('success' => false);
1950
+		$success = isset($result['success']) && $result['success'];
1951
+		//setup success message
1952
+		if ($success) {
1953
+			if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1954
+				$msg = sprintf(esc_html__('Registration status has been set to %s', 'event_espresso'),
1955
+					EEH_Template::pretty_status($STS_ID, false, 'lower'));
1956
+			} else {
1957
+				$msg = sprintf(esc_html__('Registrations have been set to %s.', 'event_espresso'),
1958
+					EEH_Template::pretty_status($STS_ID, false, 'lower'));
1959
+			}
1960
+			EE_Error::add_success($msg);
1961
+		} else {
1962
+			EE_Error::add_error(
1963
+				esc_html__(
1964
+					'Something went wrong, and the status was not changed',
1965
+					'event_espresso'
1966
+				), __FILE__, __LINE__, __FUNCTION__
1967
+			);
1968
+		}
1969
+		if (isset($this->_req_data['return']) && $this->_req_data['return'] == 'view_registration') {
1970
+			$route = array('action' => 'view_registration', '_REG_ID' => reset($result['REG_ID']));
1971
+		} else {
1972
+			$route = array('action' => 'default');
1973
+		}
1974
+		//unset nonces
1975
+		foreach ($this->_req_data as $ref => $value) {
1976
+			if (strpos($ref, 'nonce') !== false) {
1977
+				unset($this->_req_data[$ref]);
1978
+				continue;
1979
+			}
1980
+			$value                 = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
1981
+			$this->_req_data[$ref] = $value;
1982
+		}
1983
+		//merge request vars so that the reloaded list table contains any existing filter query params
1984
+		$route = array_merge($this->_req_data, $route);
1985
+		$this->_redirect_after_action($success, '', '', $route, true);
1986
+	}
1987
+
1988
+
1989
+	/**
1990
+	 * incoming reg status change from reg details page.
1991
+	 *
1992
+	 * @return void
1993
+	 */
1994
+	protected function _change_reg_status()
1995
+	{
1996
+		$this->_req_data['return'] = 'view_registration';
1997
+		//set notify based on whether the send notifications toggle is set or not
1998
+		$notify = ! empty($this->_req_data['reg_status_change_form']['send_notifications']);
1999
+		//$notify = ! empty( $this->_req_data['txn_reg_status_change']['send_notifications'] );
2000
+		$this->_req_data['reg_status_change_form']['reg_status'] = isset($this->_req_data['reg_status_change_form']['reg_status'])
2001
+			? $this->_req_data['reg_status_change_form']['reg_status'] : '';
2002
+		switch ($this->_req_data['reg_status_change_form']['reg_status']) {
2003
+			case EEM_Registration::status_id_approved :
2004
+			case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence') :
2005
+				$this->approve_registration($notify);
2006
+				break;
2007
+			case EEM_Registration::status_id_pending_payment :
2008
+			case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence') :
2009
+				$this->pending_registration($notify);
2010
+				break;
2011
+			case EEM_Registration::status_id_not_approved :
2012
+			case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence') :
2013
+				$this->not_approve_registration($notify);
2014
+				break;
2015
+			case EEM_Registration::status_id_declined :
2016
+			case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence') :
2017
+				$this->decline_registration($notify);
2018
+				break;
2019
+			case EEM_Registration::status_id_cancelled :
2020
+			case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence') :
2021
+				$this->cancel_registration($notify);
2022
+				break;
2023
+			case EEM_Registration::status_id_wait_list :
2024
+			case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence') :
2025
+				$this->wait_list_registration($notify);
2026
+				break;
2027
+			case EEM_Registration::status_id_incomplete :
2028
+			default :
2029
+				$result['success'] = false;
2030
+				unset($this->_req_data['return']);
2031
+				$this->_reg_status_change_return('', false);
2032
+				break;
2033
+		}
2034
+	}
2035
+
2036
+
2037
+	/**
2038
+	 * Callback for bulk action routes.
2039
+	 * Note: although we could just register the singular route callbacks for each bulk action route as well, this
2040
+	 * method was chosen so there is one central place all the registration status bulk actions are going through.
2041
+	 * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
2042
+	 * when an action is happening on just a single registration).
2043
+	 * @param      $action
2044
+	 * @param bool $notify
2045
+	 */
2046
+	protected function bulk_action_on_registrations($action, $notify = false) {
2047
+		do_action(
2048
+			'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
2049
+			$this,
2050
+			$action,
2051
+			$notify
2052
+		);
2053
+		$method = $action . '_registration';
2054
+		if (method_exists($this, $method)) {
2055
+			$this->$method($notify);
2056
+		}
2057
+	}
2058
+
2059
+
2060
+	/**
2061
+	 * approve_registration
2062
+	 *
2063
+	 * @access protected
2064
+	 * @param bool $notify whether or not to notify the registrant about their approval.
2065
+	 * @return void
2066
+	 */
2067
+	protected function approve_registration($notify = false)
2068
+	{
2069
+		$this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
2070
+	}
2071
+
2072
+
2073
+	/**
2074
+	 *        decline_registration
2075
+	 *
2076
+	 * @access protected
2077
+	 * @param bool $notify whether or not to notify the registrant about their status change.
2078
+	 * @return void
2079
+	 */
2080
+	protected function decline_registration($notify = false)
2081
+	{
2082
+		$this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
2083
+	}
2084
+
2085
+
2086
+	/**
2087
+	 *        cancel_registration
2088
+	 *
2089
+	 * @access protected
2090
+	 * @param bool $notify whether or not to notify the registrant about their status change.
2091
+	 * @return void
2092
+	 */
2093
+	protected function cancel_registration($notify = false)
2094
+	{
2095
+		$this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
2096
+	}
2097
+
2098
+
2099
+	/**
2100
+	 *        not_approve_registration
2101
+	 *
2102
+	 * @access protected
2103
+	 * @param bool $notify whether or not to notify the registrant about their status change.
2104
+	 * @return void
2105
+	 */
2106
+	protected function not_approve_registration($notify = false)
2107
+	{
2108
+		$this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
2109
+	}
2110
+
2111
+
2112
+	/**
2113
+	 *        decline_registration
2114
+	 *
2115
+	 * @access protected
2116
+	 * @param bool $notify whether or not to notify the registrant about their status change.
2117
+	 * @return void
2118
+	 */
2119
+	protected function pending_registration($notify = false)
2120
+	{
2121
+		$this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
2122
+	}
2123
+
2124
+
2125
+	/**
2126
+	 * waitlist_registration
2127
+	 *
2128
+	 * @access protected
2129
+	 * @param bool $notify whether or not to notify the registrant about their status change.
2130
+	 * @return void
2131
+	 */
2132
+	protected function wait_list_registration($notify = false)
2133
+	{
2134
+		$this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
2135
+	}
2136
+
2137
+
2138
+	/**
2139
+	 *        generates HTML for the Registration main meta box
2140
+	 *
2141
+	 * @access public
2142
+	 * @return void
2143
+	 * @throws DomainException
2144
+	 * @throws EE_Error
2145
+	 * @throws InvalidArgumentException
2146
+	 * @throws InvalidDataTypeException
2147
+	 * @throws InvalidInterfaceException
2148
+	 * @throws ReflectionException
2149
+	 * @throws EntityNotFoundException
2150
+	 */
2151
+	public function _reg_details_meta_box()
2152
+	{
2153
+		EEH_Autoloader::register_line_item_display_autoloaders();
2154
+		EEH_Autoloader::register_line_item_filter_autoloaders();
2155
+		EE_Registry::instance()->load_helper('Line_Item');
2156
+		$transaction    = $this->_registration->transaction() ? $this->_registration->transaction()
2157
+			: EE_Transaction::new_instance();
2158
+		$this->_session = $transaction->session_data();
2159
+		$filters        = new EE_Line_Item_Filter_Collection();
2160
+		//$filters->add( new EE_Non_Zero_Line_Item_Filter() );
2161
+		$filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2162
+		$line_item_filter_processor              = new EE_Line_Item_Filter_Processor($filters,
2163
+			$transaction->total_line_item());
2164
+		$filtered_line_item_tree                 = $line_item_filter_processor->process();
2165
+		$line_item_display                       = new EE_Line_Item_Display('reg_admin_table',
2166
+			'EE_Admin_Table_Registration_Line_Item_Display_Strategy');
2167
+		$this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2168
+			$filtered_line_item_tree,
2169
+			array('EE_Registration' => $this->_registration)
2170
+		);
2171
+		$attendee                                = $this->_registration->attendee();
2172
+		if (EE_Registry::instance()->CAP->current_user_can(
2173
+			'ee_read_transaction',
2174
+			'espresso_transactions_view_transaction'
2175
+		)) {
2176
+			$this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2177
+				EE_Admin_Page::add_query_args_and_nonce(
2178
+					array(
2179
+						'action' => 'view_transaction',
2180
+						'TXN_ID' => $transaction->ID(),
2181
+					),
2182
+					TXN_ADMIN_URL
2183
+				),
2184
+				esc_html__(' View Transaction', 'event_espresso'),
2185
+				'button secondary-button right',
2186
+				'dashicons dashicons-cart'
2187
+			);
2188
+		} else {
2189
+			$this->_template_args['view_transaction_button'] = '';
2190
+		}
2191
+		if ($attendee instanceof EE_Attendee
2192
+			&& EE_Registry::instance()->CAP->current_user_can(
2193
+				'ee_send_message',
2194
+				'espresso_registrations_resend_registration'
2195
+			)
2196
+		) {
2197
+			$this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2198
+				EE_Admin_Page::add_query_args_and_nonce(
2199
+					array(
2200
+						'action'      => 'resend_registration',
2201
+						'_REG_ID'     => $this->_registration->ID(),
2202
+						'redirect_to' => 'view_registration',
2203
+					),
2204
+					REG_ADMIN_URL
2205
+				),
2206
+				esc_html__(' Resend Registration', 'event_espresso'),
2207
+				'button secondary-button right',
2208
+				'dashicons dashicons-email-alt'
2209
+			);
2210
+		} else {
2211
+			$this->_template_args['resend_registration_button'] = '';
2212
+		}
2213
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2214
+		$payment                               = $transaction->get_first_related('Payment');
2215
+		$payment                               = ! $payment instanceof EE_Payment
2216
+			? EE_Payment::new_instance()
2217
+			: $payment;
2218
+		$payment_method                        = $payment->get_first_related('Payment_Method');
2219
+		$payment_method                        = ! $payment_method instanceof EE_Payment_Method
2220
+			? EE_Payment_Method::new_instance()
2221
+			: $payment_method;
2222
+		$reg_details                           = array(
2223
+			'payment_method'       => $payment_method->name(),
2224
+			'response_msg'         => $payment->gateway_response(),
2225
+			'registration_id'      => $this->_registration->get('REG_code'),
2226
+			'registration_session' => $this->_registration->session_ID(),
2227
+			'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2228
+			'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2229
+		);
2230
+		if (isset($reg_details['registration_id'])) {
2231
+			$this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2232
+			$this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2233
+				'Registration ID',
2234
+				'event_espresso'
2235
+			);
2236
+			$this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2237
+		}
2238
+		if (isset($reg_details['payment_method'])) {
2239
+			$this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2240
+			$this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2241
+				'Most Recent Payment Method',
2242
+				'event_espresso'
2243
+			);
2244
+			$this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2245
+			$this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2246
+			$this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2247
+				'Payment method response',
2248
+				'event_espresso'
2249
+			);
2250
+			$this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2251
+		}
2252
+		$this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2253
+		$this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2254
+			'Registration Session',
2255
+			'event_espresso'
2256
+		);
2257
+		$this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2258
+		$this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2259
+		$this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2260
+			'Registration placed from IP',
2261
+			'event_espresso'
2262
+		);
2263
+		$this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2264
+		$this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2265
+		$this->_template_args['reg_details']['user_agent']['label']           = esc_html__('Registrant User Agent',
2266
+			'event_espresso');
2267
+		$this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2268
+		$this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2269
+			array(
2270
+				'action'   => 'default',
2271
+				'event_id' => $this->_registration->event_ID(),
2272
+			),
2273
+			REG_ADMIN_URL
2274
+		);
2275
+		$this->_template_args['REG_ID']                                       = $this->_registration->ID();
2276
+		$this->_template_args['event_id']                                     = $this->_registration->event_ID();
2277
+		$template_path                                                        =
2278
+			REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2279
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2280
+	}
2281
+
2282
+
2283
+	/**
2284
+	 * generates HTML for the Registration Questions meta box.
2285
+	 * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2286
+	 * otherwise uses new forms system
2287
+	 *
2288
+	 * @access public
2289
+	 * @return void
2290
+	 * @throws DomainException
2291
+	 * @throws EE_Error
2292
+	 */
2293
+	public function _reg_questions_meta_box()
2294
+	{
2295
+		//allow someone to override this method entirely
2296
+		if (apply_filters('FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default', true, $this,
2297
+			$this->_registration)) {
2298
+			$form                                              = $this->_get_reg_custom_questions_form(
2299
+				$this->_registration->ID()
2300
+			);
2301
+			$this->_template_args['att_questions']             = count($form->subforms()) > 0
2302
+				? $form->get_html_and_js()
2303
+				: '';
2304
+			$this->_template_args['reg_questions_form_action'] = 'edit_registration';
2305
+			$this->_template_args['REG_ID']                    = $this->_registration->ID();
2306
+			$template_path                                     =
2307
+				REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2308
+			echo EEH_Template::display_template($template_path, $this->_template_args, true);
2309
+		}
2310
+	}
2311
+
2312
+
2313
+	/**
2314
+	 * form_before_question_group
2315
+	 *
2316
+	 * @deprecated    as of 4.8.32.rc.000
2317
+	 * @access        public
2318
+	 * @param        string $output
2319
+	 * @return        string
2320
+	 */
2321
+	public function form_before_question_group($output)
2322
+	{
2323
+		EE_Error::doing_it_wrong(
2324
+			__CLASS__ . '::' . __FUNCTION__,
2325
+			esc_html__(
2326
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2327
+				'event_espresso'
2328
+			),
2329
+			'4.8.32.rc.000'
2330
+		);
2331
+		return '
2332 2332
 	<table class="form-table ee-width-100">
2333 2333
 		<tbody>
2334 2334
 			';
2335
-    }
2336
-
2337
-
2338
-    /**
2339
-     * form_after_question_group
2340
-     *
2341
-     * @deprecated    as of 4.8.32.rc.000
2342
-     * @access        public
2343
-     * @param        string $output
2344
-     * @return        string
2345
-     */
2346
-    public function form_after_question_group($output)
2347
-    {
2348
-        EE_Error::doing_it_wrong(
2349
-            __CLASS__ . '::' . __FUNCTION__,
2350
-            esc_html__(
2351
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2352
-                'event_espresso'
2353
-            ),
2354
-            '4.8.32.rc.000'
2355
-        );
2356
-        return '
2335
+	}
2336
+
2337
+
2338
+	/**
2339
+	 * form_after_question_group
2340
+	 *
2341
+	 * @deprecated    as of 4.8.32.rc.000
2342
+	 * @access        public
2343
+	 * @param        string $output
2344
+	 * @return        string
2345
+	 */
2346
+	public function form_after_question_group($output)
2347
+	{
2348
+		EE_Error::doing_it_wrong(
2349
+			__CLASS__ . '::' . __FUNCTION__,
2350
+			esc_html__(
2351
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2352
+				'event_espresso'
2353
+			),
2354
+			'4.8.32.rc.000'
2355
+		);
2356
+		return '
2357 2357
 			<tr class="hide-if-no-js">
2358 2358
 				<th> </th>
2359 2359
 				<td class="reg-admin-edit-attendee-question-td">
2360 2360
 					<a class="reg-admin-edit-attendee-question-lnk" href="#" title="'
2361
-               . esc_attr__('click to edit question', 'event_espresso')
2362
-               . '">
2361
+			   . esc_attr__('click to edit question', 'event_espresso')
2362
+			   . '">
2363 2363
 						<span class="reg-admin-edit-question-group-spn lt-grey-txt">'
2364
-               . esc_html__('edit the above question group', 'event_espresso')
2365
-               . '</span>
2364
+			   . esc_html__('edit the above question group', 'event_espresso')
2365
+			   . '</span>
2366 2366
 						<div class="dashicons dashicons-edit"></div>
2367 2367
 					</a>
2368 2368
 				</td>
@@ -2370,579 +2370,579 @@  discard block
 block discarded – undo
2370 2370
 		</tbody>
2371 2371
 	</table>
2372 2372
 ';
2373
-    }
2374
-
2375
-
2376
-    /**
2377
-     * form_form_field_label_wrap
2378
-     *
2379
-     * @deprecated    as of 4.8.32.rc.000
2380
-     * @access        public
2381
-     * @param        string $label
2382
-     * @return        string
2383
-     */
2384
-    public function form_form_field_label_wrap($label)
2385
-    {
2386
-        EE_Error::doing_it_wrong(
2387
-            __CLASS__ . '::' . __FUNCTION__,
2388
-            esc_html__(
2389
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2390
-                'event_espresso'
2391
-            ),
2392
-            '4.8.32.rc.000'
2393
-        );
2394
-        return '
2373
+	}
2374
+
2375
+
2376
+	/**
2377
+	 * form_form_field_label_wrap
2378
+	 *
2379
+	 * @deprecated    as of 4.8.32.rc.000
2380
+	 * @access        public
2381
+	 * @param        string $label
2382
+	 * @return        string
2383
+	 */
2384
+	public function form_form_field_label_wrap($label)
2385
+	{
2386
+		EE_Error::doing_it_wrong(
2387
+			__CLASS__ . '::' . __FUNCTION__,
2388
+			esc_html__(
2389
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2390
+				'event_espresso'
2391
+			),
2392
+			'4.8.32.rc.000'
2393
+		);
2394
+		return '
2395 2395
 			<tr>
2396 2396
 				<th>
2397 2397
 					' . $label . '
2398 2398
 				</th>';
2399
-    }
2400
-
2401
-
2402
-    /**
2403
-     * form_form_field_input__wrap
2404
-     *
2405
-     * @deprecated    as of 4.8.32.rc.000
2406
-     * @access        public
2407
-     * @param        string $input
2408
-     * @return        string
2409
-     */
2410
-    public function form_form_field_input__wrap($input)
2411
-    {
2412
-        EE_Error::doing_it_wrong(
2413
-            __CLASS__ . '::' . __FUNCTION__,
2414
-            esc_html__(
2415
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2416
-                'event_espresso'
2417
-            ),
2418
-            '4.8.32.rc.000'
2419
-        );
2420
-        return '
2399
+	}
2400
+
2401
+
2402
+	/**
2403
+	 * form_form_field_input__wrap
2404
+	 *
2405
+	 * @deprecated    as of 4.8.32.rc.000
2406
+	 * @access        public
2407
+	 * @param        string $input
2408
+	 * @return        string
2409
+	 */
2410
+	public function form_form_field_input__wrap($input)
2411
+	{
2412
+		EE_Error::doing_it_wrong(
2413
+			__CLASS__ . '::' . __FUNCTION__,
2414
+			esc_html__(
2415
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2416
+				'event_espresso'
2417
+			),
2418
+			'4.8.32.rc.000'
2419
+		);
2420
+		return '
2421 2421
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2422 2422
 					' . $input . '
2423 2423
 				</td>
2424 2424
 			</tr>';
2425
-    }
2426
-
2427
-
2428
-    /**
2429
-     * Updates the registration's custom questions according to the form info, if the form is submitted.
2430
-     * If it's not a post, the "view_registrations" route will be called next on the SAME request
2431
-     * to display the page
2432
-     *
2433
-     * @access protected
2434
-     * @return void
2435
-     * @throws EE_Error
2436
-     */
2437
-    protected function _update_attendee_registration_form()
2438
-    {
2439
-        do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2440
-        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
2441
-            $REG_ID  = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : false;
2442
-            $success = $this->_save_reg_custom_questions_form($REG_ID);
2443
-            if ($success) {
2444
-                $what  = esc_html__('Registration Form', 'event_espresso');
2445
-                $route = $REG_ID ? array('action' => 'view_registration', '_REG_ID' => $REG_ID)
2446
-                    : array('action' => 'default');
2447
-                $this->_redirect_after_action($success, $what, esc_html__('updated', 'event_espresso'), $route);
2448
-            }
2449
-        }
2450
-    }
2451
-
2452
-
2453
-    /**
2454
-     * Gets the form for saving registrations custom questions (if done
2455
-     * previously retrieves the cached form object, which may have validation errors in it)
2456
-     *
2457
-     * @param int $REG_ID
2458
-     * @return EE_Registration_Custom_Questions_Form
2459
-     * @throws EE_Error
2460
-     * @throws InvalidArgumentException
2461
-     * @throws InvalidDataTypeException
2462
-     * @throws InvalidInterfaceException
2463
-     */
2464
-    protected function _get_reg_custom_questions_form($REG_ID)
2465
-    {
2466
-        if ( ! $this->_reg_custom_questions_form) {
2467
-            require_once(REG_ADMIN . 'form_sections' . DS . 'EE_Registration_Custom_Questions_Form.form.php');
2468
-            $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2469
-                EEM_Registration::instance()->get_one_by_ID($REG_ID)
2470
-            );
2471
-            $this->_reg_custom_questions_form->_construct_finalize(null, null);
2472
-        }
2473
-        return $this->_reg_custom_questions_form;
2474
-    }
2475
-
2476
-
2477
-    /**
2478
-     * Saves
2479
-     *
2480
-     * @access private
2481
-     * @param bool $REG_ID
2482
-     * @return bool
2483
-     * @throws EE_Error
2484
-     * @throws InvalidArgumentException
2485
-     * @throws InvalidDataTypeException
2486
-     * @throws InvalidInterfaceException
2487
-     */
2488
-    private function _save_reg_custom_questions_form($REG_ID = false)
2489
-    {
2490
-        if ( ! $REG_ID) {
2491
-            EE_Error::add_error(
2492
-                esc_html__(
2493
-                    'An error occurred. No registration ID was received.', 'event_espresso'),
2494
-                __FILE__, __FUNCTION__, __LINE__
2495
-            );
2496
-        }
2497
-        $form = $this->_get_reg_custom_questions_form($REG_ID);
2498
-        $form->receive_form_submission($this->_req_data);
2499
-        $success = false;
2500
-        if ($form->is_valid()) {
2501
-            foreach ($form->subforms() as $question_group_id => $question_group_form) {
2502
-                foreach ($question_group_form->inputs() as $question_id => $input) {
2503
-                    $where_conditions    = array(
2504
-                        'QST_ID' => $question_id,
2505
-                        'REG_ID' => $REG_ID,
2506
-                    );
2507
-                    $possibly_new_values = array(
2508
-                        'ANS_value' => $input->normalized_value(),
2509
-                    );
2510
-                    $answer              = EEM_Answer::instance()->get_one(array($where_conditions));
2511
-                    if ($answer instanceof EE_Answer) {
2512
-                        $success = $answer->save($possibly_new_values);
2513
-                    } else {
2514
-                        //insert it then
2515
-                        $cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2516
-                        $answer      = EE_Answer::new_instance($cols_n_vals);
2517
-                        $success     = $answer->save();
2518
-                    }
2519
-                }
2520
-            }
2521
-        } else {
2522
-            EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2523
-        }
2524
-        return $success;
2525
-    }
2526
-
2527
-
2528
-    /**
2529
-     *        generates HTML for the Registration main meta box
2530
-     *
2531
-     * @access public
2532
-     * @return void
2533
-     * @throws DomainException
2534
-     * @throws EE_Error
2535
-     * @throws InvalidArgumentException
2536
-     * @throws InvalidDataTypeException
2537
-     * @throws InvalidInterfaceException
2538
-     */
2539
-    public function _reg_attendees_meta_box()
2540
-    {
2541
-        $REG = EEM_Registration::instance();
2542
-        //get all other registrations on this transaction, and cache
2543
-        //the attendees for them so we don't have to run another query using force_join
2544
-        $registrations                           = $REG->get_all(array(
2545
-            array(
2546
-                'TXN_ID' => $this->_registration->transaction_ID(),
2547
-                'REG_ID' => array('!=', $this->_registration->ID()),
2548
-            ),
2549
-            'force_join' => array('Attendee'),
2550
-        ));
2551
-        $this->_template_args['attendees']       = array();
2552
-        $this->_template_args['attendee_notice'] = '';
2553
-        if (empty($registrations)
2554
-            || (is_array($registrations)
2555
-                && ! EEH_Array::get_one_item_from_array($registrations))
2556
-        ) {
2557
-            EE_Error::add_error(
2558
-                esc_html__(
2559
-                    'There are no records attached to this registration. Something may have gone wrong with the registration',
2560
-                    'event_espresso'
2561
-                ), __FILE__, __FUNCTION__, __LINE__
2562
-            );
2563
-            $this->_template_args['attendee_notice'] = EE_Error::get_notices();
2564
-        } else {
2565
-            $att_nmbr = 1;
2566
-            foreach ($registrations as $registration) {
2567
-                /* @var $registration EE_Registration */
2568
-                $attendee                                                    = $registration->attendee()
2569
-                    ? $registration->attendee()
2570
-                    : EEM_Attendee::instance()
2571
-                                  ->create_default_object();
2572
-                $this->_template_args['attendees'][$att_nmbr]['STS_ID']      = $registration->status_ID();
2573
-                $this->_template_args['attendees'][$att_nmbr]['fname']       = $attendee->fname();
2574
-                $this->_template_args['attendees'][$att_nmbr]['lname']       = $attendee->lname();
2575
-                $this->_template_args['attendees'][$att_nmbr]['email']       = $attendee->email();
2576
-                $this->_template_args['attendees'][$att_nmbr]['final_price'] = $registration->final_price();
2577
-                $this->_template_args['attendees'][$att_nmbr]['address']     = implode(
2578
-                    ', ',
2579
-                    $attendee->full_address_as_array()
2580
-                );
2581
-                $this->_template_args['attendees'][$att_nmbr]['att_link']    = self::add_query_args_and_nonce(
2582
-                    array(
2583
-                        'action' => 'edit_attendee',
2584
-                        'post'   => $attendee->ID(),
2585
-                    ),
2586
-                    REG_ADMIN_URL
2587
-                );
2588
-                $this->_template_args['attendees'][$att_nmbr]['event_name']  = $registration->event_obj()->name();
2589
-                $att_nmbr++;
2590
-            }
2591
-            $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2592
-        }
2593
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2594
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2595
-    }
2596
-
2597
-
2598
-    /**
2599
-     *        generates HTML for the Edit Registration side meta box
2600
-     *
2601
-     * @access public
2602
-     * @return void
2603
-     * @throws DomainException
2604
-     * @throws EE_Error
2605
-     * @throws InvalidArgumentException
2606
-     * @throws InvalidDataTypeException
2607
-     * @throws InvalidInterfaceException
2608
-     */
2609
-    public function _reg_registrant_side_meta_box()
2610
-    {
2611
-        /*@var $attendee EE_Attendee */
2612
-        $att_check = $this->_registration->attendee();
2613
-        $attendee  = $att_check instanceof EE_Attendee ? $att_check : EEM_Attendee::instance()->create_default_object();
2614
-        //now let's determine if this is not the primary registration.  If it isn't then we set the
2615
-        //primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2616
-        //primary registration object (that way we know if we need to show create button or not)
2617
-        if ( ! $this->_registration->is_primary_registrant()) {
2618
-            $primary_registration = $this->_registration->get_primary_registration();
2619
-            $primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2620
-                : null;
2621
-            if ( ! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2622
-                //in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2623
-                //custom attendee object so let's not worry about the primary reg.
2624
-                $primary_registration = null;
2625
-            }
2626
-        } else {
2627
-            $primary_registration = null;
2628
-        }
2629
-        $this->_template_args['ATT_ID']            = $attendee->ID();
2630
-        $this->_template_args['fname']             = $attendee->fname();
2631
-        $this->_template_args['lname']             = $attendee->lname();
2632
-        $this->_template_args['email']             = $attendee->email();
2633
-        $this->_template_args['phone']             = $attendee->phone();
2634
-        $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2635
-        //edit link
2636
-        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(array(
2637
-            'action' => 'edit_attendee',
2638
-            'post'   => $attendee->ID(),
2639
-        ), REG_ADMIN_URL);
2640
-        $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2641
-        //create link
2642
-        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2643
-            ? EE_Admin_Page::add_query_args_and_nonce(array(
2644
-                'action'  => 'duplicate_attendee',
2645
-                '_REG_ID' => $this->_registration->ID(),
2646
-            ), REG_ADMIN_URL) : '';
2647
-        $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2648
-        $this->_template_args['att_check']    = $att_check;
2649
-        $template_path                        = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2650
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2651
-    }
2652
-
2653
-
2654
-    /**
2655
-     * trash or restore registrations
2656
-     *
2657
-     * @param  boolean $trash whether to archive or restore
2658
-     * @return void
2659
-     * @throws EE_Error
2660
-     * @throws InvalidArgumentException
2661
-     * @throws InvalidDataTypeException
2662
-     * @throws InvalidInterfaceException
2663
-     * @throws RuntimeException
2664
-     * @access protected
2665
-     */
2666
-    protected function _trash_or_restore_registrations($trash = true)
2667
-    {
2668
-        //if empty _REG_ID then get out because there's nothing to do
2669
-        if (empty($this->_req_data['_REG_ID'])) {
2670
-            EE_Error::add_error(
2671
-                sprintf(
2672
-                    esc_html__(
2673
-                        'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2674
-                        'event_espresso'
2675
-                    ),
2676
-                    $trash ? 'trash' : 'restore'
2677
-                ),
2678
-                __FILE__, __LINE__, __FUNCTION__
2679
-            );
2680
-            $this->_redirect_after_action(false, '', '', array(), true);
2681
-        }
2682
-        $success = 0;
2683
-        $overwrite_msgs = false;
2684
-        //Checkboxes
2685
-        if ( ! is_array($this->_req_data['_REG_ID'])) {
2686
-            $this->_req_data['_REG_ID'] = array($this->_req_data['_REG_ID']);
2687
-        }
2688
-        $reg_count = count($this->_req_data['_REG_ID']);
2689
-        // cycle thru checkboxes
2690
-        foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2691
-            /** @var EE_Registration $REG */
2692
-            $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID);
2693
-            $payments = $REG->registration_payments();
2694
-            if (! empty($payments)) {
2695
-                $name = $REG->attendee() instanceof EE_Attendee
2696
-                    ? $REG->attendee()->full_name()
2697
-                    : esc_html__('Unknown Attendee', 'event_espresso');
2698
-                $overwrite_msgs = true;
2699
-                EE_Error::add_error(
2700
-                    sprintf(
2701
-                        esc_html__(
2702
-                            'The registration for %s could not be trashed because it has payments attached to the related transaction.  If you wish to trash this registration you must first delete the payments on the related transaction.',
2703
-                            'event_espresso'
2704
-                        ),
2705
-                        $name
2706
-                    ),
2707
-                    __FILE__, __FUNCTION__, __LINE__
2708
-                );
2709
-                //can't trash this registration because it has payments.
2710
-                continue;
2711
-            }
2712
-            $updated = $trash ? $REG->delete() : $REG->restore();
2713
-            if ($updated) {
2714
-                $success++;
2715
-            }
2716
-        }
2717
-        $this->_redirect_after_action(
2718
-            $success === $reg_count, // were ALL registrations affected?
2719
-            $success > 1
2720
-                ? esc_html__('Registrations', 'event_espresso')
2721
-                : esc_html__('Registration', 'event_espresso'),
2722
-            $trash
2723
-                ? esc_html__('moved to the trash', 'event_espresso')
2724
-                : esc_html__('restored', 'event_espresso'),
2725
-            array('action' => 'default'),
2726
-            $overwrite_msgs
2727
-        );
2728
-    }
2729
-
2730
-
2731
-    /**
2732
-     * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2733
-     * registration but also.
2734
-     * 1. Removing relations to EE_Attendee
2735
-     * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2736
-     * ALSO trashed.
2737
-     * 3. Deleting permanently any related Line items but only if the above conditions are met.
2738
-     * 4. Removing relationships between all tickets and the related registrations
2739
-     * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2740
-     * 6. Deleting permanently any related Checkins.
2741
-     *
2742
-     * @return void
2743
-     * @throws EE_Error
2744
-     * @throws InvalidArgumentException
2745
-     * @throws InvalidDataTypeException
2746
-     * @throws InvalidInterfaceException
2747
-     */
2748
-    protected function _delete_registrations()
2749
-    {
2750
-        $REG_MDL = EEM_Registration::instance();
2751
-        $success = 1;
2752
-        //Checkboxes
2753
-        if ( ! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2754
-            // if array has more than one element than success message should be plural
2755
-            $success = count($this->_req_data['_REG_ID']) > 1 ? 2 : 1;
2756
-            // cycle thru checkboxes
2757
-            while (list($ind, $REG_ID) = each($this->_req_data['_REG_ID'])) {
2758
-                $REG = $REG_MDL->get_one_by_ID($REG_ID);
2759
-                if ( ! $REG instanceof EE_Registration) {
2760
-                    continue;
2761
-                }
2762
-                $deleted = $this->_delete_registration($REG);
2763
-                if ( ! $deleted) {
2764
-                    $success = 0;
2765
-                }
2766
-            }
2767
-        } else {
2768
-            // grab single id and delete
2769
-            $REG_ID  = $this->_req_data['_REG_ID'];
2770
-            $REG     = $REG_MDL->get_one_by_ID($REG_ID);
2771
-            $deleted = $this->_delete_registration($REG);
2772
-            if ( ! $deleted) {
2773
-                $success = 0;
2774
-            }
2775
-        }
2776
-        $what        = $success > 1
2777
-            ? esc_html__('Registrations', 'event_espresso')
2778
-            : esc_html__('Registration', 'event_espresso');
2779
-        $action_desc = esc_html__('permanently deleted.', 'event_espresso');
2780
-        $this->_redirect_after_action(
2781
-            $success,
2782
-            $what,
2783
-            $action_desc,
2784
-            array('action' => 'default'),
2785
-            true
2786
-        );
2787
-    }
2788
-
2789
-
2790
-    /**
2791
-     * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2792
-     * models get affected.
2793
-     *
2794
-     * @param  EE_Registration $REG registration to be deleted permenantly
2795
-     * @return bool true = successful deletion, false = fail.
2796
-     * @throws EE_Error
2797
-     */
2798
-    protected function _delete_registration(EE_Registration $REG)
2799
-    {
2800
-        //first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2801
-        //registrations on the transaction that are NOT trashed.
2802
-        $TXN         = $REG->get_first_related('Transaction');
2803
-        $REGS        = $TXN->get_many_related('Registration');
2804
-        $all_trashed = true;
2805
-        foreach ($REGS as $registration) {
2806
-            if ( ! $registration->get('REG_deleted')) {
2807
-                $all_trashed = false;
2808
-            }
2809
-        }
2810
-        if ( ! $all_trashed) {
2811
-            EE_Error::add_error(
2812
-                esc_html__(
2813
-                    'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
2814
-                    'event_espresso'
2815
-                ),
2816
-                __FILE__, __FUNCTION__, __LINE__
2817
-            );
2818
-            return false;
2819
-        }
2820
-        //k made it here so that means we can delete all the related transactions and their answers (but let's do them
2821
-        //separately from THIS one).
2822
-        foreach ($REGS as $registration) {
2823
-            //delete related answers
2824
-            $registration->delete_related_permanently('Answer');
2825
-            //remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2826
-            $attendee = $registration->get_first_related('Attendee');
2827
-            if ($attendee instanceof EE_Attendee) {
2828
-                $registration->_remove_relation_to($attendee, 'Attendee');
2829
-            }
2830
-            //now remove relationships to tickets on this registration.
2831
-            $registration->_remove_relations('Ticket');
2832
-            //now delete permanently the checkins related to this registration.
2833
-            $registration->delete_related_permanently('Checkin');
2834
-            if ($registration->ID() === $REG->ID()) {
2835
-                continue;
2836
-            } //we don't want to delete permanently the existing registration just yet.
2837
-            //remove relation to transaction for these registrations if NOT the existing registrations
2838
-            $registration->_remove_relations('Transaction');
2839
-            //delete permanently any related messages.
2840
-            $registration->delete_related_permanently('Message');
2841
-            //now delete this registration permanently
2842
-            $registration->delete_permanently();
2843
-        }
2844
-        //now all related registrations on the transaction are handled.  So let's just handle this registration itself
2845
-        // (the transaction and line items should be all that's left).
2846
-        // delete the line items related to the transaction for this registration.
2847
-        $TXN->delete_related_permanently('Line_Item');
2848
-        //we need to remove all the relationships on the transaction
2849
-        $TXN->delete_related_permanently('Payment');
2850
-        $TXN->delete_related_permanently('Extra_Meta');
2851
-        $TXN->delete_related_permanently('Message');
2852
-        //now we can delete this REG permanently (and the transaction of course)
2853
-        $REG->delete_related_permanently('Transaction');
2854
-        return $REG->delete_permanently();
2855
-    }
2856
-
2857
-
2858
-    /**
2859
-     *    generates HTML for the Register New Attendee Admin page
2860
-     *
2861
-     * @access private
2862
-     * @throws DomainException
2863
-     * @throws EE_Error
2864
-     */
2865
-    public function new_registration()
2866
-    {
2867
-        if ( ! $this->_set_reg_event()) {
2868
-            throw new EE_Error(
2869
-                esc_html__(
2870
-                    'Unable to continue with registering because there is no Event ID in the request',
2871
-                    'event_espresso'
2872
-                )
2873
-            );
2874
-        }
2875
-        EE_Registry::instance()->REQ->set_espresso_page(true);
2876
-        // gotta start with a clean slate if we're not coming here via ajax
2877
-        if ( ! defined('DOING_AJAX')
2878
-             && ( ! isset($this->_req_data['processing_registration']) || isset($this->_req_data['step_error']))
2879
-        ) {
2880
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2881
-        }
2882
-        $this->_template_args['event_name'] = '';
2883
-        // event name
2884
-        if ($this->_reg_event) {
2885
-            $this->_template_args['event_name'] = $this->_reg_event->name();
2886
-            $edit_event_url                     = self::add_query_args_and_nonce(array(
2887
-                'action' => 'edit',
2888
-                'post'   => $this->_reg_event->ID(),
2889
-            ), EVENTS_ADMIN_URL);
2890
-            $edit_event_lnk                     = '<a href="'
2891
-                                                  . $edit_event_url
2892
-                                                  . '" title="'
2893
-                                                  . esc_attr__('Edit ', 'event_espresso')
2894
-                                                  . $this->_reg_event->name()
2895
-                                                  . '">'
2896
-                                                  . esc_html__('Edit Event', 'event_espresso')
2897
-                                                  . '</a>';
2898
-            $this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2899
-                                                   . $edit_event_lnk
2900
-                                                   . '</span>';
2901
-        }
2902
-        $this->_template_args['step_content'] = $this->_get_registration_step_content();
2903
-        if (defined('DOING_AJAX')) {
2904
-            $this->_return_json();
2905
-        }
2906
-        // grab header
2907
-        $template_path                              =
2908
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2909
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template($template_path,
2910
-            $this->_template_args, true);
2911
-        //$this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2912
-        // the details template wrapper
2913
-        $this->display_admin_page_with_sidebar();
2914
-    }
2915
-
2916
-
2917
-    /**
2918
-     * This returns the content for a registration step
2919
-     *
2920
-     * @access protected
2921
-     * @return string html
2922
-     * @throws DomainException
2923
-     * @throws EE_Error
2924
-     * @throws InvalidArgumentException
2925
-     * @throws InvalidDataTypeException
2926
-     * @throws InvalidInterfaceException
2927
-     */
2928
-    protected function _get_registration_step_content()
2929
-    {
2930
-        if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2931
-            $warning_msg = sprintf(
2932
-                esc_html__(
2933
-                    '%2$sWARNING!!!%3$s%1$sPlease do not use the back button to return to this page for the purpose of adding another registration.%1$sThis can result in lost and/or corrupted data.%1$sIf you wish to add another registration, then please click the%1$s%7$s"Add Another New Registration to Event"%8$s button%1$son the Transaction details page, after you are redirected.%1$s%1$s%4$s redirecting in %5$s seconds %6$s',
2934
-                    'event_espresso'
2935
-                ),
2936
-                '<br />',
2937
-                '<h3 class="important-notice">',
2938
-                '</h3>',
2939
-                '<div class="float-right">',
2940
-                '<span id="redirect_timer" class="important-notice">30</span>',
2941
-                '</div>',
2942
-                '<b>',
2943
-                '</b>'
2944
-            );
2945
-            return '
2425
+	}
2426
+
2427
+
2428
+	/**
2429
+	 * Updates the registration's custom questions according to the form info, if the form is submitted.
2430
+	 * If it's not a post, the "view_registrations" route will be called next on the SAME request
2431
+	 * to display the page
2432
+	 *
2433
+	 * @access protected
2434
+	 * @return void
2435
+	 * @throws EE_Error
2436
+	 */
2437
+	protected function _update_attendee_registration_form()
2438
+	{
2439
+		do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2440
+		if ($_SERVER['REQUEST_METHOD'] == 'POST') {
2441
+			$REG_ID  = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : false;
2442
+			$success = $this->_save_reg_custom_questions_form($REG_ID);
2443
+			if ($success) {
2444
+				$what  = esc_html__('Registration Form', 'event_espresso');
2445
+				$route = $REG_ID ? array('action' => 'view_registration', '_REG_ID' => $REG_ID)
2446
+					: array('action' => 'default');
2447
+				$this->_redirect_after_action($success, $what, esc_html__('updated', 'event_espresso'), $route);
2448
+			}
2449
+		}
2450
+	}
2451
+
2452
+
2453
+	/**
2454
+	 * Gets the form for saving registrations custom questions (if done
2455
+	 * previously retrieves the cached form object, which may have validation errors in it)
2456
+	 *
2457
+	 * @param int $REG_ID
2458
+	 * @return EE_Registration_Custom_Questions_Form
2459
+	 * @throws EE_Error
2460
+	 * @throws InvalidArgumentException
2461
+	 * @throws InvalidDataTypeException
2462
+	 * @throws InvalidInterfaceException
2463
+	 */
2464
+	protected function _get_reg_custom_questions_form($REG_ID)
2465
+	{
2466
+		if ( ! $this->_reg_custom_questions_form) {
2467
+			require_once(REG_ADMIN . 'form_sections' . DS . 'EE_Registration_Custom_Questions_Form.form.php');
2468
+			$this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2469
+				EEM_Registration::instance()->get_one_by_ID($REG_ID)
2470
+			);
2471
+			$this->_reg_custom_questions_form->_construct_finalize(null, null);
2472
+		}
2473
+		return $this->_reg_custom_questions_form;
2474
+	}
2475
+
2476
+
2477
+	/**
2478
+	 * Saves
2479
+	 *
2480
+	 * @access private
2481
+	 * @param bool $REG_ID
2482
+	 * @return bool
2483
+	 * @throws EE_Error
2484
+	 * @throws InvalidArgumentException
2485
+	 * @throws InvalidDataTypeException
2486
+	 * @throws InvalidInterfaceException
2487
+	 */
2488
+	private function _save_reg_custom_questions_form($REG_ID = false)
2489
+	{
2490
+		if ( ! $REG_ID) {
2491
+			EE_Error::add_error(
2492
+				esc_html__(
2493
+					'An error occurred. No registration ID was received.', 'event_espresso'),
2494
+				__FILE__, __FUNCTION__, __LINE__
2495
+			);
2496
+		}
2497
+		$form = $this->_get_reg_custom_questions_form($REG_ID);
2498
+		$form->receive_form_submission($this->_req_data);
2499
+		$success = false;
2500
+		if ($form->is_valid()) {
2501
+			foreach ($form->subforms() as $question_group_id => $question_group_form) {
2502
+				foreach ($question_group_form->inputs() as $question_id => $input) {
2503
+					$where_conditions    = array(
2504
+						'QST_ID' => $question_id,
2505
+						'REG_ID' => $REG_ID,
2506
+					);
2507
+					$possibly_new_values = array(
2508
+						'ANS_value' => $input->normalized_value(),
2509
+					);
2510
+					$answer              = EEM_Answer::instance()->get_one(array($where_conditions));
2511
+					if ($answer instanceof EE_Answer) {
2512
+						$success = $answer->save($possibly_new_values);
2513
+					} else {
2514
+						//insert it then
2515
+						$cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2516
+						$answer      = EE_Answer::new_instance($cols_n_vals);
2517
+						$success     = $answer->save();
2518
+					}
2519
+				}
2520
+			}
2521
+		} else {
2522
+			EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2523
+		}
2524
+		return $success;
2525
+	}
2526
+
2527
+
2528
+	/**
2529
+	 *        generates HTML for the Registration main meta box
2530
+	 *
2531
+	 * @access public
2532
+	 * @return void
2533
+	 * @throws DomainException
2534
+	 * @throws EE_Error
2535
+	 * @throws InvalidArgumentException
2536
+	 * @throws InvalidDataTypeException
2537
+	 * @throws InvalidInterfaceException
2538
+	 */
2539
+	public function _reg_attendees_meta_box()
2540
+	{
2541
+		$REG = EEM_Registration::instance();
2542
+		//get all other registrations on this transaction, and cache
2543
+		//the attendees for them so we don't have to run another query using force_join
2544
+		$registrations                           = $REG->get_all(array(
2545
+			array(
2546
+				'TXN_ID' => $this->_registration->transaction_ID(),
2547
+				'REG_ID' => array('!=', $this->_registration->ID()),
2548
+			),
2549
+			'force_join' => array('Attendee'),
2550
+		));
2551
+		$this->_template_args['attendees']       = array();
2552
+		$this->_template_args['attendee_notice'] = '';
2553
+		if (empty($registrations)
2554
+			|| (is_array($registrations)
2555
+				&& ! EEH_Array::get_one_item_from_array($registrations))
2556
+		) {
2557
+			EE_Error::add_error(
2558
+				esc_html__(
2559
+					'There are no records attached to this registration. Something may have gone wrong with the registration',
2560
+					'event_espresso'
2561
+				), __FILE__, __FUNCTION__, __LINE__
2562
+			);
2563
+			$this->_template_args['attendee_notice'] = EE_Error::get_notices();
2564
+		} else {
2565
+			$att_nmbr = 1;
2566
+			foreach ($registrations as $registration) {
2567
+				/* @var $registration EE_Registration */
2568
+				$attendee                                                    = $registration->attendee()
2569
+					? $registration->attendee()
2570
+					: EEM_Attendee::instance()
2571
+								  ->create_default_object();
2572
+				$this->_template_args['attendees'][$att_nmbr]['STS_ID']      = $registration->status_ID();
2573
+				$this->_template_args['attendees'][$att_nmbr]['fname']       = $attendee->fname();
2574
+				$this->_template_args['attendees'][$att_nmbr]['lname']       = $attendee->lname();
2575
+				$this->_template_args['attendees'][$att_nmbr]['email']       = $attendee->email();
2576
+				$this->_template_args['attendees'][$att_nmbr]['final_price'] = $registration->final_price();
2577
+				$this->_template_args['attendees'][$att_nmbr]['address']     = implode(
2578
+					', ',
2579
+					$attendee->full_address_as_array()
2580
+				);
2581
+				$this->_template_args['attendees'][$att_nmbr]['att_link']    = self::add_query_args_and_nonce(
2582
+					array(
2583
+						'action' => 'edit_attendee',
2584
+						'post'   => $attendee->ID(),
2585
+					),
2586
+					REG_ADMIN_URL
2587
+				);
2588
+				$this->_template_args['attendees'][$att_nmbr]['event_name']  = $registration->event_obj()->name();
2589
+				$att_nmbr++;
2590
+			}
2591
+			$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2592
+		}
2593
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2594
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2595
+	}
2596
+
2597
+
2598
+	/**
2599
+	 *        generates HTML for the Edit Registration side meta box
2600
+	 *
2601
+	 * @access public
2602
+	 * @return void
2603
+	 * @throws DomainException
2604
+	 * @throws EE_Error
2605
+	 * @throws InvalidArgumentException
2606
+	 * @throws InvalidDataTypeException
2607
+	 * @throws InvalidInterfaceException
2608
+	 */
2609
+	public function _reg_registrant_side_meta_box()
2610
+	{
2611
+		/*@var $attendee EE_Attendee */
2612
+		$att_check = $this->_registration->attendee();
2613
+		$attendee  = $att_check instanceof EE_Attendee ? $att_check : EEM_Attendee::instance()->create_default_object();
2614
+		//now let's determine if this is not the primary registration.  If it isn't then we set the
2615
+		//primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2616
+		//primary registration object (that way we know if we need to show create button or not)
2617
+		if ( ! $this->_registration->is_primary_registrant()) {
2618
+			$primary_registration = $this->_registration->get_primary_registration();
2619
+			$primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2620
+				: null;
2621
+			if ( ! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2622
+				//in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2623
+				//custom attendee object so let's not worry about the primary reg.
2624
+				$primary_registration = null;
2625
+			}
2626
+		} else {
2627
+			$primary_registration = null;
2628
+		}
2629
+		$this->_template_args['ATT_ID']            = $attendee->ID();
2630
+		$this->_template_args['fname']             = $attendee->fname();
2631
+		$this->_template_args['lname']             = $attendee->lname();
2632
+		$this->_template_args['email']             = $attendee->email();
2633
+		$this->_template_args['phone']             = $attendee->phone();
2634
+		$this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2635
+		//edit link
2636
+		$this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(array(
2637
+			'action' => 'edit_attendee',
2638
+			'post'   => $attendee->ID(),
2639
+		), REG_ADMIN_URL);
2640
+		$this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2641
+		//create link
2642
+		$this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2643
+			? EE_Admin_Page::add_query_args_and_nonce(array(
2644
+				'action'  => 'duplicate_attendee',
2645
+				'_REG_ID' => $this->_registration->ID(),
2646
+			), REG_ADMIN_URL) : '';
2647
+		$this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2648
+		$this->_template_args['att_check']    = $att_check;
2649
+		$template_path                        = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2650
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
2651
+	}
2652
+
2653
+
2654
+	/**
2655
+	 * trash or restore registrations
2656
+	 *
2657
+	 * @param  boolean $trash whether to archive or restore
2658
+	 * @return void
2659
+	 * @throws EE_Error
2660
+	 * @throws InvalidArgumentException
2661
+	 * @throws InvalidDataTypeException
2662
+	 * @throws InvalidInterfaceException
2663
+	 * @throws RuntimeException
2664
+	 * @access protected
2665
+	 */
2666
+	protected function _trash_or_restore_registrations($trash = true)
2667
+	{
2668
+		//if empty _REG_ID then get out because there's nothing to do
2669
+		if (empty($this->_req_data['_REG_ID'])) {
2670
+			EE_Error::add_error(
2671
+				sprintf(
2672
+					esc_html__(
2673
+						'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2674
+						'event_espresso'
2675
+					),
2676
+					$trash ? 'trash' : 'restore'
2677
+				),
2678
+				__FILE__, __LINE__, __FUNCTION__
2679
+			);
2680
+			$this->_redirect_after_action(false, '', '', array(), true);
2681
+		}
2682
+		$success = 0;
2683
+		$overwrite_msgs = false;
2684
+		//Checkboxes
2685
+		if ( ! is_array($this->_req_data['_REG_ID'])) {
2686
+			$this->_req_data['_REG_ID'] = array($this->_req_data['_REG_ID']);
2687
+		}
2688
+		$reg_count = count($this->_req_data['_REG_ID']);
2689
+		// cycle thru checkboxes
2690
+		foreach ($this->_req_data['_REG_ID'] as $REG_ID) {
2691
+			/** @var EE_Registration $REG */
2692
+			$REG = EEM_Registration::instance()->get_one_by_ID($REG_ID);
2693
+			$payments = $REG->registration_payments();
2694
+			if (! empty($payments)) {
2695
+				$name = $REG->attendee() instanceof EE_Attendee
2696
+					? $REG->attendee()->full_name()
2697
+					: esc_html__('Unknown Attendee', 'event_espresso');
2698
+				$overwrite_msgs = true;
2699
+				EE_Error::add_error(
2700
+					sprintf(
2701
+						esc_html__(
2702
+							'The registration for %s could not be trashed because it has payments attached to the related transaction.  If you wish to trash this registration you must first delete the payments on the related transaction.',
2703
+							'event_espresso'
2704
+						),
2705
+						$name
2706
+					),
2707
+					__FILE__, __FUNCTION__, __LINE__
2708
+				);
2709
+				//can't trash this registration because it has payments.
2710
+				continue;
2711
+			}
2712
+			$updated = $trash ? $REG->delete() : $REG->restore();
2713
+			if ($updated) {
2714
+				$success++;
2715
+			}
2716
+		}
2717
+		$this->_redirect_after_action(
2718
+			$success === $reg_count, // were ALL registrations affected?
2719
+			$success > 1
2720
+				? esc_html__('Registrations', 'event_espresso')
2721
+				: esc_html__('Registration', 'event_espresso'),
2722
+			$trash
2723
+				? esc_html__('moved to the trash', 'event_espresso')
2724
+				: esc_html__('restored', 'event_espresso'),
2725
+			array('action' => 'default'),
2726
+			$overwrite_msgs
2727
+		);
2728
+	}
2729
+
2730
+
2731
+	/**
2732
+	 * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2733
+	 * registration but also.
2734
+	 * 1. Removing relations to EE_Attendee
2735
+	 * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2736
+	 * ALSO trashed.
2737
+	 * 3. Deleting permanently any related Line items but only if the above conditions are met.
2738
+	 * 4. Removing relationships between all tickets and the related registrations
2739
+	 * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2740
+	 * 6. Deleting permanently any related Checkins.
2741
+	 *
2742
+	 * @return void
2743
+	 * @throws EE_Error
2744
+	 * @throws InvalidArgumentException
2745
+	 * @throws InvalidDataTypeException
2746
+	 * @throws InvalidInterfaceException
2747
+	 */
2748
+	protected function _delete_registrations()
2749
+	{
2750
+		$REG_MDL = EEM_Registration::instance();
2751
+		$success = 1;
2752
+		//Checkboxes
2753
+		if ( ! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2754
+			// if array has more than one element than success message should be plural
2755
+			$success = count($this->_req_data['_REG_ID']) > 1 ? 2 : 1;
2756
+			// cycle thru checkboxes
2757
+			while (list($ind, $REG_ID) = each($this->_req_data['_REG_ID'])) {
2758
+				$REG = $REG_MDL->get_one_by_ID($REG_ID);
2759
+				if ( ! $REG instanceof EE_Registration) {
2760
+					continue;
2761
+				}
2762
+				$deleted = $this->_delete_registration($REG);
2763
+				if ( ! $deleted) {
2764
+					$success = 0;
2765
+				}
2766
+			}
2767
+		} else {
2768
+			// grab single id and delete
2769
+			$REG_ID  = $this->_req_data['_REG_ID'];
2770
+			$REG     = $REG_MDL->get_one_by_ID($REG_ID);
2771
+			$deleted = $this->_delete_registration($REG);
2772
+			if ( ! $deleted) {
2773
+				$success = 0;
2774
+			}
2775
+		}
2776
+		$what        = $success > 1
2777
+			? esc_html__('Registrations', 'event_espresso')
2778
+			: esc_html__('Registration', 'event_espresso');
2779
+		$action_desc = esc_html__('permanently deleted.', 'event_espresso');
2780
+		$this->_redirect_after_action(
2781
+			$success,
2782
+			$what,
2783
+			$action_desc,
2784
+			array('action' => 'default'),
2785
+			true
2786
+		);
2787
+	}
2788
+
2789
+
2790
+	/**
2791
+	 * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2792
+	 * models get affected.
2793
+	 *
2794
+	 * @param  EE_Registration $REG registration to be deleted permenantly
2795
+	 * @return bool true = successful deletion, false = fail.
2796
+	 * @throws EE_Error
2797
+	 */
2798
+	protected function _delete_registration(EE_Registration $REG)
2799
+	{
2800
+		//first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2801
+		//registrations on the transaction that are NOT trashed.
2802
+		$TXN         = $REG->get_first_related('Transaction');
2803
+		$REGS        = $TXN->get_many_related('Registration');
2804
+		$all_trashed = true;
2805
+		foreach ($REGS as $registration) {
2806
+			if ( ! $registration->get('REG_deleted')) {
2807
+				$all_trashed = false;
2808
+			}
2809
+		}
2810
+		if ( ! $all_trashed) {
2811
+			EE_Error::add_error(
2812
+				esc_html__(
2813
+					'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
2814
+					'event_espresso'
2815
+				),
2816
+				__FILE__, __FUNCTION__, __LINE__
2817
+			);
2818
+			return false;
2819
+		}
2820
+		//k made it here so that means we can delete all the related transactions and their answers (but let's do them
2821
+		//separately from THIS one).
2822
+		foreach ($REGS as $registration) {
2823
+			//delete related answers
2824
+			$registration->delete_related_permanently('Answer');
2825
+			//remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2826
+			$attendee = $registration->get_first_related('Attendee');
2827
+			if ($attendee instanceof EE_Attendee) {
2828
+				$registration->_remove_relation_to($attendee, 'Attendee');
2829
+			}
2830
+			//now remove relationships to tickets on this registration.
2831
+			$registration->_remove_relations('Ticket');
2832
+			//now delete permanently the checkins related to this registration.
2833
+			$registration->delete_related_permanently('Checkin');
2834
+			if ($registration->ID() === $REG->ID()) {
2835
+				continue;
2836
+			} //we don't want to delete permanently the existing registration just yet.
2837
+			//remove relation to transaction for these registrations if NOT the existing registrations
2838
+			$registration->_remove_relations('Transaction');
2839
+			//delete permanently any related messages.
2840
+			$registration->delete_related_permanently('Message');
2841
+			//now delete this registration permanently
2842
+			$registration->delete_permanently();
2843
+		}
2844
+		//now all related registrations on the transaction are handled.  So let's just handle this registration itself
2845
+		// (the transaction and line items should be all that's left).
2846
+		// delete the line items related to the transaction for this registration.
2847
+		$TXN->delete_related_permanently('Line_Item');
2848
+		//we need to remove all the relationships on the transaction
2849
+		$TXN->delete_related_permanently('Payment');
2850
+		$TXN->delete_related_permanently('Extra_Meta');
2851
+		$TXN->delete_related_permanently('Message');
2852
+		//now we can delete this REG permanently (and the transaction of course)
2853
+		$REG->delete_related_permanently('Transaction');
2854
+		return $REG->delete_permanently();
2855
+	}
2856
+
2857
+
2858
+	/**
2859
+	 *    generates HTML for the Register New Attendee Admin page
2860
+	 *
2861
+	 * @access private
2862
+	 * @throws DomainException
2863
+	 * @throws EE_Error
2864
+	 */
2865
+	public function new_registration()
2866
+	{
2867
+		if ( ! $this->_set_reg_event()) {
2868
+			throw new EE_Error(
2869
+				esc_html__(
2870
+					'Unable to continue with registering because there is no Event ID in the request',
2871
+					'event_espresso'
2872
+				)
2873
+			);
2874
+		}
2875
+		EE_Registry::instance()->REQ->set_espresso_page(true);
2876
+		// gotta start with a clean slate if we're not coming here via ajax
2877
+		if ( ! defined('DOING_AJAX')
2878
+			 && ( ! isset($this->_req_data['processing_registration']) || isset($this->_req_data['step_error']))
2879
+		) {
2880
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2881
+		}
2882
+		$this->_template_args['event_name'] = '';
2883
+		// event name
2884
+		if ($this->_reg_event) {
2885
+			$this->_template_args['event_name'] = $this->_reg_event->name();
2886
+			$edit_event_url                     = self::add_query_args_and_nonce(array(
2887
+				'action' => 'edit',
2888
+				'post'   => $this->_reg_event->ID(),
2889
+			), EVENTS_ADMIN_URL);
2890
+			$edit_event_lnk                     = '<a href="'
2891
+												  . $edit_event_url
2892
+												  . '" title="'
2893
+												  . esc_attr__('Edit ', 'event_espresso')
2894
+												  . $this->_reg_event->name()
2895
+												  . '">'
2896
+												  . esc_html__('Edit Event', 'event_espresso')
2897
+												  . '</a>';
2898
+			$this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2899
+												   . $edit_event_lnk
2900
+												   . '</span>';
2901
+		}
2902
+		$this->_template_args['step_content'] = $this->_get_registration_step_content();
2903
+		if (defined('DOING_AJAX')) {
2904
+			$this->_return_json();
2905
+		}
2906
+		// grab header
2907
+		$template_path                              =
2908
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2909
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template($template_path,
2910
+			$this->_template_args, true);
2911
+		//$this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2912
+		// the details template wrapper
2913
+		$this->display_admin_page_with_sidebar();
2914
+	}
2915
+
2916
+
2917
+	/**
2918
+	 * This returns the content for a registration step
2919
+	 *
2920
+	 * @access protected
2921
+	 * @return string html
2922
+	 * @throws DomainException
2923
+	 * @throws EE_Error
2924
+	 * @throws InvalidArgumentException
2925
+	 * @throws InvalidDataTypeException
2926
+	 * @throws InvalidInterfaceException
2927
+	 */
2928
+	protected function _get_registration_step_content()
2929
+	{
2930
+		if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2931
+			$warning_msg = sprintf(
2932
+				esc_html__(
2933
+					'%2$sWARNING!!!%3$s%1$sPlease do not use the back button to return to this page for the purpose of adding another registration.%1$sThis can result in lost and/or corrupted data.%1$sIf you wish to add another registration, then please click the%1$s%7$s"Add Another New Registration to Event"%8$s button%1$son the Transaction details page, after you are redirected.%1$s%1$s%4$s redirecting in %5$s seconds %6$s',
2934
+					'event_espresso'
2935
+				),
2936
+				'<br />',
2937
+				'<h3 class="important-notice">',
2938
+				'</h3>',
2939
+				'<div class="float-right">',
2940
+				'<span id="redirect_timer" class="important-notice">30</span>',
2941
+				'</div>',
2942
+				'<b>',
2943
+				'</b>'
2944
+			);
2945
+			return '
2946 2946
 	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2947 2947
 	<script >
2948 2948
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
@@ -2955,841 +2955,841 @@  discard block
 block discarded – undo
2955 2955
 	        }
2956 2956
 	    }, 800 );
2957 2957
 	</script >';
2958
-        }
2959
-        $template_args = array(
2960
-            'title'                    => '',
2961
-            'content'                  => '',
2962
-            'step_button_text'         => '',
2963
-            'show_notification_toggle' => false,
2964
-        );
2965
-        //to indicate we're processing a new registration
2966
-        $hidden_fields = array(
2967
-            'processing_registration' => array(
2968
-                'type'  => 'hidden',
2969
-                'value' => 0,
2970
-            ),
2971
-            'event_id'                => array(
2972
-                'type'  => 'hidden',
2973
-                'value' => $this->_reg_event->ID(),
2974
-            ),
2975
-        );
2976
-        //if the cart is empty then we know we're at step one so we'll display ticket selector
2977
-        $cart = EE_Registry::instance()->SSN->cart();
2978
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2979
-        switch ($step) {
2980
-            case 'ticket' :
2981
-                $hidden_fields['processing_registration']['value'] = 1;
2982
-                $template_args['title']                            = esc_html__(
2983
-                    'Step One: Select the Ticket for this registration',
2984
-                    'event_espresso'
2985
-                );
2986
-                $template_args['content']                          =
2987
-                    EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2988
-                $template_args['step_button_text']                 = esc_html__(
2989
-                    'Add Tickets and Continue to Registrant Details',
2990
-                    'event_espresso'
2991
-                );
2992
-                $template_args['show_notification_toggle']         = false;
2993
-                break;
2994
-            case 'questions' :
2995
-                $hidden_fields['processing_registration']['value'] = 2;
2996
-                $template_args['title']                            = esc_html__(
2997
-                    'Step Two: Add Registrant Details for this Registration',
2998
-                    'event_espresso'
2999
-                );
3000
-                //in theory we should be able to run EED_SPCO at this point because the cart should have been setup
3001
-                // properly by the first process_reg_step run.
3002
-                $template_args['content']                  =
3003
-                    EED_Single_Page_Checkout::registration_checkout_for_admin();
3004
-                $template_args['step_button_text']         = esc_html__(
3005
-                    'Save Registration and Continue to Details',
3006
-                    'event_espresso'
3007
-                );
3008
-                $template_args['show_notification_toggle'] = true;
3009
-                break;
3010
-        }
3011
-        //we come back to the process_registration_step route.
3012
-        $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
3013
-        return EEH_Template::display_template(
3014
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
3015
-            $template_args,
3016
-            true
3017
-        );
3018
-    }
3019
-
3020
-
3021
-    /**
3022
-     *        set_reg_event
3023
-     *
3024
-     * @access private
3025
-     * @return bool
3026
-     * @throws EE_Error
3027
-     * @throws InvalidArgumentException
3028
-     * @throws InvalidDataTypeException
3029
-     * @throws InvalidInterfaceException
3030
-     */
3031
-    private function _set_reg_event()
3032
-    {
3033
-        if (is_object($this->_reg_event)) {
3034
-            return true;
3035
-        }
3036
-        $EVT_ID = (! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
3037
-        if ( ! $EVT_ID) {
3038
-            return false;
3039
-        }
3040
-        $this->_reg_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
3041
-        return true;
3042
-    }
3043
-
3044
-
3045
-    /**
3046
-     * process_reg_step
3047
-     *
3048
-     * @access        public
3049
-     * @return string
3050
-     * @throws DomainException
3051
-     * @throws EE_Error
3052
-     * @throws InvalidArgumentException
3053
-     * @throws InvalidDataTypeException
3054
-     * @throws InvalidInterfaceException
3055
-     * @throws ReflectionException
3056
-     * @throws RuntimeException
3057
-     */
3058
-    public function process_reg_step()
3059
-    {
3060
-        EE_System::do_not_cache();
3061
-        $this->_set_reg_event();
3062
-        EE_Registry::instance()->REQ->set_espresso_page(true);
3063
-        EE_Registry::instance()->REQ->set('uts', time());
3064
-        //what step are we on?
3065
-        $cart = EE_Registry::instance()->SSN->cart();
3066
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
3067
-        //if doing ajax then we need to verify the nonce
3068
-        if (defined('DOING_AJAX')) {
3069
-            $nonce = isset($this->_req_data[$this->_req_nonce])
3070
-                ? sanitize_text_field($this->_req_data[$this->_req_nonce]) : '';
3071
-            $this->_verify_nonce($nonce, $this->_req_nonce);
3072
-        }
3073
-        switch ($step) {
3074
-            case 'ticket' :
3075
-                //process ticket selection
3076
-                $success = EED_Ticket_Selector::instance()->process_ticket_selections();
3077
-                if ($success) {
3078
-                    EE_Error::add_success(
3079
-                        esc_html__(
3080
-                            'Tickets Selected. Now complete the registration.',
3081
-                            'event_espresso'
3082
-                        )
3083
-                    );
3084
-                } else {
3085
-                    $query_args['step_error'] = $this->_req_data['step_error'] = true;
3086
-                }
3087
-                if (defined('DOING_AJAX')) {
3088
-                    $this->new_registration(); //display next step
3089
-                } else {
3090
-                    $query_args = array(
3091
-                        'action'                  => 'new_registration',
3092
-                        'processing_registration' => 1,
3093
-                        'event_id'                => $this->_reg_event->ID(),
3094
-                        'uts'                     => time(),
3095
-                    );
3096
-                    $this->_redirect_after_action(
3097
-                        false,
3098
-                        '',
3099
-                        '',
3100
-                        $query_args,
3101
-                        true
3102
-                    );
3103
-                }
3104
-                break;
3105
-            case 'questions' :
3106
-                if (! isset(
3107
-                    $this->_req_data['txn_reg_status_change'],
3108
-                    $this->_req_data['txn_reg_status_change']['send_notifications'])
3109
-                ) {
3110
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3111
-                }
3112
-                //process registration
3113
-                $transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3114
-                if ($cart instanceof EE_Cart) {
3115
-                    $grand_total = $cart->get_cart_grand_total();
3116
-                    if ($grand_total instanceof EE_Line_Item) {
3117
-                        $grand_total->save_this_and_descendants_to_txn();
3118
-                    }
3119
-                }
3120
-                if ( ! $transaction instanceof EE_Transaction) {
3121
-                    $query_args = array(
3122
-                        'action'                  => 'new_registration',
3123
-                        'processing_registration' => 2,
3124
-                        'event_id'                => $this->_reg_event->ID(),
3125
-                        'uts'                     => time(),
3126
-                    );
3127
-                    if (defined('DOING_AJAX')) {
3128
-                        //display registration form again because there are errors (maybe validation?)
3129
-                        $this->new_registration();
3130
-                        return;
3131
-                    } else {
3132
-                        $this->_redirect_after_action(
3133
-                            false,
3134
-                            '',
3135
-                            '',
3136
-                            $query_args,
3137
-                            true
3138
-                        );
3139
-                        return;
3140
-                    }
3141
-                }
3142
-                // maybe update status, and make sure to save transaction if not done already
3143
-                if ( ! $transaction->update_status_based_on_total_paid()) {
3144
-                    $transaction->save();
3145
-                }
3146
-                EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3147
-                $this->_req_data = array();
3148
-                $query_args      = array(
3149
-                    'action'        => 'redirect_to_txn',
3150
-                    'TXN_ID'        => $transaction->ID(),
3151
-                    'EVT_ID'        => $this->_reg_event->ID(),
3152
-                    'event_name'    => urlencode($this->_reg_event->name()),
3153
-                    'redirect_from' => 'new_registration',
3154
-                );
3155
-                $this->_redirect_after_action(false, '', '', $query_args, true);
3156
-                break;
3157
-        }
3158
-        //what are you looking here for?  Should be nothing to do at this point.
3159
-    }
3160
-
3161
-
3162
-    /**
3163
-     * redirect_to_txn
3164
-     *
3165
-     * @access public
3166
-     * @return void
3167
-     * @throws EE_Error
3168
-     * @throws InvalidArgumentException
3169
-     * @throws InvalidDataTypeException
3170
-     * @throws InvalidInterfaceException
3171
-     */
3172
-    public function redirect_to_txn()
3173
-    {
3174
-        EE_System::do_not_cache();
3175
-        EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3176
-        $query_args = array(
3177
-            'action' => 'view_transaction',
3178
-            'TXN_ID' => isset($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : 0,
3179
-            'page'   => 'espresso_transactions',
3180
-        );
3181
-        if (isset($this->_req_data['EVT_ID'], $this->_req_data['redirect_from'])) {
3182
-            $query_args['EVT_ID']        = $this->_req_data['EVT_ID'];
3183
-            $query_args['event_name']    = urlencode($this->_req_data['event_name']);
3184
-            $query_args['redirect_from'] = $this->_req_data['redirect_from'];
3185
-        }
3186
-        EE_Error::add_success(
3187
-            esc_html__(
3188
-                'Registration Created.  Please review the transaction and add any payments as necessary',
3189
-                'event_espresso'
3190
-            )
3191
-        );
3192
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3193
-    }
3194
-
3195
-
3196
-    /**
3197
-     *        generates HTML for the Attendee Contact List
3198
-     *
3199
-     * @access protected
3200
-     * @return void
3201
-     */
3202
-    protected function _attendee_contact_list_table()
3203
-    {
3204
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3205
-        $this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3206
-        $this->display_admin_list_table_page_with_no_sidebar();
3207
-    }
3208
-
3209
-
3210
-    /**
3211
-     *        get_attendees
3212
-     *
3213
-     * @param      $per_page
3214
-     * @param bool $count whether to return count or data.
3215
-     * @param bool $trash
3216
-     * @return array
3217
-     * @throws EE_Error
3218
-     * @throws InvalidArgumentException
3219
-     * @throws InvalidDataTypeException
3220
-     * @throws InvalidInterfaceException
3221
-     * @access public
3222
-     */
3223
-    public function get_attendees($per_page, $count = false, $trash = false)
3224
-    {
3225
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3226
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3227
-        $ATT_MDL                    = EEM_Attendee::instance();
3228
-        $this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
3229
-        switch ($this->_req_data['orderby']) {
3230
-            case 'ATT_ID':
3231
-                $orderby = 'ATT_ID';
3232
-                break;
3233
-            case 'ATT_fname':
3234
-                $orderby = 'ATT_fname';
3235
-                break;
3236
-            case 'ATT_email':
3237
-                $orderby = 'ATT_email';
3238
-                break;
3239
-            case 'ATT_city':
3240
-                $orderby = 'ATT_city';
3241
-                break;
3242
-            case 'STA_ID':
3243
-                $orderby = 'STA_ID';
3244
-                break;
3245
-            case 'CNT_ID':
3246
-                $orderby = 'CNT_ID';
3247
-                break;
3248
-            case 'Registration_Count':
3249
-                $orderby = 'Registration_Count';
3250
-                break;
3251
-            default:
3252
-                $orderby = 'ATT_lname';
3253
-        }
3254
-        $sort         = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
3255
-            ? $this->_req_data['order']
3256
-            : 'ASC';
3257
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
3258
-            ? $this->_req_data['paged']
3259
-            : 1;
3260
-        $per_page     = isset($per_page) && ! empty($per_page) ? $per_page : 10;
3261
-        $per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
3262
-            ? $this->_req_data['perpage']
3263
-            : $per_page;
3264
-        $_where       = array();
3265
-        if ( ! empty($this->_req_data['s'])) {
3266
-            $sstr         = '%' . $this->_req_data['s'] . '%';
3267
-            $_where['OR'] = array(
3268
-                'Registration.Event.EVT_name'       => array('LIKE', $sstr),
3269
-                'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
3270
-                'Registration.Event.EVT_short_desc' => array('LIKE', $sstr),
3271
-                'ATT_fname'                         => array('LIKE', $sstr),
3272
-                'ATT_lname'                         => array('LIKE', $sstr),
3273
-                'ATT_short_bio'                     => array('LIKE', $sstr),
3274
-                'ATT_email'                         => array('LIKE', $sstr),
3275
-                'ATT_address'                       => array('LIKE', $sstr),
3276
-                'ATT_address2'                      => array('LIKE', $sstr),
3277
-                'ATT_city'                          => array('LIKE', $sstr),
3278
-                'Country.CNT_name'                  => array('LIKE', $sstr),
3279
-                'State.STA_name'                    => array('LIKE', $sstr),
3280
-                'ATT_phone'                         => array('LIKE', $sstr),
3281
-                'Registration.REG_final_price'      => array('LIKE', $sstr),
3282
-                'Registration.REG_code'             => array('LIKE', $sstr),
3283
-                'Registration.REG_group_size'       => array('LIKE', $sstr),
3284
-            );
3285
-        }
3286
-        $offset = ($current_page - 1) * $per_page;
3287
-        $limit  = $count ? null : array($offset, $per_page);
3288
-        $query_args = array(
3289
-            $_where,
3290
-            'extra_selects' => array('Registration_Count' => array('Registration.REG_ID', 'count', '%d')),
3291
-            'limit' => $limit
3292
-        );
3293
-        if (! $count) {
3294
-            $query_args['order_by'] = array($orderby => $sort);
3295
-        }
3296
-        if ($trash) {
3297
-            $query_args[0]['status'] = array('!=', 'publish');
3298
-            $all_attendees    = $count
3299
-                ? $ATT_MDL->count($query_args, 'ATT_ID', true)
3300
-                : $ATT_MDL->get_all($query_args);
3301
-        } else {
3302
-            $query_args[0]['status'] = array('IN', array('publish'));
3303
-            $all_attendees    = $count
3304
-                ? $ATT_MDL->count($query_args, 'ATT_ID', true)
3305
-                : $ATT_MDL->get_all($query_args);
3306
-        }
3307
-        return $all_attendees;
3308
-    }
3309
-
3310
-
3311
-    /**
3312
-     * This is just taking care of resending the registration confirmation
3313
-     *
3314
-     * @access protected
3315
-     * @return void
3316
-     */
3317
-    protected function _resend_registration()
3318
-    {
3319
-        $this->_process_resend_registration();
3320
-        $query_args = isset($this->_req_data['redirect_to'])
3321
-            ? array('action' => $this->_req_data['redirect_to'], '_REG_ID' => $this->_req_data['_REG_ID'])
3322
-            : array('action' => 'default');
3323
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3324
-    }
3325
-
3326
-    /**
3327
-     * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3328
-     * to use when selecting registrations
3329
-     * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3330
-     *                                                     the query parameters from the request
3331
-     * @return void ends the request with a redirect or download
3332
-     */
3333
-    public function _registrations_report_base( $method_name_for_getting_query_params )
3334
-    {
3335
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3336
-            wp_redirect(EE_Admin_Page::add_query_args_and_nonce(
3337
-                array(
3338
-                    'page'        => 'espresso_batch',
3339
-                    'batch'       => 'file',
3340
-                    'EVT_ID'      => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3341
-                    'filters'     => urlencode(
3342
-                        serialize(
3343
-                            call_user_func(
3344
-                                array( $this, $method_name_for_getting_query_params ),
3345
-                                EEH_Array::is_set(
3346
-                                    $this->_req_data,
3347
-                                    'filters',
3348
-                                    array()
3349
-                                )
3350
-                            )
3351
-                        )
3352
-                ),
3353
-                'use_filters' => EEH_Array::is_set($this->_req_data, 'use_filters', false),
3354
-                'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3355
-                'return_url'  => urlencode($this->_req_data['return_url']),
3356
-            )));
3357
-        } else {
3358
-            $new_request_args = array(
3359
-                'export' => 'report',
3360
-                'action' => 'registrations_report_for_event',
3361
-                'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3362
-            );
3363
-            $this->_req_data = array_merge($this->_req_data, $new_request_args);
3364
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3365
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3366
-                $EE_Export = EE_Export::instance($this->_req_data);
3367
-                $EE_Export->export();
3368
-            }
3369
-        }
3370
-    }
3371
-
3372
-
3373
-
3374
-    /**
3375
-     * Creates a registration report using only query parameters in the request
3376
-     * @return void
3377
-     */
3378
-    public function _registrations_report()
3379
-    {
3380
-        $this->_registrations_report_base('_get_registration_query_parameters');
3381
-    }
3382
-
3383
-
3384
-    public function _contact_list_export()
3385
-    {
3386
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3387
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3388
-            $EE_Export = EE_Export::instance($this->_req_data);
3389
-            $EE_Export->export_attendees();
3390
-        }
3391
-    }
3392
-
3393
-
3394
-    public function _contact_list_report()
3395
-    {
3396
-        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3397
-            wp_redirect(EE_Admin_Page::add_query_args_and_nonce(array(
3398
-                'page'        => 'espresso_batch',
3399
-                'batch'       => 'file',
3400
-                'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3401
-                'return_url'  => urlencode($this->_req_data['return_url']),
3402
-            )));
3403
-        } else {
3404
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3405
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3406
-                $EE_Export = EE_Export::instance($this->_req_data);
3407
-                $EE_Export->report_attendees();
3408
-            }
3409
-        }
3410
-    }
3411
-
3412
-
3413
-
3414
-
3415
-
3416
-    /***************************************        ATTENDEE DETAILS        ***************************************/
3417
-    /**
3418
-     * This duplicates the attendee object for the given incoming registration id and attendee_id.
3419
-     *
3420
-     * @return void
3421
-     * @throws EE_Error
3422
-     * @throws InvalidArgumentException
3423
-     * @throws InvalidDataTypeException
3424
-     * @throws InvalidInterfaceException
3425
-     */
3426
-    protected function _duplicate_attendee()
3427
-    {
3428
-        $action = ! empty($this->_req_data['return']) ? $this->_req_data['return'] : 'default';
3429
-        //verify we have necessary info
3430
-        if (empty($this->_req_data['_REG_ID'])) {
3431
-            EE_Error::add_error(
3432
-                esc_html__(
3433
-                    'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3434
-                    'event_espresso'
3435
-                ), __FILE__, __LINE__, __FUNCTION__
3436
-            );
3437
-            $query_args = array('action' => $action);
3438
-            $this->_redirect_after_action('', '', '', $query_args, true);
3439
-        }
3440
-        //okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3441
-        $registration = EEM_Registration::instance()->get_one_by_ID($this->_req_data['_REG_ID']);
3442
-        $attendee     = $registration->attendee();
3443
-        //remove relation of existing attendee on registration
3444
-        $registration->_remove_relation_to($attendee, 'Attendee');
3445
-        //new attendee
3446
-        $new_attendee = clone $attendee;
3447
-        $new_attendee->set('ATT_ID', 0);
3448
-        $new_attendee->save();
3449
-        //add new attendee to reg
3450
-        $registration->_add_relation_to($new_attendee, 'Attendee');
3451
-        EE_Error::add_success(
3452
-            esc_html__(
3453
-                'New Contact record created.  Now make any edits you wish to make for this contact.',
3454
-                'event_espresso'
3455
-            )
3456
-        );
3457
-        //redirect to edit page for attendee
3458
-        $query_args = array('post' => $new_attendee->ID(), 'action' => 'edit_attendee');
3459
-        $this->_redirect_after_action('', '', '', $query_args, true);
3460
-    }
3461
-
3462
-
3463
-    /**
3464
-     * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3465
-     * @param int      $post_id
3466
-     * @param WP_POST $post
3467
-     * @throws DomainException
3468
-     * @throws EE_Error
3469
-     * @throws InvalidArgumentException
3470
-     * @throws InvalidDataTypeException
3471
-     * @throws InvalidInterfaceException
3472
-     * @throws LogicException
3473
-     * @throws InvalidFormSubmissionException
3474
-     */
3475
-    protected function _insert_update_cpt_item($post_id, $post)
3476
-    {
3477
-        $success  = true;
3478
-        $attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3479
-            ? EEM_Attendee::instance()->get_one_by_ID($post_id)
3480
-            : null;
3481
-        //for attendee updates
3482
-        if ($attendee instanceof EE_Attendee) {
3483
-            //note we should only be UPDATING attendees at this point.
3484
-            $updated_fields = array(
3485
-                'ATT_fname'     => $this->_req_data['ATT_fname'],
3486
-                'ATT_lname'     => $this->_req_data['ATT_lname'],
3487
-                'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
3488
-                'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
3489
-                'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
3490
-                'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
3491
-                'STA_ID'        => isset($this->_req_data['STA_ID']) ? $this->_req_data['STA_ID'] : '',
3492
-                'CNT_ISO'       => isset($this->_req_data['CNT_ISO']) ? $this->_req_data['CNT_ISO'] : '',
3493
-                'ATT_zip'       => isset($this->_req_data['ATT_zip']) ? $this->_req_data['ATT_zip'] : '',
3494
-            );
3495
-            foreach ($updated_fields as $field => $value) {
3496
-                $attendee->set($field, $value);
3497
-            }
3498
-
3499
-            //process contact details metabox form handler (which will also save the attendee)
3500
-            $contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3501
-            $success = $contact_details_form->process($this->_req_data);
3502
-
3503
-            $attendee_update_callbacks = apply_filters(
3504
-                'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3505
-                array()
3506
-            );
3507
-            foreach ($attendee_update_callbacks as $a_callback) {
3508
-                if (false === call_user_func_array($a_callback, array($attendee, $this->_req_data))) {
3509
-                    throw new EE_Error(
3510
-                        sprintf(
3511
-                            esc_html__(
3512
-                                'The %s callback given for the "FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update" filter is not a valid callback.  Please check the spelling.',
3513
-                                'event_espresso'
3514
-                            ),
3515
-                            $a_callback
3516
-                        )
3517
-                    );
3518
-                }
3519
-            }
3520
-        }
3521
-
3522
-        if ($success === false) {
3523
-            EE_Error::add_error(
3524
-                esc_html__(
3525
-                    'Something went wrong with updating the meta table data for the registration.',
3526
-                    'event_espresso'
3527
-                ),
3528
-                __FILE__, __FUNCTION__, __LINE__
3529
-            );
3530
-        }
3531
-    }
3532
-
3533
-
3534
-    public function trash_cpt_item($post_id)
3535
-    {
3536
-    }
3537
-
3538
-
3539
-    public function delete_cpt_item($post_id)
3540
-    {
3541
-    }
3542
-
3543
-
3544
-    public function restore_cpt_item($post_id)
3545
-    {
3546
-    }
3547
-
3548
-
3549
-    protected function _restore_cpt_item($post_id, $revision_id)
3550
-    {
3551
-    }
3552
-
3553
-
3554
-    public function attendee_editor_metaboxes()
3555
-    {
3556
-        $this->verify_cpt_object();
3557
-        remove_meta_box(
3558
-            'postexcerpt',
3559
-            esc_html__('Excerpt', 'event_espresso'),
3560
-            'post_excerpt_meta_box',
3561
-            $this->_cpt_routes[$this->_req_action],
3562
-            'normal',
3563
-            'core'
3564
-        );
3565
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[$this->_req_action], 'normal', 'core');
3566
-        if (post_type_supports('espresso_attendees', 'excerpt')) {
3567
-            add_meta_box(
3568
-                'postexcerpt',
3569
-                esc_html__('Short Biography', 'event_espresso'),
3570
-                'post_excerpt_meta_box',
3571
-                $this->_cpt_routes[$this->_req_action],
3572
-                'normal'
3573
-            );
3574
-        }
3575
-        if (post_type_supports('espresso_attendees', 'comments')) {
3576
-            add_meta_box(
3577
-                'commentsdiv',
3578
-                esc_html__('Notes on the Contact', 'event_espresso'),
3579
-                'post_comment_meta_box',
3580
-                $this->_cpt_routes[$this->_req_action],
3581
-                'normal',
3582
-                'core'
3583
-            );
3584
-        }
3585
-        add_meta_box(
3586
-            'attendee_contact_info',
3587
-            esc_html__('Contact Info', 'event_espresso'),
3588
-            array($this, 'attendee_contact_info'),
3589
-            $this->_cpt_routes[$this->_req_action],
3590
-            'side',
3591
-            'core'
3592
-        );
3593
-        add_meta_box(
3594
-            'attendee_details_address',
3595
-            esc_html__('Address Details', 'event_espresso'),
3596
-            array($this, 'attendee_address_details'),
3597
-            $this->_cpt_routes[$this->_req_action],
3598
-            'normal',
3599
-            'core'
3600
-        );
3601
-        add_meta_box(
3602
-            'attendee_registrations',
3603
-            esc_html__('Registrations for this Contact', 'event_espresso'),
3604
-            array($this, 'attendee_registrations_meta_box'),
3605
-            $this->_cpt_routes[$this->_req_action],
3606
-            'normal',
3607
-            'high'
3608
-        );
3609
-    }
3610
-
3611
-
3612
-    /**
3613
-     * Metabox for attendee contact info
3614
-     *
3615
-     * @param  WP_Post $post wp post object
3616
-     * @return string attendee contact info ( and form )
3617
-     * @throws EE_Error
3618
-     * @throws InvalidArgumentException
3619
-     * @throws InvalidDataTypeException
3620
-     * @throws InvalidInterfaceException
3621
-     * @throws LogicException
3622
-     * @throws DomainException
3623
-     */
3624
-    public function attendee_contact_info($post)
3625
-    {
3626
-        //get attendee object ( should already have it )
3627
-        $form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3628
-        $form->enqueueStylesAndScripts();
3629
-        echo $form->display();
3630
-    }
3631
-
3632
-
3633
-    /**
3634
-     * Return form handler for the contact details metabox
3635
-     *
3636
-     * @param EE_Attendee $attendee
3637
-     * @return AttendeeContactDetailsMetaboxFormHandler
3638
-     * @throws DomainException
3639
-     * @throws InvalidArgumentException
3640
-     * @throws InvalidDataTypeException
3641
-     * @throws InvalidInterfaceException
3642
-     */
3643
-    protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3644
-    {
3645
-        return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3646
-    }
3647
-
3648
-
3649
-    /**
3650
-     * Metabox for attendee details
3651
-     *
3652
-     * @param  WP_Post $post wp post object
3653
-     * @throws DomainException
3654
-     */
3655
-    public function attendee_address_details($post)
3656
-    {
3657
-        //get attendee object (should already have it)
3658
-        $this->_template_args['attendee']     = $this->_cpt_model_obj;
3659
-        $this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3660
-            new EE_Question_Form_Input(
3661
-                EE_Question::new_instance(
3662
-                    array(
3663
-                        'QST_ID'           => 0,
3664
-                        'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3665
-                        'QST_system'       => 'admin-state',
3666
-                    )
3667
-                ),
3668
-                EE_Answer::new_instance(
3669
-                    array(
3670
-                        'ANS_ID'    => 0,
3671
-                        'ANS_value' => $this->_cpt_model_obj->state_ID(),
3672
-                    )
3673
-                ),
3674
-                array(
3675
-                    'input_id'       => 'STA_ID',
3676
-                    'input_name'     => 'STA_ID',
3677
-                    'input_prefix'   => '',
3678
-                    'append_qstn_id' => false,
3679
-                )
3680
-            )
3681
-        );
3682
-        $this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3683
-            new EE_Question_Form_Input(
3684
-                EE_Question::new_instance(
3685
-                    array(
3686
-                        'QST_ID'           => 0,
3687
-                        'QST_display_text' => esc_html__('Country', 'event_espresso'),
3688
-                        'QST_system'       => 'admin-country',
3689
-                    )
3690
-                ),
3691
-                EE_Answer::new_instance(
3692
-                    array(
3693
-                        'ANS_ID'    => 0,
3694
-                        'ANS_value' => $this->_cpt_model_obj->country_ID(),
3695
-                    )
3696
-                ),
3697
-                array(
3698
-                    'input_id'       => 'CNT_ISO',
3699
-                    'input_name'     => 'CNT_ISO',
3700
-                    'input_prefix'   => '',
3701
-                    'append_qstn_id' => false,
3702
-                )
3703
-            )
3704
-        );
3705
-        $template                             =
3706
-            REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3707
-        EEH_Template::display_template($template, $this->_template_args);
3708
-    }
3709
-
3710
-
3711
-    /**
3712
-     *        _attendee_details
3713
-     *
3714
-     * @access protected
3715
-     * @param $post
3716
-     * @return void
3717
-     * @throws DomainException
3718
-     * @throws EE_Error
3719
-     */
3720
-    public function attendee_registrations_meta_box($post)
3721
-    {
3722
-        $this->_template_args['attendee']      = $this->_cpt_model_obj;
3723
-        $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3724
-        $template                              =
3725
-            REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3726
-        EEH_Template::display_template($template, $this->_template_args);
3727
-    }
3728
-
3729
-
3730
-    /**
3731
-     * add in the form fields for the attendee edit
3732
-     *
3733
-     * @param  WP_Post $post wp post object
3734
-     * @return string html for new form.
3735
-     * @throws DomainException
3736
-     */
3737
-    public function after_title_form_fields($post)
3738
-    {
3739
-        if ($post->post_type == 'espresso_attendees') {
3740
-            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3741
-            $template_args['attendee'] = $this->_cpt_model_obj;
3742
-            EEH_Template::display_template($template, $template_args);
3743
-        }
3744
-    }
3745
-
3746
-
3747
-    /**
3748
-     *        _trash_or_restore_attendee
3749
-     *
3750
-     * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3751
-     * @return void
3752
-     * @throws EE_Error
3753
-     * @throws InvalidArgumentException
3754
-     * @throws InvalidDataTypeException
3755
-     * @throws InvalidInterfaceException
3756
-     * @access protected
3757
-     */
3758
-    protected function _trash_or_restore_attendees($trash = true)
3759
-    {
3760
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3761
-        $ATT_MDL = EEM_Attendee::instance();
3762
-        $success = 1;
3763
-        //Checkboxes
3764
-        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3765
-            // if array has more than one element than success message should be plural
3766
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3767
-            // cycle thru checkboxes
3768
-            while (list($ATT_ID, $value) = each($this->_req_data['checkbox'])) {
3769
-                $updated = $trash ? $ATT_MDL->update_by_ID(array('status' => 'trash'), $ATT_ID)
3770
-                    : $ATT_MDL->update_by_ID(array('status' => 'publish'), $ATT_ID);
3771
-                if ( ! $updated) {
3772
-                    $success = 0;
3773
-                }
3774
-            }
3775
-        } else {
3776
-            // grab single id and delete
3777
-            $ATT_ID = absint($this->_req_data['ATT_ID']);
3778
-            //get attendee
3779
-            $att     = $ATT_MDL->get_one_by_ID($ATT_ID);
3780
-            $updated = $trash ? $att->set_status('trash') : $att->set_status('publish');
3781
-            $updated = $att->save();
3782
-            if ( ! $updated) {
3783
-                $success = 0;
3784
-            }
3785
-        }
3786
-        $what        = $success > 1
3787
-            ? esc_html__('Contacts', 'event_espresso')
3788
-            : esc_html__('Contact', 'event_espresso');
3789
-        $action_desc = $trash
3790
-            ? esc_html__('moved to the trash', 'event_espresso')
3791
-            : esc_html__('restored', 'event_espresso');
3792
-        $this->_redirect_after_action($success, $what, $action_desc, array('action' => 'contact_list'));
3793
-    }
2958
+		}
2959
+		$template_args = array(
2960
+			'title'                    => '',
2961
+			'content'                  => '',
2962
+			'step_button_text'         => '',
2963
+			'show_notification_toggle' => false,
2964
+		);
2965
+		//to indicate we're processing a new registration
2966
+		$hidden_fields = array(
2967
+			'processing_registration' => array(
2968
+				'type'  => 'hidden',
2969
+				'value' => 0,
2970
+			),
2971
+			'event_id'                => array(
2972
+				'type'  => 'hidden',
2973
+				'value' => $this->_reg_event->ID(),
2974
+			),
2975
+		);
2976
+		//if the cart is empty then we know we're at step one so we'll display ticket selector
2977
+		$cart = EE_Registry::instance()->SSN->cart();
2978
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2979
+		switch ($step) {
2980
+			case 'ticket' :
2981
+				$hidden_fields['processing_registration']['value'] = 1;
2982
+				$template_args['title']                            = esc_html__(
2983
+					'Step One: Select the Ticket for this registration',
2984
+					'event_espresso'
2985
+				);
2986
+				$template_args['content']                          =
2987
+					EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2988
+				$template_args['step_button_text']                 = esc_html__(
2989
+					'Add Tickets and Continue to Registrant Details',
2990
+					'event_espresso'
2991
+				);
2992
+				$template_args['show_notification_toggle']         = false;
2993
+				break;
2994
+			case 'questions' :
2995
+				$hidden_fields['processing_registration']['value'] = 2;
2996
+				$template_args['title']                            = esc_html__(
2997
+					'Step Two: Add Registrant Details for this Registration',
2998
+					'event_espresso'
2999
+				);
3000
+				//in theory we should be able to run EED_SPCO at this point because the cart should have been setup
3001
+				// properly by the first process_reg_step run.
3002
+				$template_args['content']                  =
3003
+					EED_Single_Page_Checkout::registration_checkout_for_admin();
3004
+				$template_args['step_button_text']         = esc_html__(
3005
+					'Save Registration and Continue to Details',
3006
+					'event_espresso'
3007
+				);
3008
+				$template_args['show_notification_toggle'] = true;
3009
+				break;
3010
+		}
3011
+		//we come back to the process_registration_step route.
3012
+		$this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
3013
+		return EEH_Template::display_template(
3014
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
3015
+			$template_args,
3016
+			true
3017
+		);
3018
+	}
3019
+
3020
+
3021
+	/**
3022
+	 *        set_reg_event
3023
+	 *
3024
+	 * @access private
3025
+	 * @return bool
3026
+	 * @throws EE_Error
3027
+	 * @throws InvalidArgumentException
3028
+	 * @throws InvalidDataTypeException
3029
+	 * @throws InvalidInterfaceException
3030
+	 */
3031
+	private function _set_reg_event()
3032
+	{
3033
+		if (is_object($this->_reg_event)) {
3034
+			return true;
3035
+		}
3036
+		$EVT_ID = (! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
3037
+		if ( ! $EVT_ID) {
3038
+			return false;
3039
+		}
3040
+		$this->_reg_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
3041
+		return true;
3042
+	}
3043
+
3044
+
3045
+	/**
3046
+	 * process_reg_step
3047
+	 *
3048
+	 * @access        public
3049
+	 * @return string
3050
+	 * @throws DomainException
3051
+	 * @throws EE_Error
3052
+	 * @throws InvalidArgumentException
3053
+	 * @throws InvalidDataTypeException
3054
+	 * @throws InvalidInterfaceException
3055
+	 * @throws ReflectionException
3056
+	 * @throws RuntimeException
3057
+	 */
3058
+	public function process_reg_step()
3059
+	{
3060
+		EE_System::do_not_cache();
3061
+		$this->_set_reg_event();
3062
+		EE_Registry::instance()->REQ->set_espresso_page(true);
3063
+		EE_Registry::instance()->REQ->set('uts', time());
3064
+		//what step are we on?
3065
+		$cart = EE_Registry::instance()->SSN->cart();
3066
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
3067
+		//if doing ajax then we need to verify the nonce
3068
+		if (defined('DOING_AJAX')) {
3069
+			$nonce = isset($this->_req_data[$this->_req_nonce])
3070
+				? sanitize_text_field($this->_req_data[$this->_req_nonce]) : '';
3071
+			$this->_verify_nonce($nonce, $this->_req_nonce);
3072
+		}
3073
+		switch ($step) {
3074
+			case 'ticket' :
3075
+				//process ticket selection
3076
+				$success = EED_Ticket_Selector::instance()->process_ticket_selections();
3077
+				if ($success) {
3078
+					EE_Error::add_success(
3079
+						esc_html__(
3080
+							'Tickets Selected. Now complete the registration.',
3081
+							'event_espresso'
3082
+						)
3083
+					);
3084
+				} else {
3085
+					$query_args['step_error'] = $this->_req_data['step_error'] = true;
3086
+				}
3087
+				if (defined('DOING_AJAX')) {
3088
+					$this->new_registration(); //display next step
3089
+				} else {
3090
+					$query_args = array(
3091
+						'action'                  => 'new_registration',
3092
+						'processing_registration' => 1,
3093
+						'event_id'                => $this->_reg_event->ID(),
3094
+						'uts'                     => time(),
3095
+					);
3096
+					$this->_redirect_after_action(
3097
+						false,
3098
+						'',
3099
+						'',
3100
+						$query_args,
3101
+						true
3102
+					);
3103
+				}
3104
+				break;
3105
+			case 'questions' :
3106
+				if (! isset(
3107
+					$this->_req_data['txn_reg_status_change'],
3108
+					$this->_req_data['txn_reg_status_change']['send_notifications'])
3109
+				) {
3110
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3111
+				}
3112
+				//process registration
3113
+				$transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3114
+				if ($cart instanceof EE_Cart) {
3115
+					$grand_total = $cart->get_cart_grand_total();
3116
+					if ($grand_total instanceof EE_Line_Item) {
3117
+						$grand_total->save_this_and_descendants_to_txn();
3118
+					}
3119
+				}
3120
+				if ( ! $transaction instanceof EE_Transaction) {
3121
+					$query_args = array(
3122
+						'action'                  => 'new_registration',
3123
+						'processing_registration' => 2,
3124
+						'event_id'                => $this->_reg_event->ID(),
3125
+						'uts'                     => time(),
3126
+					);
3127
+					if (defined('DOING_AJAX')) {
3128
+						//display registration form again because there are errors (maybe validation?)
3129
+						$this->new_registration();
3130
+						return;
3131
+					} else {
3132
+						$this->_redirect_after_action(
3133
+							false,
3134
+							'',
3135
+							'',
3136
+							$query_args,
3137
+							true
3138
+						);
3139
+						return;
3140
+					}
3141
+				}
3142
+				// maybe update status, and make sure to save transaction if not done already
3143
+				if ( ! $transaction->update_status_based_on_total_paid()) {
3144
+					$transaction->save();
3145
+				}
3146
+				EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3147
+				$this->_req_data = array();
3148
+				$query_args      = array(
3149
+					'action'        => 'redirect_to_txn',
3150
+					'TXN_ID'        => $transaction->ID(),
3151
+					'EVT_ID'        => $this->_reg_event->ID(),
3152
+					'event_name'    => urlencode($this->_reg_event->name()),
3153
+					'redirect_from' => 'new_registration',
3154
+				);
3155
+				$this->_redirect_after_action(false, '', '', $query_args, true);
3156
+				break;
3157
+		}
3158
+		//what are you looking here for?  Should be nothing to do at this point.
3159
+	}
3160
+
3161
+
3162
+	/**
3163
+	 * redirect_to_txn
3164
+	 *
3165
+	 * @access public
3166
+	 * @return void
3167
+	 * @throws EE_Error
3168
+	 * @throws InvalidArgumentException
3169
+	 * @throws InvalidDataTypeException
3170
+	 * @throws InvalidInterfaceException
3171
+	 */
3172
+	public function redirect_to_txn()
3173
+	{
3174
+		EE_System::do_not_cache();
3175
+		EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3176
+		$query_args = array(
3177
+			'action' => 'view_transaction',
3178
+			'TXN_ID' => isset($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : 0,
3179
+			'page'   => 'espresso_transactions',
3180
+		);
3181
+		if (isset($this->_req_data['EVT_ID'], $this->_req_data['redirect_from'])) {
3182
+			$query_args['EVT_ID']        = $this->_req_data['EVT_ID'];
3183
+			$query_args['event_name']    = urlencode($this->_req_data['event_name']);
3184
+			$query_args['redirect_from'] = $this->_req_data['redirect_from'];
3185
+		}
3186
+		EE_Error::add_success(
3187
+			esc_html__(
3188
+				'Registration Created.  Please review the transaction and add any payments as necessary',
3189
+				'event_espresso'
3190
+			)
3191
+		);
3192
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3193
+	}
3194
+
3195
+
3196
+	/**
3197
+	 *        generates HTML for the Attendee Contact List
3198
+	 *
3199
+	 * @access protected
3200
+	 * @return void
3201
+	 */
3202
+	protected function _attendee_contact_list_table()
3203
+	{
3204
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3205
+		$this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3206
+		$this->display_admin_list_table_page_with_no_sidebar();
3207
+	}
3208
+
3209
+
3210
+	/**
3211
+	 *        get_attendees
3212
+	 *
3213
+	 * @param      $per_page
3214
+	 * @param bool $count whether to return count or data.
3215
+	 * @param bool $trash
3216
+	 * @return array
3217
+	 * @throws EE_Error
3218
+	 * @throws InvalidArgumentException
3219
+	 * @throws InvalidDataTypeException
3220
+	 * @throws InvalidInterfaceException
3221
+	 * @access public
3222
+	 */
3223
+	public function get_attendees($per_page, $count = false, $trash = false)
3224
+	{
3225
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3226
+		require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3227
+		$ATT_MDL                    = EEM_Attendee::instance();
3228
+		$this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
3229
+		switch ($this->_req_data['orderby']) {
3230
+			case 'ATT_ID':
3231
+				$orderby = 'ATT_ID';
3232
+				break;
3233
+			case 'ATT_fname':
3234
+				$orderby = 'ATT_fname';
3235
+				break;
3236
+			case 'ATT_email':
3237
+				$orderby = 'ATT_email';
3238
+				break;
3239
+			case 'ATT_city':
3240
+				$orderby = 'ATT_city';
3241
+				break;
3242
+			case 'STA_ID':
3243
+				$orderby = 'STA_ID';
3244
+				break;
3245
+			case 'CNT_ID':
3246
+				$orderby = 'CNT_ID';
3247
+				break;
3248
+			case 'Registration_Count':
3249
+				$orderby = 'Registration_Count';
3250
+				break;
3251
+			default:
3252
+				$orderby = 'ATT_lname';
3253
+		}
3254
+		$sort         = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
3255
+			? $this->_req_data['order']
3256
+			: 'ASC';
3257
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
3258
+			? $this->_req_data['paged']
3259
+			: 1;
3260
+		$per_page     = isset($per_page) && ! empty($per_page) ? $per_page : 10;
3261
+		$per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
3262
+			? $this->_req_data['perpage']
3263
+			: $per_page;
3264
+		$_where       = array();
3265
+		if ( ! empty($this->_req_data['s'])) {
3266
+			$sstr         = '%' . $this->_req_data['s'] . '%';
3267
+			$_where['OR'] = array(
3268
+				'Registration.Event.EVT_name'       => array('LIKE', $sstr),
3269
+				'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
3270
+				'Registration.Event.EVT_short_desc' => array('LIKE', $sstr),
3271
+				'ATT_fname'                         => array('LIKE', $sstr),
3272
+				'ATT_lname'                         => array('LIKE', $sstr),
3273
+				'ATT_short_bio'                     => array('LIKE', $sstr),
3274
+				'ATT_email'                         => array('LIKE', $sstr),
3275
+				'ATT_address'                       => array('LIKE', $sstr),
3276
+				'ATT_address2'                      => array('LIKE', $sstr),
3277
+				'ATT_city'                          => array('LIKE', $sstr),
3278
+				'Country.CNT_name'                  => array('LIKE', $sstr),
3279
+				'State.STA_name'                    => array('LIKE', $sstr),
3280
+				'ATT_phone'                         => array('LIKE', $sstr),
3281
+				'Registration.REG_final_price'      => array('LIKE', $sstr),
3282
+				'Registration.REG_code'             => array('LIKE', $sstr),
3283
+				'Registration.REG_group_size'       => array('LIKE', $sstr),
3284
+			);
3285
+		}
3286
+		$offset = ($current_page - 1) * $per_page;
3287
+		$limit  = $count ? null : array($offset, $per_page);
3288
+		$query_args = array(
3289
+			$_where,
3290
+			'extra_selects' => array('Registration_Count' => array('Registration.REG_ID', 'count', '%d')),
3291
+			'limit' => $limit
3292
+		);
3293
+		if (! $count) {
3294
+			$query_args['order_by'] = array($orderby => $sort);
3295
+		}
3296
+		if ($trash) {
3297
+			$query_args[0]['status'] = array('!=', 'publish');
3298
+			$all_attendees    = $count
3299
+				? $ATT_MDL->count($query_args, 'ATT_ID', true)
3300
+				: $ATT_MDL->get_all($query_args);
3301
+		} else {
3302
+			$query_args[0]['status'] = array('IN', array('publish'));
3303
+			$all_attendees    = $count
3304
+				? $ATT_MDL->count($query_args, 'ATT_ID', true)
3305
+				: $ATT_MDL->get_all($query_args);
3306
+		}
3307
+		return $all_attendees;
3308
+	}
3309
+
3310
+
3311
+	/**
3312
+	 * This is just taking care of resending the registration confirmation
3313
+	 *
3314
+	 * @access protected
3315
+	 * @return void
3316
+	 */
3317
+	protected function _resend_registration()
3318
+	{
3319
+		$this->_process_resend_registration();
3320
+		$query_args = isset($this->_req_data['redirect_to'])
3321
+			? array('action' => $this->_req_data['redirect_to'], '_REG_ID' => $this->_req_data['_REG_ID'])
3322
+			: array('action' => 'default');
3323
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3324
+	}
3325
+
3326
+	/**
3327
+	 * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3328
+	 * to use when selecting registrations
3329
+	 * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3330
+	 *                                                     the query parameters from the request
3331
+	 * @return void ends the request with a redirect or download
3332
+	 */
3333
+	public function _registrations_report_base( $method_name_for_getting_query_params )
3334
+	{
3335
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3336
+			wp_redirect(EE_Admin_Page::add_query_args_and_nonce(
3337
+				array(
3338
+					'page'        => 'espresso_batch',
3339
+					'batch'       => 'file',
3340
+					'EVT_ID'      => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3341
+					'filters'     => urlencode(
3342
+						serialize(
3343
+							call_user_func(
3344
+								array( $this, $method_name_for_getting_query_params ),
3345
+								EEH_Array::is_set(
3346
+									$this->_req_data,
3347
+									'filters',
3348
+									array()
3349
+								)
3350
+							)
3351
+						)
3352
+				),
3353
+				'use_filters' => EEH_Array::is_set($this->_req_data, 'use_filters', false),
3354
+				'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3355
+				'return_url'  => urlencode($this->_req_data['return_url']),
3356
+			)));
3357
+		} else {
3358
+			$new_request_args = array(
3359
+				'export' => 'report',
3360
+				'action' => 'registrations_report_for_event',
3361
+				'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3362
+			);
3363
+			$this->_req_data = array_merge($this->_req_data, $new_request_args);
3364
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3365
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3366
+				$EE_Export = EE_Export::instance($this->_req_data);
3367
+				$EE_Export->export();
3368
+			}
3369
+		}
3370
+	}
3371
+
3372
+
3373
+
3374
+	/**
3375
+	 * Creates a registration report using only query parameters in the request
3376
+	 * @return void
3377
+	 */
3378
+	public function _registrations_report()
3379
+	{
3380
+		$this->_registrations_report_base('_get_registration_query_parameters');
3381
+	}
3382
+
3383
+
3384
+	public function _contact_list_export()
3385
+	{
3386
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3387
+			require_once(EE_CLASSES . 'EE_Export.class.php');
3388
+			$EE_Export = EE_Export::instance($this->_req_data);
3389
+			$EE_Export->export_attendees();
3390
+		}
3391
+	}
3392
+
3393
+
3394
+	public function _contact_list_report()
3395
+	{
3396
+		if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3397
+			wp_redirect(EE_Admin_Page::add_query_args_and_nonce(array(
3398
+				'page'        => 'espresso_batch',
3399
+				'batch'       => 'file',
3400
+				'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3401
+				'return_url'  => urlencode($this->_req_data['return_url']),
3402
+			)));
3403
+		} else {
3404
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3405
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3406
+				$EE_Export = EE_Export::instance($this->_req_data);
3407
+				$EE_Export->report_attendees();
3408
+			}
3409
+		}
3410
+	}
3411
+
3412
+
3413
+
3414
+
3415
+
3416
+	/***************************************        ATTENDEE DETAILS        ***************************************/
3417
+	/**
3418
+	 * This duplicates the attendee object for the given incoming registration id and attendee_id.
3419
+	 *
3420
+	 * @return void
3421
+	 * @throws EE_Error
3422
+	 * @throws InvalidArgumentException
3423
+	 * @throws InvalidDataTypeException
3424
+	 * @throws InvalidInterfaceException
3425
+	 */
3426
+	protected function _duplicate_attendee()
3427
+	{
3428
+		$action = ! empty($this->_req_data['return']) ? $this->_req_data['return'] : 'default';
3429
+		//verify we have necessary info
3430
+		if (empty($this->_req_data['_REG_ID'])) {
3431
+			EE_Error::add_error(
3432
+				esc_html__(
3433
+					'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3434
+					'event_espresso'
3435
+				), __FILE__, __LINE__, __FUNCTION__
3436
+			);
3437
+			$query_args = array('action' => $action);
3438
+			$this->_redirect_after_action('', '', '', $query_args, true);
3439
+		}
3440
+		//okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3441
+		$registration = EEM_Registration::instance()->get_one_by_ID($this->_req_data['_REG_ID']);
3442
+		$attendee     = $registration->attendee();
3443
+		//remove relation of existing attendee on registration
3444
+		$registration->_remove_relation_to($attendee, 'Attendee');
3445
+		//new attendee
3446
+		$new_attendee = clone $attendee;
3447
+		$new_attendee->set('ATT_ID', 0);
3448
+		$new_attendee->save();
3449
+		//add new attendee to reg
3450
+		$registration->_add_relation_to($new_attendee, 'Attendee');
3451
+		EE_Error::add_success(
3452
+			esc_html__(
3453
+				'New Contact record created.  Now make any edits you wish to make for this contact.',
3454
+				'event_espresso'
3455
+			)
3456
+		);
3457
+		//redirect to edit page for attendee
3458
+		$query_args = array('post' => $new_attendee->ID(), 'action' => 'edit_attendee');
3459
+		$this->_redirect_after_action('', '', '', $query_args, true);
3460
+	}
3461
+
3462
+
3463
+	/**
3464
+	 * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3465
+	 * @param int      $post_id
3466
+	 * @param WP_POST $post
3467
+	 * @throws DomainException
3468
+	 * @throws EE_Error
3469
+	 * @throws InvalidArgumentException
3470
+	 * @throws InvalidDataTypeException
3471
+	 * @throws InvalidInterfaceException
3472
+	 * @throws LogicException
3473
+	 * @throws InvalidFormSubmissionException
3474
+	 */
3475
+	protected function _insert_update_cpt_item($post_id, $post)
3476
+	{
3477
+		$success  = true;
3478
+		$attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3479
+			? EEM_Attendee::instance()->get_one_by_ID($post_id)
3480
+			: null;
3481
+		//for attendee updates
3482
+		if ($attendee instanceof EE_Attendee) {
3483
+			//note we should only be UPDATING attendees at this point.
3484
+			$updated_fields = array(
3485
+				'ATT_fname'     => $this->_req_data['ATT_fname'],
3486
+				'ATT_lname'     => $this->_req_data['ATT_lname'],
3487
+				'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
3488
+				'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
3489
+				'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
3490
+				'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
3491
+				'STA_ID'        => isset($this->_req_data['STA_ID']) ? $this->_req_data['STA_ID'] : '',
3492
+				'CNT_ISO'       => isset($this->_req_data['CNT_ISO']) ? $this->_req_data['CNT_ISO'] : '',
3493
+				'ATT_zip'       => isset($this->_req_data['ATT_zip']) ? $this->_req_data['ATT_zip'] : '',
3494
+			);
3495
+			foreach ($updated_fields as $field => $value) {
3496
+				$attendee->set($field, $value);
3497
+			}
3498
+
3499
+			//process contact details metabox form handler (which will also save the attendee)
3500
+			$contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3501
+			$success = $contact_details_form->process($this->_req_data);
3502
+
3503
+			$attendee_update_callbacks = apply_filters(
3504
+				'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3505
+				array()
3506
+			);
3507
+			foreach ($attendee_update_callbacks as $a_callback) {
3508
+				if (false === call_user_func_array($a_callback, array($attendee, $this->_req_data))) {
3509
+					throw new EE_Error(
3510
+						sprintf(
3511
+							esc_html__(
3512
+								'The %s callback given for the "FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update" filter is not a valid callback.  Please check the spelling.',
3513
+								'event_espresso'
3514
+							),
3515
+							$a_callback
3516
+						)
3517
+					);
3518
+				}
3519
+			}
3520
+		}
3521
+
3522
+		if ($success === false) {
3523
+			EE_Error::add_error(
3524
+				esc_html__(
3525
+					'Something went wrong with updating the meta table data for the registration.',
3526
+					'event_espresso'
3527
+				),
3528
+				__FILE__, __FUNCTION__, __LINE__
3529
+			);
3530
+		}
3531
+	}
3532
+
3533
+
3534
+	public function trash_cpt_item($post_id)
3535
+	{
3536
+	}
3537
+
3538
+
3539
+	public function delete_cpt_item($post_id)
3540
+	{
3541
+	}
3542
+
3543
+
3544
+	public function restore_cpt_item($post_id)
3545
+	{
3546
+	}
3547
+
3548
+
3549
+	protected function _restore_cpt_item($post_id, $revision_id)
3550
+	{
3551
+	}
3552
+
3553
+
3554
+	public function attendee_editor_metaboxes()
3555
+	{
3556
+		$this->verify_cpt_object();
3557
+		remove_meta_box(
3558
+			'postexcerpt',
3559
+			esc_html__('Excerpt', 'event_espresso'),
3560
+			'post_excerpt_meta_box',
3561
+			$this->_cpt_routes[$this->_req_action],
3562
+			'normal',
3563
+			'core'
3564
+		);
3565
+		remove_meta_box('commentstatusdiv', $this->_cpt_routes[$this->_req_action], 'normal', 'core');
3566
+		if (post_type_supports('espresso_attendees', 'excerpt')) {
3567
+			add_meta_box(
3568
+				'postexcerpt',
3569
+				esc_html__('Short Biography', 'event_espresso'),
3570
+				'post_excerpt_meta_box',
3571
+				$this->_cpt_routes[$this->_req_action],
3572
+				'normal'
3573
+			);
3574
+		}
3575
+		if (post_type_supports('espresso_attendees', 'comments')) {
3576
+			add_meta_box(
3577
+				'commentsdiv',
3578
+				esc_html__('Notes on the Contact', 'event_espresso'),
3579
+				'post_comment_meta_box',
3580
+				$this->_cpt_routes[$this->_req_action],
3581
+				'normal',
3582
+				'core'
3583
+			);
3584
+		}
3585
+		add_meta_box(
3586
+			'attendee_contact_info',
3587
+			esc_html__('Contact Info', 'event_espresso'),
3588
+			array($this, 'attendee_contact_info'),
3589
+			$this->_cpt_routes[$this->_req_action],
3590
+			'side',
3591
+			'core'
3592
+		);
3593
+		add_meta_box(
3594
+			'attendee_details_address',
3595
+			esc_html__('Address Details', 'event_espresso'),
3596
+			array($this, 'attendee_address_details'),
3597
+			$this->_cpt_routes[$this->_req_action],
3598
+			'normal',
3599
+			'core'
3600
+		);
3601
+		add_meta_box(
3602
+			'attendee_registrations',
3603
+			esc_html__('Registrations for this Contact', 'event_espresso'),
3604
+			array($this, 'attendee_registrations_meta_box'),
3605
+			$this->_cpt_routes[$this->_req_action],
3606
+			'normal',
3607
+			'high'
3608
+		);
3609
+	}
3610
+
3611
+
3612
+	/**
3613
+	 * Metabox for attendee contact info
3614
+	 *
3615
+	 * @param  WP_Post $post wp post object
3616
+	 * @return string attendee contact info ( and form )
3617
+	 * @throws EE_Error
3618
+	 * @throws InvalidArgumentException
3619
+	 * @throws InvalidDataTypeException
3620
+	 * @throws InvalidInterfaceException
3621
+	 * @throws LogicException
3622
+	 * @throws DomainException
3623
+	 */
3624
+	public function attendee_contact_info($post)
3625
+	{
3626
+		//get attendee object ( should already have it )
3627
+		$form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3628
+		$form->enqueueStylesAndScripts();
3629
+		echo $form->display();
3630
+	}
3631
+
3632
+
3633
+	/**
3634
+	 * Return form handler for the contact details metabox
3635
+	 *
3636
+	 * @param EE_Attendee $attendee
3637
+	 * @return AttendeeContactDetailsMetaboxFormHandler
3638
+	 * @throws DomainException
3639
+	 * @throws InvalidArgumentException
3640
+	 * @throws InvalidDataTypeException
3641
+	 * @throws InvalidInterfaceException
3642
+	 */
3643
+	protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3644
+	{
3645
+		return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3646
+	}
3647
+
3648
+
3649
+	/**
3650
+	 * Metabox for attendee details
3651
+	 *
3652
+	 * @param  WP_Post $post wp post object
3653
+	 * @throws DomainException
3654
+	 */
3655
+	public function attendee_address_details($post)
3656
+	{
3657
+		//get attendee object (should already have it)
3658
+		$this->_template_args['attendee']     = $this->_cpt_model_obj;
3659
+		$this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3660
+			new EE_Question_Form_Input(
3661
+				EE_Question::new_instance(
3662
+					array(
3663
+						'QST_ID'           => 0,
3664
+						'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3665
+						'QST_system'       => 'admin-state',
3666
+					)
3667
+				),
3668
+				EE_Answer::new_instance(
3669
+					array(
3670
+						'ANS_ID'    => 0,
3671
+						'ANS_value' => $this->_cpt_model_obj->state_ID(),
3672
+					)
3673
+				),
3674
+				array(
3675
+					'input_id'       => 'STA_ID',
3676
+					'input_name'     => 'STA_ID',
3677
+					'input_prefix'   => '',
3678
+					'append_qstn_id' => false,
3679
+				)
3680
+			)
3681
+		);
3682
+		$this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3683
+			new EE_Question_Form_Input(
3684
+				EE_Question::new_instance(
3685
+					array(
3686
+						'QST_ID'           => 0,
3687
+						'QST_display_text' => esc_html__('Country', 'event_espresso'),
3688
+						'QST_system'       => 'admin-country',
3689
+					)
3690
+				),
3691
+				EE_Answer::new_instance(
3692
+					array(
3693
+						'ANS_ID'    => 0,
3694
+						'ANS_value' => $this->_cpt_model_obj->country_ID(),
3695
+					)
3696
+				),
3697
+				array(
3698
+					'input_id'       => 'CNT_ISO',
3699
+					'input_name'     => 'CNT_ISO',
3700
+					'input_prefix'   => '',
3701
+					'append_qstn_id' => false,
3702
+				)
3703
+			)
3704
+		);
3705
+		$template                             =
3706
+			REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3707
+		EEH_Template::display_template($template, $this->_template_args);
3708
+	}
3709
+
3710
+
3711
+	/**
3712
+	 *        _attendee_details
3713
+	 *
3714
+	 * @access protected
3715
+	 * @param $post
3716
+	 * @return void
3717
+	 * @throws DomainException
3718
+	 * @throws EE_Error
3719
+	 */
3720
+	public function attendee_registrations_meta_box($post)
3721
+	{
3722
+		$this->_template_args['attendee']      = $this->_cpt_model_obj;
3723
+		$this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3724
+		$template                              =
3725
+			REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3726
+		EEH_Template::display_template($template, $this->_template_args);
3727
+	}
3728
+
3729
+
3730
+	/**
3731
+	 * add in the form fields for the attendee edit
3732
+	 *
3733
+	 * @param  WP_Post $post wp post object
3734
+	 * @return string html for new form.
3735
+	 * @throws DomainException
3736
+	 */
3737
+	public function after_title_form_fields($post)
3738
+	{
3739
+		if ($post->post_type == 'espresso_attendees') {
3740
+			$template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3741
+			$template_args['attendee'] = $this->_cpt_model_obj;
3742
+			EEH_Template::display_template($template, $template_args);
3743
+		}
3744
+	}
3745
+
3746
+
3747
+	/**
3748
+	 *        _trash_or_restore_attendee
3749
+	 *
3750
+	 * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3751
+	 * @return void
3752
+	 * @throws EE_Error
3753
+	 * @throws InvalidArgumentException
3754
+	 * @throws InvalidDataTypeException
3755
+	 * @throws InvalidInterfaceException
3756
+	 * @access protected
3757
+	 */
3758
+	protected function _trash_or_restore_attendees($trash = true)
3759
+	{
3760
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3761
+		$ATT_MDL = EEM_Attendee::instance();
3762
+		$success = 1;
3763
+		//Checkboxes
3764
+		if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
3765
+			// if array has more than one element than success message should be plural
3766
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
3767
+			// cycle thru checkboxes
3768
+			while (list($ATT_ID, $value) = each($this->_req_data['checkbox'])) {
3769
+				$updated = $trash ? $ATT_MDL->update_by_ID(array('status' => 'trash'), $ATT_ID)
3770
+					: $ATT_MDL->update_by_ID(array('status' => 'publish'), $ATT_ID);
3771
+				if ( ! $updated) {
3772
+					$success = 0;
3773
+				}
3774
+			}
3775
+		} else {
3776
+			// grab single id and delete
3777
+			$ATT_ID = absint($this->_req_data['ATT_ID']);
3778
+			//get attendee
3779
+			$att     = $ATT_MDL->get_one_by_ID($ATT_ID);
3780
+			$updated = $trash ? $att->set_status('trash') : $att->set_status('publish');
3781
+			$updated = $att->save();
3782
+			if ( ! $updated) {
3783
+				$success = 0;
3784
+			}
3785
+		}
3786
+		$what        = $success > 1
3787
+			? esc_html__('Contacts', 'event_espresso')
3788
+			: esc_html__('Contact', 'event_espresso');
3789
+		$action_desc = $trash
3790
+			? esc_html__('moved to the trash', 'event_espresso')
3791
+			: esc_html__('restored', 'event_espresso');
3792
+		$this->_redirect_after_action($success, $what, $action_desc, array('action' => 'contact_list'));
3793
+	}
3794 3794
 
3795 3795
 }
Please login to merge, or discard this patch.
Spacing   +93 added lines, -93 removed lines patch added patch discarded remove patch
@@ -76,7 +76,7 @@  discard block
 block discarded – undo
76 76
         // when adding a new registration...
77 77
         if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
78 78
             EE_System::do_not_cache();
79
-            if (! isset($this->_req_data['processing_registration'])
79
+            if ( ! isset($this->_req_data['processing_registration'])
80 80
                  || absint($this->_req_data['processing_registration']) !== 1
81 81
             ) {
82 82
                 // and it's NOT the attendee information reg step
@@ -171,7 +171,7 @@  discard block
 block discarded – undo
171 171
     public function _set_page_routes()
172 172
     {
173 173
         $this->_get_registration_status_array();
174
-        $reg_id             = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
174
+        $reg_id = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
175 175
             ? $this->_req_data['_REG_ID'] : 0;
176 176
         $reg_id = empty($reg_id) && ! empty($this->_req_data['reg_status_change_form']['REG_ID'])
177 177
             ? $this->_req_data['reg_status_change_form']['REG_ID']
@@ -669,7 +669,7 @@  discard block
 block discarded – undo
669 669
         //style
670 670
         wp_register_style(
671 671
             'espresso_reg',
672
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
672
+            REG_ASSETS_URL.'espresso_registrations_admin.css',
673 673
             array('ee-admin-css'),
674 674
             EVENT_ESPRESSO_VERSION
675 675
         );
@@ -677,7 +677,7 @@  discard block
 block discarded – undo
677 677
         //script
678 678
         wp_register_script(
679 679
             'espresso_reg',
680
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
680
+            REG_ASSETS_URL.'espresso_registrations_admin.js',
681 681
             array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'),
682 682
             EVENT_ESPRESSO_VERSION,
683 683
             true
@@ -715,7 +715,7 @@  discard block
 block discarded – undo
715 715
         wp_dequeue_style('espresso_reg');
716 716
         wp_register_style(
717 717
             'espresso_att',
718
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
718
+            REG_ASSETS_URL.'espresso_attendees_admin.css',
719 719
             array('ee-admin-css'),
720 720
             EVENT_ESPRESSO_VERSION
721 721
         );
@@ -727,7 +727,7 @@  discard block
 block discarded – undo
727 727
     {
728 728
         wp_register_script(
729 729
             'ee-spco-for-admin',
730
-            REG_ASSETS_URL . 'spco_for_admin.js',
730
+            REG_ASSETS_URL.'spco_for_admin.js',
731 731
             array('underscore', 'jquery'),
732 732
             EVENT_ESPRESSO_VERSION,
733 733
             true
@@ -861,7 +861,7 @@  discard block
 block discarded – undo
861 861
                     'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
862 862
                 ),
863 863
             );
864
-            $this->_views['trash']      = array(
864
+            $this->_views['trash'] = array(
865 865
                 'slug'        => 'trash',
866 866
                 'label'       => esc_html__('Trash', 'event_espresso'),
867 867
                 'count'       => 0,
@@ -950,7 +950,7 @@  discard block
 block discarded – undo
950 950
         }
951 951
         $sc_items = array(
952 952
             'approved_status'   => array(
953
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
953
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_approved,
954 954
                 'desc'  => EEH_Template::pretty_status(
955 955
                     EEM_Registration::status_id_approved,
956 956
                     false,
@@ -958,7 +958,7 @@  discard block
 block discarded – undo
958 958
                 ),
959 959
             ),
960 960
             'pending_status'    => array(
961
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
961
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_pending_payment,
962 962
                 'desc'  => EEH_Template::pretty_status(
963 963
                     EEM_Registration::status_id_pending_payment,
964 964
                     false,
@@ -966,7 +966,7 @@  discard block
 block discarded – undo
966 966
                 ),
967 967
             ),
968 968
             'wait_list'         => array(
969
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
969
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_wait_list,
970 970
                 'desc'  => EEH_Template::pretty_status(
971 971
                     EEM_Registration::status_id_wait_list,
972 972
                     false,
@@ -974,7 +974,7 @@  discard block
 block discarded – undo
974 974
                 ),
975 975
             ),
976 976
             'incomplete_status' => array(
977
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
977
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_incomplete,
978 978
                 'desc'  => EEH_Template::pretty_status(
979 979
                     EEM_Registration::status_id_incomplete,
980 980
                     false,
@@ -982,7 +982,7 @@  discard block
 block discarded – undo
982 982
                 ),
983 983
             ),
984 984
             'not_approved'      => array(
985
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
985
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_not_approved,
986 986
                 'desc'  => EEH_Template::pretty_status(
987 987
                     EEM_Registration::status_id_not_approved,
988 988
                     false,
@@ -990,7 +990,7 @@  discard block
 block discarded – undo
990 990
                 ),
991 991
             ),
992 992
             'declined_status'   => array(
993
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
993
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_declined,
994 994
                 'desc'  => EEH_Template::pretty_status(
995 995
                     EEM_Registration::status_id_declined,
996 996
                     false,
@@ -998,7 +998,7 @@  discard block
 block discarded – undo
998 998
                 ),
999 999
             ),
1000 1000
             'cancelled_status'  => array(
1001
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
1001
+                'class' => 'ee-status-legend ee-status-legend-'.EEM_Registration::status_id_cancelled,
1002 1002
                 'desc'  => EEH_Template::pretty_status(
1003 1003
                     EEM_Registration::status_id_cancelled,
1004 1004
                     false,
@@ -1021,7 +1021,7 @@  discard block
 block discarded – undo
1021 1021
         $EVT_ID                                    = ! empty($this->_req_data['event_id'])
1022 1022
             ? absint($this->_req_data['event_id'])
1023 1023
             : 0;
1024
-        $ATT_ID = !empty($this->_req_data['ATT_ID'])
1024
+        $ATT_ID = ! empty($this->_req_data['ATT_ID'])
1025 1025
             ? absint($this->_req_data['ATT_ID'])
1026 1026
             : 0;
1027 1027
         if ($ATT_ID) {
@@ -1033,13 +1033,13 @@  discard block
 block discarded – undo
1033 1033
                         'event_espresso'
1034 1034
                     ),
1035 1035
                     '<h3 style="line-height:1.5em;">',
1036
-                    '<a href="' . EE_Admin_Page::add_query_args_and_nonce(
1036
+                    '<a href="'.EE_Admin_Page::add_query_args_and_nonce(
1037 1037
                         array(
1038 1038
                             'action' => 'edit_attendee',
1039 1039
                             'post' => $ATT_ID
1040 1040
                         ),
1041 1041
                         REG_ADMIN_URL
1042
-                    ) . '">' . $attendee->full_name() . '</a>',
1042
+                    ).'">'.$attendee->full_name().'</a>',
1043 1043
                     '</h3>'
1044 1044
                 );
1045 1045
             }
@@ -1050,7 +1050,7 @@  discard block
 block discarded – undo
1050 1050
                 'espresso_registrations_new_registration',
1051 1051
                 $EVT_ID
1052 1052
             )) {
1053
-                $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1053
+                $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
1054 1054
                     'new_registration',
1055 1055
                     'add-registrant',
1056 1056
                     array('event_id' => $EVT_ID),
@@ -1090,7 +1090,7 @@  discard block
 block discarded – undo
1090 1090
                 $this->_template_args['admin_page_header'] .= ' &nbsp;<span class="drk-grey-text">';
1091 1091
                 $this->_template_args['admin_page_header'] .= '<span class="dashicons dashicons-calendar"></span>';
1092 1092
                 $this->_template_args['admin_page_header'] .= $datetime->name();
1093
-                $this->_template_args['admin_page_header'] .= ' ( ' . $datetime->start_date() . ' )';
1093
+                $this->_template_args['admin_page_header'] .= ' ( '.$datetime->start_date().' )';
1094 1094
                 $this->_template_args['admin_page_header'] .= '</span></h3>';
1095 1095
             }
1096 1096
         }
@@ -1197,7 +1197,7 @@  discard block
 block discarded – undo
1197 1197
             'caps'                     => EEM_Registration::caps_read_admin,
1198 1198
             'default_where_conditions' => 'this_model_only',
1199 1199
         );
1200
-        if (! $count) {
1200
+        if ( ! $count) {
1201 1201
             $query_params = array_merge(
1202 1202
                 $query_params,
1203 1203
                 $this->_get_orderby_for_registrations_query(),
@@ -1218,7 +1218,7 @@  discard block
 block discarded – undo
1218 1218
     protected function addAttendeeIdToWhereConditions(array $request)
1219 1219
     {
1220 1220
         $where = array();
1221
-        if (! empty($request['ATT_ID'])) {
1221
+        if ( ! empty($request['ATT_ID'])) {
1222 1222
             $where['ATT_ID'] = absint($request['ATT_ID']);
1223 1223
         }
1224 1224
         return $where;
@@ -1234,7 +1234,7 @@  discard block
 block discarded – undo
1234 1234
     protected function _add_event_id_to_where_conditions(array $request)
1235 1235
     {
1236 1236
         $where = array();
1237
-        if (! empty($request['event_id'])) {
1237
+        if ( ! empty($request['event_id'])) {
1238 1238
             $where['EVT_ID'] = absint($request['event_id']);
1239 1239
         }
1240 1240
         return $where;
@@ -1250,7 +1250,7 @@  discard block
 block discarded – undo
1250 1250
     protected function _add_category_id_to_where_conditions(array $request)
1251 1251
     {
1252 1252
         $where = array();
1253
-        if (! empty($request['EVT_CAT']) && (int)$request['EVT_CAT'] !== -1) {
1253
+        if ( ! empty($request['EVT_CAT']) && (int) $request['EVT_CAT'] !== -1) {
1254 1254
             $where['Event.Term_Taxonomy.term_id'] = absint($request['EVT_CAT']);
1255 1255
         }
1256 1256
         return $where;
@@ -1266,10 +1266,10 @@  discard block
 block discarded – undo
1266 1266
     protected function _add_datetime_id_to_where_conditions(array $request)
1267 1267
     {
1268 1268
         $where = array();
1269
-        if (! empty($request['datetime_id'])) {
1269
+        if ( ! empty($request['datetime_id'])) {
1270 1270
             $where['Ticket.Datetime.DTT_ID'] = absint($request['datetime_id']);
1271 1271
         }
1272
-        if (! empty($request['DTT_ID'])) {
1272
+        if ( ! empty($request['DTT_ID'])) {
1273 1273
             $where['Ticket.Datetime.DTT_ID'] = absint($request['DTT_ID']);
1274 1274
         }
1275 1275
         return $where;
@@ -1295,7 +1295,7 @@  discard block
 block discarded – undo
1295 1295
          * If not filtering by specified status, then we show all registrations excluding incomplete registrations
1296 1296
          * UNLESS viewing trashed registrations.
1297 1297
          */
1298
-        if (! empty($registration_status)) {
1298
+        if ( ! empty($registration_status)) {
1299 1299
             $where['STS_ID'] = $registration_status;
1300 1300
         } else {
1301 1301
             //make sure we exclude incomplete registrations, but only if not trashed.
@@ -1338,12 +1338,12 @@  discard block
 block discarded – undo
1338 1338
                 array(
1339 1339
                     EEM_Registration::instance()->convert_datetime_for_query(
1340 1340
                         'REG_date',
1341
-                        $now . ' 00:00:00',
1341
+                        $now.' 00:00:00',
1342 1342
                         'Y-m-d H:i:s'
1343 1343
                     ),
1344 1344
                     EEM_Registration::instance()->convert_datetime_for_query(
1345 1345
                         'REG_date',
1346
-                        $now . ' 23:59:59',
1346
+                        $now.' 23:59:59',
1347 1347
                         'Y-m-d H:i:s'
1348 1348
                     ),
1349 1349
                 ),
@@ -1356,12 +1356,12 @@  discard block
 block discarded – undo
1356 1356
                 array(
1357 1357
                     EEM_Registration::instance()->convert_datetime_for_query(
1358 1358
                         'REG_date',
1359
-                        $current_year_and_month . '-01 00:00:00',
1359
+                        $current_year_and_month.'-01 00:00:00',
1360 1360
                         'Y-m-d H:i:s'
1361 1361
                     ),
1362 1362
                     EEM_Registration::instance()->convert_datetime_for_query(
1363 1363
                         'REG_date',
1364
-                        $current_year_and_month . '-' . $days_this_month . ' 23:59:59',
1364
+                        $current_year_and_month.'-'.$days_this_month.' 23:59:59',
1365 1365
                         'Y-m-d H:i:s'
1366 1366
                     ),
1367 1367
                 ),
@@ -1376,18 +1376,18 @@  discard block
 block discarded – undo
1376 1376
                 : '';
1377 1377
             //if there is not a month or year then we can't go further
1378 1378
             if ($month_requested && $year_requested) {
1379
-                $days_in_month     = date('t', strtotime($year_requested . '-' . $month_requested . '-' . '01'));
1379
+                $days_in_month     = date('t', strtotime($year_requested.'-'.$month_requested.'-'.'01'));
1380 1380
                 $where['REG_date'] = array(
1381 1381
                     'BETWEEN',
1382 1382
                     array(
1383 1383
                         EEM_Registration::instance()->convert_datetime_for_query(
1384 1384
                             'REG_date',
1385
-                            $year_requested . '-' . $month_requested . '-01 00:00:00',
1385
+                            $year_requested.'-'.$month_requested.'-01 00:00:00',
1386 1386
                             'Y-m-d H:i:s'
1387 1387
                         ),
1388 1388
                         EEM_Registration::instance()->convert_datetime_for_query(
1389 1389
                             'REG_date',
1390
-                            $year_requested . '-' . $month_requested . '-' . $days_in_month . ' 23:59:59',
1390
+                            $year_requested.'-'.$month_requested.'-'.$days_in_month.' 23:59:59',
1391 1391
                             'Y-m-d H:i:s'
1392 1392
                         ),
1393 1393
                     ),
@@ -1407,8 +1407,8 @@  discard block
 block discarded – undo
1407 1407
     protected function _add_search_to_where_conditions(array $request)
1408 1408
     {
1409 1409
         $where = array();
1410
-        if (! empty($request['s'])) {
1411
-            $search_string = '%' . sanitize_text_field($request['s']) . '%';
1410
+        if ( ! empty($request['s'])) {
1411
+            $search_string = '%'.sanitize_text_field($request['s']).'%';
1412 1412
             $where['OR*search_conditions'] = array(
1413 1413
                 'Event.EVT_name'                          => array('LIKE', $search_string),
1414 1414
                 'Event.EVT_desc'                          => array('LIKE', $search_string),
@@ -1525,7 +1525,7 @@  discard block
 block discarded – undo
1525 1525
             : $per_page;
1526 1526
 
1527 1527
         //-1 means return all results so get out if that's set.
1528
-        if ((int)$per_page === -1) {
1528
+        if ((int) $per_page === -1) {
1529 1529
             return array();
1530 1530
         }
1531 1531
         $per_page = absint($per_page);
@@ -1581,7 +1581,7 @@  discard block
 block discarded – undo
1581 1581
                 ),
1582 1582
                 REG_ADMIN_URL
1583 1583
             );
1584
-            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1584
+            $this->_template_args['filtered_transactions_link'] = EE_Admin_Page::add_query_args_and_nonce(
1585 1585
                 array(
1586 1586
                     'action' => 'default',
1587 1587
                     'EVT_ID' => $event_id,
@@ -1589,7 +1589,7 @@  discard block
 block discarded – undo
1589 1589
                 ),
1590 1590
                 admin_url('admin.php')
1591 1591
             );
1592
-            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1592
+            $this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
1593 1593
                 array(
1594 1594
                     'page'   => 'espresso_events',
1595 1595
                     'action' => 'edit',
@@ -1598,12 +1598,12 @@  discard block
 block discarded – undo
1598 1598
                 admin_url('admin.php')
1599 1599
             );
1600 1600
             //next and previous links
1601
-            $next_reg                                      = $this->_registration->next(
1601
+            $next_reg = $this->_registration->next(
1602 1602
                 null,
1603 1603
                 array(),
1604 1604
                 'REG_ID'
1605 1605
             );
1606
-            $this->_template_args['next_registration']     = $next_reg
1606
+            $this->_template_args['next_registration'] = $next_reg
1607 1607
                 ? $this->_next_link(
1608 1608
                     EE_Admin_Page::add_query_args_and_nonce(
1609 1609
                         array(
@@ -1615,7 +1615,7 @@  discard block
 block discarded – undo
1615 1615
                     'dashicons dashicons-arrow-right ee-icon-size-22'
1616 1616
                 )
1617 1617
                 : '';
1618
-            $previous_reg                                  = $this->_registration->previous(
1618
+            $previous_reg = $this->_registration->previous(
1619 1619
                 null,
1620 1620
                 array(),
1621 1621
                 'REG_ID'
@@ -1633,7 +1633,7 @@  discard block
 block discarded – undo
1633 1633
                 )
1634 1634
                 : '';
1635 1635
             // grab header
1636
-            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1636
+            $template_path                             = REG_TEMPLATE_PATH.'reg_admin_details_header.template.php';
1637 1637
             $this->_template_args['REG_ID']            = $this->_registration->ID();
1638 1638
             $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1639 1639
                 $template_path,
@@ -1753,7 +1753,7 @@  discard block
 block discarded – undo
1753 1753
                             EEH_HTML::strong(
1754 1754
                                 $this->_registration->pretty_status(),
1755 1755
                                 '',
1756
-                                'status-' . $this->_registration->status_ID(),
1756
+                                'status-'.$this->_registration->status_ID(),
1757 1757
                                 'line-height: 1em; font-size: 1.5em; font-weight: bold;'
1758 1758
                             )
1759 1759
                         )
@@ -1833,11 +1833,11 @@  discard block
 block discarded – undo
1833 1833
     {
1834 1834
         if (isset($this->_req_data['reg_status_change_form'])) {
1835 1835
             $REG_IDs = isset($this->_req_data['reg_status_change_form']['REG_ID'])
1836
-                ? (array)$this->_req_data['reg_status_change_form']['REG_ID']
1836
+                ? (array) $this->_req_data['reg_status_change_form']['REG_ID']
1837 1837
                 : array();
1838 1838
         } else {
1839 1839
             $REG_IDs = isset($this->_req_data['_REG_ID'])
1840
-                ? (array)$this->_req_data['_REG_ID']
1840
+                ? (array) $this->_req_data['_REG_ID']
1841 1841
                 : array();
1842 1842
         }
1843 1843
         // sanitize $REG_IDs
@@ -1900,7 +1900,7 @@  discard block
 block discarded – undo
1900 1900
     {
1901 1901
         $success = false;
1902 1902
         // typecast $REG_IDs
1903
-        $REG_IDs = (array)$REG_IDs;
1903
+        $REG_IDs = (array) $REG_IDs;
1904 1904
         if ( ! empty($REG_IDs)) {
1905 1905
             $success = true;
1906 1906
             // set default status if none is passed
@@ -2050,7 +2050,7 @@  discard block
 block discarded – undo
2050 2050
             $action,
2051 2051
             $notify
2052 2052
         );
2053
-        $method = $action . '_registration';
2053
+        $method = $action.'_registration';
2054 2054
         if (method_exists($this, $method)) {
2055 2055
             $this->$method($notify);
2056 2056
         }
@@ -2168,7 +2168,7 @@  discard block
 block discarded – undo
2168 2168
             $filtered_line_item_tree,
2169 2169
             array('EE_Registration' => $this->_registration)
2170 2170
         );
2171
-        $attendee                                = $this->_registration->attendee();
2171
+        $attendee = $this->_registration->attendee();
2172 2172
         if (EE_Registry::instance()->CAP->current_user_can(
2173 2173
             'ee_read_transaction',
2174 2174
             'espresso_transactions_view_transaction'
@@ -2247,7 +2247,7 @@  discard block
 block discarded – undo
2247 2247
                 'Payment method response',
2248 2248
                 'event_espresso'
2249 2249
             );
2250
-            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2250
+            $this->_template_args['reg_details']['response_msg']['class'] = 'regular-text';
2251 2251
         }
2252 2252
         $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2253 2253
         $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
@@ -2275,7 +2275,7 @@  discard block
 block discarded – undo
2275 2275
         $this->_template_args['REG_ID']                                       = $this->_registration->ID();
2276 2276
         $this->_template_args['event_id']                                     = $this->_registration->event_ID();
2277 2277
         $template_path                                                        =
2278
-            REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2278
+            REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_details.template.php';
2279 2279
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
2280 2280
     }
2281 2281
 
@@ -2304,7 +2304,7 @@  discard block
 block discarded – undo
2304 2304
             $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2305 2305
             $this->_template_args['REG_ID']                    = $this->_registration->ID();
2306 2306
             $template_path                                     =
2307
-                REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2307
+                REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_questions.template.php';
2308 2308
             echo EEH_Template::display_template($template_path, $this->_template_args, true);
2309 2309
         }
2310 2310
     }
@@ -2321,7 +2321,7 @@  discard block
 block discarded – undo
2321 2321
     public function form_before_question_group($output)
2322 2322
     {
2323 2323
         EE_Error::doing_it_wrong(
2324
-            __CLASS__ . '::' . __FUNCTION__,
2324
+            __CLASS__.'::'.__FUNCTION__,
2325 2325
             esc_html__(
2326 2326
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2327 2327
                 'event_espresso'
@@ -2346,7 +2346,7 @@  discard block
 block discarded – undo
2346 2346
     public function form_after_question_group($output)
2347 2347
     {
2348 2348
         EE_Error::doing_it_wrong(
2349
-            __CLASS__ . '::' . __FUNCTION__,
2349
+            __CLASS__.'::'.__FUNCTION__,
2350 2350
             esc_html__(
2351 2351
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2352 2352
                 'event_espresso'
@@ -2384,7 +2384,7 @@  discard block
 block discarded – undo
2384 2384
     public function form_form_field_label_wrap($label)
2385 2385
     {
2386 2386
         EE_Error::doing_it_wrong(
2387
-            __CLASS__ . '::' . __FUNCTION__,
2387
+            __CLASS__.'::'.__FUNCTION__,
2388 2388
             esc_html__(
2389 2389
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2390 2390
                 'event_espresso'
@@ -2394,7 +2394,7 @@  discard block
 block discarded – undo
2394 2394
         return '
2395 2395
 			<tr>
2396 2396
 				<th>
2397
-					' . $label . '
2397
+					' . $label.'
2398 2398
 				</th>';
2399 2399
     }
2400 2400
 
@@ -2410,7 +2410,7 @@  discard block
 block discarded – undo
2410 2410
     public function form_form_field_input__wrap($input)
2411 2411
     {
2412 2412
         EE_Error::doing_it_wrong(
2413
-            __CLASS__ . '::' . __FUNCTION__,
2413
+            __CLASS__.'::'.__FUNCTION__,
2414 2414
             esc_html__(
2415 2415
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2416 2416
                 'event_espresso'
@@ -2419,7 +2419,7 @@  discard block
 block discarded – undo
2419 2419
         );
2420 2420
         return '
2421 2421
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2422
-					' . $input . '
2422
+					' . $input.'
2423 2423
 				</td>
2424 2424
 			</tr>';
2425 2425
     }
@@ -2464,7 +2464,7 @@  discard block
 block discarded – undo
2464 2464
     protected function _get_reg_custom_questions_form($REG_ID)
2465 2465
     {
2466 2466
         if ( ! $this->_reg_custom_questions_form) {
2467
-            require_once(REG_ADMIN . 'form_sections' . DS . 'EE_Registration_Custom_Questions_Form.form.php');
2467
+            require_once(REG_ADMIN.'form_sections'.DS.'EE_Registration_Custom_Questions_Form.form.php');
2468 2468
             $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2469 2469
                 EEM_Registration::instance()->get_one_by_ID($REG_ID)
2470 2470
             );
@@ -2500,7 +2500,7 @@  discard block
 block discarded – undo
2500 2500
         if ($form->is_valid()) {
2501 2501
             foreach ($form->subforms() as $question_group_id => $question_group_form) {
2502 2502
                 foreach ($question_group_form->inputs() as $question_id => $input) {
2503
-                    $where_conditions    = array(
2503
+                    $where_conditions = array(
2504 2504
                         'QST_ID' => $question_id,
2505 2505
                         'REG_ID' => $REG_ID,
2506 2506
                     );
@@ -2541,7 +2541,7 @@  discard block
 block discarded – undo
2541 2541
         $REG = EEM_Registration::instance();
2542 2542
         //get all other registrations on this transaction, and cache
2543 2543
         //the attendees for them so we don't have to run another query using force_join
2544
-        $registrations                           = $REG->get_all(array(
2544
+        $registrations = $REG->get_all(array(
2545 2545
             array(
2546 2546
                 'TXN_ID' => $this->_registration->transaction_ID(),
2547 2547
                 'REG_ID' => array('!=', $this->_registration->ID()),
@@ -2565,7 +2565,7 @@  discard block
 block discarded – undo
2565 2565
             $att_nmbr = 1;
2566 2566
             foreach ($registrations as $registration) {
2567 2567
                 /* @var $registration EE_Registration */
2568
-                $attendee                                                    = $registration->attendee()
2568
+                $attendee = $registration->attendee()
2569 2569
                     ? $registration->attendee()
2570 2570
                     : EEM_Attendee::instance()
2571 2571
                                   ->create_default_object();
@@ -2578,19 +2578,19 @@  discard block
 block discarded – undo
2578 2578
                     ', ',
2579 2579
                     $attendee->full_address_as_array()
2580 2580
                 );
2581
-                $this->_template_args['attendees'][$att_nmbr]['att_link']    = self::add_query_args_and_nonce(
2581
+                $this->_template_args['attendees'][$att_nmbr]['att_link'] = self::add_query_args_and_nonce(
2582 2582
                     array(
2583 2583
                         'action' => 'edit_attendee',
2584 2584
                         'post'   => $attendee->ID(),
2585 2585
                     ),
2586 2586
                     REG_ADMIN_URL
2587 2587
                 );
2588
-                $this->_template_args['attendees'][$att_nmbr]['event_name']  = $registration->event_obj()->name();
2588
+                $this->_template_args['attendees'][$att_nmbr]['event_name'] = $registration->event_obj()->name();
2589 2589
                 $att_nmbr++;
2590 2590
             }
2591 2591
             $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2592 2592
         }
2593
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2593
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_attendees.template.php';
2594 2594
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
2595 2595
     }
2596 2596
 
@@ -2633,20 +2633,20 @@  discard block
 block discarded – undo
2633 2633
         $this->_template_args['phone']             = $attendee->phone();
2634 2634
         $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2635 2635
         //edit link
2636
-        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(array(
2636
+        $this->_template_args['att_edit_link'] = EE_Admin_Page::add_query_args_and_nonce(array(
2637 2637
             'action' => 'edit_attendee',
2638 2638
             'post'   => $attendee->ID(),
2639 2639
         ), REG_ADMIN_URL);
2640 2640
         $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2641 2641
         //create link
2642
-        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2642
+        $this->_template_args['create_link'] = $primary_registration instanceof EE_Registration
2643 2643
             ? EE_Admin_Page::add_query_args_and_nonce(array(
2644 2644
                 'action'  => 'duplicate_attendee',
2645 2645
                 '_REG_ID' => $this->_registration->ID(),
2646 2646
             ), REG_ADMIN_URL) : '';
2647 2647
         $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2648 2648
         $this->_template_args['att_check']    = $att_check;
2649
-        $template_path                        = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2649
+        $template_path                        = REG_TEMPLATE_PATH.'reg_admin_details_side_meta_box_registrant.template.php';
2650 2650
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
2651 2651
     }
2652 2652
 
@@ -2691,7 +2691,7 @@  discard block
 block discarded – undo
2691 2691
             /** @var EE_Registration $REG */
2692 2692
             $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID);
2693 2693
             $payments = $REG->registration_payments();
2694
-            if (! empty($payments)) {
2694
+            if ( ! empty($payments)) {
2695 2695
                 $name = $REG->attendee() instanceof EE_Attendee
2696 2696
                     ? $REG->attendee()->full_name()
2697 2697
                     : esc_html__('Unknown Attendee', 'event_espresso');
@@ -2887,7 +2887,7 @@  discard block
 block discarded – undo
2887 2887
                 'action' => 'edit',
2888 2888
                 'post'   => $this->_reg_event->ID(),
2889 2889
             ), EVENTS_ADMIN_URL);
2890
-            $edit_event_lnk                     = '<a href="'
2890
+            $edit_event_lnk = '<a href="'
2891 2891
                                                   . $edit_event_url
2892 2892
                                                   . '" title="'
2893 2893
                                                   . esc_attr__('Edit ', 'event_espresso')
@@ -2905,7 +2905,7 @@  discard block
 block discarded – undo
2905 2905
         }
2906 2906
         // grab header
2907 2907
         $template_path                              =
2908
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2908
+            REG_TEMPLATE_PATH.'reg_admin_register_new_attendee.template.php';
2909 2909
         $this->_template_args['admin_page_content'] = EEH_Template::display_template($template_path,
2910 2910
             $this->_template_args, true);
2911 2911
         //$this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
@@ -2943,7 +2943,7 @@  discard block
 block discarded – undo
2943 2943
                 '</b>'
2944 2944
             );
2945 2945
             return '
2946
-	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2946
+	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg.'</p></div>
2947 2947
 	<script >
2948 2948
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
2949 2949
 		// after just adding a new registration... we gotta try to put a stop to that !!!
@@ -3011,7 +3011,7 @@  discard block
 block discarded – undo
3011 3011
         //we come back to the process_registration_step route.
3012 3012
         $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
3013 3013
         return EEH_Template::display_template(
3014
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
3014
+            REG_TEMPLATE_PATH.'reg_admin_register_new_attendee_step_content.template.php',
3015 3015
             $template_args,
3016 3016
             true
3017 3017
         );
@@ -3033,7 +3033,7 @@  discard block
 block discarded – undo
3033 3033
         if (is_object($this->_reg_event)) {
3034 3034
             return true;
3035 3035
         }
3036
-        $EVT_ID = (! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
3036
+        $EVT_ID = ( ! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
3037 3037
         if ( ! $EVT_ID) {
3038 3038
             return false;
3039 3039
         }
@@ -3103,7 +3103,7 @@  discard block
 block discarded – undo
3103 3103
                 }
3104 3104
                 break;
3105 3105
             case 'questions' :
3106
-                if (! isset(
3106
+                if ( ! isset(
3107 3107
                     $this->_req_data['txn_reg_status_change'],
3108 3108
                     $this->_req_data['txn_reg_status_change']['send_notifications'])
3109 3109
                 ) {
@@ -3223,7 +3223,7 @@  discard block
 block discarded – undo
3223 3223
     public function get_attendees($per_page, $count = false, $trash = false)
3224 3224
     {
3225 3225
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3226
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3226
+        require_once(REG_ADMIN.'EE_Attendee_Contact_List_Table.class.php');
3227 3227
         $ATT_MDL                    = EEM_Attendee::instance();
3228 3228
         $this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
3229 3229
         switch ($this->_req_data['orderby']) {
@@ -3263,7 +3263,7 @@  discard block
 block discarded – undo
3263 3263
             : $per_page;
3264 3264
         $_where       = array();
3265 3265
         if ( ! empty($this->_req_data['s'])) {
3266
-            $sstr         = '%' . $this->_req_data['s'] . '%';
3266
+            $sstr         = '%'.$this->_req_data['s'].'%';
3267 3267
             $_where['OR'] = array(
3268 3268
                 'Registration.Event.EVT_name'       => array('LIKE', $sstr),
3269 3269
                 'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
@@ -3290,17 +3290,17 @@  discard block
 block discarded – undo
3290 3290
             'extra_selects' => array('Registration_Count' => array('Registration.REG_ID', 'count', '%d')),
3291 3291
             'limit' => $limit
3292 3292
         );
3293
-        if (! $count) {
3293
+        if ( ! $count) {
3294 3294
             $query_args['order_by'] = array($orderby => $sort);
3295 3295
         }
3296 3296
         if ($trash) {
3297 3297
             $query_args[0]['status'] = array('!=', 'publish');
3298
-            $all_attendees    = $count
3298
+            $all_attendees = $count
3299 3299
                 ? $ATT_MDL->count($query_args, 'ATT_ID', true)
3300 3300
                 : $ATT_MDL->get_all($query_args);
3301 3301
         } else {
3302 3302
             $query_args[0]['status'] = array('IN', array('publish'));
3303
-            $all_attendees    = $count
3303
+            $all_attendees = $count
3304 3304
                 ? $ATT_MDL->count($query_args, 'ATT_ID', true)
3305 3305
                 : $ATT_MDL->get_all($query_args);
3306 3306
         }
@@ -3330,9 +3330,9 @@  discard block
 block discarded – undo
3330 3330
      *                                                     the query parameters from the request
3331 3331
      * @return void ends the request with a redirect or download
3332 3332
      */
3333
-    public function _registrations_report_base( $method_name_for_getting_query_params )
3333
+    public function _registrations_report_base($method_name_for_getting_query_params)
3334 3334
     {
3335
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3335
+        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3336 3336
             wp_redirect(EE_Admin_Page::add_query_args_and_nonce(
3337 3337
                 array(
3338 3338
                     'page'        => 'espresso_batch',
@@ -3341,7 +3341,7 @@  discard block
 block discarded – undo
3341 3341
                     'filters'     => urlencode(
3342 3342
                         serialize(
3343 3343
                             call_user_func(
3344
-                                array( $this, $method_name_for_getting_query_params ),
3344
+                                array($this, $method_name_for_getting_query_params),
3345 3345
                                 EEH_Array::is_set(
3346 3346
                                     $this->_req_data,
3347 3347
                                     'filters',
@@ -3361,8 +3361,8 @@  discard block
 block discarded – undo
3361 3361
                 'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
3362 3362
             );
3363 3363
             $this->_req_data = array_merge($this->_req_data, $new_request_args);
3364
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3365
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3364
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3365
+                require_once(EE_CLASSES.'EE_Export.class.php');
3366 3366
                 $EE_Export = EE_Export::instance($this->_req_data);
3367 3367
                 $EE_Export->export();
3368 3368
             }
@@ -3383,8 +3383,8 @@  discard block
 block discarded – undo
3383 3383
 
3384 3384
     public function _contact_list_export()
3385 3385
     {
3386
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3387
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3386
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3387
+            require_once(EE_CLASSES.'EE_Export.class.php');
3388 3388
             $EE_Export = EE_Export::instance($this->_req_data);
3389 3389
             $EE_Export->export_attendees();
3390 3390
         }
@@ -3401,8 +3401,8 @@  discard block
 block discarded – undo
3401 3401
                 'return_url'  => urlencode($this->_req_data['return_url']),
3402 3402
             )));
3403 3403
         } else {
3404
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3405
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3404
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3405
+                require_once(EE_CLASSES.'EE_Export.class.php');
3406 3406
                 $EE_Export = EE_Export::instance($this->_req_data);
3407 3407
                 $EE_Export->report_attendees();
3408 3408
             }
@@ -3484,7 +3484,7 @@  discard block
 block discarded – undo
3484 3484
             $updated_fields = array(
3485 3485
                 'ATT_fname'     => $this->_req_data['ATT_fname'],
3486 3486
                 'ATT_lname'     => $this->_req_data['ATT_lname'],
3487
-                'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
3487
+                'ATT_full_name' => $this->_req_data['ATT_fname'].' '.$this->_req_data['ATT_lname'],
3488 3488
                 'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
3489 3489
                 'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
3490 3490
                 'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
@@ -3702,8 +3702,8 @@  discard block
 block discarded – undo
3702 3702
                 )
3703 3703
             )
3704 3704
         );
3705
-        $template                             =
3706
-            REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3705
+        $template =
3706
+            REG_TEMPLATE_PATH.'attendee_address_details_metabox_content.template.php';
3707 3707
         EEH_Template::display_template($template, $this->_template_args);
3708 3708
     }
3709 3709
 
@@ -3722,7 +3722,7 @@  discard block
 block discarded – undo
3722 3722
         $this->_template_args['attendee']      = $this->_cpt_model_obj;
3723 3723
         $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3724 3724
         $template                              =
3725
-            REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3725
+            REG_TEMPLATE_PATH.'attendee_registrations_main_meta_box.template.php';
3726 3726
         EEH_Template::display_template($template, $this->_template_args);
3727 3727
     }
3728 3728
 
@@ -3737,7 +3737,7 @@  discard block
 block discarded – undo
3737 3737
     public function after_title_form_fields($post)
3738 3738
     {
3739 3739
         if ($post->post_type == 'espresso_attendees') {
3740
-            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3740
+            $template                  = REG_TEMPLATE_PATH.'attendee_details_after_title_form_fields.template.php';
3741 3741
             $template_args['attendee'] = $this->_cpt_model_obj;
3742 3742
             EEH_Template::display_template($template, $template_args);
3743 3743
         }
Please login to merge, or discard this patch.
core/db_models/EEM_CPT_Base.model.php 2 patches
Indentation   +514 added lines, -514 removed lines patch added patch discarded remove patch
@@ -18,519 +18,519 @@
 block discarded – undo
18 18
 abstract class EEM_CPT_Base extends EEM_Soft_Delete_Base
19 19
 {
20 20
 
21
-    /**
22
-     * @var string post_status_publish - the wp post status for published cpts
23
-     */
24
-    const post_status_publish = 'publish';
25
-
26
-    /**
27
-     * @var string post_status_future - the wp post status for scheduled cpts
28
-     */
29
-    const post_status_future = 'future';
30
-
31
-    /**
32
-     * @var string post_status_draft - the wp post status for draft cpts
33
-     */
34
-    const post_status_draft = 'draft';
35
-
36
-    /**
37
-     * @var string post_status_pending - the wp post status for pending cpts
38
-     */
39
-    const post_status_pending = 'pending';
40
-
41
-    /**
42
-     * @var string post_status_private - the wp post status for private cpts
43
-     */
44
-    const post_status_private = 'private';
45
-
46
-    /**
47
-     * @var string post_status_trashed - the wp post status for trashed cpts
48
-     */
49
-    const post_status_trashed = 'trash';
50
-
51
-    /**
52
-     * This is an array of custom statuses for the given CPT model (modified by children)
53
-     * format:
54
-     * array(
55
-     *        'status_name' => array(
56
-     *            'label' => __('Status Name', 'event_espresso'),
57
-     *            'public' => TRUE //whether a public status or not.
58
-     *        )
59
-     * )
60
-     *
61
-     * @var array
62
-     */
63
-    protected $_custom_stati = array();
64
-
65
-
66
-
67
-    /**
68
-     * Adds a relationship to Term_Taxonomy for each CPT_Base
69
-     *
70
-     * @param string $timezone
71
-     * @throws \EE_Error
72
-     */
73
-    protected function __construct($timezone = null)
74
-    {
75
-        //adds a relationship to Term_Taxonomy for all these models. For this to work
76
-        //Term_Relationship must have a relation to each model subclassing EE_CPT_Base explicitly
77
-        //eg, in EEM_Term_Relationship, inside the _model_relations array, there must be an entry
78
-        //with key equalling the subclassing model's model name (eg 'Event' or 'Venue'), and the value
79
-        //must also be new EE_HABTM_Relation('Term_Relationship');
80
-        $this->_model_relations['Term_Taxonomy'] = new EE_HABTM_Relation('Term_Relationship');
81
-        $primary_table_name = null;
82
-        //add  the common _status field to all CPT primary tables.
83
-        foreach ($this->_tables as $alias => $table_obj) {
84
-            if ($table_obj instanceof EE_Primary_Table) {
85
-                $primary_table_name = $alias;
86
-            }
87
-        }
88
-        //set default wp post statuses if child has not already set.
89
-        if ( ! isset($this->_fields[$primary_table_name]['status'])) {
90
-            $this->_fields[$primary_table_name]['status'] = new EE_WP_Post_Status_Field('post_status',
91
-                __("Event Status", "event_espresso"), false, 'draft');
92
-        }
93
-        if ( ! isset($this->_fields[$primary_table_name]['to_ping'])) {
94
-            $this->_fields[$primary_table_name]['to_ping'] = new EE_DB_Only_Text_Field('to_ping',
95
-                __('To Ping', 'event_espresso'), false, '');
96
-        }
97
-        if ( ! isset($this->_fields[$primary_table_name]['pinged'])) {
98
-            $this->_fields[$primary_table_name]['pinged'] = new EE_DB_Only_Text_Field('pinged',
99
-                __('Pinged', 'event_espresso'), false, '');
100
-        }
101
-        if ( ! isset($this->_fields[$primary_table_name]['comment_status'])) {
102
-            $this->_fields[$primary_table_name]['comment_status'] = new EE_Plain_Text_Field('comment_status',
103
-                __('Comment Status', 'event_espresso'), false, 'open');
104
-        }
105
-        if ( ! isset($this->_fields[$primary_table_name]['ping_status'])) {
106
-            $this->_fields[$primary_table_name]['ping_status'] = new EE_Plain_Text_Field('ping_status',
107
-                __('Ping Status', 'event_espresso'), false, 'open');
108
-        }
109
-        if ( ! isset($this->_fields[$primary_table_name]['post_content_filtered'])) {
110
-            $this->_fields[$primary_table_name]['post_content_filtered'] = new EE_DB_Only_Text_Field('post_content_filtered',
111
-                __('Post Content Filtered', 'event_espresso'), false, '');
112
-        }
113
-        if ( ! isset($this->_model_relations['Post_Meta'])) {
114
-            //don't block deletes though because we want to maintain the current behaviour
115
-            $this->_model_relations['Post_Meta'] = new EE_Has_Many_Relation(false);
116
-        }
117
-        if ( ! $this->_minimum_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
118
-            //nothing was set during child constructor, so set default
119
-            $this->_minimum_where_conditions_strategy = new EE_CPT_Minimum_Where_Conditions($this->post_type());
120
-        }
121
-        if ( ! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
122
-            //nothing was set during child constructor, so set default
123
-            //it's ok for child classes to specify this, but generally this is more DRY
124
-            $this->_default_where_conditions_strategy = new EE_CPT_Where_Conditions($this->post_type());
125
-        }
126
-        parent::__construct($timezone);
127
-    }
128
-
129
-
130
-
131
-    /**
132
-     * @return array
133
-     */
134
-    public function public_event_stati()
135
-    {
136
-        // @see wp-includes/post.php
137
-        return get_post_stati(array('public' => true));
138
-    }
139
-
140
-
141
-
142
-    /**
143
-     * Searches for field on this model of type 'deleted_flag'. if it is found,
144
-     * returns it's name. BUT That doesn't apply to CPTs. We should instead use post_status_field_name
145
-     *
146
-     * @return string
147
-     * @throws EE_Error
148
-     */
149
-    public function deleted_field_name()
150
-    {
151
-        throw new EE_Error(sprintf(__("EEM_CPT_Base should nto call deleted_field_name! It should instead use post_status_field_name",
152
-            "event_espresso")));
153
-    }
154
-
155
-
156
-
157
-    /**
158
-     * Gets the field's name that sets the post status
159
-     *
160
-     * @return string
161
-     * @throws EE_Error
162
-     */
163
-    public function post_status_field_name()
164
-    {
165
-        $field = $this->get_a_field_of_type('EE_WP_Post_Status_Field');
166
-        if ($field) {
167
-            return $field->get_name();
168
-        } else {
169
-            throw new EE_Error(sprintf(__('We are trying to find the post status flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?',
170
-                'event_espresso'), get_class($this), get_class($this)));
171
-        }
172
-    }
173
-
174
-
175
-
176
-    /**
177
-     * Alters the query params so that only trashed/soft-deleted items are considered
178
-     *
179
-     * @param array $query_params like EEM_Base::get_all's $query_params
180
-     * @return array like EEM_Base::get_all's $query_params
181
-     */
182
-    protected function _alter_query_params_so_only_trashed_items_included($query_params)
183
-    {
184
-        $post_status_field_name = $this->post_status_field_name();
185
-        $query_params[0][$post_status_field_name] = self::post_status_trashed;
186
-        return $query_params;
187
-    }
188
-
189
-
190
-
191
-    /**
192
-     * Alters the query params so each item's deleted status is ignored.
193
-     *
194
-     * @param array $query_params
195
-     * @return array
196
-     */
197
-    protected function _alter_query_params_so_deleted_and_undeleted_items_included($query_params)
198
-    {
199
-        $query_params['default_where_conditions'] = 'minimum';
200
-        return $query_params;
201
-    }
202
-
203
-
204
-
205
-    /**
206
-     * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered.
207
-     *
208
-     * @param boolean $delete       true to indicate deletion, false to indicate restoration
209
-     * @param array   $query_params like EEM_Base::get_all
210
-     * @return boolean success
211
-     */
212
-    function delete_or_restore($delete = true, $query_params = array())
213
-    {
214
-        $post_status_field_name = $this->post_status_field_name();
215
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
216
-        $new_status = $delete ? self::post_status_trashed : 'draft';
217
-        if ($this->update(array($post_status_field_name => $new_status), $query_params)) {
218
-            return true;
219
-        } else {
220
-            return false;
221
-        }
222
-    }
223
-
224
-
225
-
226
-    /**
227
-     * meta_table
228
-     * returns first EE_Secondary_Table table name
229
-     *
230
-     * @access public
231
-     * @return string
232
-     */
233
-    public function meta_table()
234
-    {
235
-        $meta_table = $this->_get_other_tables();
236
-        $meta_table = reset($meta_table);
237
-        return $meta_table instanceof EE_Secondary_Table ? $meta_table->get_table_name() : null;
238
-    }
239
-
240
-
241
-
242
-    /**
243
-     * This simply returns an array of the meta table fields (useful for when we just need to update those fields)
244
-     *
245
-     * @param  bool $all triggers whether we include DB_Only fields or JUST non DB_Only fields.  Defaults to false (no
246
-     *                   db only fields)
247
-     * @return array
248
-     */
249
-    public function get_meta_table_fields($all = false)
250
-    {
251
-        $all_fields = $fields_to_return = array();
252
-        foreach ($this->_tables as $alias => $table_obj) {
253
-            if ($table_obj instanceof EE_Secondary_Table) {
254
-                $all_fields = array_merge($this->_get_fields_for_table($alias), $all_fields);
255
-            }
256
-        }
257
-        if ( ! $all) {
258
-            foreach ($all_fields as $name => $obj) {
259
-                if ($obj instanceof EE_DB_Only_Field_Base) {
260
-                    continue;
261
-                }
262
-                $fields_to_return[] = $name;
263
-            }
264
-        } else {
265
-            $fields_to_return = array_keys($all_fields);
266
-        }
267
-        return $fields_to_return;
268
-    }
269
-
270
-
271
-
272
-    /**
273
-     * Adds an event category with the specified name and description to the specified
274
-     * $cpt_model_object. Intelligently adds a term if necessary, and adds a term_taxonomy if necessary,
275
-     * and adds an entry in the term_relationship if necessary.
276
-     *
277
-     * @param EE_CPT_Base $cpt_model_object
278
-     * @param string      $category_name (used to derive the term slug too)
279
-     * @param string      $category_description
280
-     * @param int         $parent_term_taxonomy_id
281
-     * @return EE_Term_Taxonomy
282
-     */
283
-    function add_event_category(
284
-        EE_CPT_Base $cpt_model_object,
285
-        $category_name,
286
-        $category_description = '',
287
-        $parent_term_taxonomy_id = null
288
-    ) {
289
-        //create term
290
-        require_once(EE_MODELS . 'EEM_Term.model.php');
291
-        //first, check for a term by the same name or slug
292
-        $category_slug = sanitize_title($category_name);
293
-        $term = EEM_Term::instance()->get_one(array(
294
-            array(
295
-                'OR' => array(
296
-                    'name' => $category_name,
297
-                    'slug' => $category_slug,
298
-                ),
299
-            ),
300
-        ));
301
-        if ( ! $term) {
302
-            $term = EE_Term::new_instance(array(
303
-                'name' => $category_name,
304
-                'slug' => $category_slug,
305
-            ));
306
-            $term->save();
307
-        }
308
-        //make sure there's a term-taxonomy entry too
309
-        require_once(EE_MODELS . 'EEM_Term_Taxonomy.model.php');
310
-        $term_taxonomy = EEM_Term_Taxonomy::instance()->get_one(array(
311
-            array(
312
-                'term_id'  => $term->ID(),
313
-                'taxonomy' => EE_Event_Category_Taxonomy,
314
-            ),
315
-        ));
316
-        /** @var $term_taxonomy EE_Term_Taxonomy */
317
-        if ( ! $term_taxonomy) {
318
-            $term_taxonomy = EE_Term_Taxonomy::new_instance(array(
319
-                'term_id'     => $term->ID(),
320
-                'taxonomy'    => EE_Event_Category_Taxonomy,
321
-                'description' => $category_description,
322
-                'count'       => 1,
323
-                'parent'      => $parent_term_taxonomy_id,
324
-            ));
325
-            $term_taxonomy->save();
326
-        } else {
327
-            $term_taxonomy->set_count($term_taxonomy->count() + 1);
328
-            $term_taxonomy->save();
329
-        }
330
-        return $this->add_relationship_to($cpt_model_object, $term_taxonomy, 'Term_Taxonomy');
331
-    }
332
-
333
-
334
-
335
-    /**
336
-     * Removed the category specified by name as having a relation to this event.
337
-     * Does not remove the term or term_taxonomy.
338
-     *
339
-     * @param EE_CPT_Base $cpt_model_object_event
340
-     * @param string      $category_name name of the event category (term)
341
-     * @return bool
342
-     */
343
-    function remove_event_category(EE_CPT_Base $cpt_model_object_event, $category_name)
344
-    {
345
-        //find the term_taxonomy by that name
346
-        $term_taxonomy = $this->get_first_related($cpt_model_object_event, 'Term_Taxonomy',
347
-            array(array('Term.name' => $category_name, 'taxonomy' => EE_Event_Category_Taxonomy)));
348
-        /** @var $term_taxonomy EE_Term_Taxonomy */
349
-        if ($term_taxonomy) {
350
-            $term_taxonomy->set_count($term_taxonomy->count() - 1);
351
-            $term_taxonomy->save();
352
-        }
353
-        return $this->remove_relationship_to($cpt_model_object_event, $term_taxonomy, 'Term_Taxonomy');
354
-    }
355
-
356
-
357
-
358
-    /**
359
-     * This is a wrapper for the WordPress get_the_post_thumbnail() function that returns the feature image for the
360
-     * given CPT ID.  It accepts the same params as what get_the_post_thumbnail() accepts.
361
-     *
362
-     * @link   http://codex.wordpress.org/Function_Reference/get_the_post_thumbnail
363
-     * @access public
364
-     * @param int          $id   the ID for the cpt we want the feature image for
365
-     * @param string|array $size (optional) Image size. Defaults to 'post-thumbnail' but can also be a 2-item array
366
-     *                           representing width and height in pixels (i.e. array(32,32) ).
367
-     * @param string|array $attr Optional. Query string or array of attributes.
368
-     * @return string HTML image element
369
-     */
370
-    public function get_feature_image($id, $size = 'thumbnail', $attr = '')
371
-    {
372
-        return get_the_post_thumbnail($id, $size, $attr);
373
-    }
374
-
375
-
376
-
377
-    /**
378
-     * Just a handy way to get the list of post statuses currently registered with WP.
379
-     *
380
-     * @global array $wp_post_statuses set in wp core for storing all the post stati
381
-     * @return array
382
-     */
383
-    public function get_post_statuses()
384
-    {
385
-        global $wp_post_statuses;
386
-        $statuses = array();
387
-        foreach ($wp_post_statuses as $post_status => $args_object) {
388
-            $statuses[$post_status] = $args_object->label;
389
-        }
390
-        return $statuses;
391
-    }
392
-
393
-
394
-
395
-    /**
396
-     * public method that can be used to retrieve the protected status array on the instantiated cpt model
397
-     *
398
-     * @return array array of statuses.
399
-     */
400
-    public function get_status_array()
401
-    {
402
-        $statuses = $this->get_post_statuses();
403
-        //first the global filter
404
-        $statuses = apply_filters('FHEE_EEM_CPT_Base__get_status_array', $statuses);
405
-        //now the class specific filter
406
-        $statuses = apply_filters('FHEE_EEM_' . get_class($this) . '__get_status_array', $statuses);
407
-        return $statuses;
408
-    }
409
-
410
-
411
-
412
-    /**
413
-     * this returns the post statuses that are NOT the default wordpress status
414
-     *
415
-     * @return array
416
-     */
417
-    public function get_custom_post_statuses()
418
-    {
419
-        $new_stati = array();
420
-        foreach ($this->_custom_stati as $status => $props) {
421
-            $new_stati[$status] = $props['label'];
422
-        }
423
-        return $new_stati;
424
-    }
425
-
426
-
427
-
428
-    /**
429
-     * Creates a child of EE_CPT_Base given a WP_Post or array of wpdb results which
430
-     * are a row from the posts table. If we're missing any fields required for the model,
431
-     * we just fetch the entire entry from the DB (ie, if you want to use this to save DB queries,
432
-     * make sure you are attaching all the model's fields onto the post)
433
-     *
434
-     * @param WP_Post|array $post
435
-     * @return EE_Base_Class|EE_Soft_Delete_Base_Class
436
-     */
437
-    public function instantiate_class_from_post_object_orig($post)
438
-    {
439
-        $post = (array)$post;
440
-        $has_all_necessary_fields_for_table = true;
441
-        //check if the post has fields on the meta table already
442
-        foreach ($this->_get_other_tables() as $table_obj) {
443
-            $fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias());
444
-            foreach ($fields_for_that_table as $field_obj) {
445
-                if ( ! isset($post[$field_obj->get_table_column()])
446
-                     && ! isset($post[$field_obj->get_qualified_column()])
447
-                ) {
448
-                    $has_all_necessary_fields_for_table = false;
449
-                }
450
-            }
451
-        }
452
-        //if we don't have all the fields we need, then just fetch the proper model from the DB
453
-        if ( ! $has_all_necessary_fields_for_table) {
454
-            return $this->get_one_by_ID($post['ID']);
455
-        } else {
456
-            return $this->instantiate_class_from_array_or_object($post);
457
-        }
458
-    }
459
-
460
-
461
-
462
-    /**
463
-     * @param null $post
464
-     * @return EE_Base_Class|EE_Soft_Delete_Base_Class
465
-     */
466
-    public function instantiate_class_from_post_object($post = null)
467
-    {
468
-        if (empty($post)) {
469
-            global $post;
470
-        }
471
-        $post = (array)$post;
472
-        $tables_needing_to_be_queried = array();
473
-        //check if the post has fields on the meta table already
474
-        foreach ($this->get_tables() as $table_obj) {
475
-            $fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias());
476
-            foreach ($fields_for_that_table as $field_obj) {
477
-                if ( ! isset($post[$field_obj->get_table_column()])
478
-                     && ! isset($post[$field_obj->get_qualified_column()])
479
-                ) {
480
-                    $tables_needing_to_be_queried[$table_obj->get_table_alias()] = $table_obj;
481
-                }
482
-            }
483
-        }
484
-        //if we don't have all the fields we need, then just fetch the proper model from the DB
485
-        if ($tables_needing_to_be_queried) {
486
-            if (count($tables_needing_to_be_queried) == 1
487
-                && reset($tables_needing_to_be_queried)
488
-                   instanceof
489
-                   EE_Secondary_Table
490
-            ) {
491
-                //so we're only missing data from a secondary table. Well that's not too hard to query for
492
-                $table_to_query = reset($tables_needing_to_be_queried);
493
-                $missing_data = $this->_do_wpdb_query('get_row', array(
494
-                    'SELECT * FROM '
495
-                    . $table_to_query->get_table_name()
496
-                    . ' WHERE '
497
-                    . $table_to_query->get_fk_on_table()
498
-                    . ' = '
499
-                    . $post['ID'],
500
-                    ARRAY_A,
501
-                ));
502
-                if ( ! empty($missing_data)) {
503
-                    $post = array_merge($post, $missing_data);
504
-                }
505
-            } else {
506
-                return $this->get_one_by_ID($post['ID']);
507
-            }
508
-        }
509
-        return $this->instantiate_class_from_array_or_object($post);
510
-    }
511
-
512
-
513
-
514
-    /**
515
-     * Gets the post type associated with this
516
-     *
517
-     * @throws EE_Error
518
-     * @return string
519
-     */
520
-    public function post_type()
521
-    {
522
-        $post_type_field = null;
523
-        foreach ($this->field_settings(true) as $field_obj) {
524
-            if ($field_obj instanceof EE_WP_Post_Type_Field) {
525
-                $post_type_field = $field_obj;
526
-                break;
527
-            }
528
-        }
529
-        if ($post_type_field == null) {
530
-            throw new EE_Error(sprintf(__("CPT Model %s should have a field of type EE_WP_Post_Type, but doesnt",
531
-                "event_espresso"), get_class($this)));
532
-        }
533
-        return $post_type_field->get_default_value();
534
-    }
21
+	/**
22
+	 * @var string post_status_publish - the wp post status for published cpts
23
+	 */
24
+	const post_status_publish = 'publish';
25
+
26
+	/**
27
+	 * @var string post_status_future - the wp post status for scheduled cpts
28
+	 */
29
+	const post_status_future = 'future';
30
+
31
+	/**
32
+	 * @var string post_status_draft - the wp post status for draft cpts
33
+	 */
34
+	const post_status_draft = 'draft';
35
+
36
+	/**
37
+	 * @var string post_status_pending - the wp post status for pending cpts
38
+	 */
39
+	const post_status_pending = 'pending';
40
+
41
+	/**
42
+	 * @var string post_status_private - the wp post status for private cpts
43
+	 */
44
+	const post_status_private = 'private';
45
+
46
+	/**
47
+	 * @var string post_status_trashed - the wp post status for trashed cpts
48
+	 */
49
+	const post_status_trashed = 'trash';
50
+
51
+	/**
52
+	 * This is an array of custom statuses for the given CPT model (modified by children)
53
+	 * format:
54
+	 * array(
55
+	 *        'status_name' => array(
56
+	 *            'label' => __('Status Name', 'event_espresso'),
57
+	 *            'public' => TRUE //whether a public status or not.
58
+	 *        )
59
+	 * )
60
+	 *
61
+	 * @var array
62
+	 */
63
+	protected $_custom_stati = array();
64
+
65
+
66
+
67
+	/**
68
+	 * Adds a relationship to Term_Taxonomy for each CPT_Base
69
+	 *
70
+	 * @param string $timezone
71
+	 * @throws \EE_Error
72
+	 */
73
+	protected function __construct($timezone = null)
74
+	{
75
+		//adds a relationship to Term_Taxonomy for all these models. For this to work
76
+		//Term_Relationship must have a relation to each model subclassing EE_CPT_Base explicitly
77
+		//eg, in EEM_Term_Relationship, inside the _model_relations array, there must be an entry
78
+		//with key equalling the subclassing model's model name (eg 'Event' or 'Venue'), and the value
79
+		//must also be new EE_HABTM_Relation('Term_Relationship');
80
+		$this->_model_relations['Term_Taxonomy'] = new EE_HABTM_Relation('Term_Relationship');
81
+		$primary_table_name = null;
82
+		//add  the common _status field to all CPT primary tables.
83
+		foreach ($this->_tables as $alias => $table_obj) {
84
+			if ($table_obj instanceof EE_Primary_Table) {
85
+				$primary_table_name = $alias;
86
+			}
87
+		}
88
+		//set default wp post statuses if child has not already set.
89
+		if ( ! isset($this->_fields[$primary_table_name]['status'])) {
90
+			$this->_fields[$primary_table_name]['status'] = new EE_WP_Post_Status_Field('post_status',
91
+				__("Event Status", "event_espresso"), false, 'draft');
92
+		}
93
+		if ( ! isset($this->_fields[$primary_table_name]['to_ping'])) {
94
+			$this->_fields[$primary_table_name]['to_ping'] = new EE_DB_Only_Text_Field('to_ping',
95
+				__('To Ping', 'event_espresso'), false, '');
96
+		}
97
+		if ( ! isset($this->_fields[$primary_table_name]['pinged'])) {
98
+			$this->_fields[$primary_table_name]['pinged'] = new EE_DB_Only_Text_Field('pinged',
99
+				__('Pinged', 'event_espresso'), false, '');
100
+		}
101
+		if ( ! isset($this->_fields[$primary_table_name]['comment_status'])) {
102
+			$this->_fields[$primary_table_name]['comment_status'] = new EE_Plain_Text_Field('comment_status',
103
+				__('Comment Status', 'event_espresso'), false, 'open');
104
+		}
105
+		if ( ! isset($this->_fields[$primary_table_name]['ping_status'])) {
106
+			$this->_fields[$primary_table_name]['ping_status'] = new EE_Plain_Text_Field('ping_status',
107
+				__('Ping Status', 'event_espresso'), false, 'open');
108
+		}
109
+		if ( ! isset($this->_fields[$primary_table_name]['post_content_filtered'])) {
110
+			$this->_fields[$primary_table_name]['post_content_filtered'] = new EE_DB_Only_Text_Field('post_content_filtered',
111
+				__('Post Content Filtered', 'event_espresso'), false, '');
112
+		}
113
+		if ( ! isset($this->_model_relations['Post_Meta'])) {
114
+			//don't block deletes though because we want to maintain the current behaviour
115
+			$this->_model_relations['Post_Meta'] = new EE_Has_Many_Relation(false);
116
+		}
117
+		if ( ! $this->_minimum_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
118
+			//nothing was set during child constructor, so set default
119
+			$this->_minimum_where_conditions_strategy = new EE_CPT_Minimum_Where_Conditions($this->post_type());
120
+		}
121
+		if ( ! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
122
+			//nothing was set during child constructor, so set default
123
+			//it's ok for child classes to specify this, but generally this is more DRY
124
+			$this->_default_where_conditions_strategy = new EE_CPT_Where_Conditions($this->post_type());
125
+		}
126
+		parent::__construct($timezone);
127
+	}
128
+
129
+
130
+
131
+	/**
132
+	 * @return array
133
+	 */
134
+	public function public_event_stati()
135
+	{
136
+		// @see wp-includes/post.php
137
+		return get_post_stati(array('public' => true));
138
+	}
139
+
140
+
141
+
142
+	/**
143
+	 * Searches for field on this model of type 'deleted_flag'. if it is found,
144
+	 * returns it's name. BUT That doesn't apply to CPTs. We should instead use post_status_field_name
145
+	 *
146
+	 * @return string
147
+	 * @throws EE_Error
148
+	 */
149
+	public function deleted_field_name()
150
+	{
151
+		throw new EE_Error(sprintf(__("EEM_CPT_Base should nto call deleted_field_name! It should instead use post_status_field_name",
152
+			"event_espresso")));
153
+	}
154
+
155
+
156
+
157
+	/**
158
+	 * Gets the field's name that sets the post status
159
+	 *
160
+	 * @return string
161
+	 * @throws EE_Error
162
+	 */
163
+	public function post_status_field_name()
164
+	{
165
+		$field = $this->get_a_field_of_type('EE_WP_Post_Status_Field');
166
+		if ($field) {
167
+			return $field->get_name();
168
+		} else {
169
+			throw new EE_Error(sprintf(__('We are trying to find the post status flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?',
170
+				'event_espresso'), get_class($this), get_class($this)));
171
+		}
172
+	}
173
+
174
+
175
+
176
+	/**
177
+	 * Alters the query params so that only trashed/soft-deleted items are considered
178
+	 *
179
+	 * @param array $query_params like EEM_Base::get_all's $query_params
180
+	 * @return array like EEM_Base::get_all's $query_params
181
+	 */
182
+	protected function _alter_query_params_so_only_trashed_items_included($query_params)
183
+	{
184
+		$post_status_field_name = $this->post_status_field_name();
185
+		$query_params[0][$post_status_field_name] = self::post_status_trashed;
186
+		return $query_params;
187
+	}
188
+
189
+
190
+
191
+	/**
192
+	 * Alters the query params so each item's deleted status is ignored.
193
+	 *
194
+	 * @param array $query_params
195
+	 * @return array
196
+	 */
197
+	protected function _alter_query_params_so_deleted_and_undeleted_items_included($query_params)
198
+	{
199
+		$query_params['default_where_conditions'] = 'minimum';
200
+		return $query_params;
201
+	}
202
+
203
+
204
+
205
+	/**
206
+	 * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered.
207
+	 *
208
+	 * @param boolean $delete       true to indicate deletion, false to indicate restoration
209
+	 * @param array   $query_params like EEM_Base::get_all
210
+	 * @return boolean success
211
+	 */
212
+	function delete_or_restore($delete = true, $query_params = array())
213
+	{
214
+		$post_status_field_name = $this->post_status_field_name();
215
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
216
+		$new_status = $delete ? self::post_status_trashed : 'draft';
217
+		if ($this->update(array($post_status_field_name => $new_status), $query_params)) {
218
+			return true;
219
+		} else {
220
+			return false;
221
+		}
222
+	}
223
+
224
+
225
+
226
+	/**
227
+	 * meta_table
228
+	 * returns first EE_Secondary_Table table name
229
+	 *
230
+	 * @access public
231
+	 * @return string
232
+	 */
233
+	public function meta_table()
234
+	{
235
+		$meta_table = $this->_get_other_tables();
236
+		$meta_table = reset($meta_table);
237
+		return $meta_table instanceof EE_Secondary_Table ? $meta_table->get_table_name() : null;
238
+	}
239
+
240
+
241
+
242
+	/**
243
+	 * This simply returns an array of the meta table fields (useful for when we just need to update those fields)
244
+	 *
245
+	 * @param  bool $all triggers whether we include DB_Only fields or JUST non DB_Only fields.  Defaults to false (no
246
+	 *                   db only fields)
247
+	 * @return array
248
+	 */
249
+	public function get_meta_table_fields($all = false)
250
+	{
251
+		$all_fields = $fields_to_return = array();
252
+		foreach ($this->_tables as $alias => $table_obj) {
253
+			if ($table_obj instanceof EE_Secondary_Table) {
254
+				$all_fields = array_merge($this->_get_fields_for_table($alias), $all_fields);
255
+			}
256
+		}
257
+		if ( ! $all) {
258
+			foreach ($all_fields as $name => $obj) {
259
+				if ($obj instanceof EE_DB_Only_Field_Base) {
260
+					continue;
261
+				}
262
+				$fields_to_return[] = $name;
263
+			}
264
+		} else {
265
+			$fields_to_return = array_keys($all_fields);
266
+		}
267
+		return $fields_to_return;
268
+	}
269
+
270
+
271
+
272
+	/**
273
+	 * Adds an event category with the specified name and description to the specified
274
+	 * $cpt_model_object. Intelligently adds a term if necessary, and adds a term_taxonomy if necessary,
275
+	 * and adds an entry in the term_relationship if necessary.
276
+	 *
277
+	 * @param EE_CPT_Base $cpt_model_object
278
+	 * @param string      $category_name (used to derive the term slug too)
279
+	 * @param string      $category_description
280
+	 * @param int         $parent_term_taxonomy_id
281
+	 * @return EE_Term_Taxonomy
282
+	 */
283
+	function add_event_category(
284
+		EE_CPT_Base $cpt_model_object,
285
+		$category_name,
286
+		$category_description = '',
287
+		$parent_term_taxonomy_id = null
288
+	) {
289
+		//create term
290
+		require_once(EE_MODELS . 'EEM_Term.model.php');
291
+		//first, check for a term by the same name or slug
292
+		$category_slug = sanitize_title($category_name);
293
+		$term = EEM_Term::instance()->get_one(array(
294
+			array(
295
+				'OR' => array(
296
+					'name' => $category_name,
297
+					'slug' => $category_slug,
298
+				),
299
+			),
300
+		));
301
+		if ( ! $term) {
302
+			$term = EE_Term::new_instance(array(
303
+				'name' => $category_name,
304
+				'slug' => $category_slug,
305
+			));
306
+			$term->save();
307
+		}
308
+		//make sure there's a term-taxonomy entry too
309
+		require_once(EE_MODELS . 'EEM_Term_Taxonomy.model.php');
310
+		$term_taxonomy = EEM_Term_Taxonomy::instance()->get_one(array(
311
+			array(
312
+				'term_id'  => $term->ID(),
313
+				'taxonomy' => EE_Event_Category_Taxonomy,
314
+			),
315
+		));
316
+		/** @var $term_taxonomy EE_Term_Taxonomy */
317
+		if ( ! $term_taxonomy) {
318
+			$term_taxonomy = EE_Term_Taxonomy::new_instance(array(
319
+				'term_id'     => $term->ID(),
320
+				'taxonomy'    => EE_Event_Category_Taxonomy,
321
+				'description' => $category_description,
322
+				'count'       => 1,
323
+				'parent'      => $parent_term_taxonomy_id,
324
+			));
325
+			$term_taxonomy->save();
326
+		} else {
327
+			$term_taxonomy->set_count($term_taxonomy->count() + 1);
328
+			$term_taxonomy->save();
329
+		}
330
+		return $this->add_relationship_to($cpt_model_object, $term_taxonomy, 'Term_Taxonomy');
331
+	}
332
+
333
+
334
+
335
+	/**
336
+	 * Removed the category specified by name as having a relation to this event.
337
+	 * Does not remove the term or term_taxonomy.
338
+	 *
339
+	 * @param EE_CPT_Base $cpt_model_object_event
340
+	 * @param string      $category_name name of the event category (term)
341
+	 * @return bool
342
+	 */
343
+	function remove_event_category(EE_CPT_Base $cpt_model_object_event, $category_name)
344
+	{
345
+		//find the term_taxonomy by that name
346
+		$term_taxonomy = $this->get_first_related($cpt_model_object_event, 'Term_Taxonomy',
347
+			array(array('Term.name' => $category_name, 'taxonomy' => EE_Event_Category_Taxonomy)));
348
+		/** @var $term_taxonomy EE_Term_Taxonomy */
349
+		if ($term_taxonomy) {
350
+			$term_taxonomy->set_count($term_taxonomy->count() - 1);
351
+			$term_taxonomy->save();
352
+		}
353
+		return $this->remove_relationship_to($cpt_model_object_event, $term_taxonomy, 'Term_Taxonomy');
354
+	}
355
+
356
+
357
+
358
+	/**
359
+	 * This is a wrapper for the WordPress get_the_post_thumbnail() function that returns the feature image for the
360
+	 * given CPT ID.  It accepts the same params as what get_the_post_thumbnail() accepts.
361
+	 *
362
+	 * @link   http://codex.wordpress.org/Function_Reference/get_the_post_thumbnail
363
+	 * @access public
364
+	 * @param int          $id   the ID for the cpt we want the feature image for
365
+	 * @param string|array $size (optional) Image size. Defaults to 'post-thumbnail' but can also be a 2-item array
366
+	 *                           representing width and height in pixels (i.e. array(32,32) ).
367
+	 * @param string|array $attr Optional. Query string or array of attributes.
368
+	 * @return string HTML image element
369
+	 */
370
+	public function get_feature_image($id, $size = 'thumbnail', $attr = '')
371
+	{
372
+		return get_the_post_thumbnail($id, $size, $attr);
373
+	}
374
+
375
+
376
+
377
+	/**
378
+	 * Just a handy way to get the list of post statuses currently registered with WP.
379
+	 *
380
+	 * @global array $wp_post_statuses set in wp core for storing all the post stati
381
+	 * @return array
382
+	 */
383
+	public function get_post_statuses()
384
+	{
385
+		global $wp_post_statuses;
386
+		$statuses = array();
387
+		foreach ($wp_post_statuses as $post_status => $args_object) {
388
+			$statuses[$post_status] = $args_object->label;
389
+		}
390
+		return $statuses;
391
+	}
392
+
393
+
394
+
395
+	/**
396
+	 * public method that can be used to retrieve the protected status array on the instantiated cpt model
397
+	 *
398
+	 * @return array array of statuses.
399
+	 */
400
+	public function get_status_array()
401
+	{
402
+		$statuses = $this->get_post_statuses();
403
+		//first the global filter
404
+		$statuses = apply_filters('FHEE_EEM_CPT_Base__get_status_array', $statuses);
405
+		//now the class specific filter
406
+		$statuses = apply_filters('FHEE_EEM_' . get_class($this) . '__get_status_array', $statuses);
407
+		return $statuses;
408
+	}
409
+
410
+
411
+
412
+	/**
413
+	 * this returns the post statuses that are NOT the default wordpress status
414
+	 *
415
+	 * @return array
416
+	 */
417
+	public function get_custom_post_statuses()
418
+	{
419
+		$new_stati = array();
420
+		foreach ($this->_custom_stati as $status => $props) {
421
+			$new_stati[$status] = $props['label'];
422
+		}
423
+		return $new_stati;
424
+	}
425
+
426
+
427
+
428
+	/**
429
+	 * Creates a child of EE_CPT_Base given a WP_Post or array of wpdb results which
430
+	 * are a row from the posts table. If we're missing any fields required for the model,
431
+	 * we just fetch the entire entry from the DB (ie, if you want to use this to save DB queries,
432
+	 * make sure you are attaching all the model's fields onto the post)
433
+	 *
434
+	 * @param WP_Post|array $post
435
+	 * @return EE_Base_Class|EE_Soft_Delete_Base_Class
436
+	 */
437
+	public function instantiate_class_from_post_object_orig($post)
438
+	{
439
+		$post = (array)$post;
440
+		$has_all_necessary_fields_for_table = true;
441
+		//check if the post has fields on the meta table already
442
+		foreach ($this->_get_other_tables() as $table_obj) {
443
+			$fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias());
444
+			foreach ($fields_for_that_table as $field_obj) {
445
+				if ( ! isset($post[$field_obj->get_table_column()])
446
+					 && ! isset($post[$field_obj->get_qualified_column()])
447
+				) {
448
+					$has_all_necessary_fields_for_table = false;
449
+				}
450
+			}
451
+		}
452
+		//if we don't have all the fields we need, then just fetch the proper model from the DB
453
+		if ( ! $has_all_necessary_fields_for_table) {
454
+			return $this->get_one_by_ID($post['ID']);
455
+		} else {
456
+			return $this->instantiate_class_from_array_or_object($post);
457
+		}
458
+	}
459
+
460
+
461
+
462
+	/**
463
+	 * @param null $post
464
+	 * @return EE_Base_Class|EE_Soft_Delete_Base_Class
465
+	 */
466
+	public function instantiate_class_from_post_object($post = null)
467
+	{
468
+		if (empty($post)) {
469
+			global $post;
470
+		}
471
+		$post = (array)$post;
472
+		$tables_needing_to_be_queried = array();
473
+		//check if the post has fields on the meta table already
474
+		foreach ($this->get_tables() as $table_obj) {
475
+			$fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias());
476
+			foreach ($fields_for_that_table as $field_obj) {
477
+				if ( ! isset($post[$field_obj->get_table_column()])
478
+					 && ! isset($post[$field_obj->get_qualified_column()])
479
+				) {
480
+					$tables_needing_to_be_queried[$table_obj->get_table_alias()] = $table_obj;
481
+				}
482
+			}
483
+		}
484
+		//if we don't have all the fields we need, then just fetch the proper model from the DB
485
+		if ($tables_needing_to_be_queried) {
486
+			if (count($tables_needing_to_be_queried) == 1
487
+				&& reset($tables_needing_to_be_queried)
488
+				   instanceof
489
+				   EE_Secondary_Table
490
+			) {
491
+				//so we're only missing data from a secondary table. Well that's not too hard to query for
492
+				$table_to_query = reset($tables_needing_to_be_queried);
493
+				$missing_data = $this->_do_wpdb_query('get_row', array(
494
+					'SELECT * FROM '
495
+					. $table_to_query->get_table_name()
496
+					. ' WHERE '
497
+					. $table_to_query->get_fk_on_table()
498
+					. ' = '
499
+					. $post['ID'],
500
+					ARRAY_A,
501
+				));
502
+				if ( ! empty($missing_data)) {
503
+					$post = array_merge($post, $missing_data);
504
+				}
505
+			} else {
506
+				return $this->get_one_by_ID($post['ID']);
507
+			}
508
+		}
509
+		return $this->instantiate_class_from_array_or_object($post);
510
+	}
511
+
512
+
513
+
514
+	/**
515
+	 * Gets the post type associated with this
516
+	 *
517
+	 * @throws EE_Error
518
+	 * @return string
519
+	 */
520
+	public function post_type()
521
+	{
522
+		$post_type_field = null;
523
+		foreach ($this->field_settings(true) as $field_obj) {
524
+			if ($field_obj instanceof EE_WP_Post_Type_Field) {
525
+				$post_type_field = $field_obj;
526
+				break;
527
+			}
528
+		}
529
+		if ($post_type_field == null) {
530
+			throw new EE_Error(sprintf(__("CPT Model %s should have a field of type EE_WP_Post_Type, but doesnt",
531
+				"event_espresso"), get_class($this)));
532
+		}
533
+		return $post_type_field->get_default_value();
534
+	}
535 535
 
536 536
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -287,7 +287,7 @@  discard block
 block discarded – undo
287 287
         $parent_term_taxonomy_id = null
288 288
     ) {
289 289
         //create term
290
-        require_once(EE_MODELS . 'EEM_Term.model.php');
290
+        require_once(EE_MODELS.'EEM_Term.model.php');
291 291
         //first, check for a term by the same name or slug
292 292
         $category_slug = sanitize_title($category_name);
293 293
         $term = EEM_Term::instance()->get_one(array(
@@ -306,7 +306,7 @@  discard block
 block discarded – undo
306 306
             $term->save();
307 307
         }
308 308
         //make sure there's a term-taxonomy entry too
309
-        require_once(EE_MODELS . 'EEM_Term_Taxonomy.model.php');
309
+        require_once(EE_MODELS.'EEM_Term_Taxonomy.model.php');
310 310
         $term_taxonomy = EEM_Term_Taxonomy::instance()->get_one(array(
311 311
             array(
312 312
                 'term_id'  => $term->ID(),
@@ -403,7 +403,7 @@  discard block
 block discarded – undo
403 403
         //first the global filter
404 404
         $statuses = apply_filters('FHEE_EEM_CPT_Base__get_status_array', $statuses);
405 405
         //now the class specific filter
406
-        $statuses = apply_filters('FHEE_EEM_' . get_class($this) . '__get_status_array', $statuses);
406
+        $statuses = apply_filters('FHEE_EEM_'.get_class($this).'__get_status_array', $statuses);
407 407
         return $statuses;
408 408
     }
409 409
 
@@ -436,7 +436,7 @@  discard block
 block discarded – undo
436 436
      */
437 437
     public function instantiate_class_from_post_object_orig($post)
438 438
     {
439
-        $post = (array)$post;
439
+        $post = (array) $post;
440 440
         $has_all_necessary_fields_for_table = true;
441 441
         //check if the post has fields on the meta table already
442 442
         foreach ($this->_get_other_tables() as $table_obj) {
@@ -468,7 +468,7 @@  discard block
 block discarded – undo
468 468
         if (empty($post)) {
469 469
             global $post;
470 470
         }
471
-        $post = (array)$post;
471
+        $post = (array) $post;
472 472
         $tables_needing_to_be_queried = array();
473 473
         //check if the post has fields on the meta table already
474 474
         foreach ($this->get_tables() as $table_obj) {
Please login to merge, or discard this patch.
core/db_models/EEM_Venue.model.php 2 patches
Indentation   +79 added lines, -79 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 /**
5 5
  * Event Espresso
@@ -25,87 +25,87 @@  discard block
 block discarded – undo
25 25
 class EEM_Venue extends EEM_CPT_Base
26 26
 {
27 27
 
28
-    // private instance of the Attendee object
29
-    protected static $_instance = null;
28
+	// private instance of the Attendee object
29
+	protected static $_instance = null;
30 30
 
31 31
 
32 32
 
33
-    protected function __construct($timezone = null)
34
-    {
35
-        $this->singular_item = __('Venue', 'event_espresso');
36
-        $this->plural_item = __('Venues', 'event_espresso');
37
-        $this->_tables = array(
38
-            'Venue_CPT'  => new EE_Primary_Table('posts', 'ID'),
39
-            'Venue_Meta' => new EE_Secondary_Table('esp_venue_meta', 'VNUM_ID', 'VNU_ID'),
40
-        );
41
-        $this->_fields = array(
42
-            'Venue_CPT'  => array(
43
-                'VNU_ID'         => new EE_Primary_Key_Int_Field('ID', __("Venue ID", "event_espresso")),
44
-                'VNU_name'       => new EE_Plain_Text_Field('post_title', __("Venue Name", "event_espresso"), false,
45
-                    ''),
46
-                'VNU_desc'       => new EE_Post_Content_Field('post_content', __("Venue Description", "event_espresso"),
47
-                    false, ''),
48
-                'VNU_identifier' => new EE_Slug_Field('post_name', __("Venue Identifier", "event_espresso"), false, ''),
49
-                'VNU_created'    => new EE_Datetime_Field('post_date', __("Date Venue Created", "event_espresso"),
50
-                    false, EE_Datetime_Field::now),
51
-                'VNU_short_desc' => new EE_Plain_Text_Field('post_excerpt',
52
-                    __("Short Description of Venue", "event_espresso"), true, ''),
53
-                'VNU_modified'   => new EE_Datetime_Field('post_modified', __("Venue Modified Date", "event_espresso"),
54
-                    false, EE_Datetime_Field::now),
55
-                'VNU_wp_user'    => new EE_WP_User_Field('post_author', __("Venue Creator ID", "event_espresso"),
56
-                    false),
57
-                'parent'         => new EE_Integer_Field('post_parent', __("Venue Parent ID", "event_espresso"), false,
58
-                    0),
59
-                'VNU_order'      => new EE_Integer_Field('menu_order', __("Venue order", "event_espresso"), false, 1),
60
-                'post_type'      => new EE_WP_Post_Type_Field('espresso_venues'),
61
-                // EE_Plain_Text_Field('post_type', __("Venue post type", "event_espresso"), false, 'espresso_venues'),
62
-            ),
63
-            'Venue_Meta' => array(
64
-                'VNUM_ID'             => new EE_DB_Only_Int_Field('VNUM_ID',
65
-                    __("ID of Venue Meta Row", "event_espresso"), false),
66
-                'VNU_ID_fk'           => new EE_DB_Only_Int_Field('VNU_ID',
67
-                    __("Foreign Key to Venue Post ", "event_espresso"), false),
68
-                'VNU_address'         => new EE_Plain_Text_Field('VNU_address',
69
-                    __("Venue Address line 1", "event_espresso"), true, ''),
70
-                'VNU_address2'        => new EE_Plain_Text_Field('VNU_address2',
71
-                    __("Venue Address line 2", "event_espresso"), true, ''),
72
-                'VNU_city'            => new EE_Plain_Text_Field('VNU_city', __("Venue City", "event_espresso"), true,
73
-                    ''),
74
-                'STA_ID'              => new EE_Foreign_Key_Int_Field('STA_ID', __("State ID", "event_espresso"), true,
75
-                    null, 'State'),
76
-                'CNT_ISO'             => new EE_Foreign_Key_String_Field('CNT_ISO',
77
-                    __("Country Code", "event_espresso"), true, null, 'Country'),
78
-                'VNU_zip'             => new EE_Plain_Text_Field('VNU_zip',
79
-                    __("Venue Zip/Postal Code", "event_espresso"), true),
80
-                'VNU_phone'           => new EE_Plain_Text_Field('VNU_phone', __("Venue Phone", "event_espresso"),
81
-                    true),
82
-                'VNU_capacity'        => new EE_Infinite_Integer_Field('VNU_capacity',
83
-                    __("Venue Capacity", "event_espresso"), true, EE_INF),
84
-                'VNU_url'             => new EE_Plain_Text_Field('VNU_url', __('Venue Website', 'event_espresso'),
85
-                    true),
86
-                'VNU_virtual_phone'   => new EE_Plain_Text_Field('VNU_virtual_phone',
87
-                    __('Call in Number', 'event_espresso'), true),
88
-                'VNU_virtual_url'     => new EE_Plain_Text_Field('VNU_virtual_url', __('Virtual URL', 'event_espresso'),
89
-                    true),
90
-                'VNU_google_map_link' => new EE_Plain_Text_Field('VNU_google_map_link',
91
-                    __('Google Map Link', 'event_espresso'), true),
92
-                'VNU_enable_for_gmap' => new EE_Boolean_Field('VNU_enable_for_gmap',
93
-                    __('Show Google Map?', 'event_espresso'), false, false),
94
-            ),
95
-        );
96
-        $this->_model_relations = array(
97
-            'Event'             => new EE_HABTM_Relation('Event_Venue'),
98
-            'State'             => new EE_Belongs_To_Relation(),
99
-            'Country'           => new EE_Belongs_To_Relation(),
100
-            'Event_Venue'       => new EE_Has_Many_Relation(),
101
-            'WP_User'           => new EE_Belongs_To_Relation(),
102
-            'Term_Relationship' => new EE_Has_Many_Relation(),
103
-            'Term_Taxonomy'     => new EE_HABTM_Relation('Term_Relationship'),
104
-        );
105
-        //this model is generally available for reading
106
-        $this->_cap_restriction_generators[EEM_Base::caps_read] = new EE_Restriction_Generator_Public();
107
-        parent::__construct($timezone);
108
-    }
33
+	protected function __construct($timezone = null)
34
+	{
35
+		$this->singular_item = __('Venue', 'event_espresso');
36
+		$this->plural_item = __('Venues', 'event_espresso');
37
+		$this->_tables = array(
38
+			'Venue_CPT'  => new EE_Primary_Table('posts', 'ID'),
39
+			'Venue_Meta' => new EE_Secondary_Table('esp_venue_meta', 'VNUM_ID', 'VNU_ID'),
40
+		);
41
+		$this->_fields = array(
42
+			'Venue_CPT'  => array(
43
+				'VNU_ID'         => new EE_Primary_Key_Int_Field('ID', __("Venue ID", "event_espresso")),
44
+				'VNU_name'       => new EE_Plain_Text_Field('post_title', __("Venue Name", "event_espresso"), false,
45
+					''),
46
+				'VNU_desc'       => new EE_Post_Content_Field('post_content', __("Venue Description", "event_espresso"),
47
+					false, ''),
48
+				'VNU_identifier' => new EE_Slug_Field('post_name', __("Venue Identifier", "event_espresso"), false, ''),
49
+				'VNU_created'    => new EE_Datetime_Field('post_date', __("Date Venue Created", "event_espresso"),
50
+					false, EE_Datetime_Field::now),
51
+				'VNU_short_desc' => new EE_Plain_Text_Field('post_excerpt',
52
+					__("Short Description of Venue", "event_espresso"), true, ''),
53
+				'VNU_modified'   => new EE_Datetime_Field('post_modified', __("Venue Modified Date", "event_espresso"),
54
+					false, EE_Datetime_Field::now),
55
+				'VNU_wp_user'    => new EE_WP_User_Field('post_author', __("Venue Creator ID", "event_espresso"),
56
+					false),
57
+				'parent'         => new EE_Integer_Field('post_parent', __("Venue Parent ID", "event_espresso"), false,
58
+					0),
59
+				'VNU_order'      => new EE_Integer_Field('menu_order', __("Venue order", "event_espresso"), false, 1),
60
+				'post_type'      => new EE_WP_Post_Type_Field('espresso_venues'),
61
+				// EE_Plain_Text_Field('post_type', __("Venue post type", "event_espresso"), false, 'espresso_venues'),
62
+			),
63
+			'Venue_Meta' => array(
64
+				'VNUM_ID'             => new EE_DB_Only_Int_Field('VNUM_ID',
65
+					__("ID of Venue Meta Row", "event_espresso"), false),
66
+				'VNU_ID_fk'           => new EE_DB_Only_Int_Field('VNU_ID',
67
+					__("Foreign Key to Venue Post ", "event_espresso"), false),
68
+				'VNU_address'         => new EE_Plain_Text_Field('VNU_address',
69
+					__("Venue Address line 1", "event_espresso"), true, ''),
70
+				'VNU_address2'        => new EE_Plain_Text_Field('VNU_address2',
71
+					__("Venue Address line 2", "event_espresso"), true, ''),
72
+				'VNU_city'            => new EE_Plain_Text_Field('VNU_city', __("Venue City", "event_espresso"), true,
73
+					''),
74
+				'STA_ID'              => new EE_Foreign_Key_Int_Field('STA_ID', __("State ID", "event_espresso"), true,
75
+					null, 'State'),
76
+				'CNT_ISO'             => new EE_Foreign_Key_String_Field('CNT_ISO',
77
+					__("Country Code", "event_espresso"), true, null, 'Country'),
78
+				'VNU_zip'             => new EE_Plain_Text_Field('VNU_zip',
79
+					__("Venue Zip/Postal Code", "event_espresso"), true),
80
+				'VNU_phone'           => new EE_Plain_Text_Field('VNU_phone', __("Venue Phone", "event_espresso"),
81
+					true),
82
+				'VNU_capacity'        => new EE_Infinite_Integer_Field('VNU_capacity',
83
+					__("Venue Capacity", "event_espresso"), true, EE_INF),
84
+				'VNU_url'             => new EE_Plain_Text_Field('VNU_url', __('Venue Website', 'event_espresso'),
85
+					true),
86
+				'VNU_virtual_phone'   => new EE_Plain_Text_Field('VNU_virtual_phone',
87
+					__('Call in Number', 'event_espresso'), true),
88
+				'VNU_virtual_url'     => new EE_Plain_Text_Field('VNU_virtual_url', __('Virtual URL', 'event_espresso'),
89
+					true),
90
+				'VNU_google_map_link' => new EE_Plain_Text_Field('VNU_google_map_link',
91
+					__('Google Map Link', 'event_espresso'), true),
92
+				'VNU_enable_for_gmap' => new EE_Boolean_Field('VNU_enable_for_gmap',
93
+					__('Show Google Map?', 'event_espresso'), false, false),
94
+			),
95
+		);
96
+		$this->_model_relations = array(
97
+			'Event'             => new EE_HABTM_Relation('Event_Venue'),
98
+			'State'             => new EE_Belongs_To_Relation(),
99
+			'Country'           => new EE_Belongs_To_Relation(),
100
+			'Event_Venue'       => new EE_Has_Many_Relation(),
101
+			'WP_User'           => new EE_Belongs_To_Relation(),
102
+			'Term_Relationship' => new EE_Has_Many_Relation(),
103
+			'Term_Taxonomy'     => new EE_HABTM_Relation('Term_Relationship'),
104
+		);
105
+		//this model is generally available for reading
106
+		$this->_cap_restriction_generators[EEM_Base::caps_read] = new EE_Restriction_Generator_Public();
107
+		parent::__construct($timezone);
108
+	}
109 109
 
110 110
 }
111 111
 // End of file EEM_Venue.model.php
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -18,7 +18,7 @@
 block discarded – undo
18 18
  * @author                Michael Nelson
19 19
  *                        ------------------------------------------------------------------------
20 20
  */
21
-require_once(EE_MODELS . 'EEM_Base.model.php');
21
+require_once(EE_MODELS.'EEM_Base.model.php');
22 22
 
23 23
 
24 24
 
Please login to merge, or discard this patch.
core/libraries/batch/Helpers/JobParameters.php 1 patch
Spacing   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -96,12 +96,12 @@  discard block
 block discarded – undo
96 96
 	 * @param array $request_data
97 97
 	 * @param array $extra_data
98 98
 	 */
99
-	function __construct( $job_id, $classname, $request_data, $extra_data = array() ) {
100
-		$this->set_job_id( $job_id );
101
-		$this->set_classname( $classname );
102
-		$this->set_request_data( $request_data );
103
-		$this->set_extra_data( $extra_data );
104
-		$this->set_status( JobParameters::status_continue );
99
+	function __construct($job_id, $classname, $request_data, $extra_data = array()) {
100
+		$this->set_job_id($job_id);
101
+		$this->set_classname($classname);
102
+		$this->set_request_data($request_data);
103
+		$this->set_extra_data($extra_data);
104
+		$this->set_status(JobParameters::status_continue);
105 105
 	}
106 106
 
107 107
 
@@ -126,12 +126,12 @@  discard block
 block discarded – undo
126 126
 	 * @param boolean $first
127 127
 	 * @return boolean success
128 128
 	 */
129
-	function save( $first = false ) {
130
-		$object_vars = get_object_vars( $this );
131
-		if( $first ) {
132
-			return add_option( $this->option_name(), $object_vars, null, 'no' );
133
-		} else{
134
-			return update_option( $this->option_name(), $object_vars );
129
+	function save($first = false) {
130
+		$object_vars = get_object_vars($this);
131
+		if ($first) {
132
+			return add_option($this->option_name(), $object_vars, null, 'no');
133
+		} else {
134
+			return update_option($this->option_name(), $object_vars);
135 135
 		}
136 136
 	}
137 137
 
@@ -143,7 +143,7 @@  discard block
 block discarded – undo
143 143
 	 * @return boolean
144 144
 	 */
145 145
 	function delete() {
146
-		return delete_option( $this->option_name() );
146
+		return delete_option($this->option_name());
147 147
 	}
148 148
 
149 149
 
@@ -154,26 +154,26 @@  discard block
 block discarded – undo
154 154
 	 * @return JobParameters
155 155
 	 * @throws BatchRequestException
156 156
 	 */
157
-	static function load( $job_id ) {
158
-		$job_parameter_vars = get_option( JobParameters::wp_option_prefix . $job_id );
159
-		if(
160
-			! is_array( $job_parameter_vars ) ||
161
-			! isset( $job_parameter_vars[ '_classname' ] ) ||
162
-			! isset( $job_parameter_vars[ '_request_data' ] )
157
+	static function load($job_id) {
158
+		$job_parameter_vars = get_option(JobParameters::wp_option_prefix.$job_id);
159
+		if (
160
+			! is_array($job_parameter_vars) ||
161
+			! isset($job_parameter_vars['_classname']) ||
162
+			! isset($job_parameter_vars['_request_data'])
163 163
 		) {
164 164
 			throw new BatchRequestException(
165 165
 				sprintf(
166 166
 					__('Could not retrieve job %1$s from the Wordpress options table, and so the job could not continue. The wordpress option was %2$s', 'event_espresso'),
167 167
 					$job_id,
168
-					get_option( JobParameters::wp_option_prefix . $job_id )
168
+					get_option(JobParameters::wp_option_prefix.$job_id)
169 169
 				)
170 170
 			);
171 171
 		}
172 172
 		$job_parameters = new JobParameters(
173 173
 				$job_id,
174
-				$job_parameter_vars[ '_classname' ],
175
-				$job_parameter_vars[ '_request_data'] );
176
-		foreach( $job_parameter_vars as $key => $value ) {
174
+				$job_parameter_vars['_classname'],
175
+				$job_parameter_vars['_request_data'] );
176
+		foreach ($job_parameter_vars as $key => $value) {
177 177
 			$job_parameters->{$key} = $value;
178 178
 		}
179 179
 		return $job_parameters;
@@ -217,9 +217,9 @@  discard block
 block discarded – undo
217 217
 	 * @param string|array $default
218 218
 	 * @return string|array
219 219
 	 */
220
-	function request_datum( $key, $default = '' ) {
221
-		if( isset( $this->_request_data[ $key ] ) ) {
222
-			return $this->_request_data[ $key ];
220
+	function request_datum($key, $default = '') {
221
+		if (isset($this->_request_data[$key])) {
222
+			return $this->_request_data[$key];
223 223
 		} else {
224 224
 			return $default;
225 225
 		}
@@ -233,9 +233,9 @@  discard block
 block discarded – undo
233 233
 	 * @param string|array $default
234 234
 	 * @return string|array
235 235
 	 */
236
-	function extra_datum( $key, $default = '' ) {
237
-		if( isset( $this->_extra_data[ $key ] ) ) {
238
-			return $this->_extra_data[ $key ];
236
+	function extra_datum($key, $default = '') {
237
+		if (isset($this->_extra_data[$key])) {
238
+			return $this->_extra_data[$key];
239 239
 		} else {
240 240
 			return $default;
241 241
 		}
@@ -248,8 +248,8 @@  discard block
 block discarded – undo
248 248
 	 * @param string $key
249 249
 	 * @param string|int|array|null $value almost any extra data you want to store
250 250
 	 */
251
-	function add_extra_data( $key, $value ) {
252
-		$this->_extra_data[ $key ] = $value;
251
+	function add_extra_data($key, $value) {
252
+		$this->_extra_data[$key] = $value;
253 253
 	}
254 254
 
255 255
 
@@ -278,7 +278,7 @@  discard block
 block discarded – undo
278 278
 	 * Sets the job size. You decide what units to use
279 279
 	 * @param int $size
280 280
 	 */
281
-	function set_job_size( $size ) {
281
+	function set_job_size($size) {
282 282
 		$this->_job_size = $size;
283 283
 	}
284 284
 
@@ -299,7 +299,7 @@  discard block
 block discarded – undo
299 299
 	 * @param int $newly_processed
300 300
 	 * @return int updated units processed
301 301
 	 */
302
-	function mark_processed( $newly_processed ) {
302
+	function mark_processed($newly_processed) {
303 303
 		$this->_units_processed += $newly_processed;
304 304
 		return $this->_units_processed;
305 305
 	}
@@ -310,7 +310,7 @@  discard block
 block discarded – undo
310 310
 	 * Sets the total count of units processed. You might prefer to use mark_processed
311 311
 	 * @param int $total_units_processed
312 312
 	 */
313
-	function set_units_processed( $total_units_processed ) {
313
+	function set_units_processed($total_units_processed) {
314 314
 		$this->_units_processed = $total_units_processed;
315 315
 	}
316 316
 
@@ -320,7 +320,7 @@  discard block
 block discarded – undo
320 320
 	 * Sets the job's ID
321 321
 	 * @param string $job_id
322 322
 	 */
323
-	function set_job_id( $job_id ) {
323
+	function set_job_id($job_id) {
324 324
 		$this->_job_id = $job_id;
325 325
 	}
326 326
 
@@ -330,7 +330,7 @@  discard block
 block discarded – undo
330 330
 	 * sets the classname
331 331
 	 * @param string $classname
332 332
 	 */
333
-	function set_classname( $classname ) {
333
+	function set_classname($classname) {
334 334
 		$this->_classname = $classname;
335 335
 	}
336 336
 
@@ -340,7 +340,7 @@  discard block
 block discarded – undo
340 340
 	 * Sets the request data
341 341
 	 * @param array $request_data
342 342
 	 */
343
-	function set_request_data( $request_data ) {
343
+	function set_request_data($request_data) {
344 344
 		$this->_request_data = $request_data;
345 345
 	}
346 346
 
@@ -350,7 +350,7 @@  discard block
 block discarded – undo
350 350
 	 * Sets the array of extra data we want to store on this request
351 351
 	 * @param array $extra_data
352 352
 	 */
353
-	function set_extra_data( $extra_data ) {
353
+	function set_extra_data($extra_data) {
354 354
 		$this->_extra_data = $extra_data;
355 355
 	}
356 356
 
@@ -361,7 +361,7 @@  discard block
 block discarded – undo
361 361
 	 * @return string
362 362
 	 */
363 363
 	function option_name() {
364
-		return JobParameters::wp_option_prefix . $this->job_id();
364
+		return JobParameters::wp_option_prefix.$this->job_id();
365 365
 	}
366 366
 
367 367
 
@@ -380,7 +380,7 @@  discard block
 block discarded – undo
380 380
 	 *
381 381
 	 * @param string $status on eof JobParameters::valid_stati()
382 382
 	 */
383
-	public function set_status( $status ) {
383
+	public function set_status($status) {
384 384
 		$this->_status = $status;
385 385
 	}
386 386
 
Please login to merge, or discard this patch.
core/db_classes/EE_Message.class.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -697,7 +697,7 @@
 block discarded – undo
697 697
     /**
698 698
      * Gets any error message.
699 699
      *
700
-     * @return mixed|null
700
+     * @return string
701 701
      */
702 702
     public function error_message()
703 703
     {
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -1,4 +1,4 @@  discard block
 block discarded – undo
1
-<?php if (! defined('EVENT_ESPRESSO_VERSION')) {
1
+<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2 2
     exit('No direct script access allowed');
3 3
 }
4 4
 
@@ -859,7 +859,7 @@  discard block
 block discarded – undo
859 859
      */
860 860
     public function set_messenger_is_executing()
861 861
     {
862
-        $this->set_STS_ID( EEM_Message::status_messenger_executing );
862
+        $this->set_STS_ID(EEM_Message::status_messenger_executing);
863 863
         $this->set_error_message(
864 864
             esc_html__(
865 865
                 'A message with this status indicates that there was a problem that occurred while the message was being
Please login to merge, or discard this patch.
Indentation   +860 added lines, -860 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if (! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 /**
@@ -12,869 +12,869 @@  discard block
 block discarded – undo
12 12
 class EE_Message extends EE_Base_Class implements EEI_Admin_Links
13 13
 {
14 14
 
15
-    /**
16
-     * @deprecated 4.9.0  Added for backward compat with add-on's
17
-     * @type null
18
-     */
19
-    public $template_pack;
20
-
21
-    /**
22
-     * @deprecated 4.9.0 Added for backward compat with add-on's
23
-     * @type null
24
-     */
25
-    public $template_variation;
26
-
27
-    /**
28
-     * @deprecated 4.9.0 Added for backward compat with add-on's
29
-     * @type string
30
-     */
31
-    public $content = '';
32
-
33
-
34
-    /**
35
-     * @type EE_messenger $_messenger
36
-     */
37
-    protected $_messenger = null;
38
-
39
-    /**
40
-     * @type EE_message_type $_message_type
41
-     */
42
-    protected $_message_type = null;
43
-
44
-
45
-    /**
46
-     * @param array  $props_n_values
47
-     * @param string $timezone
48
-     * @param array  $date_formats incoming date formats in an array.  First value is the date_format, second is time
49
-     *                             format.
50
-     * @return EE_Message
51
-     */
52
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
53
-    {
54
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__);
55
-        //if object doesn't exist, let's generate a unique token on instantiation so that its available even before saving to db.
56
-        if ( ! $has_object) {
57
-            EE_Registry::instance()->load_helper('URL');
58
-            $props_n_values['MSG_token'] = EEH_URL::generate_unique_token();
59
-        }
60
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
61
-    }
62
-
63
-
64
-    /**
65
-     * @param array  $props_n_values
66
-     * @param string $timezone
67
-     * @return EE_Message
68
-     */
69
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
70
-    {
71
-        return new self($props_n_values, true, $timezone);
72
-    }
73
-
74
-
75
-    /**
76
-     * Gets MSG_token
77
-     *
78
-     * @return int
79
-     */
80
-    public function MSG_token()
81
-    {
82
-        return $this->get('MSG_token');
83
-    }
84
-
85
-
86
-    /**
87
-     * Sets MSG_token
88
-     *
89
-     * @param int $MSG_token
90
-     */
91
-    public function set_MSG_token($MSG_token)
92
-    {
93
-        $this->set('MSG_token', $MSG_token);
94
-    }
95
-
96
-
97
-    /**
98
-     * Gets GRP_ID
99
-     *
100
-     * @return int
101
-     */
102
-    public function GRP_ID()
103
-    {
104
-        return $this->get('GRP_ID');
105
-    }
106
-
107
-
108
-    /**
109
-     * Sets GRP_ID
110
-     *
111
-     * @param int $GRP_ID
112
-     */
113
-    public function set_GRP_ID($GRP_ID)
114
-    {
115
-        $this->set('GRP_ID', $GRP_ID);
116
-    }
117
-
118
-
119
-    /**
120
-     * Gets TXN_ID
121
-     *
122
-     * @return int
123
-     */
124
-    public function TXN_ID()
125
-    {
126
-        return $this->get('TXN_ID');
127
-    }
128
-
129
-
130
-    /**
131
-     * Sets TXN_ID
132
-     *
133
-     * @param int $TXN_ID
134
-     */
135
-    public function set_TXN_ID($TXN_ID)
136
-    {
137
-        $this->set('TXN_ID', $TXN_ID);
138
-    }
139
-
140
-
141
-    /**
142
-     * Gets messenger
143
-     *
144
-     * @return string
145
-     */
146
-    public function messenger()
147
-    {
148
-        return $this->get('MSG_messenger');
149
-    }
150
-
151
-
152
-    /**
153
-     * Sets messenger
154
-     *
155
-     * @param string $messenger
156
-     */
157
-    public function set_messenger($messenger)
158
-    {
159
-        $this->set('MSG_messenger', $messenger);
160
-    }
161
-
162
-
163
-    /**
164
-     * Returns corresponding messenger object for the set messenger on this message
165
-     *
166
-     * @return EE_messenger | null
167
-     */
168
-    public function messenger_object()
169
-    {
170
-        return $this->_messenger;
171
-    }
172
-
173
-
174
-    /**
175
-     * Sets messenger
176
-     *
177
-     * @param EE_messenger $messenger
178
-     */
179
-    public function set_messenger_object(EE_messenger $messenger)
180
-    {
181
-        $this->_messenger = $messenger;
182
-    }
183
-
184
-
185
-    /**
186
-     * validates messenger
187
-     *
188
-     * @param bool $throw_exceptions
189
-     * @return bool
190
-     * @throws \EE_Error
191
-     */
192
-    public function valid_messenger($throw_exceptions = false)
193
-    {
194
-        if ($this->_messenger instanceof EE_messenger) {
195
-            return true;
196
-        }
197
-        if ($throw_exceptions) {
198
-            throw new EE_Error(
199
-                sprintf(
200
-                    __(
201
-                        'The "%1$s" messenger set for this message is missing or invalid. Please double-check the spelling and verify that the correct files exist.',
202
-                        'event_espresso'
203
-                    ),
204
-                    $this->messenger()
205
-                )
206
-            );
207
-        }
208
-        return false;
209
-    }
210
-
211
-
212
-    /**
213
-     * This returns the set localized label for the messenger on this message.
214
-     * Note, if unable to retrieve the EE_messenger object then will just return the messenger slug saved
215
-     * with this message.
216
-     *
217
-     * @param   bool $plural whether to return the plural label or not.
218
-     * @return string
219
-     */
220
-    public function messenger_label($plural = false)
221
-    {
222
-        $label_type = $plural ? 'plural' : 'singular';
223
-        $messenger  = $this->messenger_object();
224
-        return $messenger instanceof EE_messenger ? $messenger->label[$label_type] : $this->messenger();
225
-    }
226
-
227
-
228
-    /**
229
-     * Gets message_type
230
-     *
231
-     * @return string
232
-     */
233
-    public function message_type()
234
-    {
235
-        return $this->get('MSG_message_type');
236
-    }
237
-
238
-
239
-    /**
240
-     * Sets message_type
241
-     *
242
-     * @param string $message_type
243
-     */
244
-    public function set_message_type($message_type)
245
-    {
246
-        $this->set('MSG_message_type', $message_type);
247
-    }
248
-
249
-
250
-    /**
251
-     * Returns the message type object for the set message type on this message
252
-     *
253
-     * @return EE_message_type | null
254
-     */
255
-    public function message_type_object()
256
-    {
257
-        return $this->_message_type;
258
-    }
259
-
260
-
261
-    /**
262
-     * Sets message_type
263
-     *
264
-     * @param EE_message_type $message_type
265
-     * @param bool            $set_priority   This indicates whether to set the priority to whatever the priority is on
266
-     *                                        the message type or not.
267
-     */
268
-    public function set_message_type_object(EE_message_type $message_type, $set_priority = false)
269
-    {
270
-        $this->_message_type = $message_type;
271
-        if ($set_priority) {
272
-            $this->set_priority($this->_message_type->get_priority());
273
-        }
274
-    }
275
-
276
-
277
-    /**
278
-     * validates message_type
279
-     *
280
-     * @param bool $throw_exceptions
281
-     * @return bool
282
-     * @throws \EE_Error
283
-     */
284
-    public function valid_message_type($throw_exceptions = false)
285
-    {
286
-        if ($this->_message_type instanceof EE_message_type) {
287
-            return true;
288
-        }
289
-        if ($throw_exceptions) {
290
-            throw new EE_Error(
291
-                sprintf(
292
-                    __(
293
-                        'The %1$s message type set for this message is missing or invalid. Please double-check the spelling and verify that the correct files exist.',
294
-                        'event_espresso'
295
-                    ),
296
-                    $this->message_type()
297
-                )
298
-            );
299
-        }
300
-        return false;
301
-    }
302
-
303
-
304
-    /**
305
-     * validates messenger and message_type (that they are valid EE_messenger and EE_message_type objects).
306
-     *
307
-     * @param bool $throw_exceptions
308
-     * @return bool
309
-     * @throws \EE_Error
310
-     */
311
-    public function is_valid($throw_exceptions = false)
312
-    {
313
-        if ($this->valid_messenger($throw_exceptions) && $this->valid_message_type($throw_exceptions)) {
314
-            return true;
315
-        }
316
-        return false;
317
-    }
318
-
319
-
320
-    /**
321
-     * This validates whether the internal messenger and message type objects are valid for sending.
322
-     * Three checks are done:
323
-     * 1. There is a valid messenger object.
324
-     * 2. There is a valid message type object.
325
-     * 3. The message type object is active for the messenger.
326
-     *
327
-     * @throws EE_Error  But only if $throw_exceptions is set to true.
328
-     * @param bool $throw_exceptions
329
-     * @return bool
330
-     */
331
-    public function is_valid_for_sending_or_generation($throw_exceptions = false)
332
-    {
333
-        $valid = false;
334
-        if ($this->is_valid($throw_exceptions)) {
335
-            /** @var EE_Message_Resource_Manager $message_resource_manager */
336
-            $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
337
-            $valid                    = $message_resource_manager->is_message_type_active_for_messenger($this->messenger(),
338
-                $this->message_type());
339
-            if ( ! $valid && $throw_exceptions) {
340
-                throw new EE_Error(
341
-                    sprintf(
342
-                        __('The %1$s message type is not a valid message type for the %2$s messenger so it will not be sent.',
343
-                            'event_espresso'),
344
-                        $this->message_type(),
345
-                        $this->messenger()
346
-                    )
347
-                );
348
-            }
349
-        }
350
-        return $valid;
351
-    }
352
-
353
-
354
-    /**
355
-     * This returns the set localized label for the message type on this message.
356
-     * Note, if unable to retrieve the EE_message_type object then will just return the message type slug saved
357
-     * with this message.
358
-     *
359
-     * @param   bool $plural whether to return the plural label or not.
360
-     * @return string
361
-     */
362
-    public function message_type_label($plural = false)
363
-    {
364
-        $label_type   = $plural ? 'plural' : 'singular';
365
-        $message_type = $this->message_type_object();
366
-        return $message_type instanceof EE_message_type ? $message_type->label[$label_type] : str_replace(
367
-            '_',
368
-            ' ',
369
-            $this->message_type()
370
-        );
371
-    }
372
-
373
-
374
-    /**
375
-     * Gets context
376
-     *
377
-     * @return string
378
-     */
379
-    public function context()
380
-    {
381
-        return $this->get('MSG_context');
382
-    }
383
-
384
-
385
-    /**
386
-     * This returns the corresponding localized label for the given context slug, if possible from installed message
387
-     * types. Otherwise, this will just return the set context slug on this object.
388
-     *
389
-     * @return string
390
-     */
391
-    public function context_label()
392
-    {
393
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
394
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
395
-        $contexts                 = $message_resource_manager->get_all_contexts();
396
-        return isset($contexts[$this->context()]) ? $contexts[$this->context()] : $this->context();
397
-    }
398
-
399
-
400
-    /**
401
-     * Sets context
402
-     *
403
-     * @param string $context
404
-     */
405
-    public function set_context($context)
406
-    {
407
-        $this->set('MSG_context', $context);
408
-    }
409
-
410
-
411
-    /**
412
-     * Gets recipient_ID
413
-     *
414
-     * @return int
415
-     */
416
-    public function recipient_ID()
417
-    {
418
-        return $this->get('MSG_recipient_ID');
419
-    }
420
-
421
-
422
-    /**
423
-     * Sets recipient_ID
424
-     *
425
-     * @param string $recipient_ID
426
-     */
427
-    public function set_recipient_ID($recipient_ID)
428
-    {
429
-        $this->set('MSG_recipient_ID', $recipient_ID);
430
-    }
431
-
432
-
433
-    /**
434
-     * Gets recipient_type
435
-     *
436
-     * @return string
437
-     */
438
-    public function recipient_type()
439
-    {
440
-        return $this->get('MSG_recipient_type');
441
-    }
442
-
443
-
444
-    /**
445
-     * Return the related object matching the recipient type and ID.
446
-     *
447
-     * @return EE_Base_Class | null
448
-     */
449
-    public function recipient_object()
450
-    {
451
-        if ( ! $this->recipient_type() || ! $this->recipient_ID()) {
452
-            return null;
453
-        }
454
-
455
-        return $this->get_first_related($this->recipient_type());
456
-    }
457
-
458
-
459
-    /**
460
-     * Sets recipient_type
461
-     *
462
-     * @param string $recipient_type
463
-     */
464
-    public function set_recipient_type($recipient_type)
465
-    {
466
-        $this->set('MSG_recipient_type', $recipient_type);
467
-    }
468
-
469
-
470
-    /**
471
-     * Gets content
472
-     *
473
-     * @return string
474
-     */
475
-    public function content()
476
-    {
477
-        return $this->get('MSG_content');
478
-    }
479
-
480
-
481
-    /**
482
-     * Sets content
483
-     *
484
-     * @param string $content
485
-     */
486
-    public function set_content($content)
487
-    {
488
-        $this->set('MSG_content', $content);
489
-    }
490
-
491
-
492
-    /**
493
-     * Gets subject
494
-     *
495
-     * @return string
496
-     */
497
-    public function subject()
498
-    {
499
-        return $this->get('MSG_subject');
500
-    }
501
-
502
-
503
-    /**
504
-     * Sets subject
505
-     *
506
-     * @param string $subject
507
-     */
508
-    public function set_subject($subject)
509
-    {
510
-        $this->set('MSG_subject', $subject);
511
-    }
512
-
513
-
514
-    /**
515
-     * Gets to
516
-     *
517
-     * @return string
518
-     */
519
-    public function to()
520
-    {
521
-        $to = $this->get('MSG_to');
522
-        return empty($to) ? __('No recipient', 'event_espresso') : $to;
523
-    }
524
-
525
-
526
-    /**
527
-     * Sets to
528
-     *
529
-     * @param string $to
530
-     */
531
-    public function set_to($to)
532
-    {
533
-        $this->set('MSG_to', $to);
534
-    }
535
-
536
-
537
-    /**
538
-     * Gets from
539
-     *
540
-     * @return string
541
-     */
542
-    public function from()
543
-    {
544
-        return $this->get('MSG_from');
545
-    }
546
-
547
-
548
-    /**
549
-     * Sets from
550
-     *
551
-     * @param string $from
552
-     */
553
-    public function set_from($from)
554
-    {
555
-        $this->set('MSG_from', $from);
556
-    }
557
-
558
-
559
-    /**
560
-     * Gets priority
561
-     *
562
-     * @return int
563
-     */
564
-    public function priority()
565
-    {
566
-        return $this->get('MSG_priority');
567
-    }
568
-
569
-
570
-    /**
571
-     * Sets priority
572
-     * Note.  Send Now Messengers always override any priority that may be set on a Message.  So
573
-     * this method calls the send_now method to verify that.
574
-     *
575
-     * @param int $priority
576
-     */
577
-    public function set_priority($priority)
578
-    {
579
-        $priority = $this->send_now() ? EEM_Message::priority_high : $priority;
580
-        parent::set('MSG_priority', $priority);
581
-    }
582
-
583
-
584
-    /**
585
-     * Overrides parent::set method so we can capture any sets for priority.
586
-     *
587
-     * @see parent::set() for phpdocs
588
-     * @param string $field_name
589
-     * @param mixed  $field_value
590
-     * @param bool   $use_default
591
-     * @throws EE_Error
592
-     */
593
-    public function set($field_name, $field_value, $use_default = false)
594
-    {
595
-        if ($field_name === 'MSG_priority') {
596
-            $this->set_priority($field_value);
597
-        }
598
-        parent::set($field_name, $field_value, $use_default);
599
-    }
600
-
601
-
602
-    /**
603
-     * @return bool
604
-     * @throws \EE_Error
605
-     */
606
-    public function send_now()
607
-    {
608
-        $send_now = $this->valid_messenger() && $this->messenger_object()->send_now() ? EEM_Message::priority_high : $this->priority();
609
-        return $send_now === EEM_Message::priority_high ? true : false;
610
-    }
611
-
612
-
613
-    /**
614
-     * Gets STS_ID
615
-     *
616
-     * @return string
617
-     */
618
-    public function STS_ID()
619
-    {
620
-        return $this->get('STS_ID');
621
-    }
622
-
623
-
624
-    /**
625
-     * Sets STS_ID
626
-     *
627
-     * @param string $STS_ID
628
-     */
629
-    public function set_STS_ID($STS_ID)
630
-    {
631
-        $this->set('STS_ID', $STS_ID);
632
-    }
633
-
634
-
635
-    /**
636
-     * Gets created
637
-     *
638
-     * @return string
639
-     */
640
-    public function created()
641
-    {
642
-        return $this->get('MSG_created');
643
-    }
644
-
645
-
646
-    /**
647
-     * Sets created
648
-     *
649
-     * @param string $created
650
-     */
651
-    public function set_created($created)
652
-    {
653
-        $this->set('MSG_created', $created);
654
-    }
655
-
656
-
657
-    /**
658
-     * Gets modified
659
-     *
660
-     * @return string
661
-     */
662
-    public function modified()
663
-    {
664
-        return $this->get('MSG_modified');
665
-    }
666
-
667
-
668
-    /**
669
-     * Sets modified
670
-     *
671
-     * @param string $modified
672
-     */
673
-    public function set_modified($modified)
674
-    {
675
-        $this->set('MSG_modified', $modified);
676
-    }
677
-
678
-
679
-    /**
680
-     * Sets generation data for this message.
681
-     *
682
-     * @param mixed $data
683
-     */
684
-    public function set_generation_data($data)
685
-    {
686
-        $this->set_field_or_extra_meta('MSG_generation_data', $data);
687
-    }
688
-
689
-
690
-    /**
691
-     * Returns any set generation data for this message.
692
-     *
693
-     * @return mixed|null
694
-     */
695
-    public function get_generation_data()
696
-    {
697
-        return $this->get_field_or_extra_meta('MSG_generation_data');
698
-    }
699
-
700
-
701
-    /**
702
-     * Gets any error message.
703
-     *
704
-     * @return mixed|null
705
-     */
706
-    public function error_message()
707
-    {
708
-        return $this->get_field_or_extra_meta('MSG_error');
709
-    }
710
-
711
-
712
-    /**
713
-     * Sets an error message.
714
-     *
715
-     * @param $message
716
-     * @return bool|int
717
-     */
718
-    public function set_error_message($message)
719
-    {
720
-        return $this->set_field_or_extra_meta('MSG_error', $message);
721
-    }
722
-
723
-
724
-    /**
725
-     * This retrieves the associated template pack with this message.
726
-     *
727
-     * @return EE_Messages_Template_Pack | null
728
-     */
729
-    public function get_template_pack()
730
-    {
731
-        /**
732
-         * This is deprecated functionality that will be removed eventually but included here now for backward compat.
733
-         */
734
-        if ( ! empty($this->template_pack)) {
735
-            return $this->template_pack;
736
-        }
737
-        /** @type EE_Message_Template_Group $grp */
738
-        $grp = $this->get_first_related('Message_Template_Group');
739
-        //if no group then let's try to get the first related group by internal messenger and message type (will use global grp).
740
-        if ( ! $grp instanceof EE_Message_Template_Group) {
741
-            $grp = EEM_Message_Template_Group::instance()->get_one(
742
-                array(
743
-                    array(
744
-                        'MTP_messenger'    => $this->messenger(),
745
-                        'MTP_message_type' => $this->message_type(),
746
-                        'MTP_is_global'    => true,
747
-                    ),
748
-                )
749
-            );
750
-        }
751
-
752
-        return $grp instanceof EE_Message_Template_Group ? $grp->get_template_pack() : null;
753
-    }
754
-
755
-
756
-    /**
757
-     * Retrieves the variation used for generating this message.
758
-     *
759
-     * @return string
760
-     */
761
-    public function get_template_pack_variation()
762
-    {
763
-        /**
764
-         * This is deprecated functionality that will be removed eventually but included here now for backward compat.
765
-         */
766
-        if ( ! empty($this->template_variation)) {
767
-            return $this->template_variation;
768
-        }
769
-
770
-        /** @type EE_Message_Template_Group $grp */
771
-        $grp = $this->get_first_related('Message_Template_Group');
772
-
773
-        //if no group then let's try to get the first related group by internal messenger and message type (will use global grp).
774
-        if ( ! $grp instanceof EE_Message_Template_Group) {
775
-            $grp = EEM_Message_Template_Group::instance()->get_one(
776
-                array(
777
-                    array(
778
-                        'MTP_messenger'    => $this->messenger(),
779
-                        'MTP_message_type' => $this->message_type(),
780
-                        'MTP_is_global'    => true,
781
-                    ),
782
-                )
783
-            );
784
-        }
785
-
786
-        return $grp instanceof EE_Message_Template_Group ? $grp->get_template_pack_variation() : '';
787
-    }
788
-
789
-    /**
790
-     * Return the link to the admin details for the object.
791
-     *
792
-     * @return string
793
-     */
794
-    public function get_admin_details_link()
795
-    {
796
-        EE_Registry::instance()->load_helper('URL');
797
-        EE_Registry::instance()->load_helper('MSG_Template');
798
-        switch ($this->STS_ID()) {
799
-            case EEM_Message::status_failed :
800
-            case EEM_Message::status_debug_only :
801
-                return EEH_MSG_Template::generate_error_display_trigger($this);
802
-                break;
803
-
804
-            case EEM_Message::status_sent :
805
-                return EEH_MSG_Template::generate_browser_trigger($this);
806
-                break;
807
-
808
-            default :
809
-                return '';
810
-        }
811
-    }
812
-
813
-    /**
814
-     * Returns the link to the editor for the object.  Sometimes this is the same as the details.
815
-     *
816
-     * @return string
817
-     */
818
-    public function get_admin_edit_link()
819
-    {
820
-        return $this->get_admin_details_link();
821
-    }
822
-
823
-    /**
824
-     * Returns the link to a settings page for the object.
825
-     *
826
-     * @return string
827
-     */
828
-    public function get_admin_settings_link()
829
-    {
830
-        EE_Registry::instance()->load_helper('URL');
831
-        return EEH_URL::add_query_args_and_nonce(
832
-            array(
833
-                'page'   => 'espresso_messages',
834
-                'action' => 'settings',
835
-            ),
836
-            admin_url('admin.php')
837
-        );
838
-    }
839
-
840
-    /**
841
-     * Returns the link to the "overview" for the object (typically the "list table" view).
842
-     *
843
-     * @return string
844
-     */
845
-    public function get_admin_overview_link()
846
-    {
847
-        EE_Registry::instance()->load_helper('URL');
848
-        return EEH_URL::add_query_args_and_nonce(
849
-            array(
850
-                'page'   => 'espresso_messages',
851
-                'action' => 'default',
852
-            ),
853
-            admin_url('admin.php')
854
-        );
855
-    }
856
-
857
-
858
-    /**
859
-     * This sets the EEM_Message::status_messenger_executing class on the message and the appropriate error message for
860
-     * it.
861
-     * Note this also SAVES the current message object to the db because it adds an error message to accompany the status.
862
-     *
863
-     */
864
-    public function set_messenger_is_executing()
865
-    {
866
-        $this->set_STS_ID( EEM_Message::status_messenger_executing );
867
-        $this->set_error_message(
868
-            esc_html__(
869
-                'A message with this status indicates that there was a problem that occurred while the message was being
15
+	/**
16
+	 * @deprecated 4.9.0  Added for backward compat with add-on's
17
+	 * @type null
18
+	 */
19
+	public $template_pack;
20
+
21
+	/**
22
+	 * @deprecated 4.9.0 Added for backward compat with add-on's
23
+	 * @type null
24
+	 */
25
+	public $template_variation;
26
+
27
+	/**
28
+	 * @deprecated 4.9.0 Added for backward compat with add-on's
29
+	 * @type string
30
+	 */
31
+	public $content = '';
32
+
33
+
34
+	/**
35
+	 * @type EE_messenger $_messenger
36
+	 */
37
+	protected $_messenger = null;
38
+
39
+	/**
40
+	 * @type EE_message_type $_message_type
41
+	 */
42
+	protected $_message_type = null;
43
+
44
+
45
+	/**
46
+	 * @param array  $props_n_values
47
+	 * @param string $timezone
48
+	 * @param array  $date_formats incoming date formats in an array.  First value is the date_format, second is time
49
+	 *                             format.
50
+	 * @return EE_Message
51
+	 */
52
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
53
+	{
54
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__);
55
+		//if object doesn't exist, let's generate a unique token on instantiation so that its available even before saving to db.
56
+		if ( ! $has_object) {
57
+			EE_Registry::instance()->load_helper('URL');
58
+			$props_n_values['MSG_token'] = EEH_URL::generate_unique_token();
59
+		}
60
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
61
+	}
62
+
63
+
64
+	/**
65
+	 * @param array  $props_n_values
66
+	 * @param string $timezone
67
+	 * @return EE_Message
68
+	 */
69
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
70
+	{
71
+		return new self($props_n_values, true, $timezone);
72
+	}
73
+
74
+
75
+	/**
76
+	 * Gets MSG_token
77
+	 *
78
+	 * @return int
79
+	 */
80
+	public function MSG_token()
81
+	{
82
+		return $this->get('MSG_token');
83
+	}
84
+
85
+
86
+	/**
87
+	 * Sets MSG_token
88
+	 *
89
+	 * @param int $MSG_token
90
+	 */
91
+	public function set_MSG_token($MSG_token)
92
+	{
93
+		$this->set('MSG_token', $MSG_token);
94
+	}
95
+
96
+
97
+	/**
98
+	 * Gets GRP_ID
99
+	 *
100
+	 * @return int
101
+	 */
102
+	public function GRP_ID()
103
+	{
104
+		return $this->get('GRP_ID');
105
+	}
106
+
107
+
108
+	/**
109
+	 * Sets GRP_ID
110
+	 *
111
+	 * @param int $GRP_ID
112
+	 */
113
+	public function set_GRP_ID($GRP_ID)
114
+	{
115
+		$this->set('GRP_ID', $GRP_ID);
116
+	}
117
+
118
+
119
+	/**
120
+	 * Gets TXN_ID
121
+	 *
122
+	 * @return int
123
+	 */
124
+	public function TXN_ID()
125
+	{
126
+		return $this->get('TXN_ID');
127
+	}
128
+
129
+
130
+	/**
131
+	 * Sets TXN_ID
132
+	 *
133
+	 * @param int $TXN_ID
134
+	 */
135
+	public function set_TXN_ID($TXN_ID)
136
+	{
137
+		$this->set('TXN_ID', $TXN_ID);
138
+	}
139
+
140
+
141
+	/**
142
+	 * Gets messenger
143
+	 *
144
+	 * @return string
145
+	 */
146
+	public function messenger()
147
+	{
148
+		return $this->get('MSG_messenger');
149
+	}
150
+
151
+
152
+	/**
153
+	 * Sets messenger
154
+	 *
155
+	 * @param string $messenger
156
+	 */
157
+	public function set_messenger($messenger)
158
+	{
159
+		$this->set('MSG_messenger', $messenger);
160
+	}
161
+
162
+
163
+	/**
164
+	 * Returns corresponding messenger object for the set messenger on this message
165
+	 *
166
+	 * @return EE_messenger | null
167
+	 */
168
+	public function messenger_object()
169
+	{
170
+		return $this->_messenger;
171
+	}
172
+
173
+
174
+	/**
175
+	 * Sets messenger
176
+	 *
177
+	 * @param EE_messenger $messenger
178
+	 */
179
+	public function set_messenger_object(EE_messenger $messenger)
180
+	{
181
+		$this->_messenger = $messenger;
182
+	}
183
+
184
+
185
+	/**
186
+	 * validates messenger
187
+	 *
188
+	 * @param bool $throw_exceptions
189
+	 * @return bool
190
+	 * @throws \EE_Error
191
+	 */
192
+	public function valid_messenger($throw_exceptions = false)
193
+	{
194
+		if ($this->_messenger instanceof EE_messenger) {
195
+			return true;
196
+		}
197
+		if ($throw_exceptions) {
198
+			throw new EE_Error(
199
+				sprintf(
200
+					__(
201
+						'The "%1$s" messenger set for this message is missing or invalid. Please double-check the spelling and verify that the correct files exist.',
202
+						'event_espresso'
203
+					),
204
+					$this->messenger()
205
+				)
206
+			);
207
+		}
208
+		return false;
209
+	}
210
+
211
+
212
+	/**
213
+	 * This returns the set localized label for the messenger on this message.
214
+	 * Note, if unable to retrieve the EE_messenger object then will just return the messenger slug saved
215
+	 * with this message.
216
+	 *
217
+	 * @param   bool $plural whether to return the plural label or not.
218
+	 * @return string
219
+	 */
220
+	public function messenger_label($plural = false)
221
+	{
222
+		$label_type = $plural ? 'plural' : 'singular';
223
+		$messenger  = $this->messenger_object();
224
+		return $messenger instanceof EE_messenger ? $messenger->label[$label_type] : $this->messenger();
225
+	}
226
+
227
+
228
+	/**
229
+	 * Gets message_type
230
+	 *
231
+	 * @return string
232
+	 */
233
+	public function message_type()
234
+	{
235
+		return $this->get('MSG_message_type');
236
+	}
237
+
238
+
239
+	/**
240
+	 * Sets message_type
241
+	 *
242
+	 * @param string $message_type
243
+	 */
244
+	public function set_message_type($message_type)
245
+	{
246
+		$this->set('MSG_message_type', $message_type);
247
+	}
248
+
249
+
250
+	/**
251
+	 * Returns the message type object for the set message type on this message
252
+	 *
253
+	 * @return EE_message_type | null
254
+	 */
255
+	public function message_type_object()
256
+	{
257
+		return $this->_message_type;
258
+	}
259
+
260
+
261
+	/**
262
+	 * Sets message_type
263
+	 *
264
+	 * @param EE_message_type $message_type
265
+	 * @param bool            $set_priority   This indicates whether to set the priority to whatever the priority is on
266
+	 *                                        the message type or not.
267
+	 */
268
+	public function set_message_type_object(EE_message_type $message_type, $set_priority = false)
269
+	{
270
+		$this->_message_type = $message_type;
271
+		if ($set_priority) {
272
+			$this->set_priority($this->_message_type->get_priority());
273
+		}
274
+	}
275
+
276
+
277
+	/**
278
+	 * validates message_type
279
+	 *
280
+	 * @param bool $throw_exceptions
281
+	 * @return bool
282
+	 * @throws \EE_Error
283
+	 */
284
+	public function valid_message_type($throw_exceptions = false)
285
+	{
286
+		if ($this->_message_type instanceof EE_message_type) {
287
+			return true;
288
+		}
289
+		if ($throw_exceptions) {
290
+			throw new EE_Error(
291
+				sprintf(
292
+					__(
293
+						'The %1$s message type set for this message is missing or invalid. Please double-check the spelling and verify that the correct files exist.',
294
+						'event_espresso'
295
+					),
296
+					$this->message_type()
297
+				)
298
+			);
299
+		}
300
+		return false;
301
+	}
302
+
303
+
304
+	/**
305
+	 * validates messenger and message_type (that they are valid EE_messenger and EE_message_type objects).
306
+	 *
307
+	 * @param bool $throw_exceptions
308
+	 * @return bool
309
+	 * @throws \EE_Error
310
+	 */
311
+	public function is_valid($throw_exceptions = false)
312
+	{
313
+		if ($this->valid_messenger($throw_exceptions) && $this->valid_message_type($throw_exceptions)) {
314
+			return true;
315
+		}
316
+		return false;
317
+	}
318
+
319
+
320
+	/**
321
+	 * This validates whether the internal messenger and message type objects are valid for sending.
322
+	 * Three checks are done:
323
+	 * 1. There is a valid messenger object.
324
+	 * 2. There is a valid message type object.
325
+	 * 3. The message type object is active for the messenger.
326
+	 *
327
+	 * @throws EE_Error  But only if $throw_exceptions is set to true.
328
+	 * @param bool $throw_exceptions
329
+	 * @return bool
330
+	 */
331
+	public function is_valid_for_sending_or_generation($throw_exceptions = false)
332
+	{
333
+		$valid = false;
334
+		if ($this->is_valid($throw_exceptions)) {
335
+			/** @var EE_Message_Resource_Manager $message_resource_manager */
336
+			$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
337
+			$valid                    = $message_resource_manager->is_message_type_active_for_messenger($this->messenger(),
338
+				$this->message_type());
339
+			if ( ! $valid && $throw_exceptions) {
340
+				throw new EE_Error(
341
+					sprintf(
342
+						__('The %1$s message type is not a valid message type for the %2$s messenger so it will not be sent.',
343
+							'event_espresso'),
344
+						$this->message_type(),
345
+						$this->messenger()
346
+					)
347
+				);
348
+			}
349
+		}
350
+		return $valid;
351
+	}
352
+
353
+
354
+	/**
355
+	 * This returns the set localized label for the message type on this message.
356
+	 * Note, if unable to retrieve the EE_message_type object then will just return the message type slug saved
357
+	 * with this message.
358
+	 *
359
+	 * @param   bool $plural whether to return the plural label or not.
360
+	 * @return string
361
+	 */
362
+	public function message_type_label($plural = false)
363
+	{
364
+		$label_type   = $plural ? 'plural' : 'singular';
365
+		$message_type = $this->message_type_object();
366
+		return $message_type instanceof EE_message_type ? $message_type->label[$label_type] : str_replace(
367
+			'_',
368
+			' ',
369
+			$this->message_type()
370
+		);
371
+	}
372
+
373
+
374
+	/**
375
+	 * Gets context
376
+	 *
377
+	 * @return string
378
+	 */
379
+	public function context()
380
+	{
381
+		return $this->get('MSG_context');
382
+	}
383
+
384
+
385
+	/**
386
+	 * This returns the corresponding localized label for the given context slug, if possible from installed message
387
+	 * types. Otherwise, this will just return the set context slug on this object.
388
+	 *
389
+	 * @return string
390
+	 */
391
+	public function context_label()
392
+	{
393
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
394
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
395
+		$contexts                 = $message_resource_manager->get_all_contexts();
396
+		return isset($contexts[$this->context()]) ? $contexts[$this->context()] : $this->context();
397
+	}
398
+
399
+
400
+	/**
401
+	 * Sets context
402
+	 *
403
+	 * @param string $context
404
+	 */
405
+	public function set_context($context)
406
+	{
407
+		$this->set('MSG_context', $context);
408
+	}
409
+
410
+
411
+	/**
412
+	 * Gets recipient_ID
413
+	 *
414
+	 * @return int
415
+	 */
416
+	public function recipient_ID()
417
+	{
418
+		return $this->get('MSG_recipient_ID');
419
+	}
420
+
421
+
422
+	/**
423
+	 * Sets recipient_ID
424
+	 *
425
+	 * @param string $recipient_ID
426
+	 */
427
+	public function set_recipient_ID($recipient_ID)
428
+	{
429
+		$this->set('MSG_recipient_ID', $recipient_ID);
430
+	}
431
+
432
+
433
+	/**
434
+	 * Gets recipient_type
435
+	 *
436
+	 * @return string
437
+	 */
438
+	public function recipient_type()
439
+	{
440
+		return $this->get('MSG_recipient_type');
441
+	}
442
+
443
+
444
+	/**
445
+	 * Return the related object matching the recipient type and ID.
446
+	 *
447
+	 * @return EE_Base_Class | null
448
+	 */
449
+	public function recipient_object()
450
+	{
451
+		if ( ! $this->recipient_type() || ! $this->recipient_ID()) {
452
+			return null;
453
+		}
454
+
455
+		return $this->get_first_related($this->recipient_type());
456
+	}
457
+
458
+
459
+	/**
460
+	 * Sets recipient_type
461
+	 *
462
+	 * @param string $recipient_type
463
+	 */
464
+	public function set_recipient_type($recipient_type)
465
+	{
466
+		$this->set('MSG_recipient_type', $recipient_type);
467
+	}
468
+
469
+
470
+	/**
471
+	 * Gets content
472
+	 *
473
+	 * @return string
474
+	 */
475
+	public function content()
476
+	{
477
+		return $this->get('MSG_content');
478
+	}
479
+
480
+
481
+	/**
482
+	 * Sets content
483
+	 *
484
+	 * @param string $content
485
+	 */
486
+	public function set_content($content)
487
+	{
488
+		$this->set('MSG_content', $content);
489
+	}
490
+
491
+
492
+	/**
493
+	 * Gets subject
494
+	 *
495
+	 * @return string
496
+	 */
497
+	public function subject()
498
+	{
499
+		return $this->get('MSG_subject');
500
+	}
501
+
502
+
503
+	/**
504
+	 * Sets subject
505
+	 *
506
+	 * @param string $subject
507
+	 */
508
+	public function set_subject($subject)
509
+	{
510
+		$this->set('MSG_subject', $subject);
511
+	}
512
+
513
+
514
+	/**
515
+	 * Gets to
516
+	 *
517
+	 * @return string
518
+	 */
519
+	public function to()
520
+	{
521
+		$to = $this->get('MSG_to');
522
+		return empty($to) ? __('No recipient', 'event_espresso') : $to;
523
+	}
524
+
525
+
526
+	/**
527
+	 * Sets to
528
+	 *
529
+	 * @param string $to
530
+	 */
531
+	public function set_to($to)
532
+	{
533
+		$this->set('MSG_to', $to);
534
+	}
535
+
536
+
537
+	/**
538
+	 * Gets from
539
+	 *
540
+	 * @return string
541
+	 */
542
+	public function from()
543
+	{
544
+		return $this->get('MSG_from');
545
+	}
546
+
547
+
548
+	/**
549
+	 * Sets from
550
+	 *
551
+	 * @param string $from
552
+	 */
553
+	public function set_from($from)
554
+	{
555
+		$this->set('MSG_from', $from);
556
+	}
557
+
558
+
559
+	/**
560
+	 * Gets priority
561
+	 *
562
+	 * @return int
563
+	 */
564
+	public function priority()
565
+	{
566
+		return $this->get('MSG_priority');
567
+	}
568
+
569
+
570
+	/**
571
+	 * Sets priority
572
+	 * Note.  Send Now Messengers always override any priority that may be set on a Message.  So
573
+	 * this method calls the send_now method to verify that.
574
+	 *
575
+	 * @param int $priority
576
+	 */
577
+	public function set_priority($priority)
578
+	{
579
+		$priority = $this->send_now() ? EEM_Message::priority_high : $priority;
580
+		parent::set('MSG_priority', $priority);
581
+	}
582
+
583
+
584
+	/**
585
+	 * Overrides parent::set method so we can capture any sets for priority.
586
+	 *
587
+	 * @see parent::set() for phpdocs
588
+	 * @param string $field_name
589
+	 * @param mixed  $field_value
590
+	 * @param bool   $use_default
591
+	 * @throws EE_Error
592
+	 */
593
+	public function set($field_name, $field_value, $use_default = false)
594
+	{
595
+		if ($field_name === 'MSG_priority') {
596
+			$this->set_priority($field_value);
597
+		}
598
+		parent::set($field_name, $field_value, $use_default);
599
+	}
600
+
601
+
602
+	/**
603
+	 * @return bool
604
+	 * @throws \EE_Error
605
+	 */
606
+	public function send_now()
607
+	{
608
+		$send_now = $this->valid_messenger() && $this->messenger_object()->send_now() ? EEM_Message::priority_high : $this->priority();
609
+		return $send_now === EEM_Message::priority_high ? true : false;
610
+	}
611
+
612
+
613
+	/**
614
+	 * Gets STS_ID
615
+	 *
616
+	 * @return string
617
+	 */
618
+	public function STS_ID()
619
+	{
620
+		return $this->get('STS_ID');
621
+	}
622
+
623
+
624
+	/**
625
+	 * Sets STS_ID
626
+	 *
627
+	 * @param string $STS_ID
628
+	 */
629
+	public function set_STS_ID($STS_ID)
630
+	{
631
+		$this->set('STS_ID', $STS_ID);
632
+	}
633
+
634
+
635
+	/**
636
+	 * Gets created
637
+	 *
638
+	 * @return string
639
+	 */
640
+	public function created()
641
+	{
642
+		return $this->get('MSG_created');
643
+	}
644
+
645
+
646
+	/**
647
+	 * Sets created
648
+	 *
649
+	 * @param string $created
650
+	 */
651
+	public function set_created($created)
652
+	{
653
+		$this->set('MSG_created', $created);
654
+	}
655
+
656
+
657
+	/**
658
+	 * Gets modified
659
+	 *
660
+	 * @return string
661
+	 */
662
+	public function modified()
663
+	{
664
+		return $this->get('MSG_modified');
665
+	}
666
+
667
+
668
+	/**
669
+	 * Sets modified
670
+	 *
671
+	 * @param string $modified
672
+	 */
673
+	public function set_modified($modified)
674
+	{
675
+		$this->set('MSG_modified', $modified);
676
+	}
677
+
678
+
679
+	/**
680
+	 * Sets generation data for this message.
681
+	 *
682
+	 * @param mixed $data
683
+	 */
684
+	public function set_generation_data($data)
685
+	{
686
+		$this->set_field_or_extra_meta('MSG_generation_data', $data);
687
+	}
688
+
689
+
690
+	/**
691
+	 * Returns any set generation data for this message.
692
+	 *
693
+	 * @return mixed|null
694
+	 */
695
+	public function get_generation_data()
696
+	{
697
+		return $this->get_field_or_extra_meta('MSG_generation_data');
698
+	}
699
+
700
+
701
+	/**
702
+	 * Gets any error message.
703
+	 *
704
+	 * @return mixed|null
705
+	 */
706
+	public function error_message()
707
+	{
708
+		return $this->get_field_or_extra_meta('MSG_error');
709
+	}
710
+
711
+
712
+	/**
713
+	 * Sets an error message.
714
+	 *
715
+	 * @param $message
716
+	 * @return bool|int
717
+	 */
718
+	public function set_error_message($message)
719
+	{
720
+		return $this->set_field_or_extra_meta('MSG_error', $message);
721
+	}
722
+
723
+
724
+	/**
725
+	 * This retrieves the associated template pack with this message.
726
+	 *
727
+	 * @return EE_Messages_Template_Pack | null
728
+	 */
729
+	public function get_template_pack()
730
+	{
731
+		/**
732
+		 * This is deprecated functionality that will be removed eventually but included here now for backward compat.
733
+		 */
734
+		if ( ! empty($this->template_pack)) {
735
+			return $this->template_pack;
736
+		}
737
+		/** @type EE_Message_Template_Group $grp */
738
+		$grp = $this->get_first_related('Message_Template_Group');
739
+		//if no group then let's try to get the first related group by internal messenger and message type (will use global grp).
740
+		if ( ! $grp instanceof EE_Message_Template_Group) {
741
+			$grp = EEM_Message_Template_Group::instance()->get_one(
742
+				array(
743
+					array(
744
+						'MTP_messenger'    => $this->messenger(),
745
+						'MTP_message_type' => $this->message_type(),
746
+						'MTP_is_global'    => true,
747
+					),
748
+				)
749
+			);
750
+		}
751
+
752
+		return $grp instanceof EE_Message_Template_Group ? $grp->get_template_pack() : null;
753
+	}
754
+
755
+
756
+	/**
757
+	 * Retrieves the variation used for generating this message.
758
+	 *
759
+	 * @return string
760
+	 */
761
+	public function get_template_pack_variation()
762
+	{
763
+		/**
764
+		 * This is deprecated functionality that will be removed eventually but included here now for backward compat.
765
+		 */
766
+		if ( ! empty($this->template_variation)) {
767
+			return $this->template_variation;
768
+		}
769
+
770
+		/** @type EE_Message_Template_Group $grp */
771
+		$grp = $this->get_first_related('Message_Template_Group');
772
+
773
+		//if no group then let's try to get the first related group by internal messenger and message type (will use global grp).
774
+		if ( ! $grp instanceof EE_Message_Template_Group) {
775
+			$grp = EEM_Message_Template_Group::instance()->get_one(
776
+				array(
777
+					array(
778
+						'MTP_messenger'    => $this->messenger(),
779
+						'MTP_message_type' => $this->message_type(),
780
+						'MTP_is_global'    => true,
781
+					),
782
+				)
783
+			);
784
+		}
785
+
786
+		return $grp instanceof EE_Message_Template_Group ? $grp->get_template_pack_variation() : '';
787
+	}
788
+
789
+	/**
790
+	 * Return the link to the admin details for the object.
791
+	 *
792
+	 * @return string
793
+	 */
794
+	public function get_admin_details_link()
795
+	{
796
+		EE_Registry::instance()->load_helper('URL');
797
+		EE_Registry::instance()->load_helper('MSG_Template');
798
+		switch ($this->STS_ID()) {
799
+			case EEM_Message::status_failed :
800
+			case EEM_Message::status_debug_only :
801
+				return EEH_MSG_Template::generate_error_display_trigger($this);
802
+				break;
803
+
804
+			case EEM_Message::status_sent :
805
+				return EEH_MSG_Template::generate_browser_trigger($this);
806
+				break;
807
+
808
+			default :
809
+				return '';
810
+		}
811
+	}
812
+
813
+	/**
814
+	 * Returns the link to the editor for the object.  Sometimes this is the same as the details.
815
+	 *
816
+	 * @return string
817
+	 */
818
+	public function get_admin_edit_link()
819
+	{
820
+		return $this->get_admin_details_link();
821
+	}
822
+
823
+	/**
824
+	 * Returns the link to a settings page for the object.
825
+	 *
826
+	 * @return string
827
+	 */
828
+	public function get_admin_settings_link()
829
+	{
830
+		EE_Registry::instance()->load_helper('URL');
831
+		return EEH_URL::add_query_args_and_nonce(
832
+			array(
833
+				'page'   => 'espresso_messages',
834
+				'action' => 'settings',
835
+			),
836
+			admin_url('admin.php')
837
+		);
838
+	}
839
+
840
+	/**
841
+	 * Returns the link to the "overview" for the object (typically the "list table" view).
842
+	 *
843
+	 * @return string
844
+	 */
845
+	public function get_admin_overview_link()
846
+	{
847
+		EE_Registry::instance()->load_helper('URL');
848
+		return EEH_URL::add_query_args_and_nonce(
849
+			array(
850
+				'page'   => 'espresso_messages',
851
+				'action' => 'default',
852
+			),
853
+			admin_url('admin.php')
854
+		);
855
+	}
856
+
857
+
858
+	/**
859
+	 * This sets the EEM_Message::status_messenger_executing class on the message and the appropriate error message for
860
+	 * it.
861
+	 * Note this also SAVES the current message object to the db because it adds an error message to accompany the status.
862
+	 *
863
+	 */
864
+	public function set_messenger_is_executing()
865
+	{
866
+		$this->set_STS_ID( EEM_Message::status_messenger_executing );
867
+		$this->set_error_message(
868
+			esc_html__(
869
+				'A message with this status indicates that there was a problem that occurred while the message was being
870 870
                 processed by the messenger.  It is still possible that the message was sent successfully, but at some
871 871
                 point during the processing there was a failure.  This usually is indicative of a timeout issue with PHP 
872 872
                 or memory limits being reached.  If you see this repeatedly you may want to consider upgrading the memory 
873 873
                 available to PHP on your server.',
874
-                'event_espresso'
875
-            )
876
-        );
877
-    }
874
+				'event_espresso'
875
+			)
876
+		);
877
+	}
878 878
 }
879 879
 /* End of file EE_Message.class.php */
880 880
 /* Location: /core/db_classes/EE_Message.class.php */
881 881
\ No newline at end of file
Please login to merge, or discard this patch.
core/libraries/messages/EE_Messages_Queue.lib.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -603,7 +603,7 @@
 block discarded – undo
603 603
      * @param EE_Message      $message
604 604
      * @param EE_messenger    $messenger
605 605
      * @param EE_message_type $message_type
606
-     * @param                 $test_send
606
+     * @param                 boolean $test_send
607 607
      * @return bool   true means all went well, false means, not so much.
608 608
      */
609 609
     protected function _do_preview(
Please login to merge, or discard this patch.
Indentation   +689 added lines, -689 removed lines patch added patch discarded remove patch
@@ -2,7 +2,7 @@  discard block
 block discarded – undo
2 2
 use \EventEspresso\core\exceptions\SendMessageException;
3 3
 
4 4
 if (! defined('EVENT_ESPRESSO_VERSION')) {
5
-    exit('No direct script access allowed');
5
+	exit('No direct script access allowed');
6 6
 }
7 7
 
8 8
 /**
@@ -18,693 +18,693 @@  discard block
 block discarded – undo
18 18
 {
19 19
 
20 20
 
21
-    /**
22
-     * @type    string  reference for sending action
23
-     */
24
-    const action_sending = 'sending';
25
-
26
-    /**
27
-     * @type    string  reference for generation action
28
-     */
29
-    const action_generating = 'generation';
30
-
31
-
32
-    /**
33
-     * @type EE_Message_Repository $_message_repository
34
-     */
35
-    protected $_message_repository;
36
-
37
-    /**
38
-     * Sets the limit of how many messages are generated per process.
39
-     *
40
-     * @type int
41
-     */
42
-    protected $_batch_count;
43
-
44
-
45
-    /**
46
-     * This is an array of cached queue items being stored in this object.
47
-     * The array keys will be the ID of the EE_Message in the db if saved.  If the EE_Message
48
-     * is not saved to the db then its key will be an increment of "UNS" (i.e. UNS1, UNS2 etc.)
49
-     *
50
-     * @type EE_Message[]
51
-     */
52
-    protected $_cached_queue_items;
53
-
54
-    /**
55
-     * Tracks the number of unsaved queue items.
56
-     *
57
-     * @type int
58
-     */
59
-    protected $_unsaved_count = 0;
60
-
61
-    /**
62
-     * used to record if a do_messenger_hooks has already been called for a message type.  This prevents multiple
63
-     * hooks getting fired if users have setup their action/filter hooks to prevent duplicate calls.
64
-     *
65
-     * @type array
66
-     */
67
-    protected $_did_hook = array();
68
-
69
-
70
-    /**
71
-     * Constructor.
72
-     * Setup all the initial properties and load a EE_Message_Repository.
73
-     *
74
-     * @param \EE_Message_Repository $message_repository
75
-     */
76
-    public function __construct(EE_Message_Repository $message_repository)
77
-    {
78
-        $this->_batch_count        = apply_filters('FHEE__EE_Messages_Queue___batch_count', 50);
79
-        $this->_message_repository = $message_repository;
80
-    }
81
-
82
-
83
-    /**
84
-     * Add a EE_Message object to the queue
85
-     *
86
-     * @param EE_Message $message
87
-     * @param array      $data         This will be an array of data to attach to the object in the repository.  If the
88
-     *                                 object is persisted, this data will be saved on an extra_meta object related to
89
-     *                                 EE_Message.
90
-     * @param  bool      $preview      Whether this EE_Message represents a preview or not.
91
-     * @param  bool      $test_send    This indicates whether to do a test send instead of actual send. A test send will
92
-     *                                 use the messenger send method but typically is based on preview data.
93
-     * @return bool          Whether the message was successfully added to the repository or not.
94
-     */
95
-    public function add(EE_Message $message, $data = array(), $preview = false, $test_send = false)
96
-    {
97
-        $data['preview']   = $preview;
98
-        $data['test_send'] = $test_send;
99
-        return $this->_message_repository->add($message, $data);
100
-    }
101
-
102
-
103
-    /**
104
-     * Removes EE_Message from _queue that matches the given EE_Message if the pointer is on a matching EE_Message
105
-     *
106
-     * @param EE_Message $message The message to detach from the queue
107
-     * @param bool       $persist This flag indicates whether to attempt to delete the object from the db as well.
108
-     * @return bool
109
-     */
110
-    public function remove(EE_Message $message, $persist = false)
111
-    {
112
-        if ($persist && $this->_message_repository->current() !== $message) {
113
-            //get pointer on right message
114
-            if ($this->_message_repository->has($message)) {
115
-                $this->_message_repository->rewind();
116
-                while ($this->_message_repository->valid()) {
117
-                    if ($this->_message_repository->current() === $message) {
118
-                        break;
119
-                    }
120
-                    $this->_message_repository->next();
121
-                }
122
-            } else {
123
-                return false;
124
-            }
125
-        }
126
-        return $persist ? $this->_message_repository->delete() : $this->_message_repository->remove($message);
127
-    }
128
-
129
-
130
-    /**
131
-     * Persists all queued EE_Message objects to the db.
132
-     *
133
-     * @param bool $do_hooks_only       @see EE_Message_Repository::saveAll
134
-     * @return array @see EE_Messages_Repository::saveAll() for return values.
135
-     */
136
-    public function save($do_hooks_only = false)
137
-    {
138
-        return $this->_message_repository->saveAll($do_hooks_only);
139
-    }
140
-
141
-
142
-    /**
143
-     * @return EE_Message_Repository
144
-     */
145
-    public function get_message_repository()
146
-    {
147
-        return $this->_message_repository;
148
-    }
149
-
150
-
151
-    /**
152
-     * This does the following things:
153
-     * 1. Checks if there is a lock on generation (prevents race conditions).  If there is a lock then exits (return
154
-     * false).
155
-     * 2. If no lock, sets lock, then retrieves a batch of non-generated EE_Message objects and adds to queue
156
-     * 3. Returns bool.  True = batch ready.  False = no batch ready (or nothing available for generation).
157
-     * Note: Callers should make sure they release the lock otherwise batch generation will be prevented from
158
-     * continuing. The lock is on a transient that is set to expire after one hour as a fallback in case locks are not
159
-     * removed.
160
-     *
161
-     * @return bool  true if successfully retrieved batch, false no batch ready.
162
-     */
163
-    public function get_batch_to_generate()
164
-    {
165
-        if ($this->is_locked(EE_Messages_Queue::action_generating)) {
166
-            return false;
167
-        }
168
-
169
-        //lock batch generation to prevent race conditions.
170
-        $this->lock_queue(EE_Messages_Queue::action_generating);
171
-
172
-        $query_args = array(
173
-            // key 0 = where conditions
174
-            0          => array('STS_ID' => EEM_Message::status_incomplete),
175
-            'order_by' => $this->_get_priority_orderby(),
176
-            'limit'    => $this->_batch_count,
177
-        );
178
-        $messages   = EEM_Message::instance()->get_all($query_args);
179
-
180
-        if ( ! $messages) {
181
-            return false; //nothing to generate
182
-        }
183
-
184
-        foreach ($messages as $message) {
185
-            if ($message instanceof EE_Message) {
186
-                $data = $message->all_extra_meta_array();
187
-                $this->add($message, $data);
188
-            }
189
-        }
190
-        return true;
191
-    }
192
-
193
-
194
-    /**
195
-     * This does the following things:
196
-     * 1. Checks if there is a lock on sending (prevents race conditions).  If there is a lock then exits (return
197
-     * false).
198
-     * 2. Grabs the allowed number of messages to send for the rate_limit.  If cannot send any more messages, then
199
-     * return false.
200
-     * 2. If no lock, sets lock, then retrieves a batch of EE_Message objects, adds to queue and triggers execution.
201
-     * 3. On success or unsuccessful send, sets status appropriately.
202
-     * 4. Saves messages via the queue
203
-     * 5. Releases lock.
204
-     *
205
-     * @return bool  true on success, false if something preventing sending (i.e. lock set).  Note: true does not
206
-     *               necessarily mean that all messages were successfully sent.  It just means that this method
207
-     *               successfully completed. On true, client may want to call $this->count_STS_in_queue(
208
-     *               EEM_Message::status_failed ) to see if any failed EE_Message objects.  Each failed message object
209
-     *               will also have a saved error message on it to assist with notifying user.
210
-     */
211
-    public function get_to_send_batch_and_send()
212
-    {
213
-        $rate_limit = $this->get_rate_limit();
214
-        if ($rate_limit < 1 || $this->is_locked(EE_Messages_Queue::action_sending)) {
215
-            return false;
216
-        }
217
-
218
-        $this->lock_queue(EE_Messages_Queue::action_sending);
219
-
220
-        $batch = $this->_batch_count < $rate_limit ? $this->_batch_count : $rate_limit;
221
-
222
-        $query_args = array(
223
-            // key 0 = where conditions
224
-            0          => array('STS_ID' => array('IN', EEM_Message::instance()->stati_indicating_to_send())),
225
-            'order_by' => $this->_get_priority_orderby(),
226
-            'limit'    => $batch,
227
-        );
228
-
229
-        $messages_to_send = EEM_Message::instance()->get_all($query_args);
230
-
231
-
232
-        //any to send?
233
-        if ( ! $messages_to_send) {
234
-            $this->unlock_queue(EE_Messages_Queue::action_sending);
235
-            return false;
236
-        }
237
-
238
-        $queue_count = 0;
239
-
240
-        //add to queue.
241
-        foreach ($messages_to_send as $message) {
242
-            if ($message instanceof EE_Message) {
243
-                $queue_count++;
244
-                $this->add($message);
245
-            }
246
-        }
247
-
248
-        //send messages  (this also updates the rate limit)
249
-        $this->execute();
250
-
251
-        //release lock
252
-        $this->unlock_queue(EE_Messages_Queue::action_sending);
253
-        //update rate limit
254
-        $this->set_rate_limit($queue_count);
255
-        return true;
256
-    }
257
-
258
-
259
-    /**
260
-     * Locks the queue so that no other queues can call the "batch" methods.
261
-     *
262
-     * @param   string $type The type of queue being locked.
263
-     */
264
-    public function lock_queue($type = EE_Messages_Queue::action_generating)
265
-    {
266
-        update_option($this->_get_lock_key($type), $this->_get_lock_expiry($type));
267
-    }
268
-
269
-
270
-    /**
271
-     * Unlocks the queue so that batch methods can be used.
272
-     *
273
-     * @param   string $type The type of queue being unlocked.
274
-     */
275
-    public function unlock_queue($type = EE_Messages_Queue::action_generating)
276
-    {
277
-        delete_option($this->_get_lock_key($type));
278
-    }
279
-
280
-
281
-    /**
282
-     * Retrieve the key used for the lock transient.
283
-     *
284
-     * @param string $type The type of lock.
285
-     * @return string
286
-     */
287
-    protected function _get_lock_key($type = EE_Messages_Queue::action_generating)
288
-    {
289
-        return '_ee_lock_' . $type;
290
-    }
291
-
292
-
293
-    /**
294
-     * Retrieve the expiry time for the lock transient.
295
-     *
296
-     * @param string $type The type of lock
297
-     * @return int   time to expiry in seconds.
298
-     */
299
-    protected function _get_lock_expiry($type = EE_Messages_Queue::action_generating)
300
-    {
301
-        return time() + (int) apply_filters('FHEE__EE_Messages_Queue__lock_expiry', HOUR_IN_SECONDS, $type);
302
-    }
303
-
304
-
305
-    /**
306
-     * Returns the key used for rate limit transient.
307
-     *
308
-     * @return string
309
-     */
310
-    protected function _get_rate_limit_key()
311
-    {
312
-        return '_ee_rate_limit';
313
-    }
314
-
315
-
316
-    /**
317
-     * Returns the rate limit expiry time.
318
-     *
319
-     * @return int
320
-     */
321
-    protected function _get_rate_limit_expiry()
322
-    {
323
-        return time() + (int) apply_filters('FHEE__EE_Messages_Queue__rate_limit_expiry', HOUR_IN_SECONDS);
324
-    }
325
-
326
-
327
-    /**
328
-     * Returns the default rate limit for sending messages.
329
-     *
330
-     * @return int
331
-     */
332
-    protected function _default_rate_limit()
333
-    {
334
-        return (int) apply_filters('FHEE__EE_Messages_Queue___rate_limit', 200);
335
-    }
336
-
337
-
338
-    /**
339
-     * Return the orderby array for priority.
340
-     *
341
-     * @return array
342
-     */
343
-    protected function _get_priority_orderby()
344
-    {
345
-        return array(
346
-            'MSG_priority' => 'ASC',
347
-            'MSG_modified' => 'DESC',
348
-        );
349
-    }
350
-
351
-
352
-    /**
353
-     * Returns whether batch methods are "locked" or not.
354
-     *
355
-     * @param  string $type The type of lock being checked for.
356
-     * @return bool
357
-     */
358
-    public function is_locked($type = EE_Messages_Queue::action_generating)
359
-    {
360
-        $lock = (int) get_option($this->_get_lock_key($type), 0);
361
-        /**
362
-         * This filters the default is_locked behaviour.
363
-         */
364
-        $is_locked = filter_var(
365
-            apply_filters(
366
-                'FHEE__EE_Messages_Queue__is_locked',
367
-                $lock > time(),
368
-                $this
369
-            ),
370
-            FILTER_VALIDATE_BOOLEAN
371
-        );
372
-
373
-        /**
374
-         * @see usage of this filter in EE_Messages_Queue::initiate_request_by_priority() method.
375
-         *            Also implemented here because messages processed on the same request should not have any locks applied.
376
-         */
377
-        if (
378
-            apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
379
-            || EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
380
-        ) {
381
-            $is_locked = false;
382
-        }
383
-
384
-
385
-        return $is_locked;
386
-    }
387
-
388
-
389
-    /**
390
-     * Retrieves the rate limit that may be cached as a transient.
391
-     * If the rate limit is not set, then this sets the default rate limit and expiry and returns it.
392
-     *
393
-     * @param bool $return_expiry  If true then return the expiry time not the rate_limit.
394
-     * @return int
395
-     */
396
-    protected function get_rate_limit($return_expiry = false)
397
-    {
398
-        $stored_rate_info = get_option($this->_get_rate_limit_key(), array());
399
-        $rate_limit = isset($stored_rate_info[0])
400
-            ? (int) $stored_rate_info[0]
401
-            : 0;
402
-        $expiry = isset($stored_rate_info[1])
403
-            ? (int) $stored_rate_info[1]
404
-            : 0;
405
-        //set the default for tracking?
406
-        if (empty($stored_rate_info) || time() > $expiry) {
407
-            $expiry = $this->_get_rate_limit_expiry();
408
-            $rate_limit = $this->_default_rate_limit();
409
-            update_option($this->_get_rate_limit_key(), array($rate_limit, $expiry));
410
-        }
411
-        return $return_expiry ? $expiry : $rate_limit;
412
-    }
413
-
414
-
415
-    /**
416
-     * This updates existing rate limit with the new limit which is the old minus the batch.
417
-     *
418
-     * @param int $batch_completed This sets the new rate limit based on the given batch that was completed.
419
-     */
420
-    protected function set_rate_limit($batch_completed)
421
-    {
422
-        //first get the most up to date rate limit (in case its expired and reset)
423
-        $rate_limit = $this->get_rate_limit();
424
-        $expiry = $this->get_rate_limit(true);
425
-        $new_limit  = $rate_limit - $batch_completed;
426
-        //updating the transient option directly to avoid resetting the expiry.
427
-
428
-        update_option($this->_get_rate_limit_key(), array($new_limit, $expiry));
429
-    }
430
-
431
-
432
-    /**
433
-     * This method checks the queue for ANY EE_Message objects with a priority matching the given priority passed in.
434
-     * If that exists, then we immediately initiate a non-blocking request to do the requested action type.
435
-     * Note: Keep in mind that there is the possibility that the request will not execute if there is already another
436
-     * request running on a queue for the given task.
437
-     *
438
-     * @param string $task     This indicates what type of request is going to be initiated.
439
-     * @param int    $priority This indicates the priority that triggers initiating the request.
440
-     */
441
-    public function initiate_request_by_priority($task = 'generate', $priority = EEM_Message::priority_high)
442
-    {
443
-        //determine what status is matched with the priority as part of the trigger conditions.
444
-        $status = $task == 'generate'
445
-            ? EEM_Message::status_incomplete
446
-            : EEM_Message::instance()->stati_indicating_to_send();
447
-        // always make sure we save because either this will get executed immediately on a separate request
448
-        // or remains in the queue for the regularly scheduled queue batch.
449
-        $this->save();
450
-        /**
451
-         * This filter/option allows users to override processing of messages on separate requests and instead have everything
452
-         * happen on the same request.  If this is utilized remember:
453
-         * - message priorities don't matter
454
-         * - existing unprocessed messages in the queue will not get processed unless manually triggered.
455
-         * - things will be perceived to take longer to happen for end users (i.e. registrations) because of the additional
456
-         *   processing happening on the same request.
457
-         * - any race condition protection (locks) are removed because they don't apply when things are processed on
458
-         *   the same request.
459
-         */
460
-        if (
461
-            apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
462
-            || EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
463
-        ) {
464
-            $messages_processor = EE_Registry::instance()->load_lib('Messages_Processor');
465
-            if ($messages_processor instanceof EE_Messages_Processor) {
466
-                return $messages_processor->process_immediately_from_queue($this);
467
-            }
468
-            //if we get here then that means the messages processor couldn't be loaded so messages will just remain
469
-            //queued for manual triggering by end user.
470
-        }
471
-
472
-        if ($this->_message_repository->count_by_priority_and_status($priority, $status)) {
473
-            EE_Messages_Scheduler::initiate_scheduled_non_blocking_request($task);
474
-        }
475
-    }
476
-
477
-
478
-    /**
479
-     *  Loops through the EE_Message objects in the _queue and calls the messenger send methods for each message.
480
-     *
481
-     * @param   bool     $save                    Used to indicate whether to save the message queue after sending
482
-     *                                            (default will save).
483
-     * @param   mixed    $sending_messenger       (optional) When the sending messenger is different than
484
-     *                                            what is on the EE_Message object in the queue.
485
-     *                                            For instance, showing the browser view of an email message,
486
-     *                                            or giving a pdf generated view of an html document.
487
-     *                                            This should be an instance of EE_messenger but if you call this
488
-     *                                            method
489
-     *                                            intending it to be a sending messenger but a valid one could not be
490
-     *                                            retrieved then send in an instance of EE_Error that contains the
491
-     *                                            related error message.
492
-     * @param   bool|int $by_priority             When set, this indicates that only messages
493
-     *                                            matching the given priority should be executed.
494
-     * @return int        Number of messages sent.  Note, 0 does not mean that no messages were processed.
495
-     *                                            Also, if the messenger is an request type messenger (or a preview),
496
-     *                                            its entirely possible that the messenger will exit before
497
-     */
498
-    public function execute($save = true, $sending_messenger = null, $by_priority = false)
499
-    {
500
-        $messages_sent   = 0;
501
-        $this->_did_hook = array();
502
-        $this->_message_repository->rewind();
503
-
504
-        while ($this->_message_repository->valid()) {
505
-            $error_messages = array();
506
-            /** @type EE_Message $message */
507
-            $message = $this->_message_repository->current();
508
-            //only process things that are queued for sending
509
-            if (! in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_to_send())) {
510
-                $this->_message_repository->next();
511
-                continue;
512
-            }
513
-            //if $by_priority is set and does not match then continue;
514
-            if ($by_priority && $by_priority != $message->priority()) {
515
-                $this->_message_repository->next();
516
-                continue;
517
-            }
518
-            //error checking
519
-            if (! $message->valid_messenger()) {
520
-                $error_messages[] = sprintf(
521
-                    __('The %s messenger is not active at time of sending.', 'event_espresso'),
522
-                    $message->messenger()
523
-                );
524
-            }
525
-            if (! $message->valid_message_type()) {
526
-                $error_messages[] = sprintf(
527
-                    __('The %s message type is not active at the time of sending.', 'event_espresso'),
528
-                    $message->message_type()
529
-                );
530
-            }
531
-            // if there was supposed to be a sending messenger for this message, but it was invalid/inactive,
532
-            // then it will instead be an EE_Error object, so let's check for that
533
-            if ($sending_messenger instanceof EE_Error) {
534
-                $error_messages[] = $sending_messenger->getMessage();
535
-            }
536
-            // if there are no errors, then let's process the message
537
-            if (empty($error_messages)) {
538
-                if ($save) {
539
-                    $message->set_messenger_is_executing();
540
-                }
541
-                if ($this->_process_message($message, $sending_messenger)) {
542
-                    $messages_sent++;
543
-                }
544
-            }
545
-            $this->_set_error_message($message, $error_messages);
546
-            //add modified time
547
-            $message->set_modified(time());
548
-            //we save each message after its processed to make sure its status persists in case PHP times-out or runs
549
-            //out of memory. @see https://events.codebasehq.com/projects/event-espresso/tickets/10281
550
-            if ($save) {
551
-                $message->save();
552
-            }
553
-
554
-            $this->_message_repository->next();
555
-        }
556
-        if ($save) {
557
-            $this->save(true);
558
-        }
559
-        return $messages_sent;
560
-    }
561
-
562
-
563
-    /**
564
-     * _process_message
565
-     *
566
-     * @param EE_Message $message
567
-     * @param mixed      $sending_messenger (optional)
568
-     * @return bool
569
-     */
570
-    protected function _process_message(EE_Message $message, $sending_messenger = null)
571
-    {
572
-        // these *should* have been validated in the execute() method above
573
-        $messenger    = $message->messenger_object();
574
-        $message_type = $message->message_type_object();
575
-        //do actions for sending messenger if it differs from generating messenger and swap values.
576
-        if (
577
-            $sending_messenger instanceof EE_messenger
578
-            && $messenger instanceof EE_messenger
579
-            && $sending_messenger->name != $messenger->name
580
-        ) {
581
-            $messenger->do_secondary_messenger_hooks($sending_messenger->name);
582
-            $messenger = $sending_messenger;
583
-        }
584
-        // send using messenger, but double check objects
585
-        if ($messenger instanceof EE_messenger && $message_type instanceof EE_message_type) {
586
-            //set hook for message type (but only if not using another messenger to send).
587
-            if ( ! isset($this->_did_hook[$message_type->name])) {
588
-                $message_type->do_messenger_hooks($messenger);
589
-                $this->_did_hook[$message_type->name] = 1;
590
-            }
591
-            //if preview then use preview method
592
-            return $this->_message_repository->is_preview()
593
-                ? $this->_do_preview($message, $messenger, $message_type, $this->_message_repository->is_test_send())
594
-                : $this->_do_send($message, $messenger, $message_type);
595
-        }
596
-        return false;
597
-    }
598
-
599
-
600
-    /**
601
-     * The intention of this method is to count how many EE_Message objects
602
-     * are in the queue with a given status.
603
-     * Example usage:
604
-     * After a caller calls the "EE_Message_Queue::execute()" method, the caller can check if there were any failed
605
-     * sends by calling $queue->count_STS_in_queue( EEM_Message_Queue::status_failed ).
606
-     *
607
-     * @param array|string $status Stati to check for in queue
608
-     * @return int  Count of EE_Message's matching the given status.
609
-     */
610
-    public function count_STS_in_queue($status)
611
-    {
612
-        $count  = 0;
613
-        $status = is_array($status) ? $status : array($status);
614
-        $this->_message_repository->rewind();
615
-        foreach ($this->_message_repository as $message) {
616
-            if (in_array($message->STS_ID(), $status)) {
617
-                $count++;
618
-            }
619
-        }
620
-        return $count;
621
-    }
622
-
623
-
624
-    /**
625
-     * Executes the get_preview method on the provided messenger.
626
-     *
627
-     * @param EE_Message      $message
628
-     * @param EE_messenger    $messenger
629
-     * @param EE_message_type $message_type
630
-     * @param                 $test_send
631
-     * @return bool   true means all went well, false means, not so much.
632
-     */
633
-    protected function _do_preview(
634
-        EE_Message $message,
635
-        EE_messenger $messenger,
636
-        EE_message_type $message_type,
637
-        $test_send
638
-    ) {
639
-        if ($preview = $messenger->get_preview($message, $message_type, $test_send)) {
640
-            if ( ! $test_send) {
641
-                $message->set_content($preview);
642
-            }
643
-            $message->set_STS_ID(EEM_Message::status_sent);
644
-            return true;
645
-        } else {
646
-            $message->set_STS_ID(EEM_Message::status_failed);
647
-            return false;
648
-        }
649
-    }
650
-
651
-
652
-    /**
653
-     * Executes the send method on the provided messenger
654
-     * EE_Messengers are expected to:
655
-     * - return true if the send was successful.
656
-     * - return false if the send was unsuccessful but can be tried again.
657
-     * - throw an Exception if the send was unsuccessful and cannot be tried again.
658
-     *
659
-     * @param EE_Message      $message
660
-     * @param EE_messenger    $messenger
661
-     * @param EE_message_type $message_type
662
-     * @return bool true means all went well, false means, not so much.
663
-     */
664
-    protected function _do_send(EE_Message $message, EE_messenger $messenger, EE_message_type $message_type)
665
-    {
666
-        try {
667
-            if ($messenger->send_message($message, $message_type)) {
668
-                $message->set_STS_ID(EEM_Message::status_sent);
669
-                return true;
670
-            } else {
671
-                $message->set_STS_ID(EEM_Message::status_retry);
672
-                return false;
673
-            }
674
-        } catch (SendMessageException $e) {
675
-            $message->set_STS_ID(EEM_Message::status_failed);
676
-            $message->set_error_message($e->getMessage());
677
-            return false;
678
-        }
679
-    }
680
-
681
-
682
-    /**
683
-     * This sets any necessary error messages on the message object and its status to failed.
684
-     *
685
-     * @param EE_Message $message
686
-     * @param array      $error_messages the response from the messenger.
687
-     */
688
-    protected function _set_error_message(EE_Message $message, $error_messages)
689
-    {
690
-        $error_messages = (array)$error_messages;
691
-        if (in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_failed_sending())) {
692
-            $notices          = EE_Error::has_notices();
693
-            $error_messages[] = __(
694
-                'Messenger and Message Type were valid and active, but the messenger send method failed.',
695
-                'event_espresso'
696
-            );
697
-            if ($notices === 1) {
698
-                $notices           = EE_Error::get_vanilla_notices();
699
-                $notices['errors'] = isset($notices['errors']) ? $notices['errors'] : array();
700
-                $error_messages[]  = implode("\n", $notices['errors']);
701
-            }
702
-        }
703
-        if (count($error_messages) > 0) {
704
-            $msg = __('Message was not executed successfully.', 'event_espresso');
705
-            $msg = $msg . "\n" . implode("\n", $error_messages);
706
-            $message->set_error_message($msg);
707
-        }
708
-    }
21
+	/**
22
+	 * @type    string  reference for sending action
23
+	 */
24
+	const action_sending = 'sending';
25
+
26
+	/**
27
+	 * @type    string  reference for generation action
28
+	 */
29
+	const action_generating = 'generation';
30
+
31
+
32
+	/**
33
+	 * @type EE_Message_Repository $_message_repository
34
+	 */
35
+	protected $_message_repository;
36
+
37
+	/**
38
+	 * Sets the limit of how many messages are generated per process.
39
+	 *
40
+	 * @type int
41
+	 */
42
+	protected $_batch_count;
43
+
44
+
45
+	/**
46
+	 * This is an array of cached queue items being stored in this object.
47
+	 * The array keys will be the ID of the EE_Message in the db if saved.  If the EE_Message
48
+	 * is not saved to the db then its key will be an increment of "UNS" (i.e. UNS1, UNS2 etc.)
49
+	 *
50
+	 * @type EE_Message[]
51
+	 */
52
+	protected $_cached_queue_items;
53
+
54
+	/**
55
+	 * Tracks the number of unsaved queue items.
56
+	 *
57
+	 * @type int
58
+	 */
59
+	protected $_unsaved_count = 0;
60
+
61
+	/**
62
+	 * used to record if a do_messenger_hooks has already been called for a message type.  This prevents multiple
63
+	 * hooks getting fired if users have setup their action/filter hooks to prevent duplicate calls.
64
+	 *
65
+	 * @type array
66
+	 */
67
+	protected $_did_hook = array();
68
+
69
+
70
+	/**
71
+	 * Constructor.
72
+	 * Setup all the initial properties and load a EE_Message_Repository.
73
+	 *
74
+	 * @param \EE_Message_Repository $message_repository
75
+	 */
76
+	public function __construct(EE_Message_Repository $message_repository)
77
+	{
78
+		$this->_batch_count        = apply_filters('FHEE__EE_Messages_Queue___batch_count', 50);
79
+		$this->_message_repository = $message_repository;
80
+	}
81
+
82
+
83
+	/**
84
+	 * Add a EE_Message object to the queue
85
+	 *
86
+	 * @param EE_Message $message
87
+	 * @param array      $data         This will be an array of data to attach to the object in the repository.  If the
88
+	 *                                 object is persisted, this data will be saved on an extra_meta object related to
89
+	 *                                 EE_Message.
90
+	 * @param  bool      $preview      Whether this EE_Message represents a preview or not.
91
+	 * @param  bool      $test_send    This indicates whether to do a test send instead of actual send. A test send will
92
+	 *                                 use the messenger send method but typically is based on preview data.
93
+	 * @return bool          Whether the message was successfully added to the repository or not.
94
+	 */
95
+	public function add(EE_Message $message, $data = array(), $preview = false, $test_send = false)
96
+	{
97
+		$data['preview']   = $preview;
98
+		$data['test_send'] = $test_send;
99
+		return $this->_message_repository->add($message, $data);
100
+	}
101
+
102
+
103
+	/**
104
+	 * Removes EE_Message from _queue that matches the given EE_Message if the pointer is on a matching EE_Message
105
+	 *
106
+	 * @param EE_Message $message The message to detach from the queue
107
+	 * @param bool       $persist This flag indicates whether to attempt to delete the object from the db as well.
108
+	 * @return bool
109
+	 */
110
+	public function remove(EE_Message $message, $persist = false)
111
+	{
112
+		if ($persist && $this->_message_repository->current() !== $message) {
113
+			//get pointer on right message
114
+			if ($this->_message_repository->has($message)) {
115
+				$this->_message_repository->rewind();
116
+				while ($this->_message_repository->valid()) {
117
+					if ($this->_message_repository->current() === $message) {
118
+						break;
119
+					}
120
+					$this->_message_repository->next();
121
+				}
122
+			} else {
123
+				return false;
124
+			}
125
+		}
126
+		return $persist ? $this->_message_repository->delete() : $this->_message_repository->remove($message);
127
+	}
128
+
129
+
130
+	/**
131
+	 * Persists all queued EE_Message objects to the db.
132
+	 *
133
+	 * @param bool $do_hooks_only       @see EE_Message_Repository::saveAll
134
+	 * @return array @see EE_Messages_Repository::saveAll() for return values.
135
+	 */
136
+	public function save($do_hooks_only = false)
137
+	{
138
+		return $this->_message_repository->saveAll($do_hooks_only);
139
+	}
140
+
141
+
142
+	/**
143
+	 * @return EE_Message_Repository
144
+	 */
145
+	public function get_message_repository()
146
+	{
147
+		return $this->_message_repository;
148
+	}
149
+
150
+
151
+	/**
152
+	 * This does the following things:
153
+	 * 1. Checks if there is a lock on generation (prevents race conditions).  If there is a lock then exits (return
154
+	 * false).
155
+	 * 2. If no lock, sets lock, then retrieves a batch of non-generated EE_Message objects and adds to queue
156
+	 * 3. Returns bool.  True = batch ready.  False = no batch ready (or nothing available for generation).
157
+	 * Note: Callers should make sure they release the lock otherwise batch generation will be prevented from
158
+	 * continuing. The lock is on a transient that is set to expire after one hour as a fallback in case locks are not
159
+	 * removed.
160
+	 *
161
+	 * @return bool  true if successfully retrieved batch, false no batch ready.
162
+	 */
163
+	public function get_batch_to_generate()
164
+	{
165
+		if ($this->is_locked(EE_Messages_Queue::action_generating)) {
166
+			return false;
167
+		}
168
+
169
+		//lock batch generation to prevent race conditions.
170
+		$this->lock_queue(EE_Messages_Queue::action_generating);
171
+
172
+		$query_args = array(
173
+			// key 0 = where conditions
174
+			0          => array('STS_ID' => EEM_Message::status_incomplete),
175
+			'order_by' => $this->_get_priority_orderby(),
176
+			'limit'    => $this->_batch_count,
177
+		);
178
+		$messages   = EEM_Message::instance()->get_all($query_args);
179
+
180
+		if ( ! $messages) {
181
+			return false; //nothing to generate
182
+		}
183
+
184
+		foreach ($messages as $message) {
185
+			if ($message instanceof EE_Message) {
186
+				$data = $message->all_extra_meta_array();
187
+				$this->add($message, $data);
188
+			}
189
+		}
190
+		return true;
191
+	}
192
+
193
+
194
+	/**
195
+	 * This does the following things:
196
+	 * 1. Checks if there is a lock on sending (prevents race conditions).  If there is a lock then exits (return
197
+	 * false).
198
+	 * 2. Grabs the allowed number of messages to send for the rate_limit.  If cannot send any more messages, then
199
+	 * return false.
200
+	 * 2. If no lock, sets lock, then retrieves a batch of EE_Message objects, adds to queue and triggers execution.
201
+	 * 3. On success or unsuccessful send, sets status appropriately.
202
+	 * 4. Saves messages via the queue
203
+	 * 5. Releases lock.
204
+	 *
205
+	 * @return bool  true on success, false if something preventing sending (i.e. lock set).  Note: true does not
206
+	 *               necessarily mean that all messages were successfully sent.  It just means that this method
207
+	 *               successfully completed. On true, client may want to call $this->count_STS_in_queue(
208
+	 *               EEM_Message::status_failed ) to see if any failed EE_Message objects.  Each failed message object
209
+	 *               will also have a saved error message on it to assist with notifying user.
210
+	 */
211
+	public function get_to_send_batch_and_send()
212
+	{
213
+		$rate_limit = $this->get_rate_limit();
214
+		if ($rate_limit < 1 || $this->is_locked(EE_Messages_Queue::action_sending)) {
215
+			return false;
216
+		}
217
+
218
+		$this->lock_queue(EE_Messages_Queue::action_sending);
219
+
220
+		$batch = $this->_batch_count < $rate_limit ? $this->_batch_count : $rate_limit;
221
+
222
+		$query_args = array(
223
+			// key 0 = where conditions
224
+			0          => array('STS_ID' => array('IN', EEM_Message::instance()->stati_indicating_to_send())),
225
+			'order_by' => $this->_get_priority_orderby(),
226
+			'limit'    => $batch,
227
+		);
228
+
229
+		$messages_to_send = EEM_Message::instance()->get_all($query_args);
230
+
231
+
232
+		//any to send?
233
+		if ( ! $messages_to_send) {
234
+			$this->unlock_queue(EE_Messages_Queue::action_sending);
235
+			return false;
236
+		}
237
+
238
+		$queue_count = 0;
239
+
240
+		//add to queue.
241
+		foreach ($messages_to_send as $message) {
242
+			if ($message instanceof EE_Message) {
243
+				$queue_count++;
244
+				$this->add($message);
245
+			}
246
+		}
247
+
248
+		//send messages  (this also updates the rate limit)
249
+		$this->execute();
250
+
251
+		//release lock
252
+		$this->unlock_queue(EE_Messages_Queue::action_sending);
253
+		//update rate limit
254
+		$this->set_rate_limit($queue_count);
255
+		return true;
256
+	}
257
+
258
+
259
+	/**
260
+	 * Locks the queue so that no other queues can call the "batch" methods.
261
+	 *
262
+	 * @param   string $type The type of queue being locked.
263
+	 */
264
+	public function lock_queue($type = EE_Messages_Queue::action_generating)
265
+	{
266
+		update_option($this->_get_lock_key($type), $this->_get_lock_expiry($type));
267
+	}
268
+
269
+
270
+	/**
271
+	 * Unlocks the queue so that batch methods can be used.
272
+	 *
273
+	 * @param   string $type The type of queue being unlocked.
274
+	 */
275
+	public function unlock_queue($type = EE_Messages_Queue::action_generating)
276
+	{
277
+		delete_option($this->_get_lock_key($type));
278
+	}
279
+
280
+
281
+	/**
282
+	 * Retrieve the key used for the lock transient.
283
+	 *
284
+	 * @param string $type The type of lock.
285
+	 * @return string
286
+	 */
287
+	protected function _get_lock_key($type = EE_Messages_Queue::action_generating)
288
+	{
289
+		return '_ee_lock_' . $type;
290
+	}
291
+
292
+
293
+	/**
294
+	 * Retrieve the expiry time for the lock transient.
295
+	 *
296
+	 * @param string $type The type of lock
297
+	 * @return int   time to expiry in seconds.
298
+	 */
299
+	protected function _get_lock_expiry($type = EE_Messages_Queue::action_generating)
300
+	{
301
+		return time() + (int) apply_filters('FHEE__EE_Messages_Queue__lock_expiry', HOUR_IN_SECONDS, $type);
302
+	}
303
+
304
+
305
+	/**
306
+	 * Returns the key used for rate limit transient.
307
+	 *
308
+	 * @return string
309
+	 */
310
+	protected function _get_rate_limit_key()
311
+	{
312
+		return '_ee_rate_limit';
313
+	}
314
+
315
+
316
+	/**
317
+	 * Returns the rate limit expiry time.
318
+	 *
319
+	 * @return int
320
+	 */
321
+	protected function _get_rate_limit_expiry()
322
+	{
323
+		return time() + (int) apply_filters('FHEE__EE_Messages_Queue__rate_limit_expiry', HOUR_IN_SECONDS);
324
+	}
325
+
326
+
327
+	/**
328
+	 * Returns the default rate limit for sending messages.
329
+	 *
330
+	 * @return int
331
+	 */
332
+	protected function _default_rate_limit()
333
+	{
334
+		return (int) apply_filters('FHEE__EE_Messages_Queue___rate_limit', 200);
335
+	}
336
+
337
+
338
+	/**
339
+	 * Return the orderby array for priority.
340
+	 *
341
+	 * @return array
342
+	 */
343
+	protected function _get_priority_orderby()
344
+	{
345
+		return array(
346
+			'MSG_priority' => 'ASC',
347
+			'MSG_modified' => 'DESC',
348
+		);
349
+	}
350
+
351
+
352
+	/**
353
+	 * Returns whether batch methods are "locked" or not.
354
+	 *
355
+	 * @param  string $type The type of lock being checked for.
356
+	 * @return bool
357
+	 */
358
+	public function is_locked($type = EE_Messages_Queue::action_generating)
359
+	{
360
+		$lock = (int) get_option($this->_get_lock_key($type), 0);
361
+		/**
362
+		 * This filters the default is_locked behaviour.
363
+		 */
364
+		$is_locked = filter_var(
365
+			apply_filters(
366
+				'FHEE__EE_Messages_Queue__is_locked',
367
+				$lock > time(),
368
+				$this
369
+			),
370
+			FILTER_VALIDATE_BOOLEAN
371
+		);
372
+
373
+		/**
374
+		 * @see usage of this filter in EE_Messages_Queue::initiate_request_by_priority() method.
375
+		 *            Also implemented here because messages processed on the same request should not have any locks applied.
376
+		 */
377
+		if (
378
+			apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
379
+			|| EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
380
+		) {
381
+			$is_locked = false;
382
+		}
383
+
384
+
385
+		return $is_locked;
386
+	}
387
+
388
+
389
+	/**
390
+	 * Retrieves the rate limit that may be cached as a transient.
391
+	 * If the rate limit is not set, then this sets the default rate limit and expiry and returns it.
392
+	 *
393
+	 * @param bool $return_expiry  If true then return the expiry time not the rate_limit.
394
+	 * @return int
395
+	 */
396
+	protected function get_rate_limit($return_expiry = false)
397
+	{
398
+		$stored_rate_info = get_option($this->_get_rate_limit_key(), array());
399
+		$rate_limit = isset($stored_rate_info[0])
400
+			? (int) $stored_rate_info[0]
401
+			: 0;
402
+		$expiry = isset($stored_rate_info[1])
403
+			? (int) $stored_rate_info[1]
404
+			: 0;
405
+		//set the default for tracking?
406
+		if (empty($stored_rate_info) || time() > $expiry) {
407
+			$expiry = $this->_get_rate_limit_expiry();
408
+			$rate_limit = $this->_default_rate_limit();
409
+			update_option($this->_get_rate_limit_key(), array($rate_limit, $expiry));
410
+		}
411
+		return $return_expiry ? $expiry : $rate_limit;
412
+	}
413
+
414
+
415
+	/**
416
+	 * This updates existing rate limit with the new limit which is the old minus the batch.
417
+	 *
418
+	 * @param int $batch_completed This sets the new rate limit based on the given batch that was completed.
419
+	 */
420
+	protected function set_rate_limit($batch_completed)
421
+	{
422
+		//first get the most up to date rate limit (in case its expired and reset)
423
+		$rate_limit = $this->get_rate_limit();
424
+		$expiry = $this->get_rate_limit(true);
425
+		$new_limit  = $rate_limit - $batch_completed;
426
+		//updating the transient option directly to avoid resetting the expiry.
427
+
428
+		update_option($this->_get_rate_limit_key(), array($new_limit, $expiry));
429
+	}
430
+
431
+
432
+	/**
433
+	 * This method checks the queue for ANY EE_Message objects with a priority matching the given priority passed in.
434
+	 * If that exists, then we immediately initiate a non-blocking request to do the requested action type.
435
+	 * Note: Keep in mind that there is the possibility that the request will not execute if there is already another
436
+	 * request running on a queue for the given task.
437
+	 *
438
+	 * @param string $task     This indicates what type of request is going to be initiated.
439
+	 * @param int    $priority This indicates the priority that triggers initiating the request.
440
+	 */
441
+	public function initiate_request_by_priority($task = 'generate', $priority = EEM_Message::priority_high)
442
+	{
443
+		//determine what status is matched with the priority as part of the trigger conditions.
444
+		$status = $task == 'generate'
445
+			? EEM_Message::status_incomplete
446
+			: EEM_Message::instance()->stati_indicating_to_send();
447
+		// always make sure we save because either this will get executed immediately on a separate request
448
+		// or remains in the queue for the regularly scheduled queue batch.
449
+		$this->save();
450
+		/**
451
+		 * This filter/option allows users to override processing of messages on separate requests and instead have everything
452
+		 * happen on the same request.  If this is utilized remember:
453
+		 * - message priorities don't matter
454
+		 * - existing unprocessed messages in the queue will not get processed unless manually triggered.
455
+		 * - things will be perceived to take longer to happen for end users (i.e. registrations) because of the additional
456
+		 *   processing happening on the same request.
457
+		 * - any race condition protection (locks) are removed because they don't apply when things are processed on
458
+		 *   the same request.
459
+		 */
460
+		if (
461
+			apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
462
+			|| EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
463
+		) {
464
+			$messages_processor = EE_Registry::instance()->load_lib('Messages_Processor');
465
+			if ($messages_processor instanceof EE_Messages_Processor) {
466
+				return $messages_processor->process_immediately_from_queue($this);
467
+			}
468
+			//if we get here then that means the messages processor couldn't be loaded so messages will just remain
469
+			//queued for manual triggering by end user.
470
+		}
471
+
472
+		if ($this->_message_repository->count_by_priority_and_status($priority, $status)) {
473
+			EE_Messages_Scheduler::initiate_scheduled_non_blocking_request($task);
474
+		}
475
+	}
476
+
477
+
478
+	/**
479
+	 *  Loops through the EE_Message objects in the _queue and calls the messenger send methods for each message.
480
+	 *
481
+	 * @param   bool     $save                    Used to indicate whether to save the message queue after sending
482
+	 *                                            (default will save).
483
+	 * @param   mixed    $sending_messenger       (optional) When the sending messenger is different than
484
+	 *                                            what is on the EE_Message object in the queue.
485
+	 *                                            For instance, showing the browser view of an email message,
486
+	 *                                            or giving a pdf generated view of an html document.
487
+	 *                                            This should be an instance of EE_messenger but if you call this
488
+	 *                                            method
489
+	 *                                            intending it to be a sending messenger but a valid one could not be
490
+	 *                                            retrieved then send in an instance of EE_Error that contains the
491
+	 *                                            related error message.
492
+	 * @param   bool|int $by_priority             When set, this indicates that only messages
493
+	 *                                            matching the given priority should be executed.
494
+	 * @return int        Number of messages sent.  Note, 0 does not mean that no messages were processed.
495
+	 *                                            Also, if the messenger is an request type messenger (or a preview),
496
+	 *                                            its entirely possible that the messenger will exit before
497
+	 */
498
+	public function execute($save = true, $sending_messenger = null, $by_priority = false)
499
+	{
500
+		$messages_sent   = 0;
501
+		$this->_did_hook = array();
502
+		$this->_message_repository->rewind();
503
+
504
+		while ($this->_message_repository->valid()) {
505
+			$error_messages = array();
506
+			/** @type EE_Message $message */
507
+			$message = $this->_message_repository->current();
508
+			//only process things that are queued for sending
509
+			if (! in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_to_send())) {
510
+				$this->_message_repository->next();
511
+				continue;
512
+			}
513
+			//if $by_priority is set and does not match then continue;
514
+			if ($by_priority && $by_priority != $message->priority()) {
515
+				$this->_message_repository->next();
516
+				continue;
517
+			}
518
+			//error checking
519
+			if (! $message->valid_messenger()) {
520
+				$error_messages[] = sprintf(
521
+					__('The %s messenger is not active at time of sending.', 'event_espresso'),
522
+					$message->messenger()
523
+				);
524
+			}
525
+			if (! $message->valid_message_type()) {
526
+				$error_messages[] = sprintf(
527
+					__('The %s message type is not active at the time of sending.', 'event_espresso'),
528
+					$message->message_type()
529
+				);
530
+			}
531
+			// if there was supposed to be a sending messenger for this message, but it was invalid/inactive,
532
+			// then it will instead be an EE_Error object, so let's check for that
533
+			if ($sending_messenger instanceof EE_Error) {
534
+				$error_messages[] = $sending_messenger->getMessage();
535
+			}
536
+			// if there are no errors, then let's process the message
537
+			if (empty($error_messages)) {
538
+				if ($save) {
539
+					$message->set_messenger_is_executing();
540
+				}
541
+				if ($this->_process_message($message, $sending_messenger)) {
542
+					$messages_sent++;
543
+				}
544
+			}
545
+			$this->_set_error_message($message, $error_messages);
546
+			//add modified time
547
+			$message->set_modified(time());
548
+			//we save each message after its processed to make sure its status persists in case PHP times-out or runs
549
+			//out of memory. @see https://events.codebasehq.com/projects/event-espresso/tickets/10281
550
+			if ($save) {
551
+				$message->save();
552
+			}
553
+
554
+			$this->_message_repository->next();
555
+		}
556
+		if ($save) {
557
+			$this->save(true);
558
+		}
559
+		return $messages_sent;
560
+	}
561
+
562
+
563
+	/**
564
+	 * _process_message
565
+	 *
566
+	 * @param EE_Message $message
567
+	 * @param mixed      $sending_messenger (optional)
568
+	 * @return bool
569
+	 */
570
+	protected function _process_message(EE_Message $message, $sending_messenger = null)
571
+	{
572
+		// these *should* have been validated in the execute() method above
573
+		$messenger    = $message->messenger_object();
574
+		$message_type = $message->message_type_object();
575
+		//do actions for sending messenger if it differs from generating messenger and swap values.
576
+		if (
577
+			$sending_messenger instanceof EE_messenger
578
+			&& $messenger instanceof EE_messenger
579
+			&& $sending_messenger->name != $messenger->name
580
+		) {
581
+			$messenger->do_secondary_messenger_hooks($sending_messenger->name);
582
+			$messenger = $sending_messenger;
583
+		}
584
+		// send using messenger, but double check objects
585
+		if ($messenger instanceof EE_messenger && $message_type instanceof EE_message_type) {
586
+			//set hook for message type (but only if not using another messenger to send).
587
+			if ( ! isset($this->_did_hook[$message_type->name])) {
588
+				$message_type->do_messenger_hooks($messenger);
589
+				$this->_did_hook[$message_type->name] = 1;
590
+			}
591
+			//if preview then use preview method
592
+			return $this->_message_repository->is_preview()
593
+				? $this->_do_preview($message, $messenger, $message_type, $this->_message_repository->is_test_send())
594
+				: $this->_do_send($message, $messenger, $message_type);
595
+		}
596
+		return false;
597
+	}
598
+
599
+
600
+	/**
601
+	 * The intention of this method is to count how many EE_Message objects
602
+	 * are in the queue with a given status.
603
+	 * Example usage:
604
+	 * After a caller calls the "EE_Message_Queue::execute()" method, the caller can check if there were any failed
605
+	 * sends by calling $queue->count_STS_in_queue( EEM_Message_Queue::status_failed ).
606
+	 *
607
+	 * @param array|string $status Stati to check for in queue
608
+	 * @return int  Count of EE_Message's matching the given status.
609
+	 */
610
+	public function count_STS_in_queue($status)
611
+	{
612
+		$count  = 0;
613
+		$status = is_array($status) ? $status : array($status);
614
+		$this->_message_repository->rewind();
615
+		foreach ($this->_message_repository as $message) {
616
+			if (in_array($message->STS_ID(), $status)) {
617
+				$count++;
618
+			}
619
+		}
620
+		return $count;
621
+	}
622
+
623
+
624
+	/**
625
+	 * Executes the get_preview method on the provided messenger.
626
+	 *
627
+	 * @param EE_Message      $message
628
+	 * @param EE_messenger    $messenger
629
+	 * @param EE_message_type $message_type
630
+	 * @param                 $test_send
631
+	 * @return bool   true means all went well, false means, not so much.
632
+	 */
633
+	protected function _do_preview(
634
+		EE_Message $message,
635
+		EE_messenger $messenger,
636
+		EE_message_type $message_type,
637
+		$test_send
638
+	) {
639
+		if ($preview = $messenger->get_preview($message, $message_type, $test_send)) {
640
+			if ( ! $test_send) {
641
+				$message->set_content($preview);
642
+			}
643
+			$message->set_STS_ID(EEM_Message::status_sent);
644
+			return true;
645
+		} else {
646
+			$message->set_STS_ID(EEM_Message::status_failed);
647
+			return false;
648
+		}
649
+	}
650
+
651
+
652
+	/**
653
+	 * Executes the send method on the provided messenger
654
+	 * EE_Messengers are expected to:
655
+	 * - return true if the send was successful.
656
+	 * - return false if the send was unsuccessful but can be tried again.
657
+	 * - throw an Exception if the send was unsuccessful and cannot be tried again.
658
+	 *
659
+	 * @param EE_Message      $message
660
+	 * @param EE_messenger    $messenger
661
+	 * @param EE_message_type $message_type
662
+	 * @return bool true means all went well, false means, not so much.
663
+	 */
664
+	protected function _do_send(EE_Message $message, EE_messenger $messenger, EE_message_type $message_type)
665
+	{
666
+		try {
667
+			if ($messenger->send_message($message, $message_type)) {
668
+				$message->set_STS_ID(EEM_Message::status_sent);
669
+				return true;
670
+			} else {
671
+				$message->set_STS_ID(EEM_Message::status_retry);
672
+				return false;
673
+			}
674
+		} catch (SendMessageException $e) {
675
+			$message->set_STS_ID(EEM_Message::status_failed);
676
+			$message->set_error_message($e->getMessage());
677
+			return false;
678
+		}
679
+	}
680
+
681
+
682
+	/**
683
+	 * This sets any necessary error messages on the message object and its status to failed.
684
+	 *
685
+	 * @param EE_Message $message
686
+	 * @param array      $error_messages the response from the messenger.
687
+	 */
688
+	protected function _set_error_message(EE_Message $message, $error_messages)
689
+	{
690
+		$error_messages = (array)$error_messages;
691
+		if (in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_failed_sending())) {
692
+			$notices          = EE_Error::has_notices();
693
+			$error_messages[] = __(
694
+				'Messenger and Message Type were valid and active, but the messenger send method failed.',
695
+				'event_espresso'
696
+			);
697
+			if ($notices === 1) {
698
+				$notices           = EE_Error::get_vanilla_notices();
699
+				$notices['errors'] = isset($notices['errors']) ? $notices['errors'] : array();
700
+				$error_messages[]  = implode("\n", $notices['errors']);
701
+			}
702
+		}
703
+		if (count($error_messages) > 0) {
704
+			$msg = __('Message was not executed successfully.', 'event_espresso');
705
+			$msg = $msg . "\n" . implode("\n", $error_messages);
706
+			$message->set_error_message($msg);
707
+		}
708
+	}
709 709
 
710 710
 } //end EE_Messages_Queue class
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 use \EventEspresso\core\exceptions\SendMessageException;
3 3
 
4
-if (! defined('EVENT_ESPRESSO_VERSION')) {
4
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
5 5
     exit('No direct script access allowed');
6 6
 }
7 7
 
@@ -175,7 +175,7 @@  discard block
 block discarded – undo
175 175
             'order_by' => $this->_get_priority_orderby(),
176 176
             'limit'    => $this->_batch_count,
177 177
         );
178
-        $messages   = EEM_Message::instance()->get_all($query_args);
178
+        $messages = EEM_Message::instance()->get_all($query_args);
179 179
 
180 180
         if ( ! $messages) {
181 181
             return false; //nothing to generate
@@ -286,7 +286,7 @@  discard block
 block discarded – undo
286 286
      */
287 287
     protected function _get_lock_key($type = EE_Messages_Queue::action_generating)
288 288
     {
289
-        return '_ee_lock_' . $type;
289
+        return '_ee_lock_'.$type;
290 290
     }
291 291
 
292 292
 
@@ -506,7 +506,7 @@  discard block
 block discarded – undo
506 506
             /** @type EE_Message $message */
507 507
             $message = $this->_message_repository->current();
508 508
             //only process things that are queued for sending
509
-            if (! in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_to_send())) {
509
+            if ( ! in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_to_send())) {
510 510
                 $this->_message_repository->next();
511 511
                 continue;
512 512
             }
@@ -516,13 +516,13 @@  discard block
 block discarded – undo
516 516
                 continue;
517 517
             }
518 518
             //error checking
519
-            if (! $message->valid_messenger()) {
519
+            if ( ! $message->valid_messenger()) {
520 520
                 $error_messages[] = sprintf(
521 521
                     __('The %s messenger is not active at time of sending.', 'event_espresso'),
522 522
                     $message->messenger()
523 523
                 );
524 524
             }
525
-            if (! $message->valid_message_type()) {
525
+            if ( ! $message->valid_message_type()) {
526 526
                 $error_messages[] = sprintf(
527 527
                     __('The %s message type is not active at the time of sending.', 'event_espresso'),
528 528
                     $message->message_type()
@@ -687,7 +687,7 @@  discard block
 block discarded – undo
687 687
      */
688 688
     protected function _set_error_message(EE_Message $message, $error_messages)
689 689
     {
690
-        $error_messages = (array)$error_messages;
690
+        $error_messages = (array) $error_messages;
691 691
         if (in_array($message->STS_ID(), EEM_Message::instance()->stati_indicating_failed_sending())) {
692 692
             $notices          = EE_Error::has_notices();
693 693
             $error_messages[] = __(
@@ -702,7 +702,7 @@  discard block
 block discarded – undo
702 702
         }
703 703
         if (count($error_messages) > 0) {
704 704
             $msg = __('Message was not executed successfully.', 'event_espresso');
705
-            $msg = $msg . "\n" . implode("\n", $error_messages);
705
+            $msg = $msg."\n".implode("\n", $error_messages);
706 706
             $message->set_error_message($msg);
707 707
         }
708 708
     }
Please login to merge, or discard this patch.